简介状态机应用比较广泛不同工作状态切换、寄存器数据采集多可以使用状态。比如电量灯显、从机寄存器数据获取。一、状态机框架根据不同的功能切换不同的工作状态。typedef enum ReadDeviceDat_e { PS_R_STA1, PS_R_STA2, PS_R_STA3, PS_R_STA4, PS_R_NUM }PS_ReadIDeviceDat_e; PS_ReadIDeviceDat_e g_enReadDeviceDat PS_R_STA1; switch(g_enReadDeviceDat) { case PS_R_STA1: ... break; case PS_R_STA2: ... break; case PS_R_STA3: ... break; case PS_R_STA4: ... break; default:break; }二、状态机定时器框架适用于执行一个动作之后需要定时一段时间执行另一个操作的场景。#define PS_MODULES_RX_LEN 10 #define SYSTEM_5MS_FLAG 0 #define SYSTEM_10MS_FLAG 1 #define MODBUS_SET_BIT(val,bit) val | (1bit) #define MODBUS_CLR_BIT(val,bit) val ~(1bit) #define MODBUS_GET_BIT(val,bit) val(1bit) typedef struct PS_Tim_s { uint16_t m_u16SystemTimFlag; uint16_t m_u16SysTim10ms; }PS_SysTim_S; _GLOBEXT_ PS_SysTim_S g_stuSysTim; typedef enum ReadDeviceDat_e { PS_R_STA1, PS_R_STA2, PS_R_STA3, PS_R_STA4, PS_R_NUM }PS_ReadIDeviceDat_e; PS_ReadIDeviceDat_e g_enReadDeviceDat PS_R_STA1; switch(g_enReadDeviceDat) { case PS_R_STA1: ... ... MODBUS_CLR_BIT(g_stuSysTim.m_u16SystemTimFlag,SYSTEM_10MS_FLAG); g_stuSysTim.m_u16SysTim10ms 0; g_enReadDeviceDat PS_R_STA2; break; case PS_R_STA2: if(MODBUS_GET_BIT(g_stuSysTim.m_u16SystemTimFlag,SYSTEM_10MS_FLAG)) { ... ... MODBUS_CLR_BIT(g_stuSysTim.m_u16SystemTimFlag,SYSTEM_10MS_FLAG); g_stuSysTim.m_u16SysTim10ms 0; g_enReadDeviceDat PS_R_STA3; } break; case PS_R_STA3: if(MODBUS_GET_BIT(g_stuSysTim.m_u16SystemTimFlag,SYSTEM_10MS_FLAG)) { ... ... MODBUS_CLR_BIT(g_stuSysTim.m_u16SystemTimFlag,SYSTEM_10MS_FLAG); g_stuSysTim.m_u16SysTim10ms 0; g_enReadDeviceDat PS_R_STA4; } break; case PS_R_STA4: if(MODBUS_GET_BIT(g_stuSysTim.m_u16SystemTimFlag,SYSTEM_10MS_FLAG)) { ... ... MODBUS_CLR_BIT(g_stuSysTim.m_u16SystemTimFlag,SYSTEM_10MS_FLAG); g_stuSysTim.m_u16SysTim10ms 0; g_enReadDeviceDat PS_R_STA1; } break; default:break; }定时器时间需要单独在定时器中计时计时到了就置位。void pri_iic_commu_tim5ms(void) { if(get_sta) //根据实际应用 { g_stuSysTim.m_u16SysTim10ms; if(g_stuSysTim.m_u16SysTim10ms 10) //10ms { g_stuSysTim.m_u16SysTim10ms 0; MODBUS_SET_BIT(g_stuSysTim.m_u16SystemTimFlag,SYSTEM_10MS_FLAG); } } }三、状态机定时器优化版这个代码量更少适用于FLASH、RAM空间紧张的场景使用起来也比较简单。#define SET_TIME_20MS 20 //20ms typedef enum ReadDeviceDat_e { PS_R_STA1, PS_R_STA2, PS_R_STA3, PS_R_STA4, PS_R_NUM }PS_ReadIDeviceDat_e; PS_ReadIDeviceDat_e g_enReadDeviceDat PS_R_STA1; uint16_t g_u16timer 0; void fun(void) { if(g_u16timer ! 0) { return; } g_u16timer SET_TIME_20MS; switch(g_enReadDeviceDat ) { case PS_R_STA1: ... break; case PS_R_STA2: ... break; case PS_R_STA3: ... break; case PS_R_STA4: ... break; default:break; } } void Timer(void) { if(g_u16timer 0) g_u16timer --; }