water tap
//水龙头接口typedef struct tap_protocol{uint8_t start; //协议头-0xa5uint8_t len; //数据长度-0x0b(不包括协议头和长度字节)uint8_t work_mode; //工作模式uint8_t wifi_state; //wifi状态uint8_t in_water_tds_h; //进水tds高8位uint8_t in_water_tds_l; //进水tds低8位uint8_t pure_water_tds; //纯水tdsuint8_t filter_life; //滤芯寿命状态uint8_t error; //故障uint8_t pbc_life_percent; //pbc滤芯寿命百分比uint8_t ro_life_percent; //ro滤芯寿命百分比uint8_t reverse_life_percent; //预留滤芯寿命百分比uint8_t checksum; //校验和}t_tap_protocol;typedef union tap_ptl_buf{t_tap_protocol tap_dat;uint8_t buf[13];}t_tap_ptl_buf;t_tap_ptl_buf tap;
perified
#define     pHIGHSW         RB6     //高压开关, 接通(启动)低电平, 断开(停止)高电平
#define     pWASTEVALVE     RB5     //废水阀, waste valve
#define     pINLETVALVE     RB4     //进水阀, inlet valve
#define     pBOOSTERPUMP    RB3     //增压泵, booster pump
//pHighPressSwitch
//p_SW_High
//p_VALVE_Waste
//p_Valve_Inlet
//p_Pump_Booster      
typedef enum{
    Standby = 0,    //待机
    Produce,        //制水
    Washing,        //冲洗
}e_work_mode;
uint8_t    gWorkMode;
//高压开关, 接通(启动)低电平, 断开(停止)高电平
//漏水检测, 正常高电平, 漏水低电平
void work_Proc()
{
    switch(gWorkMode)
        {
        case Standby:
            //进水阀关闭、废水阀关闭、增压泵关闭
            break;
        case Produce:
            //进水阀开启、废水阀关闭、增压泵开启
            break;
        case Washing:
            //进水阀开启、废水阀开启、增压泵开启
            break;
    }
}
isr
bit g_bRun250usFlag;
bit g_bRun1msFlag;
uint8_t g_u8Run1msCnt;
//全部中断入口
void interrupt isr()
{
    uint8_t Res1;
    //TMR2 125us中断
    if(TMR2IF)
    {
        TMR2IF = 0;
        g_bRun250usFlag = ~g_bRun250usFlag;
        if(g_bRun250usFlag)
        {
            if(++g_u8Run1msCnt >= 4)
            {
                g_u8Run1msCnt = 0;
                g_bRun1msFlag = 1;
            }
        }
        else
        {
            //串口发送数据
            if(TRMT1)        //发送数据寄存器空, 可以写入数据
            {
                if(wait_send_len > 0)
                {
                    TXREG1 = *tx_buf_ptr;
                    tx_buf_ptr++;
                    wait_send_len--;
                }
            }
            if(TRMT0)
            {
                //TXREG1 = 0xff;
            }
        }
    }
    else
    if(RC0IF)
    {
        if(FERR0)
        {
            //读RCREG0
            RCREG0;                            //帧错误
            return;
        }
    }
    else
    //串口1
    //-------------------------------------------
    //接收控制,如果接收标志位为1,说明有数据接收完毕
    //RCIF在寄存器被读出后自动清零
    if(RC1IF)   //读RCREG1清零
    {    
        #if 0
        if(FERR1)
        {
            RCREG1;                            //帧错误
            return;
        }
        Recebuffer[rececount] = RCREG1;      //将接收缓冲区内容读出
        rececount++;
        if(rececount >= 4)                    //接收完一帧数据,处理数据
        {
            rececount = 0;
        }
        if(OERR1)                            //如果有溢出错误
        {
            CREN1 = 0;                        //清零CREN位可将OERR位清零
            CREN1 = 1;                        //再次将CREN置一,以允许继续接收
        }
        #endif
//一帧24字节,9600波特率, 24*9*104=22464us=22ms, 接收一帧数据约要22ms
        Res1 = RCREG1;
        if(FERR1)  //帧错误
            return;
        #if 0
            uart_receive_input(Res1);
        #else
        //wifi
            if(1 == rx_buf_out - rx_buf_in) {
                //串口接收缓存已满
            }else if((rx_buf_in > rx_buf_out) && ((rx_buf_in - rx_buf_out) >= sizeof(wifi_uart_rx_buf))) {
                //串口接收缓存已满
            }else {
                //串口接收缓存未满
                if(rx_buf_in >= (unsigned char *)(wifi_uart_rx_buf + sizeof(wifi_uart_rx_buf))) {
                    rx_buf_in = (unsigned char *)(wifi_uart_rx_buf);
                }
                *rx_buf_in ++ = Res1;
            }
        #endif
    }
    else
    {
        //清除所有中断请求标志
        PIR1 = 0;       //外设中断请求寄存器1
        PIR2 = 0;       //外设中断请求寄存器2
    }
}
public
#ifndef __PUBLIC_H
#define __PUBLIC_H
//===============================================================================
//            Unit                    : 广东贝磁电子科技有限公司研发部软件组    |
//            Product Type            : 净水器                                    |
//            Customer & Model        : 碧信(RO-800G-WIFI)                        |
//          MCU                       : CMS79FT7381 - SOP28                          |
//          Volt                      : 5V                                        |
//          Oscillator                : 16MHz                                     |
//          Watchdog                  : Enable                                    |
//          Reset                     :                                           |
//          Description               :                                           |
//          Author                    : 陶茂亮                                       |
//            Version Info            : V1.0.0-20220610 create                    |
//          Program Language        : C                                         |
//-----------------------------------Oooo---------------------------------------+
/*
引脚定义:
//重定义为15-28pin
    01. AN3/RA3         --  DISP_DA     显示通信DAT
    02. AN4/RA4         --  DISP_CK     显示通信CLK
    03. AN5/RA5         --  BUZ
    04. AN6/RA6         --  MOTOR_PHASE_D
    05. AN7/RA7         --  MOTOR_PHASE_C
    06. AN8/RB0         --  MOTOR_PHASE_B
    07. AN9/RB1         --  MOTOR_PHASE_A
    08. AN10/RB2        --  
    09. RX1/AN11/RB3    --  BOOST_PUMP          增压泵
    10. TX1/AN12/RB4    --  INLET_VALVE         进水阀
    11. AN13/RB5        --  WASTE_VALVE         废水阀
    12. AN14/RB6        --  HIGH_PRESS_SWITCH   高压开关
    13. GND             --
    14. VDD             -- 
//重定义为1-14pin    
    15. AN16/RD2        --  
    16. ICSPDAT/TX0/SCL/AN24/RD1    --  TAP_TX   水龙头通信TX
    17. ICSPCLK/RX0/SDA/AN25/RD0    --  TAP_RX   水龙头通信RX
    18. TX1/SDA/AN16/RC7            --  WIFI_TX
    19. RX1/SCL/AN17/RC6            --  WIFI_RX
    20. AN18/RC5        --  TDS_PURE_OUT1
    21. AN19/RC4        --  TDS_PURE_AD     纯水
    22. AN20/RC3        --  TDS_PURE_OUT2
    23. AN21/RC2        --  TDS_RAW_OUT1
    24. AN22/RC1        --  TDS_RAW_AD      原水
    25. AN23/RC0        --  TDS_RAW_OUT2
    26. AN0/RA0         --
    27. AN1/RA1         --  LEAKING 漏水
    28. AN2/RA2         --  NTC     温度
*/
#define     DEV_produce_water_module    //制水
#define     DEV_wifi                    //wifi
#define     DEV_water_cap               //水龙头
#define     DEV_display_board           //显示板
#define     DEV_buzzer                  //蜂鸣器
#define     DEV_tds_module              //tds
#define     DEV_leaking                 //漏水
#define     DEV_filter_life             //滤芯寿命
//工作模式
typedef enum{
    standby = 0,    //待机
    produce_water,  //制水
    wash,           //冲洗
}purifier_mode_e;
//设备状态
typedef struct{
    uint8_t switch_highpress : 1;    //高压开关(High pressure switch)
    uint8_t pump_boost  : 1;    //增压泵
    uint8_t valve_inlet : 1;    //进水阀
    uint8_t valve_waste : 1;    //废水阀(waste water)
    uint8_t leaking     : 1;    //漏水
    uint8_t : 3;
}dev_status_t;
typedef struct{  
    uint8_t  temperature;   //用于计算TDS值
    uint16_t tds_inlet;     //进水TDS
    uint16_t tds_pure;      //纯水TDS
}tds_value_t;
//沸水流量控制器
typedef struct{
    //步进电机控制值
}waste_flow_regulator_t;
//滤芯寿命
typedef struct{
    uint16_t produce_hour;      //制水时间(小时)
    uint16_t produce_hour_cnt;  //制水时间计时
    uint16_t poweron_hour;      //通电时间(小时)
    uint16_t poweron_hour_cnt;  //通电时间计时
}filter_ele_life_t;
//滤芯
typedef struct{
    filter_ele_life_t PBC_Filter;   //PBC复合滤芯寿命
    filter_ele_life_t RO_Filter;    //RO复合滤芯寿命
}filter_ele_t;
typedef struct{
    uint8_t status;
}wifi_status_t;
typedef struct{
    purifier_mode_e   sys_mode;     //工作模式
    dev_status_t dev_st;            //设备工作状态
    tds_value_t  tds;               //tds值
    waste_flow_regulator_t rgl;
    filter_ele_t filter;
}purifier_status_t;     //净水器状态结构体
/*
    1. 高压开关
    2. 步进电机-废水比调节
    3. 漏水检测
    4. 水龙头(智能、灯环), 串口通信
    5. 进水阀、废水阀
    6. 增压泵
    7. 蜂鸣器
    8. wifi, 串口通信
    9. 纯水TDS、进水TDS
    10、温度NTC
    11. 灯板, 自定义通信协议
    按功能对象划分
    > 制水、冲洗操作
        > 高压开关、步进电机、进水阀、废水阀、增压泵
    > 外部通信(指示、输入) - 操作显示
        > wifi、水龙头、灯板
        > 蜂鸣器
    > TDS检测
        > 纯水TDS、进水TDS
        > 温度NTC
    > 故障
        > 漏水检测
*/
//#define EN_FILTER_LIFE_PRODUCE_WATER   //使能计算滤芯制水时间寿命
typedef struct{
#ifdef EN_FILTER_LIFE_PRODUCE_WATER
    uint16_t    min_prdt_wtr;   //制水时间(分钟)
    uint8_t     sec_prdt_wtr;   //制水时间(秒)
#endif
    uint16_t    hour_power;     //通电时间(小时)
    uint16_t    hcnt_power;     //通电时间(计数至小时)
}filter_life_t;    //滤芯寿命
//tds_life_t  PBC_filter;
//tds_life_t  RO_filter;
//优先存储通电小时、制水分钟这些紧急的, 
//这样即便后面的没有保存成功也能将寿命计时的影响降到最低
#define     EEP_DATA_START_1            0xa5
#define     EEP_DATA_START_2            0x5a
#define     EEP_ADDR_START_1            0
#define     EEP_ADDR_START_2            1
//PBC膜寿命记忆地址
#define     EEP_ADDR_PBC_MIN_PROD_L     2
#define     EEP_ADDR_PBC_MIN_PROD_H     3
#define     EEP_ADDR_PBC_SEC_PROD       4
#define     EEP_ADDR_PBC_HOUR_PWR_L     5
#define     EEP_ADDR_PBC_HOUR_PWR_H     6
#define     EEP_ADDR_PBC_HOURC_PWR_L    7
#define     EEP_ADDR_PBC_HOURC_PWR_H    8
//RO膜寿命记忆地址
#define     EEP_ADDR_RO_MIN_PROD_L      9
#define     EEP_ADDR_RO_MIN_PROD_H      10
#define     EEP_ADDR_RO_SEC_PROD        11
#define     EEP_ADDR_RO_HOUR_PWR_L      12
#define     EEP_ADDR_RO_HOUR_PWR_H      13
#define     EEP_ADDR_RO_HCNT_PWR_L      14
#define     EEP_ADDR_RO_HCNT_PWR_H      15
//校验
#define     EEP_ADDR_CRC_DATA           16
#endif
main
#include "public.h"
#include "./JWBR2S_sdk/wifi.h"
void app_init()
{
    //wifi模块初始化
    wifi_protocol_init();
}
/**********************************************************
函数名称: System_Init()
函数功能: 系统初始化
入口参数: 无
出口参数: 无 
**********************************************************/
void System_Init()
{
    clrwdt();
    dgi();
    mcu_init();
    drive_rigister();
    app_init();
    egi();
}
/**********************************************************
函数名称: main
函数功能: 主函数
入口参数: 无
出口参数: 无 
**********************************************************/
void main()
{
    #if 1
    /******************************************************************/
    asm("clrwdt");
    Init_ic();
    Delay_nms(200);                                                    //上电延时200ms
    Init_ram();                                                        //上电给初值
    #endif
    System_Init();
    while(1)
    {
        clrwdt();   //每次进入循环都将清看门狗
        //wifi服务程序
        wifi_uart_service();
    }
}
mcu
#include "cms79f7xx_mcu.h"
#define     T2_CTL_SET  0x0c
#define     T2_COUNT    250
/***********************************************************************
函数功能:串口1初始化
入口参数:
返回数据:
备注:
***********************************************************************/
void uart1_init()
{
    #if 0
        SPBRG1 = 102;            //设置波特率为9600 bps,误差0.16%    
        SYNC1 = 0;                //0为异步模式,1为同步模式
        SCKP1 = 0;
        SPEN1 = 1;                //允许串口操作
        RC1IE = 1;                //接收中断  
        TX1IE = 0;                //发送中断
        RX9EN1 = 0;                //0为8位接收,1为9位接收
        TX9EN1 = 0;                //0为8位发送,1为9位发送
        CREN1 = 1;                //0为禁止接收,1为使能接收
        TXEN1 = 1;                //0为禁止发送,1为使能发送
    #else
        //异步模式, 数据不取反, 8bit数据发送, 发送使能
        TXSTA1 = 0b00100000;
        //使能串口, 8bit数据接收, 接收使能
        RCSTA1 = 0b10011000;
        //波特率9600
        SPBRG1 = 103;
        //使能接收中断, 除能发送中断
        RC1IE = 1;                //接收中断  
        TX1IE = 0;                //发送中断
    #endif
}
/***********************************************************************
函数功能:串口0初始化
入口参数:
返回数据:
备注:
***********************************************************************/
void uart0_init()
{
    #if 0
        SPBRG0 = 102;
        SYNC0 = 0;  //异步
        SCKP0 = 0;  //数据是否取反后到达接收缓冲区
        SPEN0 = 1;  //使能串口
        RC0IE = 1;  //接收中断
        TX0IE = 0;  //发送中断
        RX9EN0 = 0;
        TX9EN0 = 0;
        CREN0 = 1;
        TXEN0 = 1;
    #else
        //TX9EN0=0, TXEN0=1, SYNC0=0, SCKP0=0
        //异步模式, 数据不取反, 8bit数据发送, 发送使能
        TXSTA0 = 0b00100000;
        //SPEN0=1, RX9EN0=0, CREN0=1
        //使能串口, 8bit数据接收, 接收使能
        RCSTA0 = 0b10011000;
        SPBRG0 = 103;   //波特率9600
        //使能接收中断,除能发送中断
        RC0IE = 1;
        TX0IE = 0;
    #endif
}
/***********************************************************************
函数功能: 芯片初始化
入口参数:
返回数据:
备注:
***********************************************************************/
void mcu_init()
{
    nop();
    clrwdt();
    //禁止中断
    INTCON = 0x00;
    PIR1 = 0;
    PIR2 = 0;
    PIE1 = 0;
    PIE2 = 0;
    //设置系统时钟
    OPTION_REG = 0;     //预分频器分配给 TIMER0 模块
    OSCCON = 0x71;      //振荡器控制, Fsys=Fosc/1=16MHz
    //看门狗
    WDTCON = 0x01;      //使能定时器, 18ms
    clrwdt();
    //GPIO
    PORTA = 0x00;
    PORTB = 0x00;
    PORTC = 0x00;
    PORTD = 0x00;
    TRISA = 0x00;
    TRISB = 0x00;
    TRISC = 0x00;
    TRISD = 0x00;
    WPUA  = 0x00;
    WPUB  = 0x00;
    WPUC  = 0x00;
    WPUD  = 0x00;
    IOCB  = 0x00;
    //ADC
    ADCON0 = 0x01;  //使能ADC
    ADCON1 = 0x00;  //数据左对齐, 12bit
    ADIE   = 0;
    //timer2
    TMR2   = 0;
    T2CON  = T2_CTL_SET;    //使能TMR2, 预分频1:1, 后分频1:2
    PR2    = T2_COUNT;      //125us
    TMR2IE = 1;     //使能TMR2中断
    //水龙头tap - 串口0
    uart0_init();
    //wifi - 串口1
    uart1_init();
    PEIE  = 1;  //使能所有外设中断
}
void mcu_refrush(void)
{
    asm("clrwdt");
    WDTCON = 0x01;
    OPTION_REG = 0;
    PR2 = T2_COUNT;
    if(T2_CTL_SET != T2CON)
        T2CON = T2_CTL_SET;
//    INTCON = 0XC0;
}
#ifdef USE_ADC_MD
//ADC时钟
    enum e_AD_FOSC{
        FOSC_8  = 0,
        FOSC_16 = 1,
        FOSC_32 = 2,
        FOSC_RC = 3
    };
    enum e_AN_SEL{
        AD_AN0 = 0,
        AD_AN1 = 1,
        AD_AN2 = 2,
        AD_AN3 = 3,
        AD_AN4 = 4,
        AD_AN5 = 5,
        AD_AN6 = 6,
        AD_AN7 = 7,
        AD_AN8 = 8,
        AD_AN9 = 9,
        AD_AN10 = 10,
        AD_AN11 = 11,
        AD_AN12 = 12,
        AD_AN13 = 13,
        AD_AN14 = 14,
        AD_AN15 = 15,
        AD_AN16 = 16,
        AD_AN17 = 17,
        AD_AN18 = 18,
        AD_AN19 = 19,
        AD_AN20 = 20,
        AD_AN21 = 21,
        AD_AN22 = 22,
        AD_AN23 = 23,
        AD_AN24 = 24,
        AD_AN25 = 25,
        AD_AN_1V2 = 26, //1.2V固定参考看呀
    };
    //ADC使能
    enum e_ADEN{
        AD_DIS  = 0,
        AD_EN   = 1,
    };
    //ADC中断
