我这有个按键的历程 C文件
- /****************************************************************************
- * Copyright (C), 2009-2010, www.armfly.com
- *
- * 文件名: sysytick.c
- * 内容简述: 本模块实现7个按键的检测,具有滤波机制,支持按下,弹起和长按动作。
- * 通过GetKey()函数可以读取键值
- * 文件历史:
- * 版本号 日期 作者 说明
- * v0.1 2009-12-27 armfly 创建该文件
- *
- */
- /* Includes ------------------------------------------------------------------*/
- #include "includes.h"
- #include <stdio.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 u8 IsKeyDownUser(void) {if (GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_8) == Bit_SET) return 0; return 1;}
- static u8 IsKeyDownTamper(void) {if (GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_13) == Bit_SET) return 0; return 1;}
- static u8 IsKeyDownWakeUp(void) {if (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == Bit_SET) return 1; return 0;}
- static u8 IsKeyDownUp(void) {if (GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_15) == Bit_SET) return 0; return 1;}
- static u8 IsKeyDownDown(void) {if (GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_3) == Bit_SET) return 0; return 1;}
- static u8 IsKeyDownLeft(void) {if (GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_14) == Bit_SET) return 0; return 1;}
- static u8 IsKeyDownRight(void) {if (GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_13) == Bit_SET) return 0; return 1;}
- static u8 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.LongCount = 0;
- 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(u8 _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个键值
- *******************************************************************************/
- u8 GetKey(void)
- {
- u8 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键 */
- }
头文件
- /****************************************************************************
- * Copyright (C), 2009-2010, www.armfly.com
- *
- * 文件名: button.h
- * 内容简述: 头文件
- *
- * 文件历史:
- * 版本号 日期 作者 说明
- * v0.1 2009-12-28 armfly 创建该文件
- *
- */
- /* Define to prevent recursive inclusion -------------------------------------*/
- #ifndef __BUTTON_H
- #define __BUTTON_H
- /* 按键滤波时间50ms, 单位10ms
- 只有连续检测到50ms状态不变才认为有效,包括弹起和按下两种事件
- */
- #define BUTTON_FILTER_TIME 5
- #define BUTTON_LONG_TIME 100 /* 持续1秒,认为长按事件 */
- /*
- 每个按键对应1个全局的结构体变量。
- 其成员变量是实现滤波和多种按键状态所必须的
- */
- typedef struct
- {
- /* 下面是一个函数指针,指向判断按键手否按下的函数 */
- u8 (*IsKeyDownFunc)(void); /* 按键按下的判断函数,1表示按下 */
- u8 Count; /* 滤波器计数器 */
- u8 FilterTime; /* 滤波时间(最大255,表示2550ms) */
- u16 LongCount; /* 长按计数器 */
- u16 LongTime; /* 按键按下持续时间, 0表示不检测长按 */
- u8 State; /* 按键当前状态(按下还是弹起) */
- u8 KeyCodeUp; /* 按键弹起的键值代码, 0表示不检测按键弹起 */
- u8 KeyCodeDown; /* 按键按下的键值代码, 0表示不检测按键按下 */
- u8 KeyCodeLong; /* 按键长按的键值代码, 0表示不检测长按 */
- }BUTTON_T;
- /* 定义键值代码
- 推荐使用enum, 不用#define,原因:
- (1) 便于新增键值,方便调整顺序,使代码看起来舒服点
- (2) 编译器可帮我们避免键值重复。
- */
- typedef enum
- {
- KEY_NONE = 0, /* 0 表示按键事件 */
- /* 为了演示,需要检测USER键弹起事件和长按事件 */
- KEY_DOWN_USER, /* User键按下 */
- KEY_UP_USER, /* User键弹起 */
- KEY_HOLD_USER, /* User键长按 */
- KEY_DOWN_WAKEUP, /* WakeUp键按下 */
- KEY_DOWN_TAMPER, /* Tamper键按下 */
- KEY_DOWN_JOY_UP, /* 摇杆UP键按下 */
- KEY_DOWN_JOY_DOWN, /* 摇杆DOWN键按下 */
- KEY_DOWN_JOY_LEFT, /* 摇杆LEFT键按下 */
- KEY_DOWN_JOY_RIGHT, /* 摇杆RIGHT键按下 */
- KEY_DOWN_JOY_OK /* 摇杆OK键按下 */
- }KEY_ENUM;
- /*
- 按键FIFO用到变量
- */
- #define KEY_FIFO_SIZE 20
- typedef struct
- {
- u8 Buf[KEY_FIFO_SIZE]; /* 键值缓冲区 */
- u8 Read; /* 缓冲区读指针 */
- u8 Write; /* 缓冲区写指针 */
- }KEY_FIFO_T;
- void InitButtonVar(void);
- void PutKey(u8 _KeyCode);
- u8 GetKey(void);
- void KeyPro(void);
- #endif
楼主只需更改C文件的按键端口就行了
然后在用定时器产生一个10ms左右的时基 在这个时基里调用按键扫描函数即可
然后你想检测30s 只需更改 长按键时间即可
楼主可以参考下
|