你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

净化器的滤网计时编程

[复制链接]
kimding 提问时间:2019-8-22 21:26 /
本人在做项目相关的计时功能,使用STM8控制,要求如下:
1.滤网1000小时
2.单次使用200小时进行处理,按下计时复位按键,循环利用
3.循环5此次,不足200小时按下复位按键算1次
使用DS1302时钟芯片,还要考虑掉电等突发情况如何保存数据,我现在没一点思路,求教大佬详细解答(流程+重点)

收藏 评论7 发布时间:2019-8-22 21:26

举报

7个回答
hejun96 回答时间:2019-8-25 15:38:30
//这位坛友你好,最近,我用STM32F103做过一个和你的描述很类似的一个智能饮水机
//的项目,由于本人现在的水平很低,不一定能够给予太多的帮助,请见谅,我就尽我所能
//来描述一下,当然借这个机会回顾一下自己做的项目,写的不好请多指教
//1>滤网1000小时:
//                1、定时器(Timer1),滤网计时标志位,滤网打开标志位,标志位均在结构体中定义
//2>单次使用200小时进行处理,按下计时复位按键,循环利用
//                1、定时器(Timer1),启动枚举中的定时器复位,代码框架下方给出。循环,那么就让
//                这段函数中一个while(1);
//3>循环5此次,不足200小时按下复位按键算1次
//  使用DS1302时钟芯片,还要考虑掉电等突发情况如何保存数据
//                1.循环5次,那么让定时器动作5次,if(Tick < 200*60*60*1000) 进入此循环后,
//                此处没有明白您说的不足200h 按下复位按键?这个是我们人为按下还是定时器
//                计时自动触发定时器按下?
//                2、掉电保存:把数据通过I2C上传给上位机




struct system_state//净化器
{
        purifier_strainer_timer_flag:2,/*净化器滤网计时打开标志位, 0:turn off 1:turn on*/
        purifier_strainer_tick,/*净化器滤网计时定时器*/
        
};
external volatile system_state SystemState;

enum tick_state//枚举定时器的状态,可以放在stm32f103_timer.h中定义,也就是对应的封装库
{
        TIMER_RESET = 0,//定时器复位
        TIMER_RUN,//定时器运行
        TIMER_PAUSE,//定时器暂停
        
};
external volatile tick_state TickState;


void SignleUse()//单次使用滤网
{
        if(purifier_strainer_tick < 200*60*60*1000)//定时器的延时一般为ms,此处只是拿其中一个标志位做例子,还需要您添加下系统延时的那个函数delay_ms
        {
                //此处填您要处理的东西,不足200h,按下计时复位按键?按键是手动按下?这里不太清楚
               
        }
        while(1);//在次函数中循环
}


void PurifierWork()//净化器工作
{
        SignleUse();
        

}





评分

参与人数 1蝴蝶豆 +3 收起 理由
STMCU + 3

查看全部评分

butterflyspring 回答时间:2019-8-23 14:37:21
是否可以考虑这样:1.保证你的板子失去市电后, 芯片电路还有100ms以上的掉电时间(考虑到最大操作时刻)。2. 在检测到失去市电后(大约10到20ms),立即保存数据到EEPROM中去(保存一个word大约5~8ms,外部EEPROM更快一点 )3. 计时精度允许时,每一小时主动保存一次数据(最好分布保存在不同地址中)4. 外加复位芯片。

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

kimding 回答时间:2019-8-30 16:07:42
butterflyspring 发表于 2019-8-23 14:37
是否可以考虑这样:1.保证你的板子失去市电后, 芯片电路还有100ms以上的掉电时间(考虑到最大操作时刻)。 ...

感谢版主,我会考虑的
kimding 回答时间:2019-8-30 16:21:26
hejun96 发表于 2019-8-25 15:38
//这位坛友你好,最近,我用STM32F103做过一个和你的描述很类似的一个智能饮水机
//的项目,由于本人现在的 ...

是我没说清楚,单次使用不是200h吗,你在200h内按下复位键,计时就会重新开始,比如说滤网可使用总时长为1000h,每使用200h,就需要处理一下,处理好后人为按下复位键,就会重新进行计时(指单次计时200h),当你使用了200小时,那你就要处理并按下复位按键,才重新计时;当你在使用100h就按下了复位键,那么你的使用次数就会减一,重新开始200h的倒计时
kimding 回答时间:2019-8-30 16:22:57
kimding 发表于 2019-8-30 16:21
是我没说清楚,单次使用不是200h吗,你在200h内按下复位键,计时就会重新开始,比如说滤网可使用总时长为 ...

