
STM32按键扫描之状态机.pdf
4页STM32 按键扫描之状态机问题描述 :STM32 平台 GPIOA_Pin_6连接独立按键现需要实现:当按键按下后在1秒内释放了,此时计数值加1,而当按键按下后在1 秒内没有释放,那么以后每隔0.5 秒,计数值就会自动加上10,直到按键释放为止实现原理:采用有限状态机分析,事半功倍状态转换图如下:因此该状态图有四种状态:初始状态无按键状态(NoKeyDownStatus) 、按键确认状态(KeySureDownStatus) 、单次按键状态(OnceKeyDownStatus) 、和连发状态(ContiousKeyDownStatus) 系统每 10ms 进入读按键状态函数:StateStatus ReadKeyStatus(void) 定义一个枚举类型列出该系统所有的状态:typedef enum { NoKeyDownStatus=0, KeySureDownStatus, OnceKeyDownStatus, ContiousKeyDownStatus }StateStatus; /************************************************************* *Name :StateStatus ReadKeyStatus(void) *Function :Get the key status at the frequency of 10ms *Input :None *Output :Key status *************************************************************/ StateStatus ReadKeyStatus(void) { static StateStatus state = NoKeyDownStatus; static int TimeCount=0; int KeyPress = GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_6); StateStatus KeyReturn = NoKeyDownStatus; switch(state) { case NoKeyDownStatus: if(!KeyPress) { state = KeySureDownStatus ; } break; case KeySureDownStatus: if(!KeyPress) { state = OnceKeyDownStatus ; TimeCount = 0; } else { state = NoKeyDownStatus ; } break; case OnceKeyDownStatus: if(KeyPress) //if the kye is up,so it's a normal key. { state = NoKeyDownStatus ; KeyReturn = OnceKeyDownStatus; } /*-If the status keep 1s,state switch to contious status-*/ else if(++TimeCount>=100) { state = ContiousKeyDownStatus ; TimeCount = 0; KeyReturn = ContiousKeyDownStatus ; } break; case ContiousKeyDownStatus: if(KeyPress) { state = NoKeyDownStatus ; KeyReturn = NoKeyDownStatus ; } /*-contious status have stay for 0.5s-*/ else if(++TimeCount>50) { //state = ContiousKeyDownStatus; KeyReturn = ContiousKeyDownStatus; TimeCount = 0; } /*if it dose not uplift but stay for ContiousKeyDownStatus less than 0.5s*/ else { KeyReturn = NoKeyDownStatus; } break; } return KeyReturn; } 代码微分析:如图在计时状态一时,其状态转换条件有:1)该状态没有维持1S 时,按键就已抬起,此时转换到无按键按下状态。
2)在该状态维持了1S ,则需转换到连发状态计时2在计时状态二时,其状态转换条件有:1)还没维持0.5S 时,按键已抬起,此时转换到无按键状态2)在连发状态维持了0.5S ,则需清计数值和更新按键状态3)在该状态维持时间不到0.5S,修改其函数返回值为无按键按下状态0 如不修改函数返回值,那么在该状态下,每隔10ms 返回一个连发状态值,计数值每隔10ms 加 10所以从这两种状态说明在使用状态机时,应先关注状态转换条件,然后再去分析维持本状态的条件。












