当前位置:网站首页>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
边栏推荐
- LeetCode 8. String conversion integer (ATOI)
- MySQL之函数
- 2022-02-13 work record -- PHP parsing rich text
- Common API classes and exception systems
- [Chongqing Guangdong education] Chongqing Engineering Vocational and Technical College
- FFMPEG关键结构体——AVCodecContext
- Detailed explanation of APP functions of door-to-door appointment service
- NLP basic task word segmentation third party Library: ICTCLAS [the third party library with the highest accuracy of Chinese word segmentation] [Chinese Academy of Sciences] [charge]
- Key structure of ffmpeg - avframe
- How to use the flutter framework to develop and run small programs
猜你喜欢
[EI conference sharing] the Third International Conference on intelligent manufacturing and automation frontier in 2022 (cfima 2022)
Go learning --- structure to map[string]interface{}
Introduction of motor
如何制作自己的機器人
【EI会议分享】2022年第三届智能制造与自动化前沿国际会议(CFIMA 2022)
AtCoder Beginner Contest 258【比赛记录】
【DesignMode】装饰者模式(Decorator pattern)
Notepad++ regular expression replacement string
Location based mobile terminal network video exploration app system documents + foreign language translation and original text + guidance records (8 weeks) + PPT + review + project source code
Recognize the small experiment of extracting and displaying Mel spectrum (observe the difference between different y_axis and x_axis)
随机推荐
Leetcode:20220213 week race (less bugs, top 10% 555)
notepad++正則錶達式替換字符串
FFT learning notes (I think it is detailed)
Multithreading and high concurrency (8) -- summarize AQS shared lock from countdownlatch (punch in for the third anniversary)
FFmpeg学习——核心模块
云导DNS和知识科普以及课堂笔记
Spark获取DataFrame中列的方式--col,$,column,apply
SQLServer连接数据库读取中文乱码问题解决
Knowledge about the memory size occupied by the structure
Intranet Security Learning (V) -- domain horizontal: SPN & RDP & Cobalt strike
Natural language processing (NLP) - third party Library (Toolkit):allenlp [library for building various NLP models; based on pytorch]
Anconda download + add Tsinghua +tensorflow installation +no module named 'tensorflow' +kernelrestart: restart failed, kernel restart failed
How to use the flutter framework to develop and run small programs
Opencv classic 100 questions
Reading notes of the beauty of programming
数据分析思维分析方法和业务知识——分析方法(三)
Idea远程提交spark任务到yarn集群
[noi simulation] Anaid's tree (Mobius inversion, exponential generating function, Ehrlich sieve, virtual tree)
anconda下载+添加清华+tensorflow 安装+No module named ‘tensorflow‘+KernelRestarter: restart failed,内核重启失败
Go learning --- structure to map[string]interface{}