不过没说使用5次,应该给出怎样的提示,提醒用户,你需要更换而不是处理滤网了
hejun96 回答时间:2019-8-30 19:03:03
kimding 发表于 2019-8-30 16:21
是我没说清楚,单次使用不是200h吗,你在200h内按下复位键,计时就会重新开始,比如说滤网可使用总时长为 ...

那就没错了,用定时器的复位。我上面写了一点代码,就是在枚举体里面先定义标志位还有嘀嗒定时器标志位,通过标志位判断if( 定时器的标志位 > 你需要的计时时间)
截取io.c程序
有关掉电保存数据的部分代码在下面,用的是IIC
typedef union{
        u8 save_data[4];/*保存在AT24C02的一些数据*/
        struct{
                u8    self_clean_flag;/*保存掉电前的自清洗完成状态;0:完成 1:未完成,待继续*/
//                u8    Self_Drain_Flag;//保存掉电前自排水完成状态;0:完成 1:未完成,待继续
                u8    machine_type;/*机器型号;有4款Y400\DY100A\DY400B\DY75*/  
                u16   short_current;/*缺水电流 0--4000ma范围*/
                u8    software_version[12];/*软件版本号*/
        }s;
}SAVE_DATA_UNION;
extern volatile SAVE_DATA_UNION Save_Data;