//    #define     ADC_INT_EN()        (ADIE=1)
//    #define     ADC_INT_DIS()       (ADIE=0)
//    #define     CLR_ADC_INT_FLAG()  (ADIF=0)
    //ADC结果
    #define     AD_12BIT_DAT()      
    #define     AD_8BIT_DAT()       (uchar)(ADRESH)
//作为ADC结果临时存储区
uint16_t AD_DATA;
/**********************************************************
函数名称: adc_Convert()
函数功能: 开始ADC转换
入口参数: frq-ADC时钟, ch-转换通道
出口参数: 无 
备    注: Analog-to-digital conversion
**********************************************************/
uint8_t adc_Convert(unsigned char frq, unsigned char ch)
{
    uint16_t wt;
    ADCON0 = (frq<<6) | (ch&0x07 << 2) | (AD_EN<<0);
    if(ch & 0x08)
        ADCON1 |= (1<<6);
    wt = 0;
    clrwdt();
    nop(); nop();
    GODONE = 1;
    while(GODONE)
    {
        nop();
        if((++wt) >= 0x0fff)
            return 0;
    }
    AD_DATA = (uint16_t)((ADRESH + ADRESL)>>4);
    return 1;
}
#endif
/***********************************************
函数名称: eeprom_Write
函数功能:写数据寄存器
入口参数:Addr - 写入地址
          Value - 写入数值
出口参数:返回值 0 - 写未准备好 1 - 写完毕
备注:
************************************************/
unsigned char eeprom_Write(unsigned char Addr,unsigned char Value)
{
    static volatile bit B_GIE_On;
    static volatile unsigned char i = 0;
    if(WR)                                    //写还没有结束直接返回
        return 0;
    B_GIE_On = 0;                            //记录进来前是否已经开启中断
    if(GIE)
        B_GIE_On = 1;
    //将要写入的地址放入EEADDR寄存器
    EEADR = Addr;
    EEDAT= Value;                           //将要写入的数据给EEPROM的数据寄存器
    EEPGD = 0;                                //访问数据存储器
    WREN = 1;                                //允许写周期
    GIE = 0;                                //关闭中断
    while(GIE)
    {
        GIE = 0;                            //确保中断已关闭
        if(0 == --i)
            return 0;
    }
    EECON2 = 0x55;                            //给EECON2写入0x55
    EECON2 = 0xaa;                            //给EECON2写入0xaa
    WR = 1;                                    //启动写周期
    asm("nop");
    asm("nop");
    if(B_GIE_On)                            //若原来已开启中断的就开启中断    
        GIE = 1;                                                    
    WREN = 0;                                //禁止写入
    return 1;
}
/***********************************************
函数名称: eeprom_Read
函数功能:读数据寄存器
入口参数:Addr - 读取地址
出口参数:返回读取地址相应数值
备注:
************************************************/
unsigned char eeprom_Read(unsigned char Addr)
{            
    //将要写入的地址放入EEADDR寄存器
    EEADR = Addr;
    EEPGD = 0;                            //访问数据存储器
    RD=1;                                //允许读操作
    asm("nop");
    asm("nop");
    return EEDAT;
}
                    