chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

STM32按鍵狀態(tài)機(jī)3——增加雙擊與功能優(yōu)化

碼農(nóng)愛學(xué)習(xí) ? 來(lái)源:碼農(nóng)愛學(xué)習(xí) ? 作者:碼農(nóng)愛學(xué)習(xí) ? 2022-09-04 17:05 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

上篇文章,介紹了將按鍵檢測(cè)增加長(zhǎng)按功能,并將按下抖動(dòng)與松開抖動(dòng)共用一個(gè)抖動(dòng)狀態(tài)來(lái)表示,其狀態(tài)圖如下:

pYYBAGMTVcKAAzPKAABa-BfEo28672.png

仔細(xì)研究這個(gè)狀態(tài)圖,其它還存在一些問(wèn)題:

短按狀態(tài),只要按下去,不需要等按鍵再釋放,就會(huì)觸發(fā)短按事件。對(duì)于需要按下再松開作為一次短按的應(yīng)用來(lái)說(shuō),此狀態(tài)圖也不滿足需求

長(zhǎng)按狀態(tài),必須先經(jīng)過(guò)短按狀態(tài),即長(zhǎng)按按鍵,會(huì)先觸發(fā)一個(gè)短按,再觸發(fā)一個(gè)長(zhǎng)按。如果實(shí)際應(yīng)用中需要分別使用短按和長(zhǎng)按,則此狀態(tài)圖不滿足要求

本篇,就來(lái)解決上述兩個(gè)問(wèn)題,并再增加一個(gè)按鍵雙擊檢測(cè),實(shí)現(xiàn)一個(gè)功能更全面的按鍵檢測(cè)。

1 增加雙擊檢測(cè)

增加一個(gè)雙擊檢測(cè),需要增加兩個(gè)狀態(tài):

等待再次按下

確認(rèn)第2次按下

同時(shí),之前的“短按狀態(tài)”和“長(zhǎng)按狀態(tài)”分別改為“確認(rèn)按下”和“確認(rèn)長(zhǎng)按”。

1.1 狀態(tài)圖修改

修改后的狀態(tài)圖如下,有以下幾點(diǎn)需要注意:

確認(rèn)按下”不是短按觸發(fā)的條件,需要等松開后,經(jīng)消抖進(jìn)入到“等待再次按下”一段時(shí)間后(200ms),沒(méi)有再次被按下,才觸發(fā)短按事件,這樣就解決了本篇開頭提到的第1個(gè)問(wèn)題

確認(rèn)按下”不是短按觸發(fā)的條件,另一個(gè)用途是,當(dāng)此狀態(tài)繼續(xù)保持按下狀態(tài)一段時(shí)間后(1s),則會(huì)單獨(dú)觸發(fā)長(zhǎng)按事件,同時(shí)進(jìn)入到“確認(rèn)長(zhǎng)按”狀態(tài),這樣就解決了本篇開頭提到的第2個(gè)問(wèn)題

對(duì)于雙擊事件的檢測(cè),首先按下按鍵進(jìn)入“確認(rèn)按下”狀態(tài),然后在1s內(nèi)松開進(jìn)入“等待再次按下”狀態(tài),接著在200ms內(nèi)再次按下進(jìn)入“確認(rèn)第2次按下”狀態(tài),然后在1s內(nèi)松開,即可觸發(fā)雙擊事件,并同時(shí)進(jìn)入“穩(wěn)定松開”狀態(tài)

注意,在“確認(rèn)第2次按下”狀態(tài)下,如果在1s內(nèi)沒(méi)有松開,也會(huì)進(jìn)入到“確認(rèn)長(zhǎng)按”狀態(tài)

poYBAGMUaY-AEN6DAACzMOOUn5E684.png

1.2 程序編寫

根據(jù)狀態(tài)圖,修改對(duì)應(yīng)的狀態(tài)機(jī)邏輯,修改后的代碼如下:

void key_status_check()
{
	switch(g_keyStatus)
	{
		//按鍵釋放(初始狀態(tài))
		case KS_RELEASE:
		{
			//檢測(cè)到低電平,先進(jìn)行消抖
			if (KEY0 == 0)
			{
				g_keyStatus = KS_SHAKE;
			}
		}
		break;
		
		//抖動(dòng)
		case KS_SHAKE:
		{
			if (KEY0 == 1) 
			{
				//從松開狀態(tài)來(lái)的抖動(dòng)
				if (KS_RELEASE == g_lastKeyStatus)
				{
					g_keyStatus = KS_RELEASE;
				}
				//從等待再次按下狀態(tài)來(lái)的抖動(dòng)
				else if (KS_WAIT_PRESS_AGAIN == g_lastKeyStatus)
				{
					g_keyStatus = KS_WAIT_PRESS_AGAIN;
				}
				//從確認(rèn)按下狀態(tài)來(lái)
				else if (KS_AFFIRM_SHORT_PRESS == g_lastKeyStatus)
				{
					g_WaitPressAgainCnt = 0;
					g_keyStatus = KS_WAIT_PRESS_AGAIN;
				}
				//從確認(rèn)再次按下狀態(tài)來(lái)
				else if (KS_AFFIRM_PRESS_AGAIN == g_lastKeyStatus)
				{
					printf("=====> key double press\r\n");
					g_keyStatus = KS_RELEASE;
				}
				//從確認(rèn)長(zhǎng)按狀態(tài)來(lái)
				else if (KS_AFFIRM_LONG_PRESS == g_lastKeyStatus)
				{
					g_keyStatus = KS_RELEASE;
				}
				else
				{
					printf("err!\r\n");
				}
			}
			else
			{
				//從確認(rèn)按下狀態(tài)來(lái)的抖動(dòng)
				if (KS_AFFIRM_SHORT_PRESS == g_lastKeyStatus)
				{
					g_keyStatus = KS_AFFIRM_SHORT_PRESS;
				}
		        //從第2次按下狀態(tài)來(lái)的抖動(dòng)
				else if (KS_AFFIRM_PRESS_AGAIN == g_lastKeyStatus)
				{
					g_keyStatus = KS_AFFIRM_PRESS_AGAIN;
				}
				//從確認(rèn)長(zhǎng)按狀態(tài)來(lái)的抖動(dòng)
				else if (KS_AFFIRM_LONG_PRESS == g_lastKeyStatus)
				{
					g_keyStatus = KS_AFFIRM_LONG_PRESS;
				}
				//從松開狀態(tài)而來(lái)
				else if (KS_RELEASE == g_lastKeyStatus)
				{
					g_PressTimeCnt = 0;
					g_keyStatus = KS_AFFIRM_SHORT_PRESS;
					//printf("=====> key short press\r\n");
				}
				//從等待再次看下(的松開)狀態(tài)而來(lái)
				else if (KS_WAIT_PRESS_AGAIN == g_lastKeyStatus)
				{
					g_Press2TimeCnt = 0;
					g_keyStatus = KS_AFFIRM_PRESS_AGAIN;
				}
				else
				{
					printf("err!\r\n");
				}
			}
		}
		break;
		
		//確認(rèn)按下
		case KS_AFFIRM_SHORT_PRESS:
		{
			//檢測(cè)到高電平,先進(jìn)行消抖
			if (KEY0 == 1)
			{
				g_keyStatus = KS_SHAKE;
			}
			else
			{
				if (g_LongPressTimeCnt % 20 == 0) //每隔1000ms打印一次
				{
					printf("=====> key long press:%d\r\n", g_LongPressTimeCnt/20);
					
					keyEvent = KE_LONG_PRESS;
				}
				g_LongPressTimeCnt++;
			}
		}
		break;
		
		//等待再次按下
		case KS_WAIT_PRESS_AGAIN:
		{
			//檢測(cè)到低電平,先進(jìn)行消抖
			if (KEY0 == 0)
			{
				g_keyStatus = KS_SHAKE;
			}
			
			g_WaitPressAgainCnt++;
			if (g_WaitPressAgainCnt == 4) //200ms沒(méi)有再次按下
			{
				printf("=====> key single press\r\n");
				g_keyStatus = KS_RELEASE;
			}
		}
		break;
		
		//確認(rèn)第2次按下
		case KS_AFFIRM_PRESS_AGAIN:
		{
			//檢測(cè)到高電平,先進(jìn)行消抖
			if (KEY0 == 1)
			{
				g_keyStatus = KS_SHAKE;
			}
			
			g_Press2TimeCnt++;
			if (g_Press2TimeCnt == 20) //1000ms
			{
				g_LongPressTimeCnt = 0;
				g_keyStatus = KS_AFFIRM_LONG_PRESS;
			}
		}
		break;
		
	    //確認(rèn)長(zhǎng)按
		case KS_AFFIRM_LONG_PRESS:
		{
			//檢測(cè)到高電平,先進(jìn)行消抖
			if (KEY0 == 1)
			{
				g_keyStatus = KS_SHAKE;
			}
			
			g_LongPressTimeCnt++;
			if (g_LongPressTimeCnt % 20 == 0) //每隔1000ms打印一次
			{
				printf("=====> key long press:%d\r\n", g_LongPressTimeCnt/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]);
	}
}

最后注釋掉的一句是調(diào)試打印,調(diào)試時(shí)可打開,方便觀察狀態(tài)變化

1.3 測(cè)試

短按、長(zhǎng)按、雙擊的測(cè)試結(jié)果如下:

poYBAGMUaeGAAoP2AAEtu7uP7lU210.png

還有從確認(rèn)第2次按下狀態(tài)到達(dá)的長(zhǎng)按狀態(tài):

pYYBAGMUaeeANCNHAAByVtpyQgE552.png

2 功能優(yōu)化

上面的代碼實(shí)現(xiàn),是在主函數(shù)中,每50ms延時(shí)執(zhí)行一次狀態(tài)機(jī)循環(huán)(主函數(shù)代碼如下),僅用做演示按鍵狀態(tài)機(jī)的運(yùn)行機(jī)制。

int main(void)
{	
	delay_init();
	KEY_Init();
	uart_init(115200);

	printf("hello\r\n");
	
	while(1)
	{
		key_status_check();
		delay_ms(50);
	}
}

實(shí)際開發(fā)中,按鍵檢測(cè)程序,應(yīng)該作為一個(gè)獨(dú)立的模塊運(yùn)行,當(dāng)檢測(cè)到某一按鍵狀態(tài)觸發(fā)時(shí),通知應(yīng)用程序來(lái)使用。

對(duì)于stm32裸機(jī)開發(fā)來(lái)說(shuō),可以將按鍵狀態(tài)機(jī)放到一個(gè)定時(shí)器中斷服務(wù)函數(shù)中運(yùn)行,當(dāng)檢測(cè)到某一按鍵狀態(tài)觸發(fā)后,通知應(yīng)用程序:

//主函數(shù)
int main(void)
{	
	delay_init();
	KEY_Init();
	uart_init(115200);
	TIM3_Int_Init(500-1,7200-1); //調(diào)用定時(shí)器使得50ms產(chǎn)生一個(gè)中斷

	printf("hello\r\n");
	
	while(1)
	{
	}
}

//定時(shí)器3中斷服務(wù)程序
void TIM3_IRQHandler(void)   //TIM3中斷
{
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //檢查TIM3更新中斷發(fā)生與否
	{
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx更新中斷標(biāo)志 
		
		KEY_EVENT keyEvent = key_status_check();
		switch (keyEvent)
		{
			case KE_SHORT_PRESS:  printf("檢測(cè)到單擊\r\n"); break;
			case KE_DOUBLE_PRESS: printf("檢測(cè)到雙擊\r\n"); break;
			case KE_LONG_PRESS:   printf("檢測(cè)到長(zhǎng)按\r\n"); break;
			default:break;
		}
	}
}

3 總結(jié)

本篇在前兩篇按鍵狀態(tài)機(jī)的基礎(chǔ)上,繼續(xù)介紹增加按鍵的雙擊功能,并解決之前狀態(tài)存在的兩個(gè)問(wèn)題,通過(guò)實(shí)測(cè)驗(yàn)證,演示短按、長(zhǎng)按、雙擊的使用效果。最后對(duì)代碼結(jié)構(gòu)進(jìn)行優(yōu)化,使其更符合實(shí)際開發(fā)應(yīng)用。

審核編輯 黃昊宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 單片機(jī)
    +關(guān)注

    關(guān)注

    6078

    文章

    45569

    瀏覽量

    673321
  • 嵌入式
    +關(guān)注

    關(guān)注

    5209

    文章

    20625

    瀏覽量

    336764
  • STM32
    +關(guān)注

    關(guān)注

    2312

    文章

    11189

    瀏覽量

    374520
  • 狀態(tài)機(jī)
    +關(guān)注

    關(guān)注

    2

    文章

    501

    瀏覽量

    29316
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    STM32按鍵消抖——入門狀態(tài)機(jī)思維

    本篇介紹了嵌入式軟件開發(fā)中常用的狀態(tài)機(jī)編程實(shí)現(xiàn),并通過(guò)按鍵消抖實(shí)例,以常用的switch-case形式,實(shí)現(xiàn)了對(duì)應(yīng)的狀態(tài)機(jī)編程代碼實(shí)現(xiàn),并通過(guò)測(cè)試,串口打印對(duì)應(yīng)狀態(tài),分析
    的頭像 發(fā)表于 09-02 21:54 ?6224次閱讀
    <b class='flag-5'>STM32</b><b class='flag-5'>按鍵</b>消抖——入門<b class='flag-5'>狀態(tài)機(jī)</b>思維

    STM32按鍵狀態(tài)機(jī)2——狀態(tài)簡(jiǎn)化與增加長(zhǎng)按功能

    本篇繼續(xù)介紹狀態(tài)機(jī)的使用,在上篇的基礎(chǔ)上,通過(guò)簡(jiǎn)化按鍵去抖邏輯,并增加按鍵長(zhǎng)按功能,進(jìn)一步介紹狀態(tài)圖的修改與
    的頭像 發(fā)表于 09-03 21:26 ?5601次閱讀
    <b class='flag-5'>STM32</b><b class='flag-5'>按鍵</b><b class='flag-5'>狀態(tài)機(jī)</b>2——<b class='flag-5'>狀態(tài)</b>簡(jiǎn)化與<b class='flag-5'>增加</b>長(zhǎng)按<b class='flag-5'>功能</b>

    單片機(jī)狀態(tài)機(jī)按鍵長(zhǎng)按和短按實(shí)現(xiàn)

    本文只介紹主要代碼段,完整代碼可參考我的“藍(lán)橋杯單片機(jī)狀態(tài)機(jī)按鍵按下和松開實(shí)現(xiàn)不同功能”藍(lán)橋杯單片機(jī)狀態(tài)
    發(fā)表于 01-06 08:26

    利用狀態(tài)機(jī)按鍵消抖程序

    利用狀態(tài)機(jī)按鍵消抖程序講解,很好的資料下載吧。
    發(fā)表于 01-11 09:32 ?30次下載

    狀態(tài)機(jī)原理及用法

    狀態(tài)機(jī)原理及用法狀態(tài)機(jī)原理及用法狀態(tài)機(jī)原理及用法
    發(fā)表于 03-15 15:25 ?0次下載

    基于狀態(tài)機(jī)的單片機(jī)按鍵短按長(zhǎng)按功能的實(shí)現(xiàn)

    本文主要介紹了基于狀態(tài)機(jī)的單片機(jī)按鍵短按長(zhǎng)按功能的實(shí)現(xiàn),按鍵的擊鍵過(guò)程也是一種狀態(tài)的切換,也可以
    發(fā)表于 12-28 08:43 ?2.1w次閱讀
    基于<b class='flag-5'>狀態(tài)機(jī)</b>的單片<b class='flag-5'>機(jī)</b><b class='flag-5'>按鍵</b>短按長(zhǎng)按<b class='flag-5'>功能</b>的實(shí)現(xiàn)

    FPGA:狀態(tài)機(jī)簡(jiǎn)述

    本文目錄 前言 狀態(tài)機(jī)簡(jiǎn)介 狀態(tài)機(jī)分類 Mealy 型狀態(tài)機(jī) Moore 型狀態(tài)機(jī) 狀態(tài)機(jī)描述 一段式
    的頭像 發(fā)表于 11-05 17:58 ?9003次閱讀
    FPGA:<b class='flag-5'>狀態(tài)機(jī)</b>簡(jiǎn)述

    使用Synplify設(shè)計(jì)安全的VHDL狀態(tài)機(jī)

    Synplify的優(yōu)勢(shì)之一是有限狀態(tài)機(jī)編譯器。 這是一個(gè)強(qiáng)大的功能,不僅具有自動(dòng)檢測(cè)狀態(tài)機(jī)中的狀態(tài)的能力源代碼,并使用順序編碼,灰色編碼或一鍵編碼實(shí)現(xiàn)它們。但也要進(jìn)行可達(dá)性分析,以確定
    發(fā)表于 04-07 09:20 ?12次下載
    使用Synplify設(shè)計(jì)安全的VHDL<b class='flag-5'>狀態(tài)機(jī)</b>

    基于STM32按鍵的防抖和松開處理:狀態(tài)機(jī)

    用延時(shí)和while();去處理按鍵很浪費(fèi)資源,這里我們用定時(shí)器來(lái)做一個(gè)按鍵的處理-狀態(tài)機(jī);typedef enum {KEY_RELEASED,KEY_PRESSED,KEY_PROCESSED
    發(fā)表于 12-09 09:21 ?8次下載
    基于<b class='flag-5'>STM32</b><b class='flag-5'>按鍵</b>的防抖和松開處理:<b class='flag-5'>狀態(tài)機(jī)</b>

    狀態(tài)模式(狀態(tài)機(jī))

    share,作者:亞索老哥)),原來(lái)狀態(tài)機(jī)還可以這么簡(jiǎn)單地玩~~亞索老哥提出的狀態(tài)機(jī)六步法(1)、定義狀態(tài)接口(2)、定義系統(tǒng)當(dāng)前狀態(tài)指針(3
    發(fā)表于 12-16 16:53 ?9次下載
    <b class='flag-5'>狀態(tài)</b>模式(<b class='flag-5'>狀態(tài)機(jī)</b>)

    STM32實(shí)現(xiàn)按鍵有限狀態(tài)機(jī)(超詳細(xì),易移植)

    STM32實(shí)現(xiàn)按鍵有限狀態(tài)機(jī)(超詳細(xì),易移植)一、狀態(tài)機(jī)簡(jiǎn)而言之,狀態(tài)機(jī)是使不同狀態(tài)之間的改變以
    發(fā)表于 12-17 18:37 ?26次下載
    <b class='flag-5'>STM32</b>實(shí)現(xiàn)<b class='flag-5'>按鍵</b>有限<b class='flag-5'>狀態(tài)機(jī)</b>(超詳細(xì),易移植)

    藍(lán)橋杯單片機(jī)狀態(tài)機(jī)按鍵按下和松開實(shí)現(xiàn)不同功能

    藍(lán)橋杯單片機(jī)狀態(tài)機(jī)按鍵按下和松開實(shí)現(xiàn)不同功能獨(dú)立按鍵狀態(tài)機(jī)讀取函數(shù)key_flag 鍵值讀取標(biāo)志
    發(fā)表于 12-29 19:25 ?21次下載
    藍(lán)橋杯單片<b class='flag-5'>機(jī)</b><b class='flag-5'>狀態(tài)機(jī)</b><b class='flag-5'>按鍵</b>按下和松開實(shí)現(xiàn)不同<b class='flag-5'>功能</b>

    STM32狀態(tài)機(jī)編程實(shí)例——全自動(dòng)洗衣機(jī)(上)

    本篇實(shí)現(xiàn)了一款全自動(dòng)洗衣機(jī)的基礎(chǔ)洗衣控制流程,可實(shí)現(xiàn)不同水位與清洗次數(shù)的設(shè)置,以及任務(wù)的暫停與繼續(xù)。此外,通過(guò)對(duì)之前按鍵狀態(tài)機(jī)的進(jìn)一步優(yōu)化修改,實(shí)現(xiàn)了
    的頭像 發(fā)表于 09-06 08:47 ?4660次閱讀
    <b class='flag-5'>STM32</b><b class='flag-5'>狀態(tài)機(jī)</b>編程實(shí)例——全自動(dòng)洗衣<b class='flag-5'>機(jī)</b>(上)

    按鍵狀態(tài)機(jī)代碼

    自己寫的按鍵狀態(tài)機(jī),需要的時(shí)候根據(jù)情況修改一下
    發(fā)表于 03-27 10:42 ?8次下載

    什么是狀態(tài)機(jī)?狀態(tài)機(jī)的種類與實(shí)現(xiàn)

    狀態(tài)機(jī),又稱有限狀態(tài)機(jī)(Finite State Machine,F(xiàn)SM)或米利狀態(tài)機(jī)(Mealy Machine),是一種描述系統(tǒng)狀態(tài)變化的模型。在芯片設(shè)計(jì)中,
    的頭像 發(fā)表于 10-19 10:27 ?1.3w次閱讀