|
关于状态机的一个极度确切的描述是它是一个有向图形,由一组节点和一组相应的转移函数组成。状态机通过响应一系列事件而“运行”。每个事件都在属于“当前” 节点的转移函数的控制范围内,其中函数的范围是节点的一个子集。函数返回“下一个”(也许是同一个)节点。这些节点中至少有一个必须是终态。当到达终态, 状态机停止。 有限状态机FSM思想广泛应用于硬件控制电路设计,也是软件上常用的一种处理方法(软件上称为FMM--有限消息机)。它把复杂的控制逻辑分解成有限个稳定状态,在每个状态上判断事件,变连续处理为离散数字处理,符合计算机的工作特点。同时,因为有限状态机具有有限个状态,所以可以在实际的工程上实现。但这并不意味着其只能进行有限次的处理,相反,有限状态机是闭环系统,有限无穷,可以用有限的状态,处理无穷的事务。 本次实现对按键的状态采集,以及相应状态下的LED指示动作都充分采用了状态机的编程思想,具体的就让代码来说话吧: 按键扫描头文件:定义了按键状态及相关标志位的宏定义: - #ifndef _KEYSCANDRIVE_H
- #define _KEYSCANDRIVE_H
- #define KEY_DOWN 0
- #define KEY_DOWN_UP 1
- extern uint8 KeyStateFlag; /* 按键状态 标志*/
- extern uint8 KEY_State;
- /* 按键状态 begin */
- #define Keystate0 0 //未按下
- #define Keystate1 1 //发现按下
- #define Keystate2 2 //稳定按下
- #define Keystate3 3 //释放
- /* 按键状态 end */
- extern void KeyStateScan(void); /*按键扫描状态机*/
- #endif
按键扫描的函数主体:
- #include "includes.h"
- uint8 KeyStateFlag; /* 按键状态 标志*/
- uint8 KEY_State;
- /****************************************************************************
- *函数名称:void KeyStateScan(void)
- *函数功能: 矩阵按键扫描状态机 ,对应按键控制LED
- *日期:2015 4 2
- *版本:V1.0
- *作者:yrj
- ****************************************************************************/
- void KeyStateScan(void)
- {
- switch (KeyStateFlag)
- {
- case Keystate0: /*未按下*/
- if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)== TRUE) /*未按下*/
- { KeyStateFlag = Keystate0; }
- else /* 按下 */
- { KeyStateFlag = Keystate1; }
- break;
- case Keystate1: /*发现按下*/
- if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==TRUE) /*未按下*/
- { KeyStateFlag = Keystate0; }
- else /* 按下 */
- { KeyStateFlag= Keystate2; }
- break;
- case Keystate2: /*稳定按下*/
- if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==TRUE) /*未按下*/
- { KeyStateFlag= Keystate0; }
- else /* 按下 */
- {
- KeyStateFlag= Keystate3; //保持
- KEY_State=KEY_DOWN; /* 按键按下 */
- }
- break;
- case Keystate3: /*释放*/
- {
- if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==TRUE) /*未按下*/
- {
- KeyStateFlag= Keystate0;
- KEY_State=KEY_DOWN_UP; /* 按键按下并抬起*/
- }aaa
- }
- break;
- default:
- {KeyStateFlag= Keystate0;}
- break;
- }
- }
main函数主体:
- void main(void)
- {
- bsp_init( );
- while(1)
- {
- KeyStateScan( ); /* 按键状态扫描 */
- switch(KEY_State)
- {
- case KEY_DOWN :
- LED_ON(); break;
- case KEY_DOWN_UP :
- LED_OFF(); break;
- default :break;
- }
- }
|