?? button.c
字號:
/****************************************************************************
* Copyright (C), 2009-2010, www.armfly.com
*
* 文件名: button.c
* 內容簡述: 本模塊實現7個按鍵的檢測,具有濾波機制,支持按下,彈起和長按動作。
* 通過GetKey()函數可以讀取鍵值
* 文件歷史:
* 版本號 日期 作者 說明
* v0.1 2009-12-27 armfly 創建該文件
*
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include <stdio.h>
#include "button.h"
static BUTTON_T s_BtnUser; /* USER 鍵 */
static BUTTON_T s_BtnTamper; /* TAMPER 鍵 */
static BUTTON_T s_BtnWakeUp; /* WAKEUP 鍵 */
static BUTTON_T s_BtnUp; /* 搖桿UP鍵 */
static BUTTON_T s_BtnDown; /* 搖桿DOWN鍵 */
static BUTTON_T s_BtnLeft; /* 搖桿LEFT鍵 */
static BUTTON_T s_BtnRight; /* 搖桿RIGHT鍵 */
static BUTTON_T s_BtnOk; /* 搖桿OK鍵 */
static KEY_FIFO_T s_Key; /* 按鍵FIFO變量,結構體 */
/*
安富萊STM32F103ZE-EK 按鍵口線分配:
USER鍵 : PG8 (低電平表示按下)
TAMPEER鍵 : PC13 (低電平表示按下)
WKUP鍵 : PA0 (!!!高電平表示按下)
搖桿UP鍵 : PG15 (低電平表示按下)
搖桿DOWN鍵 : PD3 (低電平表示按下)
搖桿LEFT鍵 : PG14 (低電平表示按下)
搖桿RIGHT鍵: PG13 (低電平表示按下)
搖桿OK鍵 : PG7 (低電平表示按下)
定義7個函數,判斷按鍵是否按下,返回值1 表示按下,0表示未按下
*/
static uint8_t IsKeyDownUser(void) {if (GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_8) == Bit_SET) return 0; return 1;}
static uint8_t IsKeyDownTamper(void) {if (GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_13) == Bit_SET) return 0; return 1;}
static uint8_t IsKeyDownWakeUp(void) {if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == Bit_SET) return 1; return 0;}
static uint8_t IsKeyDownUp(void) {if (GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_15) == Bit_SET) return 0; return 1;}
static uint8_t IsKeyDownDown(void) {if (GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_3) == Bit_SET) return 0; return 1;}
static uint8_t IsKeyDownLeft(void) {if (GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_14) == Bit_SET) return 0; return 1;}
static uint8_t IsKeyDownRight(void) {if (GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_13) == Bit_SET) return 0; return 1;}
static uint8_t IsKeyDownOk(void) {if (GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_7) == Bit_SET) return 0; return 1;}
/*******************************************************************************
函數名: InitButtonVar
輸 入:
輸 出:
功能說明:初始化所有的按鍵變量,這個函數需要在systic中斷啟動錢調用1次
*/
void InitButtonVar(void)
{
/* 對按鍵FIFO讀寫指針清零 */
s_Key.Read = 0;
s_Key.Write = 0;
/* 初始化USER按鍵變量 */
s_BtnUser.IsKeyDownFunc = IsKeyDownUser; /* 判斷按鍵按下的函數 */
s_BtnUser.FilterTime = BUTTON_FILTER_TIME; /* 按鍵濾波時間 */
s_BtnUser.LongTime = BUTTON_LONG_TIME; /* 長按時間 */
s_BtnUser.Count = s_BtnUser.FilterTime / 2; /* 計數器設置為濾波時間的一半 */
s_BtnUser.State = 0; /* 按鍵缺省狀態,0為未按下 */
s_BtnUser.KeyCodeDown = KEY_DOWN_USER; /* 按鍵按下的鍵值代碼 */
s_BtnUser.KeyCodeUp = KEY_UP_USER; /* 按鍵彈起的鍵值代碼 */
s_BtnUser.KeyCodeLong = KEY_HOLD_USER; /* 按鍵被持續按下的鍵值代碼 */
/* 初始化TAMPER按鍵變量 */
s_BtnTamper.IsKeyDownFunc = IsKeyDownTamper; /* 判斷按鍵按下的函數 */
s_BtnTamper.FilterTime = BUTTON_FILTER_TIME; /* 按鍵濾波時間 */
s_BtnTamper.LongTime = 0; /* 長按時間, 0表示不檢測 */
s_BtnTamper.Count = s_BtnTamper.FilterTime / 2; /* 計數器設置為濾波時間的一半 */
s_BtnTamper.State = 0; /* 按鍵缺省狀態,0為未按下 */
s_BtnTamper.KeyCodeDown = KEY_DOWN_TAMPER; /* 按鍵按下的鍵值代碼 */
s_BtnTamper.KeyCodeUp = 0; /* 按鍵彈起的鍵值代碼 */
s_BtnTamper.KeyCodeLong = 0; /* 按鍵被持續按下的鍵值代碼 */
/* 初始化WAKEUP按鍵變量 */
s_BtnWakeUp.IsKeyDownFunc = IsKeyDownWakeUp; /* 判斷按鍵按下的函數 */
s_BtnWakeUp.FilterTime = BUTTON_FILTER_TIME; /* 按鍵濾波時間 */
s_BtnWakeUp.LongTime = 0; /* 長按時間 */
s_BtnWakeUp.Count = s_BtnWakeUp.FilterTime / 2; /* 計數器設置為濾波時間的一半 */
s_BtnWakeUp.State = 0; /* 按鍵缺省狀態,0為未按下 */
s_BtnWakeUp.KeyCodeUp = 0; /* 按鍵彈起的鍵值代碼,0表示不檢測 */
s_BtnWakeUp.KeyCodeDown = KEY_DOWN_WAKEUP; /* 按鍵按下的鍵值代碼 */
s_BtnWakeUp.KeyCodeLong = 0; /* 按鍵被持續按下的鍵值代碼,0表示不檢測 */
/* 初始化UP按鍵變量 */
s_BtnUp.IsKeyDownFunc = IsKeyDownUp; /* 判斷按鍵按下的函數 */
s_BtnUp.FilterTime = BUTTON_FILTER_TIME; /* 按鍵濾波時間 */
s_BtnUp.LongTime = 0; /* 長按時間 */
s_BtnUp.Count = s_BtnUp.FilterTime / 2; /* 計數器設置為濾波時間的一半 */
s_BtnUp.State = 0; /* 按鍵缺省狀態,0為未按下 */
s_BtnUp.KeyCodeDown = KEY_DOWN_JOY_UP; /* 按鍵按下的鍵值代碼 */
s_BtnUp.KeyCodeUp = 0; /* 按鍵彈起的鍵值代碼,0表示不檢測 */
s_BtnUp.KeyCodeLong = 0; /* 按鍵被持續按下的鍵值代碼,0表示不檢測 */
/* 初始化DOWN按鍵變量 */
s_BtnDown.IsKeyDownFunc = IsKeyDownDown; /* 判斷按鍵按下的函數 */
s_BtnDown.FilterTime = BUTTON_FILTER_TIME; /* 按鍵濾波時間 */
s_BtnDown.LongTime = 0; /* 長按時間 */
s_BtnDown.Count = s_BtnDown.FilterTime / 2; /* 計數器設置為濾波時間的一半 */
s_BtnDown.State = 0; /* 按鍵缺省狀態,0為未按下 */
s_BtnDown.KeyCodeDown = KEY_DOWN_JOY_DOWN; /* 按鍵按下的鍵值代碼 */
s_BtnDown.KeyCodeUp = 0; /* 按鍵彈起的鍵值代碼,0表示不檢測 */
s_BtnDown.KeyCodeLong = 0; /* 按鍵被持續按下的鍵值代碼,0表示不檢測 */
/* 初始化LEFT按鍵變量 */
s_BtnLeft.IsKeyDownFunc = IsKeyDownLeft; /* 判斷按鍵按下的函數 */
s_BtnLeft.FilterTime = BUTTON_FILTER_TIME; /* 按鍵濾波時間 */
s_BtnLeft.LongTime = 0; /* 長按時間 */
s_BtnLeft.Count = s_BtnLeft.FilterTime / 2; /* 計數器設置為濾波時間的一半 */
s_BtnLeft.State = 0; /* 按鍵缺省狀態,0為未按下 */
s_BtnLeft.KeyCodeDown = KEY_DOWN_JOY_LEFT; /* 按鍵按下的鍵值代碼 */
s_BtnLeft.KeyCodeUp = 0; /* 按鍵彈起的鍵值代碼,0表示不檢測 */
s_BtnLeft.KeyCodeLong = 0; /* 按鍵被持續按下的鍵值代碼,0表示不檢測 */
/* 初始化RIGHT按鍵變量 */
s_BtnRight.IsKeyDownFunc = IsKeyDownRight; /* 判斷按鍵按下的函數 */
s_BtnRight.FilterTime = BUTTON_FILTER_TIME; /* 按鍵濾波時間 */
s_BtnRight.LongTime = 0; /* 長按時間 */
s_BtnRight.Count = s_BtnRight.FilterTime / 2;/* 計數器設置為濾波時間的一半 */
s_BtnRight.State = 0; /* 按鍵缺省狀態,0為未按下 */
s_BtnRight.KeyCodeDown = KEY_DOWN_JOY_RIGHT;/* 按鍵按下的鍵值代碼 */
s_BtnRight.KeyCodeUp = 0; /* 按鍵彈起的鍵值代碼,0表示不檢測 */
s_BtnRight.KeyCodeLong = 0; /* 按鍵被持續按下的鍵值代碼,0表示不檢測 */
/* 初始化OK按鍵變量 */
s_BtnOk.IsKeyDownFunc = IsKeyDownOk; /* 判斷按鍵按下的函數 */
s_BtnOk.FilterTime = BUTTON_FILTER_TIME; /* 按鍵濾波時間 */
s_BtnOk.LongTime = 0; /* 長按時間 */
s_BtnOk.Count = s_BtnOk.FilterTime / 2; /* 計數器設置為濾波時間的一半 */
s_BtnOk.State = 0; /* 按鍵缺省狀態,0為未按下 */
s_BtnOk.KeyCodeDown = KEY_DOWN_JOY_OK; /* 按鍵按下的鍵值代碼 */
s_BtnOk.KeyCodeUp = 0; /* 按鍵彈起的鍵值代碼,0表示不檢測 */
s_BtnOk.KeyCodeLong = 0; /* 按鍵被持續按下的鍵值代碼,0表示不檢測 */
}
/*******************************************************************************
函數名: PutKey
輸 入: 鍵值
輸 出:
功能說明:將1個鍵值壓入按鍵FIFO緩沖區
*/
void PutKey(uint8_t _KeyCode)
{
s_Key.Buf[s_Key.Write] = _KeyCode;
if (++s_Key.Write >= KEY_FIFO_SIZE)
{
s_Key.Write = 0;
}
}
/*******************************************************************************
函數名: GetKey
輸 入:
輸 出: 返回鍵值, KEY_NONE ( = 0) 表示無鍵按下
功能說明:從按鍵FIFO取1個鍵值
*/
uint8_t GetKey(void)
{
uint8_t ret;
if (s_Key.Read == s_Key.Write)
{
return KEY_NONE;
}
else
{
ret = s_Key.Buf[s_Key.Read];
if (++s_Key.Read >= KEY_FIFO_SIZE)
{
s_Key.Read = 0;
}
return ret;
}
}
/*******************************************************************************
函數名:DetectButton
輸 入: 按鍵結構變量指針
輸 出:
功能說明:檢測指定的按鍵
*/
static void DetectButton(BUTTON_T *_pBtn)
{
/* 如果沒有初始化按鍵函數,則報錯
if (_pBtn->IsKeyDownFunc == 0)
{
printf("Fault : DetectButton(), _pBtn->IsKeyDownFunc undefine");
}
*/
if (_pBtn->IsKeyDownFunc())
{
if (_pBtn->Count < _pBtn->FilterTime)
{
_pBtn->Count = _pBtn->FilterTime;
}
else if(_pBtn->Count < 2 * _pBtn->FilterTime)
{
_pBtn->Count++;
}
else
{
if (_pBtn->State == 0)
{
_pBtn->State = 1;
/* 發送按鈕按下的消息 */
if (_pBtn->KeyCodeDown > 0)
{
/* 鍵值放入按鍵FIFO */
PutKey(_pBtn->KeyCodeDown);
}
}
if (_pBtn->LongTime > 0)
{
if (_pBtn->LongCount < _pBtn->LongTime)
{
/* 發送按鈕持續按下的消息 */
if (++_pBtn->LongCount == _pBtn->LongTime)
{
/* 鍵值放入按鍵FIFO */
PutKey(_pBtn->KeyCodeLong);
}
}
}
}
}
else
{
if(_pBtn->Count > _pBtn->FilterTime)
{
_pBtn->Count = _pBtn->FilterTime;
}
else if(_pBtn->Count != 0)
{
_pBtn->Count--;
}
else
{
if (_pBtn->State == 1)
{
_pBtn->State = 0;
/* 發送按鈕彈起的消息 */
if (_pBtn->KeyCodeUp > 0)
{
/* 鍵值放入按鍵FIFO */
PutKey(_pBtn->KeyCodeUp);
}
}
}
_pBtn->LongCount = 0;
}
}
/*******************************************************************************
函數名:KeyPro
輸 入:
輸 出:
功能說明:檢測所有的按鍵,這個函數要被systic的中斷服務程序調用
*/
void KeyPro(void)
{
DetectButton(&s_BtnUser); /* USER 鍵 */
DetectButton(&s_BtnTamper); /* TAMPER 鍵 */
DetectButton(&s_BtnWakeUp); /* WAKEUP 鍵 */
DetectButton(&s_BtnUp); /* 搖桿UP鍵 */
DetectButton(&s_BtnDown); /* 搖桿DOWN鍵 */
DetectButton(&s_BtnLeft); /* 搖桿LEFT鍵 */
DetectButton(&s_BtnRight); /* 搖桿RIGHT鍵 */
DetectButton(&s_BtnOk); /* 搖桿OK鍵 */
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -