当前位置:网站首页>STM32 key state machine 2 - state simplification and long press function addition

STM32 key state machine 2 - state simplification and long press function addition

2022-07-06 17:58:00 Code farmer loves learning

Last article , With the key anti shake function , The basic principle and application method of state machine are introduced .

The state diagram of the previous article is as follows :

Because only press and release are detected , And it has the function of key shaking elimination , Therefore, the above 4 Status , Press jitter and release jitter are two independent States , And these two jittery States , It can also run continuously in multiple cycles , The cycle period of this state machine is set to 10ms, When a certain level is continuously detected in the jitter state 5 Next time , That is, it is considered that the chattering elimination is completed , Go to the next steady state .

For the same function , State diagrams are not static , For key debounce , The two jitter states can also be represented by sharing a jitter state .

1 De chattering state simplification

1.1 State diagram

Press jitter and release jitter share a jitter state to represent , At the same time, the cycle period of the state machine needs to be set to 50ms, such , The jitter state only needs to pass once , Whether it is really key jitter can be determined by the level . The simplified state diagram is as follows :

In order to be able to , Distinguish whether the previous state is released or pressed , Then we can judge whether this time it is the jitter or the real action of the key , You need to add a status to record the previous status

KEY_STATUS g_keyStatus = KS_RELEASE; // The end of the current cycle ( State machine ) state 
KEY_STATUS g_nowKeyStatus = KS_RELEASE; // current state ( After each cycle with g_keyStatus bring into correspondence with )
KEY_STATUS g_lastKeyStatus = KS_RELEASE; // Last state ( Used to record the previous state to distinguish the source of the state )

Be careful : Here g_lastKeyStatus Used to record the previous status , There is also this variable in the last article , But the effect is different , The function of this variable in the previous article is the same as that here g_nowKeyStatus The same effect .

1.2 Code

Compare with the simplified state diagram , Write the corresponding state machine logic code :

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_SHAKE;
			}
		}
		break;
		
		// shake 
		case KS_SHAKE:
		{
    
			if (KEY0 == 1)
			{
    
				g_keyStatus = KS_RELEASE;
				if (KS_PRESS == g_lastKeyStatus)
				{
    
					printf("=====> key release\r\n");
				}
			}
			else
			{
    
				g_keyStatus = KS_PRESS;
				if (KS_RELEASE == g_lastKeyStatus)
				{
    
					printf("=====> key press\r\n");
				}
			}
		}
		break;
		
		// Press steadily and briefly 
		case KS_PRESS:
		{
    
			// High level detected , First, eliminate the chattering 
			if (KEY0 == 1)
			{
    
				g_keyStatus = KS_SHAKE;
			}
		}
		break;
		
		default:break;
	}
	
	if (g_keyStatus != g_nowKeyStatus)
	{
    
		g_lastKeyStatus = g_nowKeyStatus;
		g_nowKeyStatus = g_keyStatus;
		printf("new key status:%d(%s)\r\n", g_keyStatus, key_status_name[g_keyStatus]);
	}
}

Be careful g_lastKeyStatus Role of variables .

1.3 test

2 Add long press function

On the basis of detecting press and release , Add long press function , You need to add a long press state in the state diagram . then , Modify the code according to the state diagram .

Again , According to whether it is necessary to distinguish the two jitter States and the difference of the cycle cycle cycle of the state machine , There are two kinds of state diagrams .

2.1 Not simplified state diagram

Let's first look at the cycle 10ms, Distinguish between press jitter and release jitter. Add the state diagram after long press function :

After clarifying the logic of the state diagram , According to the state diagram , Modify the corresponding code , No more code here , The complete code can be checked in my code warehouse

2.2 Simplified state diagram

Next, let's take a look at the state machine diagram of the specific long press function to simplify the dithering state :

The comparison shows that , Simplified state diagram , The status can be one less , But the shaking state , There will be more inputs and outputs , Because at present, every state has passed through this state .

If the requirements for jitter detection are not high , You can also keep only the logic of press jitter , Loosen the shaking branch and remove , Jump directly to the released state , State logic can be simplified again .

2.3 Code

According to the state diagram , Write the corresponding state machine logic code , as follows :

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_SHAKE;
			}
		}
		break;
		
		// shake 
		case KS_SHAKE:
		{
    
			if (KEY0 == 1)
			{
    
				g_keyStatus = KS_RELEASE;
				if (KS_SHORT_PRESS == g_lastKeyStatus || KS_LONG_PRESS == g_lastKeyStatus)
				{
    
					printf("=====> key release\r\n");
				}
			}
			else
			{
    
				if (KS_RELEASE == g_lastKeyStatus)
				{
    
					g_PressTimeCnt = 0;
					g_keyStatus = KS_SHORT_PRESS;
					printf("=====> key short press\r\n");
				}
				else if (KS_SHORT_PRESS == g_lastKeyStatus)
				{
    
					g_keyStatus = KS_SHORT_PRESS;
				}
				else
				{
    
				
				}
			}
		}
		break;
		
		// Press steadily and briefly 
		case KS_SHORT_PRESS:
		{
    
			// High level detected , First, eliminate the chattering 
			if (KEY0 == 1)
			{
    
				g_keyStatus = KS_SHAKE;
			}
			
			g_PressTimeCnt++;
			if (g_PressTimeCnt == 20) //1000ms
			{
    
				g_keyStatus = KS_LONG_PRESS;
				printf("=====> key long press\r\n");
			}
		}
		break;
		
	    // Steady long press 
		case KS_LONG_PRESS:
		{
    
			// High level detected , First, eliminate the chattering 
			if (KEY0 == 1)
			{
    
				g_keyStatus = KS_SHAKE;
			}
			
			g_PressTimeCnt++;
			if (g_PressTimeCnt % 20 == 0) // every other 1000ms Print once 
			{
    
				printf("=====> key long press:%d\r\n", g_PressTimeCnt/20);
			}
		}
		break;
		
		default:break;
	}
	
	if (g_keyStatus != g_nowKeyStatus)
	{
    
		g_lastKeyStatus = g_nowKeyStatus;
		g_nowKeyStatus = g_keyStatus;
		printf("new key status:%d(%s)\r\n", g_keyStatus, key_status_name[g_keyStatus]);
	}
}

Be careful , In the jitter state , When the detection is high ( Release the button ), Whether the previous state is short press or long press , The next state is the released state .

2.4 test

3 summary

This article continues to introduce the use of state machines , On the basis of the first part , By simplifying the button to shake the logic , And add the function of pressing and holding keys , Further introduce the modification of state diagram and the implementation of state machine code , And passed the actual test , Demonstrate the running effect of the state machine .

原网站

版权声明
本文为[Code farmer loves learning]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/187/202207061001196182.html