?? key.c~
字號:
/** ****************************************************************************** * @file key.c * @brief 用狀態機編寫的按鍵掃描 * @author ifree64 - stm8 手持示波表開源項目組 * @version V0.1.0 * @date 03/25/2009 ****************************************************************************** * * free for use * ****************************************************************************** */#include "key.h"enum KEY_ScanState{ KSCAN_START = 0, /* 無鍵按下, 鍵盤掃描初始狀態 */ KSCAN_PRESS, /* 鍵按下,判斷抖動, >0.1s */ KSCAN_LONGPRESS, /* 非抖動,判斷是否長按鍵,>0.8s */ KSCAN_PDLF, /* 判斷連發,得到一次長按鍵后1s開始連發 */ KSCAN_LIANFA, /* 連發,每0.2s產生一次連發按鍵 */};struct KEY_StateFsm{ enum KScanState KPressNext; /* 鍵按下,下一個狀態 */ enum KScanState NoKeyNext; /* 鍵抬起,下一個狀態 */ u8 KPressTime; /* 鍵按下需持續的時間, 10ms的倍數 */ u8 KPressType; /* 鍵按下滿足條件,輸出按鍵類型 */ };/* 保證狀態編號值與在數組中的位置相同 */struct KEY_StateFsm KEY_StateFsmTable[] = { /* kpress_next, nokey_next, time, type */ { KSCAN_PRESS, KSCAN_START, 0, KTYPE_NO}, /* KSCAN_START: 0 */ { KSCAN_LONGPRESS, KSCAN_START, 5, KTYPE_NORMAL}, /* KSCAN_PRESS: 1 */ { KSCAN_PDLF, KSCAN_START, 80, KTYPE_LONG}, /* KSCAN_LONGPRESS: 2 */ { KSCAN_LIANFA, KSCAN_START, 100, KTYPE_NO}, /* KSCAN_PDLF: 3 */ { KSCAN_LIANFA, KSCAN_START, 20, KTYPE_LIANFA} /* KSCAN_LIANFA: 4*/};void KEY_Init(void){ /* Initialize I/O in Input Mode with No Interrupt */ GPIO_Init(BUTTON_PORT, BUTTON_PIN, GPIO_MODE_IN_FL_NOIT); }/* 功能描述:讀取按鍵狀態, 根據不同按鍵電路和編號方式修改本函數 入口參數:無 出口參數:按鍵編號 */u8 KEY_Read(void){ u8 KMask = GPIO_ReadInputData(BUTTON_PORT); u8 KCode = 0; KMask = GPIO_ReadInputData(BUTTON_PORT) ^ 0xff; // 讀引腳狀態,取反后1表示鍵按下 // BUTTON_PORT上接8個獨立式按鍵,從低到高編號為1~8 while(KMask != 0) { KMask >>= 1; KCode++; } return KCode;}/* 使用說明:為了得到該函數提供的功能,必須每10ms調用1次 功能描述:按鍵掃描,根據狀態表的設置,返回當前按鍵狀態 入口參數:無 出口參數:按鍵編號和按鍵種類,格式如下 D7 D6 D5 D4 D3 D2 D1 D0 M1 M0 K5 K4 K3 K2 K1 K0M1:M0 表示按鍵類型, 01 普通 10 長按鍵 11 連發按鍵K5:K0 按鍵編號 1~63, 總共可以支持2^6 - 1 = 63個按鍵 */u8 KEY_Scan(void){ static enum KEY_ScanState KScan_CurrState = KSCAN_START; static u8 OldKey; static u8 KTimeCounter = 0; u8 rKeyCode = 0; // 0 for No key press u8 CurrKey = KEY_Read(); if( (CurrKey != 0) && (CurrKey == OldKey) ) { if(++KTimeCounter >= KEY_StateFsmTable[ks].KPressTime ) { KTimeCounter = 0; rKeyCode = KEY_StateFsmTable[KScan_CurrState].KPressType | CurrKey; KScan_CurrState = KEY_StateFsmTable[KScan_CurrState].KPressNext; } } else { // 抖動或新鍵 KScan_CurrState = KEY_StateFsmTable[KScan_CurrState].NoKeyNext; OldKey = CurrKey; } return rKeyCode;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -