# 通用状态机 **Repository Path**: zfqcode/universal-state-machine ## Basic Information - **Project Name**: 通用状态机 - **Description**: c语言 通用状态机 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 4 - **Forks**: 0 - **Created**: 2023-05-25 - **Last Updated**: 2024-09-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 通用状态机 ```c typedef struct state_t { uint8_t ID; void (*State_Task_Callback)(void); uint8_t(*State_Change_Callback)(void); } state_t; typedef struct state_machine_t { uint8_t State_Total; uint64_t isRegister; uint8_t ID_Now; uint8_t isInit; state_t* state; } state_machine_t; void State_Init(state_machine_t* state_machine,uint8_t State_Total,uint8_t Begin_ID); uint8_t State_Config( state_machine_t* state_machine, uint16_t ID , void (*State_Task)(void), uint8_t(*State_Change)(void)); void State_TIM(state_machine_t* handle); void State_Main(state_machine_t* handle); ``` ## 程序介绍 主要有两个结构体和4个函数 ​ 结构体是状态机和状态的结构体 ​ 函数从上到下分别作用为 初始化状态机 配置状态 还有两个主函数 一个放在定时器里 一个放在main或者说是主函数里 ```c void State_Init(state_machine_t* state_machine,uint8_t State_Total,uint8_t Begin_ID); ``` 用于初始化状态机 ​ 第一个参数是结构体,定义一个填进去就好了, ​ 第二个是状态机中一共有多少个状态 ​ 第三个是初始状态 ```c uint8_t State_Config( state_machine_t* state_machine, uint16_t ID , void (*State_Task)(void), uint8_t(*State_Change)(void)); ``` 用于配置状态 ​ 第一个参数是状态机结构体 ​ 第二个参数是当前配置的状态id号 ​ 第三个参数是当前id号状态需要执行的任务 ​ 第四个参数是在当前id号状态时,通过什么条件的变化去改变成其他状态 ​ return uint8_t 主要是返回0和1 0就是配置成功 1是配置失败 原因是该ID已经被注册过了 ```C void State_TIM(state_machine_t* handle); void State_Main(state_machine_t* handle); ``` ​ 这两条主要是主程序的运行,我将其分成了两份,因为执行主任务有时可能是阻塞的任务,导致不能及时的去判断按键状态。使用分成了两份,一份TIM里的主要用于判断改变条件,一份MAIN里的用于跑主函数。 ## 例程 ```C #include "app.h" btn_t btn[7]={0}; state_machine_t state_machine={0}; void Task_State1() { LED1_TOGGLE(); LED2_OFF(); HAL_Delay(2000); } void Task_State2() { LED1_TOGGLE(); LED2_OFF(); HAL_Delay(500); } void Task_State3() { LED2_TOGGLE(); LED1_OFF(); HAL_Delay(2000); } void Task_State4() { LED2_TOGGLE(); LED1_OFF(); HAL_Delay(500); } uint8_t Change1() { if(btn[0].shortPress_flag==1) { btn[0].shortPress_flag=0; return 2; } if(btn[1].shortPress_flag==1) { btn[1].shortPress_flag=0; return 3; } return 0; } uint8_t Change2() { if(btn[0].shortPress_flag==1) { btn[0].shortPress_flag=0; return 3; } if(btn[1].shortPress_flag==1) { btn[1].shortPress_flag=0; return 4; } return 0; } uint8_t Change3() { if(btn[0].shortPress_flag==1) { btn[0].shortPress_flag=0; return 4; } if(btn[1].shortPress_flag==1) { btn[1].shortPress_flag=0; return 1; } return 0; } uint8_t Change4() { if(btn[0].shortPress_flag==1) { btn[0].shortPress_flag=0; return 1; } if(btn[1].shortPress_flag==1) { btn[1].shortPress_flag=0; return 2; } return 0; } void TIM1_Handler() { Btn_Func(&btn[0]); Btn_Func(&btn[1]); State_TIM(&state_machine); } static void Init() { State_Init(&state_machine,4,1); Tim_Init(); BtnInit(&btn[0],KEY_1); BtnInit(&btn[1],KEY_2); State_Config(&state_machine,1,Task_State1,Change1); State_Config(&state_machine,2,Task_State2,Change2); State_Config(&state_machine,3,Task_State3,Change3); State_Config(&state_machine,4,Task_State4,Change4); } void app() { Init(); while(1) { State_Main(&state_machine); } } ```