hejun96 发表于 2019-11-30 20:47:43

STM8S控制的水龙头业务代码问题中的互斥标志位执行同一功能

   首先这是一段由水龙头控制的程序,主控板通过串口上报数据给ht1621b驱动的显示屏,显示屏只有收到串口的数据后会根据串口显示不同的图标,有问题的程序附在下面,首先在开机后,显示屏上面附带有一个触摸IC按键,显示屏上面的图标轮流闪烁(此过程是水龙头排气过程),直到按键长按10s退出排气,退出排气后可以一档二档出水由STM8S控制增压泵IO口输出(一档为PWM控制的半压输出,二档为全压输出)。在增压泵xmin 后无工作(x表示分钟数)进入自动冲洗状态,这个状态是增压泵可以为一档出水的方式工作清洗水箱中的水,退出的条件有两个:一个是缺水,一个是水泵空转5s,现在缺水时时可以退出的,但是水泵空转5s是通过AD电流采集数据,但是水泵空转5s和缺水退出的条件不一样,而且SystemStatus.work_mode (工作模式:一档和二档出水)和SystemStatus.auto_clean(自清洗模式标志位)是互斥的关系,SystemStatus.zyb_mode(增压泵是PWM半压输出还是全压输出)属于SystemStatus.work_mode的一个子集,要让这两个条件都执行不知道怎么做,但是执行的功能是类似的,有问题的代码都写在下面了,就是不知道该怎么解?


/* 主控板状态信息 */
typedef struct waterbox_info
{
uint8_t tds;
uint16_t temperature;
uint8_t out;//出水
uint8_t fullwater;
uint8_t makewater;
uint8_t uv;
uint8_t work_mode;
uint8_t auto_clean;
uint8_t err_code;   /*错误码:漏水*/
uint8_t crc_code;
uint8_t outair;//自排气
uint8_t isEmpty;      //水箱无水
uint8_t zyb;
uint8_t liquid_level; //liquid level protect
uint8_t leakwater;/*漏水*/
uint8_t jump_outair;//跳过排气
uint8_t zyb_mode;
}System_t;

/* 结构体 */
System_t SystemStatus = {0};

uint16_t Current_Aver_Buf={0};//增压泵平均值缓存区长度
uint16_t temp = 0;
uint16_t temp1 = 0;

#define ZYB_BUF_LEN    20
uint16_t get_current_average_value(uint16_t *buf,uint16_t val)
{
    volatile uint16_t sum = 0,temp = 0;
    volatile uint16_t average = 0;
      
    int i = 0;
    for (i = 0; i < ZYB_BUF_LEN - 1; ++i)
    {
      buf = buf;
    }
    buf = val;

    for (i = 0; i < ZYB_BUF_LEN; ++i)
    {
      sum += buf;
    }
    average = sum / ZYB_BUF_LEN;

    return average;
}
/*
*@function:zyb_current_check(void)
*@brief:电流检测
*@param:None
*@retval:None
*/
void zyb_current_check(void)
{
   
    if(SystemStatus.zyb_mode != 0x00 || (SystemStatus.auto_clean))//2个条件:1:工作模式为1档或者二档出水 2:自清洗模式
    {
      if (TIMER_STOP == current_timer.timer_run_flag)
      {
            /* code */
            current_timer.cnt = 0;
            current_timer.timer_run_flag = TIMER_RUN;
      }
      else if (TIMER_END == current_timer.timer_run_flag)
      {
            current_timer.timer_run_flag = TIMER_STOP;

            temp = Get_ADC_Convertion(ZYB_CURRENT);//ADC通道转换
            temp1 = get_current_average_value(Current_Aver_Buf,temp);//电流平均值
      }
      /*增压泵空转检测,增压泵空转时间超过5s停止工作*/
      if(zyb_timer.cnt >= 5000)
      {            
            if((SystemStatus.zyb_mode == 0x01) && (temp1 < 10))//50水泵一档出水PWM占空比为50%
            {
                zyb_timer.timer_run_flag = TIMER_STOP;
               
                FSF_F2_OFF;
                JSF_F1_OFF;
                PSF_F3_OFF;
               
                Close_ZYB();
               
                SystemStatus.out = 0;
                SystemStatus.work_mode = 0;//0x00:停止出水
                SystemStatus.zyb = 0;
               
               
                /*主控板部分如果增压泵空转5s则退出自清洗模式*/
               
                if(SystemStatus.auto_clean)
                {
                  SystemStatus.auto_clean = 0x00;
                }
            }
            else if((SystemStatus.zyb_mode == 0x02)&&(temp1 < 30))//100 水泵二档出水PWM占空比为100%,即全压输出
            {
                zyb_timer.timer_run_flag = TIMER_STOP;
               
                FSF_F2_OFF;
                JSF_F1_OFF;
                PSF_F3_OFF;

                Close_ZYB();
               
                SystemStatus.out = 0;
                SystemStatus.work_mode = 0;
                SystemStatus.zyb = 0;
               
                /*主控板部分如果增压泵空转5s则退出自清洗模式,自清洗是二档出水*/
                if(SystemStatus.auto_clean)
                {
                  SystemStatus.auto_clean = 0x00;
                }
               
            }
      }      
    }   
}