static u8    identifier[4];/*识别码 固定为AA55*/
/*系统状态初始化*/
void System_State_int(void)
{
    u8 i=0,temp[]="A22500000000",ident_temp[4]={'A','A','6','7'};
        System_Sta.s.ice_tube_on_cmd = 2;
        System_Sta.s.hot_tube1_on_cmd = 2;
        System_Sta.s.hot_tube2_on_cmd = 2;
        System_Sta.s.water_in_cmd = FLAG_ON;
        System_Data.fixed_state[3] = 'F';
        System_Data.fixed_state[4] = '0';
        System_Data.fixed_state[7] = 'F';
        System_Sta.s.rfid_balance_flag = 2;
        Child_Key_On_Flag = 0;//童锁键打开标志位

               
        System_Data.flash_water_flag[0]='0';
        System_Data.flash_water_flag[1]='0';

    System_Sta.s.hot_close_flag = 0;//
        System_Sta.s.drain_close_flag = 0;//关闭排水标志位
        
        i2cRead1(AT24C02_ADDR,AT24C02_REG,sizeof(SAVE_DATA_UNION),(u8*)&Save_Data);
        i2cRead1(AT24C02_ADDR,AT24C02_REG_INDENTIFIER,sizeof(identifier),(u8*)&identifier);
        
        // 增加读取上次开机前的温度
        u8 temperatue[2] = {0};
        i2cRead1(AT24C02_ADDR,AT24C02_REG_TEM,sizeof(temperatue),(u8*)&temperatue);
        if (temperatue[0] >= 40 && temperatue[0] <= 100)
        {
                System_Data.ntc1_setting_temperature = temperatue[0];
        }
    else System_Data.ntc1_setting_temperature = 100;
        if (temperatue[1] >= 40 && temperatue[1] <= 100)
        {
                System_Data.ntc2_setting_temperature = temperatue[1];
        }
    else System_Data.ntc2_setting_temperature = 100;
               
               
                /*读取上次断电前的自排水状态*/
        if(Save_Data.s.self_clean_flag==1)/*表明上次断电自排水未完成*/
        {
                System_Sta.s.clean_self_cmd = FLAG_ON;/*开启自排水命令*/
    }
        
    // add rtc time check
    else if (calendar.w_year != 1992 || \
        calendar.w_month != 10)
    {
        System_Sta.s.clean_self_cmd = FLAG_ON;/*开启自排水命令*/
            u8 tt = RTC_Set(1992,10,25,0,0,0);  //设置时间
    }
    else if(calendar.w_date * 24 - 25 * 24 + calendar.hour >= CL_TIME0/3600/1000)
    {
        System_Sta.s.clean_self_cmd = FLAG_ON;/*开启自排水命令*/
                          u8 tt = RTC_Set(1992,10,25,0,0,0);  //设置时间
    }
    else
    {
        System_Sta.s.clean_self_cmd = FLAG_OFF;/*关闭自排水命令*/
                          u8 tt = RTC_Set(1992,10,25,0,0,0);  //设置时间
    }
                #if 0
                if (calendar.min > 1)
                {
                                System_Sta.s.clean_self_cmd = FLAG_ON;/*开启自清洗命令*/
                }
                #endif

        /*读取机器型号*/
        if(Save_Data.s.machine_type>0&&Save_Data.s.machine_type<DY_NR)
        {
                Machine_Type = Save_Data.s.machine_type;
        }
        else
        {
                Machine_Type = DY_100A;
                Save_Data.s.machine_type=DY_100A;
    }
        
    // Machine_Type = DY_100B;
    // Save_Data.s.machine_type=DY_100B;
        /*读取缺水限制电流*/
        if(Save_Data.s.short_current<4000 && Save_Data.s.short_current > 0)
        {
                System_Data.press_pump_current_limit = Save_Data.s.short_current;
        }
        else
        {
                System_Data.press_pump_current_limit = 300;/*默认300ma*/
    }

        /*识别码判断*/
        for(i=0;i<4;i++)
        {
                if(identifier
!=ident_temp)
{
                        break;
                }
        }
        if(i<4)/*第一次上电*/
        {
                for(i=0;i<4;i++)
                {
                        identifier
= ident_temp;
                }
                System_Sta.s.clean_self_cmd = FLAG_OFF;
                Save_Data.s.self_clean_flag=0;
                Save_Data.s.machine_type=DY_100A;
                i2cWriteBuffer1(AT24C02_ADDR,AT24C02_REG,sizeof(SAVE_DATA_UNION),(u8*)&Save_Data);/*写入数据*/
                i2cWriteBuffer1(AT24C02_ADDR,AT24C02_REG_INDENTIFIER,sizeof(identifier),(u8*)&identifier);/*写入数据*/
        // i2cWriteBuffer1(AT24C02_ADDR,AT24C02_REG_DATE_TIME,sizeof(_calendar_obj),(u8*)&calendar);/*写入数据*/
        // i2cWriteBuffer1(AT24C02_ADDR,AT24C02_REG_NO_OUT_TIME,sizeof(System_Data.not_out_water_tick),(u8*)&System_Data.not_out_water_tick);/*写入数据*/
        }
    // else{
    //     i2cRead1(AT24C02_ADDR,AT24C02_REG_DATE_TIME,sizeof(_calendar_obj),(u8*)&calendar);
    //     i2cRead1(AT24C02_ADDR,AT24C02_REG_NO_OUT_TIME,sizeof(System_Data.not_out_water_tick),(u8*)&System_Data.not_out_water_tick);
    //     RTC_Set(calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,0,0);  //设置时间
    // }
   
        /*更新软件版本号*/
        for(i=0;i<12;i++)
        {
                Save_Data.s.software_version
= temp;
        }
        Set_IceTube(Bit_RESET);
        Set_HotTube_1(Bit_RESET);
        Set_HotTube_2(Bit_RESET);
        System_Sta.s.heat1_cmd_flag = FLAG_ON;
        System_Sta.s.heat2_cmd_flag = FLAG_ON;


        GPIO_WriteBit(GPIOB, GPIO_Pin_7, 1);//EUV
        System_Sta.s.EUV_update_flag = TIMER_RUN;
    System_Data.flash_water_flag[0]='0';
    System_Data.flash_water_flag[1]='2';/*停止清洗*/
    Trans_dat_append(STATE_23);

    // 扫码结束标志上电时默认打开
    System_Sta.s.scaven_end_flag = FLAG_ON;

    // 上电时,非满水状态下,打开电磁阀I
    if(Bit_RESET==Read_WaterFullDetection())/*非满水情况下操作*/
    {
        Set_InletValue_I(Bit_SET);/*打开进水阀*/
    }

    System_Sta.s.work_mode = WORK_MODE_SYNERGY;
    System_Sta.s.heart_beat_falg = FLAG_ON;
}

hejun96 回答时间:2020-2-13 10:20:29
kimding 发表于 2019-8-30 16:22
不过没说使用5次,应该给出怎样的提示,提醒用户,你需要更换而不是处理滤网了 ...

比如用定时器计时200小时,时间了到了用串口打印数据显示"......"(表达的意思是滤芯使用了200小时,请更换),然后手动按键复位,这个项目完成了?

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版