借鉴别人的文章借鉴写的。
ADC初始化就不多说了。
首先头文件:.h
/*键盘扫描间隔,按键响应时间 20 40 80 ms*/
/*不精准延时40ms,调试的键值*/
#define KEY_NONE 0x2E
#define KEY_MENU 0x27
//#define KEY_MENU_LONG 0x67
#define KEY_UP 0x1F
#define KEY_UP_LONG 0X5F
#define KEY_DOWN 0x17
#define KEY_DOWN_LONG 0X57
#define KEY_ENTER 0x0F
//#define KEY_ENTER_LONG 0x4F
#define S_KEY 1 // 短按
#define L_KEY 2 // 长按
#define LONG_KEY_TIME 100 // LONG_KEY_TIME*10MS = 4S
#define SINGLE_KEY_TIME 4 // SINGLE_KEY_TIME*10MS = 40MS
typedef enum {
KEY_CHECK=0x00, // 按键检测
KEY_CONFIRM=0x01, // 按键确认
KEY_TYPE=0x02, // 按键类型判断
KEY_RELEASE=0x03, //按键释放
} Key_State;
.c.文件
精准延时可以使用定时器
/*识别各个按键类型,需循环实现状态机,会break*/
uint8_t Key_driver(void)
{
static Key_State key_state=KEY_CHECK;
static uint8_t key_time=0;
uint8_t key_value,key_return;
key_return=KEY_NONE;
key_value=TM1650_Read_key();
switch(key_state)
{
case KEY_CHECK://识别有无按键按下,等待按键
{
if(key_value==KEY_NONE)//无按键按下
{
key_time=0;//清零计数
key_state=KEY_CONFIRM;
}
}
break;
case KEY_CONFIRM://按键确认,度过2 个键扫周期
{
if(key_value!=KEY_NONE)
key_time++;//一次10ms
if(key_time>=SINGLE_KEY_TIME)//大于2 个键扫周期,说明按键按下
{
key_state=KEY_TYPE;
}
}
break;
case KEY_TYPE://长短按判断
{
if(key_value!=KEY_NONE)//在长按时间内释放,说明短按
{
key_state=KEY_CHECK;//清零时间计数
switch(key_value)//短按类型
{
case KEY_MENU:
{
key_return=KEY_MENU|S_KEY;
return key_return;
}
case KEY_UP:
{
key_return=KEY_UP|S_KEY;
return key_return;
}
case KEY_DOWN:
{
key_return=KEY_DOWN|S_KEY;
return key_return;
}
case KEY_ENTER:
{
key_return=KEY_ENTER|S_KEY;
return key_return;
}
}
}
else
{
key_time++;
if(key_time>=LONG_KEY_TIME)//大于等于长按周期,说明按键长按
{
key_state=KEY_RELEASE;//去等待按键释放
switch(key_value)//长按类型
{
// case KEY_MENU:
// {
// key_return=KEY_MENU|L_KEY;
// return key_return;
// }
case KEY_UP:
{
key_return=KEY_UP|L_KEY;
return key_return;
}
case KEY_DOWN:
{
key_return=KEY_DOWN|L_KEY;
return key_return;
}
// case KEY_ENTER:
// {
// key_return=KEY_ENTER|L_KEY;
// return key_return;
// }
}
}
}
}
break;
case KEY_RELEASE://等待按键释放
{
if(key_value==KEY_NONE)//按键释放
{
key_state=KEY_CHECK;
key_return=KEY_NONE;
return key_return;
}
}
break;
default://避免上电或通信波动,造成初始键值不一致的状况
key_state=KEY_CHECK;
break;
}
/*按键识别完,*/
}