当前位置:网站首页>STM32 key chattering elimination - entry state machine thinking
STM32 key chattering elimination - entry state machine thinking
2022-07-06 00:32:00 【Hua Weiyun】
1 State machine thinking
State machine , Or finite state machine FSM(Finite State Machine), Is an important programming idea .
The state machine has 3 elements : state 、 event And Respond to
event : What is going on? ?
Respond to : In this state, something like this happens , How does the system handle ?
Before state machine programming , First, according to the functions to be realized , Sort out a corresponding state transition diagram ( The state machine diagram ), Then you can use this state transition diagram , Apply the state machine programming template , The implementation corresponds to the state machine code .
State machine programming mainly includes 3 Methods :switch-case Law 、 Table driven method 、 Function pointer method , This article first introduces the simplest and easiest to understand switch-case Law .
2 State machine instance
The following is the key shake elimination function , To introduce switch-case Law State machine programming ideas .
2.1 Button anti shake state transition diagram
Before state machine programming , First of all, the state machine corresponding to the function needs several states , The key function of this example , Only the most basic pressed and released states are detected ( Long press will not be realized for the time being 、 Double click status ), And add the corresponding button de dithering function , therefore , Need to use 4 Status :
Stable release state
Press jitter status
Steady press state
Release the jitter state
The corresponding state transition diagram is as follows :
Because the key is usually released , Here, let the initialization state of the state machine be the released state , And here 4 Switch back and forth between states .
In the picture VT Represents the level detected by the key ,VT=0 That is, low level is detected , It may be a key press , From the initial “ Stable release ” The state changes to “ Press jitter ” state
When a low level is continuously detected (VT=0) After a while , It is considered that the chattering elimination is completed , from “ Press jitter ” The state changes to “ Press steadily ” state
stay “ Press jitter ” In the state of , Within a specified period of time , High level detected again (VT=1), It shows that the button jitters ( For example, the key is quickly pushed and then bounced up , Or key jitter caused by strong vibration ), By “ Press jitter ” The state changes to “ Stable release ” state
2.2 Programming to realize
2.2.1 State definition
Corresponding to the above button state diagram , You know you need to use 4 Status :
Stable release state (KS_RELEASE)
Press jitter status (KS_PRESS_SHAKE)
Steady press state (KS_PRESS)
Release the jitter state (KS_RELEASE_SHAKE)
Enumerations are used here to define this 4 Status . For debugging , The corresponding state name can be printed in the form of string , Use here Macro definition A little trick for :
# Symbol + Custom enumeration name
It can be automatically converted to string form , Then put these strings into const char* key_status_name[] Array , You can access the string name form of these states in the form of an array .
Besides , In order not to repeatedly write the enumeration name and the corresponding enumeration string (#+ Enumeration name ), Further use of macro definitions , Define the state only once , Then define the following two macros , Realize to Enumeration item and The string corresponding to the enumeration item Separate acquisition of :
#define ENUM_ITEM(ITEM) ITEM,#define ENUM_STRING(ITEM) #ITEM,
Specifically, the macro definition 、 The enumeration definition and enumeration name array are declared as follows :
#define ENUM_ITEM(ITEM) ITEM,#define ENUM_STRING(ITEM) #ITEM,#define KEY_STATUS_ENUM(STATUS) \ STATUS(KS_RELEASE) /* Stable release state */ \ STATUS(KS_PRESS_SHAKE) /* Press jitter status */ \ STATUS(KS_PRESS) /* Steady press state */ \ STATUS(KS_RELEASE_SHAKE) /* Release the jitter state */ \ STATUS(KS_NUM) /* The total number of States ( Invalid state )*/ \ typedef enum{ KEY_STATUS_ENUM(ENUM_ITEM)}KEY_STATUS;const char* key_status_name[] = { KEY_STATUS_ENUM(ENUM_STRING)};
Macro definitions are difficult to understand , Macro definitions can be brought into , To the final result , Understand the specific form after replacement , For example, the following macro definitions are used to carry in the replacement diagram :
/*KEY_STATUS_ENUM(STATUS) --> STATUS(KS_RELEASE) ... STATUS(KS_NUM)KEY_STATUS_ENUM(ENUM_ITEM)--> ENUM_ITEM(KS_RELEASE) ... ENUM_ITEM(KS_NUM)--> KS_RELEASE, ... KS_NUM,KEY_STATUS_ENUM(ENUM_STRING)--> ENUM_STRING(KS_RELEASE) ... ENUM_STRING(KS_NUM)--> #KS_RELEASE, ... #KS_NUM,*/
2.2.2 State machine implementation
The following is the implementation of the state machine :
State machine function key_status_check In a cycle , Every 10ms Call once
Define a g_keyStatus Indicates the state of the state machine
In each cycle ,switch According to the current state , Execute the logic required by the corresponding state
Define a g_DebounceCnt It is used to calculate the buffeting time , When it continues to enter the de chattering state , Each cycle (10ms) Add... To this value 1, Last for a certain number of times (5 Time , namely 50ms), Press or release considered stable , Buffeting complete , Jump to stable direction or stable release state
In the execution logic of each state , When it is detected that certain conditions are met , Jump to another state
Through the continuous jump of state , Realize the running of state machine
Besides , For the convenience of observing the change of state in the state machine , Defined a g_lastKeyStatus Indicates the previous status , When the state changes , You can print out the status name
KEY_STATUS g_keyStatus = KS_RELEASE; // The status of the current key KEY_STATUS g_lastKeyStatus = KS_NUM; // Last state int g_DebounceCnt = 0; // Buffeting time count void key_status_check(){ switch(g_keyStatus) { // Key release ( The initial state ) case KS_RELEASE: { // Low level detected , First, eliminate the chattering if (KEY0 == 0) { g_keyStatus = KS_PRESS_SHAKE; g_DebounceCnt = 0; } } break; // Press jitter case KS_PRESS_SHAKE: { g_DebounceCnt++; // It's really jittery if (KEY0 == 1) { g_keyStatus = KS_RELEASE; } // Buffeting complete else if (g_DebounceCnt == 5) { g_keyStatus = KS_PRESS; printf("=====> key press\r\n"); } } break; // Press steadily case KS_PRESS: { // High level detected , First, eliminate the chattering if (KEY0 == 1) { g_keyStatus = KS_RELEASE_SHAKE; g_DebounceCnt = 0; } } break; // Release the jitter case KS_RELEASE_SHAKE: { g_DebounceCnt++; // It's really jittery if (KEY0 == 0) { g_keyStatus = KS_PRESS; } // Buffeting complete else if (g_DebounceCnt == 5) { g_keyStatus = KS_RELEASE; printf("=====> key release\r\n"); } } break; default:break; } if (g_keyStatus != g_lastKeyStatus) { g_lastKeyStatus = g_keyStatus; printf("new key status:%d(%s)\r\n", g_keyStatus, key_status_name[g_keyStatus]); }}int main(void){ delay_init(); // Delay function initialization KEY_Init(); uart_init(115200); printf("hello\r\n"); while(1) { key_status_check(); delay_ms(10); }}
notes : This routine requires the use of a key , You need to initialize the corresponding GPIO, No more code here .
2.3 Use tests
Compile and burn the complete code into the board , Connect the serial port , Press and release the key , Observe the serial port output information .
My test output information is as follows :
The first two toggles the button to simulate the shaking of the button , You can see that the serial port prints two state switches from release to press jitter .
Then press the key , Release the button again , You can see the change of state : Release -> Press jitter -> Press down -> Release the jitter -> Release
3 summary
边栏推荐
- Permission problem: source bash_ profile permission denied
- NLP text processing: lemma [English] [put the deformation of various types of words into one form] [wet- > go; are- > be]
- Solve the problem of reading Chinese garbled code in sqlserver connection database
- Gavin teacher's perception of transformer live class - rasa project actual combat e-commerce retail customer service intelligent business dialogue robot system behavior analysis and project summary (4
- Yolov5, pychar, Anaconda environment installation
- Power Query数据格式的转换、拆分合并提取、删除重复项、删除错误、转置与反转、透视和逆透视
- State mode design procedure: Heroes in the game can rest, defend, attack normally and attack skills according to different physical strength values.
- 【NOI模拟赛】Anaid 的树(莫比乌斯反演,指数型生成函数,埃氏筛,虚树)
- Natural language processing (NLP) - third party Library (Toolkit):allenlp [library for building various NLP models; based on pytorch]
- FFmpeg学习——核心模块
猜你喜欢
FPGA内部硬件结构与代码的关系
Configuring OSPF load sharing for Huawei devices
Key structure of ffmpeg - avformatcontext
【EI会议分享】2022年第三届智能制造与自动化前沿国际会议(CFIMA 2022)
如何利用Flutter框架开发运行小程序
Permission problem: source bash_ profile permission denied
Basic introduction and source code analysis of webrtc threads
建立时间和保持时间的模型分析
Key structure of ffmpeg -- AVCodecContext
[designmode] composite mode
随机推荐
STM32 configuration after chip replacement and possible errors
Configuring OSPF GR features for Huawei devices
多线程与高并发(8)—— 从CountDownLatch总结AQS共享锁(三周年打卡)
AtCoder Beginner Contest 254【VP记录】
[designmode] Decorator Pattern
如何制作自己的机器人
Multithreading and high concurrency (8) -- summarize AQS shared lock from countdownlatch (punch in for the third anniversary)
XML Configuration File
【线上小工具】开发过程中会用到的线上小工具合集
Global and Chinese market of water heater expansion tank 2022-2028: Research Report on technology, participants, trends, market size and share
Calculate sha256 value of data or file based on crypto++
Room cannot create an SQLite connection to verify the queries
[QT] QT uses qjson to generate JSON files and save them
认识提取与显示梅尔谱图的小实验(观察不同y_axis和x_axis的区别)
Key structure of ffmpeg - avframe
2022-02-13 work record -- PHP parsing rich text
Go learning --- structure to map[string]interface{}
Codeforces gr19 D (think more about why the first-hand value range is 100, JLS yyds)
MySql——CRUD
AtCoder Beginner Contest 258【比赛记录】