多按键驱动的思路和之前的io单按键,思路类似单按键是判断按键是按下,多按键判断是否有按键按下,按下的是哪个按键号,下面以最近工作用使用的ad按键为例
整个驱动一共4个c文件(键值、扫描、任务、驱动),6个h文件
核心思路是定时器中每10ms扫描一次按键,将按键值传入扫描函数,获得有效按键的按键号和按键状态,抄表将按键号按键状态两个变量转换成一个变量,将这个有效值传入队列,在主函数中出队列,将按键有效值作为参数哦传递给函数指针数组调用对应的任务函数,整个驱动没有使用一个与ic芯片有关的头文件,函数等,十分方便移植(整个驱动的思路来源于之前的几个项目,抄表是杰里的按键驱动,按键扫描代码是自己撸的,队列做数据透传的时候写的),可能程序的效率和代码量不够理想,但整体功能能比较好实现,最后面将会把10个文件全部贴出,附带完整工程下载
主要文件key_ad.c .h
h文件将每个按键对应电压的ad转换值算出来,选用两个键值的中值做作为有效键值判断
c文件,将h文件中的键值作为数组的元素,将获取的按键值和表对比获取获得按键号
#define R_UP 220L //22K
/* 不同电压对应的ad值 12bit adc */
#define ADC_33 (4096) //VCC
#define ADC_30 (3680) //220K
#define ADC_27 (3357) //100K
#define ADC_23 (2860) //51K
#define ADC_20 (2450) //33K
#define ADC_17 (2120) //24K
#define ADC_13 (1610) //15K
#define ADC_10 (1210) //9.1K
#define ADC_07 (915) //6.2K
#define ADC_03 (490) //3K
#define ADC_00 (0)
/* key voltage threshold */
#define AD_NOKEY ((ADC_33 + ADC_30)/2)
#define AD_KEY_0 ((ADC_30 + ADC_27)/2)
#define AD_KEY_1 ((ADC_27 + ADC_23)/2)
#define AD_KEY_2 ((ADC_23 + ADC_20)/2)
#define AD_KEY_3 ((ADC_20 + ADC_17)/2)
#define AD_KEY_4 ((ADC_17 + ADC_13)/2)
#define AD_KEY_5 ((ADC_13 + ADC_10)/2)
#define AD_KEY_6 ((ADC_10 + ADC_07)/2)
#define AD_KEY_7 ((ADC_07 + ADC_03)/2)
#define AD_KEY_8 ((ADC_03 + ADC_00)/2)
void get_key_adc_address(u16* _address);
KEY_NUMBER_U get_current_key_number(void);
/
/* c文件 */
#define KEY_SIZE (KEY_NUMBER - 1)
const static u16 ad_key_table[KEY_SIZE] = {
AD_KEY_0, AD_KEY_1, AD_KEY_2,
AD_KEY_3, AD_KEY_4, AD_KEY_5,
AD_KEY_6, AD_KEY_7, AD_KEY_8,
};
static u16* s_ad_key_value;
/* 初始化时将按键的ad值地址传进来,用指针变量存起来,就可以不用包含ad值的头文件了,方便移植 */
void get_key_adc_address(u16* _address)
{
s_ad_key_value = _address;
}
KEY_NUMBER_U get_current_key_number(void)
{
u8 l_number = KEY_NONE;
if (*s_ad_key_value > AD_NOKEY){
return KEY_NONE;
}
for (l_number = 0; l_number < KEY_SIZE; l_number++){
if (*s_ad_key_value > ad_key_table[l_number]){
break;
}
}
return (KEY_NUMBER_U)(KEY_SIZE - l_number);
}
这部分较为简单,主要文件key_scan.c .h 。将上一步扫描的键值传入key_scan中,基本是在io单按键的基础稍作修改的
void key_scan(KEY_SCAN_S *_key)
{
_key->value = NO_KEY;
_key->type = KEY_NO_PRESS;
if (_key->cur_key == NO_KEY){
switch (_key->status){
case KEY_NO_PRESS:
break;
case KEY_DOWN:
break;
case KEY_SHORT:
_key->type = KEY_SHORT;
break;
case KEY_LONG:
break;
case KEY_HOLD:
_key->type = KEY_HOLD_UP;
break;
default:
break;
}
_key->cnt = 0;
_key->status = KEY_NO_PRESS;
}else{
/* 上次的按值有效,但和这次不同 */
if ((NO_KEY != _key->last_key)&&(_key->last_key != _key->cur_key)){
/* 这次按键比上次小,认为是一个误触按键*/
if (_key->cur_key <= _key->last_key){
_key->last_key = _key->cur_key;
_key->cnt = 0;
_key->status = KEY_NO_PRESS;
return; //异常退出
}
/* 实际测试的时候抬手的一瞬间内,按键抖动,导致最后一次传入一个比当前键值大的键值
如果认为是异常则按键扫描识别率低,所以这次按键比上次大,认为是一个松手按键 */
if (KEY_SHORT == _key->status){
_key->type = KEY_SHORT;
}else if (KEY_HOLD == _key->status){
_key->type = KEY_HOLD_UP;
}
_key->cnt = 0;
_key->status = KEY_NO_PRESS;
}
_key->cnt++;
switch (_key->status){
case KEY_NO_PRESS:
_key->status = KEY_DOWN;
break;
case KEY_DOWN:
if (_key->cnt >= KEY_BASE_CNT) { //长按
_key->status = KEY_SHORT;
}
break;
case KEY_SHORT:
if (_key->cnt >= KEY_LONG_CNT) { //长按
_key->status = KEY_LONG;
_key->type = KEY_LONG;
}
break;
case KEY_LONG:
if (_key->cnt >= (KEY_LONG_CNT + KEY_HOLD_CNT)) { //连按
_key->status = KEY_HOLD;
_key->type = KEY_HOLD;
_key->cnt = KEY_LONG_CNT;
}
break;
case KEY_HOLD:
if (_key->cnt >= (KEY_LONG_CNT + KEY_HOLD_CNT)) { //连按
_key->type = KEY_HOLD;
_key->cnt = KEY_LONG_CNT;
}
break;
default:
break;
}
}
if (KEY_NO_PRESS != _key->type){
_key->number = _key->last_key;
_key->value = ((_key->type << 5)|(_key->number & 0x1f)); //高3位代表按键状态,低5位代表键值
}
_key->last_key = _key->cur_key;
}
按键处理经过上一步,就已经获得了有效的键值和按键类型,开始按键处理 主要文件 key_device.c .h
按键初始化要传入按键ad值的地址,初始化一个fifo队列,不想用队列也是可以的,但是要扫描完立马进行按键任务处理
/* 为了方便抄表,NO_PRESS不是0,初始化赋值 */
static KEY_SCAN_S s_key = {KEY_NO_PRESS,0,0,0,0,0,0,0};
static QUEUE_ELEMENT_S s_queue;
/* 传入adc地址,初始化队列 */
static void task_key_init(u16* _key_adc_address)
{
get_key_adc_address(_key_adc_address);
init_queue(&s_queue);
}
/*
按键扫描,把消息传入队列
*/
static void task_key_scan(void)
{
u8 l_msg = NO_MSG;
s_key.cur_key = get_current_key_number(); /* 获得按键值 */
key_scan(&s_key); /* 传入扫描,获取按键结果 */
if(KEY_NONE != s_key.value){ /* 将按键结果传入队列 */
/* 抄表获取对应的按键变量 */
l_msg = key_msg_buff[s_key.type][s_key.number];
if (NO_MSG != l_msg){
in_queue_fifo(&s_queue, l_msg);
}
}
}
上面三步完成了按键的扫描,接下来就是要做按键的功能函数了,个人喜欢将按键类型也分成函数,如果不喜欢可改用按键号函数,键类型传参进去,这里使用了函数指针数组来实现32个函数的调用,使得整个任务调用变得简洁,如果芯片资源紧张,也可以用switch来处理感觉代码庞大,主要文件 key_task.c .h
/*
消息出队列,调用相应的功能函数
*/
static void task_key_deal(void)
{
u8 l_smg = NO_MSG;
/* 按键消息出队列 */
if (1 == out_queue(&s_queue, &l_smg)){
/* 超出了最大任务数,退出防止指针数组访问越界 */
if (l_smg >= TASK_SIZE){
printf("key_task error\r\n");
return ;
}
key_task[l_smg]();/* 调用按键功能函数指针 */
//key_task[s_key.number](s_key.type);
}
}
/* 按键函数的类型 */
typedef void (*const KEY_TASK_CB)(void);
extern KEY_TASK_CB key_task[TASK_SIZE];
/* 函数指针声明为常量初始化之后不允许改变 */
const KEY_TASK_CB key_task[TASK_SIZE] = {
[KEY0_SHORT] = task_key0_short,
[KEY0_LONG] = task_key0_long,
[KEY0_HOLD] = task_key0_hold,
[KEY0_HOLD_UP] = task_key0_hold_up,
/* 还有20多个元素没复制 */
};
/*---------------------------key0------------------------------------*/
static void task_key0_short(void)
{
printf("task_key0_short\r\n");
// read_64bit_uid(test_id);
}
static void task_key0_long(void)
{
printf("task_key0_long\r\n");
}
static void task_key0_hold(void)
{
printf("task_key0_hold\r\n");
}
static void task_key0_hold_up(void)
{
printf("task_key0_hold_up\r\n");
}
通过队列,将扫描和处理分开,按键处理放在主函数中,主函数即使有很多阻塞操作也不会影响按键处理
int main(void)
{
system_init();
while (1){
g_key.deal();
}
return 1;/* never do there */
}
void TIM6_IRQHandler(void)
{
if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET){
TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
g_adc.finsh_detect();
g_key.scan();
}
}
有需要可以直接下载完整工程移植到stm32上测试,本人用的ic是国产cortex-m0内核ic。
#ifndef __KEY_API_H
#define __KEY_API_H
//自行定义消息在
typedef enum{
KEY0_SHORT,
KEY0_LONG,
KEY0_HOLD,
KEY0_HOLD_UP,
/
KEY1_SHORT,
KEY1_LONG,
KEY1_HOLD,
KEY1_HOLD_UP,
/
KEY2_SHORT,
KEY2_LONG,
KEY2_HOLD,
KEY2_HOLD_UP,
/
KEY3_SHORT,
KEY3_LONG,
KEY3_HOLD,
KEY3_HOLD_UP,
/
KEY4_SHORT,
KEY4_LONG,
KEY4_HOLD,
KEY4_HOLD_UP,
/
KEY5_SHORT,
KEY5_LONG,
KEY5_HOLD,
KEY5_HOLD_UP,
/
KEY6_SHORT,
KEY6_LONG,
KEY6_HOLD,
KEY6_HOLD_UP,
/
KEY7_SHORT,
KEY7_LONG,
KEY7_HOLD,
KEY7_HOLD_UP,
KEY_TASK_MAX,
NO_MSG = 0xff,
}KEY_MSG_U;
/
#define KEY_STATUS_SHORT \
/* key0 */KEY0_SHORT,\
/* key1 */KEY1_SHORT,\
/* key2 */KEY2_SHORT,\
/* key3 */KEY3_SHORT,\
/* key4 */KEY4_SHORT,\
/* key5 */KEY5_SHORT,\
/* key6 */KEY6_SHORT,\
/* key7 */KEY7_SHORT,\
/* key8 */NO_MSG,\
/* key9 */NO_MSG
/
#define KEY_STATUS_DOUBLE \
/* key0 */NO_MSG,\
/* key1 */NO_MSG,\
/* key2 */NO_MSG,\
/* key3 */NO_MSG,\
/* key4 */NO_MSG,\
/* key5 */NO_MSG,\
/* key6 */NO_MSG,\
/* key7 */NO_MSG,\
/* key8 */NO_MSG,\
/* key9 */NO_MSG
/
#define KEY_STATUS_THREE \
/* key0 */NO_MSG,\
/* key1 */NO_MSG,\
/* key2 */NO_MSG,\
/* key3 */NO_MSG,\
/* key4 */NO_MSG,\
/* key5 */NO_MSG,\
/* key6 */NO_MSG,\
/* key7 */NO_MSG,\
/* key8 */NO_MSG,\
/* key9 */NO_MSG
/
#define KEY_STATUS_LONG \
/* key0 */KEY0_LONG,\
/* key1 */KEY1_LONG,\
/* key2 */KEY2_LONG,\
/* key3 */KEY3_LONG,\
/* key4 */KEY4_LONG,\
/* key5 */KEY5_LONG,\
/* key6 */KEY6_LONG,\
/* key7 */KEY7_LONG,\
/* key8 */NO_MSG,\
/* key9 */NO_MSG
/
#define KEY_STATUS_HOLD \
/* key0 */KEY0_HOLD,\
/* key1 */KEY1_HOLD,\
/* key2 */KEY2_HOLD,\
/* key3 */KEY3_HOLD,\
/* key4 */KEY4_HOLD,\
/* key5 */KEY5_HOLD,\
/* key6 */KEY6_HOLD,\
/* key7 */KEY7_HOLD,\
/* key8 */NO_MSG,\
/* key9 */NO_MSG
/
#define KEY_STATUS_HOLD_UP \
/* key0 */KEY0_HOLD_UP,\
/* key1 */KEY1_HOLD_UP,\
/* key2 */KEY2_HOLD_UP,\
/* key3 */KEY3_HOLD_UP,\
/* key4 */KEY4_HOLD_UP,\
/* key5 */KEY5_HOLD_UP,\
/* key6 */KEY6_HOLD_UP,\
/* key7 */KEY7_HOLD_UP,\
/* key8 */NO_MSG,\
/* key9 */NO_MSG
/
#endif
#ifndef __KEY_HEAD_H
#define __KEY_HEAD_H
#define KEY_NUMBER 10
// #define TASK_SIZE 16
//typedef enum{
// AD_KEY,
// MATRIX_KEY,
// IO_KEY,
//}KEY_TYPE_U;
// #define KEY_TYPE MATRIX_KEY
typedef enum{
KEY_0 = 0,
KEY_1,
KEY_2,
KEY_3,
KEY_4,
KEY_5,
KEY_6,
KEY_7,
KEY_8,
KEY_9,
KEY_NONE = 0xff,
}KEY_NUMBER_U;
#endif // !__KEY_HEAD_H
#include "key_ad.h"
/* 最后一个键值不用判断,只要按键有效,扫描一轮,提前退出 */
#define KEY_SIZE (KEY_NUMBER - 1)
const static u16 ad_key_table[KEY_SIZE] = {
AD_KEY_0, AD_KEY_1, AD_KEY_2,
AD_KEY_3, AD_KEY_4, AD_KEY_5,
AD_KEY_6, AD_KEY_7, AD_KEY_8,
};
static u16* s_ad_key_value;
void get_key_adc_address(u16* _address)
{
s_ad_key_value = _address;
}
KEY_NUMBER_U get_current_key_number(void)
{
u8 l_number = KEY_NONE;
if (*s_ad_key_value > AD_NOKEY){
return KEY_NONE;
}
for (l_number = 0; l_number < KEY_SIZE; l_number++){
if (*s_ad_key_value > ad_key_table[l_number]){
break;
}
}
return (KEY_NUMBER_U)(KEY_SIZE - l_number);
}
#ifndef __KEY_AD_H
#define __KEY_AD_H
#include "user_typedef.h"
#include "key_head.h"
#define R_UP 220L //22K
// #define ADC_33 (1024L) //VCC
// #define ADC_33 (4096L) //VCC
// #define ADC_30 (ADC_33*2200L/(2200L + R_UP)) //220K 3700
// #define ADC_27 (ADC_33*1000L/(1000L + R_UP)) //100K 3357
// #define ADC_23 (ADC_33*510L /(510L + R_UP)) //51K 2860
// #define ADC_20 (ADC_33*330L /(330L + R_UP)) //33K 2450
// #define ADC_17 (ADC_33*240L /(240L + R_UP)) //24K 2120
// #define ADC_13 (ADC_33*150L /(150L + R_UP)) //15K 1610
// #define ADC_10 (ADC_33*91L /(91L + R_UP)) //9.1K 1210
// #define ADC_07 (ADC_33*62L /(62L + R_UP)) //6.2K 915
// #define ADC_03 (ADC_33*30L /(30L + R_UP)) //3K 490
// #define ADC_00 (0)
#define ADC_33 (4096) //VCC
#define ADC_30 (3680) //220K
#define ADC_27 (3357) //100K
#define ADC_23 (2860) //51K
#define ADC_20 (2450) //33K
#define ADC_17 (2120) //24K
#define ADC_13 (1610) //15K
#define ADC_10 (1210) //9.1K
#define ADC_07 (915) //6.2K
#define ADC_03 (490) //3K
#define ADC_00 (0)
/* key voltage threshold */
#define AD_NOKEY ((ADC_33 + ADC_30)/2)
#define AD_KEY_0 ((ADC_30 + ADC_27)/2)
#define AD_KEY_1 ((ADC_27 + ADC_23)/2)
#define AD_KEY_2 ((ADC_23 + ADC_20)/2)
#define AD_KEY_3 ((ADC_20 + ADC_17)/2)
#define AD_KEY_4 ((ADC_17 + ADC_13)/2)
#define AD_KEY_5 ((ADC_13 + ADC_10)/2)
#define AD_KEY_6 ((ADC_10 + ADC_07)/2)
#define AD_KEY_7 ((ADC_07 + ADC_03)/2)
#define AD_KEY_8 ((ADC_03 + ADC_00)/2)
void get_key_adc_address(u16* _address);
KEY_NUMBER_U get_current_key_number(void);
#endif // !__KEY_AD_H
#include "key_scan.h"
/* 将键值和类型抄表转换成一个变量 */
const u8 key_msg_buff[6][10] = {
{KEY_STATUS_SHORT},
{KEY_STATUS_DOUBLE},
{KEY_STATUS_THREE},
{KEY_STATUS_LONG},
{KEY_STATUS_HOLD},
{KEY_STATUS_HOLD_UP},
};
void key_scan(KEY_SCAN_S *_key)
{
_key->value = NO_KEY;
_key->type = KEY_NO_PRESS;
if (_key->cur_key == NO_KEY){
switch (_key->status){
case KEY_NO_PRESS:
break;
case KEY_DOWN:
break;
case KEY_SHORT:
_key->type = KEY_SHORT;
break;
case KEY_LONG:
break;
case KEY_HOLD:
_key->type = KEY_HOLD_UP;
break;
default:
break;
}
_key->cnt = 0;
_key->status = KEY_NO_PRESS;
}else{
/* 上次的按值有效,但和这次不同 */
if ((NO_KEY != _key->last_key)&&(_key->last_key != _key->cur_key)){
/* 这次按键比上次小,认为是一个误触按键*/
if (_key->cur_key <= _key->last_key){
_key->last_key = _key->cur_key;
_key->cnt = 0;
_key->status = KEY_NO_PRESS;
return; //异常退出
}
/* 实际测试的时候抬手的一瞬间内,按键抖动,导致最后一次传入一个比当前键值大的键值
如果认为是异常则按键扫描识别率低,所以这次按键比上次大,认为是一个松手按键 */
if (KEY_SHORT == _key->status){
_key->type = KEY_SHORT;
}else if (KEY_HOLD == _key->status){
_key->type = KEY_HOLD_UP;
}
_key->cnt = 0;
_key->status = KEY_NO_PRESS;
}
_key->cnt++;
switch (_key->status){
case KEY_NO_PRESS:
_key->status = KEY_DOWN;
break;
case KEY_DOWN:
if (_key->cnt >= KEY_BASE_CNT) { //长按
_key->status = KEY_SHORT;
}
break;
case KEY_SHORT:
if (_key->cnt >= KEY_LONG_CNT) { //长按
_key->status = KEY_LONG;
_key->type = KEY_LONG;
}
break;
case KEY_LONG:
if (_key->cnt >= (KEY_LONG_CNT + KEY_HOLD_CNT)) { //连按
_key->status = KEY_HOLD;
_key->type = KEY_HOLD;
_key->cnt = KEY_LONG_CNT;
}
break;
case KEY_HOLD:
if (_key->cnt >= (KEY_LONG_CNT + KEY_HOLD_CNT)) { //连按
_key->type = KEY_HOLD;
_key->cnt = KEY_LONG_CNT;
}
break;
default:
break;
}
}
if (KEY_NO_PRESS != _key->type){
_key->number = _key->last_key;
_key->value = ((_key->type << 5)|(_key->number & 0x1f)); //高3位代表按键状态,低5位代表键值
}
_key->last_key = _key->cur_key;
}
#ifndef __KEY_SCAN_H
#define __KEY_SCAN_H
#include "key_api.h"
#include "user_typedef.h"
/* 按键的8个状态 */
typedef enum{
KEY_SHORT = 0, /* 短按 */
KEY_DOUBLE, /* 双击 */
KEY_THREE, /* 三击 */
KEY_LONG, /* 长按 */
KEY_HOLD, /* 保持 */
KEY_HOLD_UP, /* 抬起 */
KEY_NO_PRESS, /* 没有按下 */
KEY_DOWN, /* 按键按下 */
}KEY_STATE_U;
/* 按键的扫描使用的结构体 */
typedef struct{
//scan
u8 status; /* 按键状态 */
u8 cur_key; /* 当前键值 */
u8 last_key; /* 上次键值 */
u8 cnt; /* 状态计数 */
u8 press_flag;/* 复按flag,用于扫描多按 */
//value
u8 value; /* 按键值,将number和type整和一个变量 */
u8 number; /* 有效键值 */
u8 type ; /* 有效按键类型 */
}KEY_SCAN_S;
extern const u8 key_msg_buff[6][10];
void key_scan(KEY_SCAN_S *_key);
#define KEY_BASE_CNT 3 /* 按键消抖 */
#define KEY_LONG_CNT 100 /* 长按触发 1000ms */
#define KEY_HOLD_CNT 50 /* 保持触发时长 500ms */
#define KEY_SHORT_CNT 7
#define KEY_DOUBLE_CNT 35 /* 连按识别350ms */
#define KEY_REPETE_CNT 35
#define NO_KEY 0xff
#endif
#include "key_drive.h"
#include "key_scan.h"
#include "queue.h"
#include "key_task.h"
#include "key_ad.h"
#include "usart.h"
// #include "key_matrix.h"
// #include "key_io.h"
/* 按键类型选择 */
// #if (KEY_TYPE == AD_KEY)
// #include "key_ad.h"
// #elif (KEY_TYPE == MATRIX_KEY)
// #include "key_matrix.h"
// #elif (KEY_TYPE == IO_KEY)
// #include "key_io.h"
// #endif
static void task_key_init(u16* _key_adc_address);
static void task_key_scan(void);
static void task_key_deal(void);
static KEY_SCAN_S s_key = {KEY_NO_PRESS,0,0,0,0,0,0,0};
static QUEUE_ELEMENT_S s_queue;
KEY_S g_key ={
.init = task_key_init,
.scan = task_key_scan,
.deal = task_key_deal,
};
/*
按键io初始化 队列初始化
*/
static void task_key_init(u16* _key_adc_address)
{
get_key_adc_address(_key_adc_address);
init_queue(&s_queue);
}
/*
按键扫描,把消息传入队列
*/
static void task_key_scan(void)
{
u8 l_msg = NO_MSG;
s_key.cur_key = get_current_key_number(); /* 获得按键值 */
key_scan(&s_key); /* 传入扫描,获取按键结果 */
if(KEY_NONE != s_key.value){ /* 将按键结果传入队列 */
l_msg = key_msg_buff[s_key.type][s_key.number];
if (NO_MSG != l_msg){
in_queue_fifo(&s_queue, l_msg);
}
}
}
/*
消息出队列,调用相应的功能函数
*/
static void task_key_deal(void)
{
u8 l_smg = NO_MSG;
/* 按键消息出队列 */
if (1 == out_queue(&s_queue, &l_smg)){
/* 超出了最大任务数,退出防止指针数组访问越界 */
if (l_smg >= TASK_SIZE){
printf("key_task error\r\n");
return ;
}
key_task[l_smg]();/* 调用按键功能函数指针 */
// key_task[s_key.number](s_key.type);
}
}
#ifndef __KEY_DRIVE_H
#define __KEY_DRIVE_H
#include "key_head.h"
#include "user_typedef.h"
typedef struct key{
// void (*init)(void);
void (*const init)(u16* _address);
void (*const scan)(void);
void (*const deal)(void);
}KEY_S;
extern KEY_S g_key;
#endif /* __KEY_DRIVE_H */
#include "key_task.h"
#include "user_typedef.h"
#include "key_api.h"
#include "usart.h"
//#include "flash.h"
static void task_key0_short(void);
static void task_key0_long(void);
static void task_key0_hold(void);
static void task_key0_hold_up(void);
static void task_key1_short(void);
static void task_key1_long(void);
static void task_key1_hold(void);
static void task_key1_hold_up(void);
static void task_key2_short(void);
static void task_key2_long(void);
static void task_key2_hold(void);
static void task_key2_hold_up(void);
static void task_key3_short(void);
static void task_key3_long(void);
static void task_key3_hold(void);
static void task_key3_hold_up(void);
static void task_key4_short(void);
static void task_key4_long(void);
static void task_key4_hold(void);
static void task_key4_hold_up(void);
static void task_key5_short(void);
static void task_key5_long(void);
static void task_key5_hold(void);
static void task_key5_hold_up(void);
static void task_key6_short(void);
static void task_key6_long(void);
static void task_key6_hold(void);
static void task_key6_hold_up(void);
static void task_key7_short(void);
static void task_key7_long(void);
static void task_key7_hold(void);
static void task_key7_hold_up(void);
/* 函数指针声明为常量初始化之后不允许改变 */
const KEY_TASK_CB key_task[TASK_SIZE] = {
[KEY0_SHORT] = task_key0_short,
[KEY0_LONG] = task_key0_long,
[KEY0_HOLD] = task_key0_hold,
[KEY0_HOLD_UP] = task_key0_hold_up,
[KEY1_SHORT] = task_key1_short,
[KEY1_LONG] = task_key1_long,
[KEY1_HOLD] = task_key1_hold,
[KEY1_HOLD_UP] = task_key1_hold_up,
[KEY2_SHORT] = task_key2_short,
[KEY2_LONG] = task_key2_long,
[KEY2_HOLD] = task_key2_hold,
[KEY2_HOLD_UP] = task_key2_hold_up,
[KEY3_SHORT] = task_key3_short,
[KEY3_LONG] = task_key3_long,
[KEY3_HOLD] = task_key3_hold,
[KEY3_HOLD_UP] = task_key3_hold_up,
[KEY4_SHORT] = task_key4_short,
[KEY4_LONG] = task_key4_long,
[KEY4_HOLD] = task_key4_hold,
[KEY4_HOLD_UP] = task_key4_hold_up,
[KEY5_SHORT] = task_key5_short,
[KEY5_LONG] = task_key5_long,
[KEY5_HOLD] = task_key5_hold,
[KEY5_HOLD_UP] = task_key5_hold_up,
[KEY6_SHORT] = task_key6_short,
[KEY6_LONG] = task_key6_long,
[KEY6_HOLD] = task_key6_hold,
[KEY6_HOLD_UP] = task_key6_hold_up,
[KEY7_SHORT] = task_key7_short,
[KEY7_LONG] = task_key7_long,
[KEY7_HOLD] = task_key7_hold,
[KEY7_HOLD_UP] = task_key7_hold_up,
};
uint8_t test_id[8];
/*---------------------------key0------------------------------------*/
static void task_key0_short(void)
{
printf("task_key0_short\r\n");
// read_64bit_uid(test_id);
}
static void task_key0_long(void)
{
printf("task_key0_long\r\n");
}
static void task_key0_hold(void)
{
printf("task_key0_hold\r\n");
}
static void task_key0_hold_up(void)
{
printf("task_key0_hold_up\r\n");
}
/*---------------------------key1------------------------------------*/
static void task_key1_short(void)
{
printf("task_key1_short\r\n");
}
static void task_key1_long(void)
{
printf("task_key1_long\r\n");
}
static void task_key1_hold(void)
{
printf("task_key1_hold\r\n");
}
static void task_key1_hold_up(void)
{
printf("task_key1_hold_up\r\n");
}
/*---------------------------key2------------------------------------*/
static void task_key2_short(void)
{
printf("task_key2_short\r\n");
}
static void task_key2_long(void)
{
printf("task_key2_long\r\n");
}
static void task_key2_hold(void)
{
printf("task_key2_hold\r\n");
}
static void task_key2_hold_up(void)
{
printf("task_key2_hold_up\r\n");
}
/*---------------------------key3------------------------------------*/
static void task_key3_short(void)
{
printf("task_key3_short\r\n");
}
static void task_key3_long(void)
{
printf("task_key3_long\r\n");
}
static void task_key3_hold(void)
{
printf("task_key3_hold\r\n");
}
static void task_key3_hold_up(void)
{
printf("task_key3_hold_up\r\n");
}
/*---------------------------key4------------------------------------*/
static void task_key4_short(void)
{
printf("task_key4_short\r\n");
}
static void task_key4_long(void)
{
printf("task_key4_long\r\n");
}
static void task_key4_hold(void)
{
printf("task_key4_hold\r\n");
}
static void task_key4_hold_up(void)
{
printf("task_key4_hold_up\r\n");
}
/*---------------------------key5------------------------------------*/
static void task_key5_short(void)
{
printf("task_key5_short\r\n");
}
static void task_key5_long(void)
{
printf("task_key5_long\r\n");
}
static void task_key5_hold(void)
{
printf("task_key5_hold\r\n");
}
static void task_key5_hold_up(void)
{
printf("task_key5_hold_up\r\n");
}
/*---------------------------key6------------------------------------*/
static void task_key6_short(void)
{
printf("task_key6_short\r\n");
}
static void task_key6_long(void)
{
printf("task_key6_long\r\n");
}
static void task_key6_hold(void)
{
printf("task_key6_hold\r\n");
}
static void task_key6_hold_up(void)
{
printf("task_key6_hold_up\r\n");
}
/*---------------------------key7------------------------------------*/
static void task_key7_short(void)
{
printf("task_key7_short\r\n");
}
static void task_key7_long(void)
{
printf("task_key7_long\r\n");
}
static void task_key7_hold(void)
{
printf("task_key7_hold\r\n");
}
static void task_key7_hold_up(void)
{
printf("task_key7_hold_up\r\n");
}
#ifndef __key_task_H
#define __key_task_H
#define TASK_SIZE 32
/* 按键函数的类型 */
typedef void (*const KEY_TASK_CB)(void);
extern KEY_TASK_CB key_task[TASK_SIZE];
#endif
c语言数组实现队列