/**
*函数:Auto_Clean_proc
*功能:自清洗进程,48小时如果没有任何操作,开始自清洗,按键无效
*参数:无
*返回值:无
*/

void Auto_Clean_proc(void)
{   
    if(Auto_clean_timer.min >= 10)   //48小时自清洗,Auto_clean_timer.hour >= 48 改时间为30min
    {   
      SystemStatus.auto_clean = AUTO_CLEAN_STATUS;//自清洗为二档出水
      
      
      
      
      
    }      
    if(SystemStatus.auto_clean && SystemStatus.outair)//自清洗中且不为自排气
    {
      static uint8_t old_status = 0;
      
      if(SystemStatus.auto_clean && old_status != SystemStatus.auto_clean)   //48小时自清洗
      {      
            PSF_F3_ON;//排水阀-F3打开

            JSF_F1_OFF; //进水阀-F1关闭

            FSF_F2_OFF; //放水阀-F2关闭

            ///Open_two_mode();   //水泵二档出水
            Open_one_mode();//测试用一档出水
         

      }
      SystemStatus.fullwater= 0x00;
      SystemStatus.makewater= 0x00;
      SystemStatus.work_mode= 0x00;
      old_status = SystemStatus.auto_clean;
      

      
    }
    if(TIMER_STOP == Auto_clean_timer.timer_run_flag)
    {
      Auto_clean_timer.timer_run_flag = TIMER_RUN;
    }
    if(SystemStatus.out || !SystemStatus.outair || SystemStatus.auto_clean)
    {
    //SystemStatus.auto_clean =0x00;
      Auto_clean_timer.hour = 0 ;
      Auto_clean_timer.min= 0 ;
      Auto_clean_timer.sec= 0 ;
      Auto_clean_timer.cnt= 0 ;
    }
   
   
}



/**
*函数:HeartBeat_Send
*功能:
*参数:无
*返回值:无
*/
void HeartBeat_Send(void)
{

    if(TIMER_STOP == HeartBeat_timer.timer_run_flag)
    {
      HeartBeat_timer.timer_run_flag = TIMER_RUN;
      HeartBeat_timer.cnt = 1000;       //1s
      
      if(TIMER_RUN == HeartBeat_timer.timer_run_flag)
      {
            uint8_t buf = "AA55";//
            uint8_t crc_code = 0;
            uint8_t i=0;
            
            buf = (SystemStatus.tds / 16) ;       //tds
            buf = (buf >= 0 &&buf<=9)?buf+'0':buf+0x37;
            buf = (SystemStatus.tds % 16) ;
            buf = (buf >= 0 &&buf<=9)?buf+'0':buf+0x37;
   
            buf = SystemStatus.out ? '1': '0';      //出水   
            buf = SystemStatus.fullwater&0x40? '1':'0';       //0x40缺水
            buf = SystemStatus.fullwater&0x20? '1':'0';      //0x20补水
            buf = SystemStatus.makewater ? '1': '0';         //制水模式
            buf = SystemStatus.uv ? '1': '0';               //uv         
            buf = SystemStatus.work_mode & 0x04 ? '1':'0';//水泵工作模式:二档出水
            buf = SystemStatus.work_mode & 0x02 ? '1':'0';//水泵工作模式:一档出水      
            buf = SystemStatus.auto_clean ? '1': '0'; //
            
            //buf = 0;          //Ô¤Áôλ
            //buf = 0;
            buf = SystemStatus.liquid_level ? '1': '0';
            buf = !SystemStatus.outair ? '1': '0';
            buf = SystemStatus.err_code ? '1': '0'; //错误码
            
                  
            for(i=0;i<=16;i++)
            {
                crc_code += buf;
            }
            buf = (crc_code / 16);
            buf = (buf >= 0 &&buf<=9)?buf+'0':buf+0x37;
            buf = (crc_code % 16);
            buf = (buf >= 0 &&buf<=9)?buf+'0':buf+0x37;
            buf = '\r';
            buf = '\n';

            //UART1_SendString(buf);
            for(i=0;i<=20;i++)
            {
                while((UART1->SR & UART1_FLAG_TXE)==RESET);
                UART1->DR = buf;
                while((UART1->SR & UART1_FLAG_TC)==RESET);
            }
      }
    }
}





butterflyspring 发表于 2019-12-10 16:41:23

可以将工作模式设置成一个变量1,2,3,4,5等代表不同的模式。达到必要条件时就修改成哪个模式

hejun96 发表于 2020-1-26 20:20:28

butterflyspring 发表于 2019-12-10 16:41
可以将工作模式设置成一个变量1,2,3,4,5等代表不同的模式。达到必要条件时就修改成哪个模式 ...

是写成消息任务切换对吧
页: [1]
查看完整版本: STM8S控制的水龙头业务代码问题中的互斥标志位执行同一功能