简介
状态机应用比较广泛,不同工作状态切换、寄存器数据采集多可以使用状态。
比如:电量灯显、从机寄存器数据获取。
一、状态机框架
根据不同的功能,切换不同的工作状态。
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 |= (1<<bit) #define MODBUS_CLR_BIT(val,bit) val &= ~(1<<bit) #define MODBUS_GET_BIT(val,bit) val&(1<<bit) 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 --; }