本文最后修改時間:2018年10月22日 01:57
一、本節簡介
本文介紹STM8S系列如何實現按鍵的短按、長按、連擊。
二、實驗平臺
編譯軟件:IAR for STM8 1.42.2
硬件平臺:stm8s003f3p6開發板
仿真器:ST-LINK
庫函數版本:V2.0.0
三、版權聲明
1)作者:甜甜的大香瓜
2)聲明:喝水不忘挖井人,轉載請注明出處。
3)糾錯/業務合作:897503845@qq.com
4)香瓜嵌入式之STM8/STM32群:164311667
5)本文出處:原創連載資料《簡單粗暴學STM8和STM32》
6)完整開源資料下載地址(電腦端打開):opengua.taobao.com
四、實驗前提
1、在進行本文步驟前,請先閱讀以下章節:
1)《簡單粗暴學STM8和STM32》的“第一章和第三章”章節?。
2、在進行本文步驟前,請先實現以下章節:
1)《簡單粗暴學STM8和STM32》的《STM8S之內外部16M晶振》。
五、基礎知識
暫無
六、硬件原理
????
由上圖可知當K1松開時PD3為高電平,K1按下后PD3為低電平。
七、實驗步驟
1、工程中添加自己寫的按鍵驅動
1)寫一個按鍵驅動GUA_Key.c(存放在工程的USER文件夾中)
//********************************************************************** //name:???????? GUA_Key.c //introduce:??? 按鍵驅動 //author:?????? 甜甜的大香瓜????? //email:???? ???897503845@qq.com?? //QQ group:???? 香瓜單片機之STM8/STM32(164311667) //shop:???????? opengua.taobao.com //changetime:?? 2018.10.16 //********************************************************************** #include "stm8s.h" #include "GUA_Key.h" /*********************宏定義************************/ //按鍵觸發宏? #define GUA_KEY_TRIGGER??????????? RESET??????????????????????????????? //低電平觸發? ? //目測的時鐘基準 //#define GUA_KEY_STANDARD_1MS??????????? 100 //按鍵消抖宏? #define GUA_KEY_DISAPPEARS_SHAKES_SHORT_COUNT?????????? 1000???????? //短按鍵消抖數 #define GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT??????????? 150000?????? //長按2.5消抖數 /*********************內部變量************************/? static GUA_U32 sGUA_Key_DisappearsShakes_TriggerCount = 0;????????????? //消抖時的觸發狀態計數值? ? //********************************************************************** //name:???????? GUA_Key_Scan //introduce:??? 按鍵檢測觸發狀態 //parameter:??? none //return:?????? GUA_KEY_STATUS_IDLE or GUA_KEY_STATUS_TRIGGER_SHORT or GUA_KEY_STATUS_TRIGGER_LONG or GUA_KEY_STATUS_NO_LOOSEN //author:?????? 甜甜的大香瓜 //email:??????? 897503845@qq.com //QQ group:???? 香瓜單片機之STM8/STM32(164311667) //shop:???????? opengua.taobao.com //changetime:?? 2018.10.16 //********************************************************************** GUA_U8 GUA_Key_Scan(void)????? {????? ? GUA_U32 nGUA_TimeOut = 0;??? ?? ? //觸發 ? if(GPIO_ReadInputPin(GUA_KEY_PORT, GUA_KEY_PIN) == GUA_KEY_TRIGGER)?? ? {? ??? //如果上一次按鍵是長按鍵結束的,需要檢測到松開方可開始下一次計數 ??? if(sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT) ??? { ????? return GUA_KEY_STATUS_NO_LOOSEN; ??? } ??? //計數 ??? sGUA_Key_DisappearsShakes_TriggerCount++;??? ??? ??? //判斷計數是否足夠? ??? while(sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_SHORT_COUNT)? ??? {? ????? //檢測到松開、超時的時候,則處理? ????? if((GPIO_ReadInputPin(GUA_KEY_PORT, GUA_KEY_PIN) != GUA_KEY_TRIGGER) || (sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT))? ????? {? ??????? //長按2.5S時? ??????? if(sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT)? ??????? {??????????? ????????? //返回 ????????? return GUA_KEY_STATUS_TRIGGER_LONG;?????????????????????????? ??????? }???????????????? ??????? //短按鍵時? ??????? else? ??????? {?????? ????????? //超時計數值清零 ????????? nGUA_TimeOut = 0; ??????????? ????????? //檢測是否有連按 ????????? while((GPIO_ReadInputPin(GUA_KEY_PORT, GUA_KEY_PIN) != GUA_KEY_TRIGGER)) ????????? {???? ??????? ??????????? //沒有被按下,超時,則表示只有1次按鍵 ??????????? if(nGUA_TimeOut++ > 100000) ??????????? { ????????????? //計數值清零 ????????????? sGUA_Key_DisappearsShakes_TriggerCount = 0; ????????????? ????????????? return GUA_KEY_STATUS_TRIGGER_SHORT; ??????????? }? ??????????????????? ????????? } ????????? ????????? //判斷計數是否足夠? ????????? while(GPIO_ReadInputPin(GUA_KEY_PORT, GUA_KEY_PIN) == GUA_KEY_TRIGGER) ????????? { ??????????? //開始計數 ??????????? sGUA_Key_DisappearsShakes_TriggerCount++; ??????????? //檢測到松開、超時的時候,則處理? ??????????? if((GPIO_ReadInputPin(GUA_KEY_PORT, GUA_KEY_PIN) != GUA_KEY_TRIGGER) || (sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT))? ??????????? {????????????? ????????????? //長按2.5S時? ? ????????????if(sGUA_Key_DisappearsShakes_TriggerCount >= GUA_KEY_DISAPPEARS_SHAKES_LONG_COUNT)? ????????????? {??????????? ??????????????? //清除計數器 ??????????????? sGUA_Key_DisappearsShakes_TriggerCount = 0; ??????????????? ??????????????? //返回 ???????? ???????return GUA_KEY_STATUS_TRIGGER_LONG;?????????????????????????? ????????????? }???????????????? ????????????? //短按鍵時? ????????????? else? ????????????? {??? ??????????????? //清除計數器 ??????????????? sGUA_Key_DisappearsShakes_TriggerCount = 0; ???? ??????????? ??????????????? //返回 ??????????????? return GUA_KEY_STATUS_TRIGGER_DOUBLE_SHORT;????????????????? ????????????? }? ??????????? }????????????????????????? ????????? } ????????? ????????? //清除計數器 ????????? sGUA_Key_DisappearsShakes_TriggerCount = 0; ??????????????? ????????? //返回 ????????? return GUA_KEY_STATUS_TRIGGER_DOUBLE_SHORT;????????? ??????? }? ????? }? ????? ????? //繼續計數用來判斷長短按鍵? ????? sGUA_Key_DisappearsShakes_TriggerCount++;?????? ??? ??? }???? ? }? ? //未觸發? ? else? ? {? ??? sGUA_Key_DisappearsShakes_TriggerCount = 0;?? ? }? ??? ? return GUA_KEY_STATUS_IDLE;??? }?? //********************************************************************** //name:???????? GUA_Key_Init //introduce:??? 按鍵初始化 //parameter:??? none //return:?????? none //author:?????? 甜甜的大香瓜 //email:??????? 897503845@qq.com //QQ group:???? 香瓜單片機之STM8/STM32(164311667) //shop:???????? opengua.taobao.com //changetime:?? 2018.10.16 //********************************************************************** void GUA_Key_Init(void) { ? //按鍵IO初始化 ? GPIO_Init(GUA_KEY_PORT, GUA_KEY_PIN, GUA_KEY_MODE);?????? } |
2)寫一個驅動頭文件GUA_Key.h(存放在工程的USER文件夾中)
//********************************************************************** //name:???????? GUA_Key.h //introduce:??? 按鍵驅動的頭文件 //author:?????? 甜甜的大香瓜????? //email:??????? 897503845@qq.com?? //QQ group:???? 香瓜單片機之STM8/STM32(164311667) //shop:???????? opengua.taobao.com //changetime:?? 2018.10.16 //********************************************************************** #ifndef _GUA_KEY_H_ #define _GUA_KEY_H_ /*********************宏定義************************/ //類型宏 #ifndef GUA_C typedef char GUA_C; #endif #ifndef GUA_U8 typedef unsigned char GUA_U8; #endif #ifndef GUA_8 typedef signed char GUA_8; #endif #ifndef GUA_U16 typedef unsigned short GUA_U16; #endif #ifndef GUA_16 typedef signed short GUA_16; #endif #ifndef GUA_U32 typedef unsigned long GUA_U32; #endif #ifndef GUA_32 typedef signed long GUA_32; #endif #ifndef GUA_U64 typedef unsigned long long GUA_U64; #endif #ifndef GUA_64 typedef signed long long GUA_64; #endif? //按鍵引腳宏 #define GUA_KEY_PORT??????????????????? GPIOD #define GUA_KEY_PIN???????????????????? GPIO_PIN_3 #define GUA_KEY_MODE??????????????????? GPIO_MODE_IN_PU_NO_IT //按鍵的觸發狀態? #define GUA_KEY_STATUS_IDLE???????????????????? 0?????? //按鍵沒觸發? #define GUA_KEY_STATUS_TRIGGER_SHORT??????????? 1?????? //短按鍵觸發 #define GUA_KEY_STATUS_TRIGGER_DOUBLE_SHORT???? 2?????? //雙擊觸發 #define GUA_KEY_STATUS_TRIGGER_LONG???????????? 3?????? //長按鍵2.5S觸發 #define GUA_KEY_STATUS_NO_LOOSEN??????????????? 4?????? //按鍵沒松開 /*********************外部函數聲明************************/ GUA_U8 GUA_Key_Scan(void);? void GUA_Key_Init(void); #endif |
3)工程中添加GUA_Key.c
4)添加驅動的路徑
$PROJ_DIR$\..\USER? |
注意USER文件夾是與“Project”、“FWlib”文件夾同級的自定義文件,用于存放香瓜寫的代碼。
2、添加庫的驅動
1)添加庫的驅動文件
2)添加庫的驅動頭文件(stm8s_conf.h中)
#include "stm8s_gpio.h" |
3、應用層中調用
1)添加頭文件(main.c中)
#include "GUA_Key.h" |
2)初始化(main.c的main函數中)
? //按鍵初始化 ? GUA_Key_Init(); |
3)添加按鍵判斷的邏輯代碼(main.c的main函數中)
? ??????GUA_U8 nGUA_Ret; ??????? //檢測按鍵當前狀態 ??????? nGUA_Ret = GUA_Key_Scan(); ??????? //短按鍵觸發時 ??????? if(nGUA_Ret == GUA_KEY_STATUS_TRIGGER_SHORT) ??????? {??? ??????? } ??????? //連擊觸發時 ??????? else if(nGUA_Ret == GUA_KEY_STATUS_TRIGGER_DOUBLE_SHORT) ??????? {? ??????? } ??????? //長按鍵觸發時 ??????? else if(nGUA_Ret == GUA_KEY_STATUS_TRIGGER_LONG) ??????? { |
??????? } |
八、注意事項
暫無
九、實驗結果
暫無