当前位置:网站首页>How to deeply understand the design idea of "finite state machine"?
How to deeply understand the design idea of "finite state machine"?
2022-07-05 14:09:00 【Dafang teacher talks about SCM】
How to understand “ Finite state machine ” Design idea ?
It is often used in program design and digital circuit design “ Finite state machine ” Design idea .
In embedded software development , State machine programming is a very important programming idea , It is also a common programming framework in embedded development . Master the programming idea of state machine , It can realize complex business logic functions more logically .
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 、 Events and responses
· state : What state is the system in ?
· 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 Method of 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 , Here is a trick to use macro definition :
# 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 the separate acquisition of enumeration items and the strings corresponding to enumeration items :
#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 )*/ \ typedefenum{
KEY_STATUS_ENUM(ENUM_ITEM)}KEY_STATUS;constchar*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_STATUSg_keyStatus=KS_RELEASE;// The status of the current key KEY_STATUSg_lastKeyStatus=KS_NUM;// Last state intg_DebounceCnt=0;// Buffeting time count voidkey_status_check(){
switch(g_keyStatus)
{
// Key release ( The initial state )caseKS_RELEASE:
{
// Low level detected , First, eliminate the chattering if(KEY0==0)
{
g_keyStatus=KS_PRESS_SHAKE;
g_DebounceCnt=0;
}
}
break;
// Press jitter caseKS_PRESS_SHAKE:
{
g_DebounceCnt++;
// It's really jittery if(KEY0==1)
{
g_keyStatus=KS_RELEASE;
}
// Buffeting complete elseif(g_DebounceCnt==5)
{
g_keyStatus=KS_PRESS;
printf("=====> key press\r\n");
}
}
break;
// Press steadily caseKS_PRESS:
{
// High level detected , First, eliminate the chattering if(KEY0==1)
{
g_keyStatus=KS_RELEASE_SHAKE;
g_DebounceCnt=0;
}
}
break;
// Release the jitter caseKS_RELEASE_SHAKE:
{
g_DebounceCnt++;
// It's really jittery if(KEY0==0)
{
g_keyStatus=KS_PRESS;
}
// Buffeting complete elseif(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]);
}}intmain(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
This paper introduces the programming implementation of state machine commonly used in embedded software development , And by pressing the key to eliminate the shaking instance , In common use switch-case form , The corresponding state machine programming code is implemented , And pass the test , Serial port print corresponding status , Analyze the state jump process of the state machine .
边栏推荐
猜你喜欢

Those things I didn't know until I took the postgraduate entrance examination

牛客网:拦截导弹

软件测试人在深圳有哪些值得去的互联网公司【软件测试人员专供版】

Brief introduction to revolutionary neural networks

Attack and defense world web WP

我为什么支持 BAT 拆掉「AI 研究院」

-Web direction attack and defense world

Detailed explanation of IP address and preparation of DOS basic commands and batch processing

LeetCode_2(两数相加)

Kotlin collaboration uses coroutinecontext to implement the retry logic after a network request fails
随机推荐
Financial one account Hong Kong listed: market value of 6.3 billion HK $Ye wangchun said to be Keeping true and true, long - term work
R语言ggplot2可视化条形图:通过双色渐变配色颜色主题可视化条形图、为每个条形添加标签文本(geom_text函数)
Xampp configuring multiple items
uplad_ Labs first three levels
POI set the data format of the column (valid)
Anchor navigation demo
鸿蒙第四次培训
Linked list (simple)
Routing in laravel framework
OSI and tcp/ip protocol cluster
Fault analysis | analysis of an example of MySQL running out of host memory
Can graduate students not learn English? As long as the score of postgraduate entrance examination English or CET-6 is high!
Set up a website with a sense of ceremony, and post it to the public 2/2 through the intranet
R语言使用MASS包的polr函数构建有序多分类logistic回归模型、使用coef函数获取模型中每个变量(自变量改变一个单位)对应的对数优势比(log odds ratio)
Blue Bridge Cup study 2022.7.5 (morning)
Those things I didn't know until I took the postgraduate entrance examination
R语言ggplot2可视化密度图:按照分组可视化密度图、自定义配置geom_density函数中的alpha参数设置图像透明度(防止多条密度曲线互相遮挡)
C - Divisors of the Divisors of An Integer Gym - 102040C
瑞能实业IPO被终止:年营收4.47亿 曾拟募资3.76亿
SAS接口有什么优势特点