嵌入式按键输入
目录
嵌入式按键输入
嵌入式按键输入
原理
传统按键:按键输入原理无非就是读取I口电平,如果按下了,延时去抖动,然后再读取IO口电平。
前言
刚学习嵌入式的时候按键输入真的是有点难搞,每个按键都得自己写一遍,想网上找现成的也没看到特别好的。后来看了正点原子的视频才产生一点想法。
本程序参考正点原子的按键输入试验而写。先上原程序。
//按键处理函数
//参数mode:0,不支持连按;1,支持连按
//返回值
//0,没有任何按键按下
//1,key1按下
//2,key2按下
//3,key3按下
//此函数有响应优先级,key1>key2>key3
uint8_t KEY_Scan(uint8_t mode)
{
static uint8_t key_up=1;//按键按松开标志
if(mode)key_up=1; //支持连按
if(key_up&&(KEY1==0||KEY2==0||KEY3==0))
{
delay_ms(10);//去抖动
key_up=0;
if(KEY1==0)return 1;
else if(KEY2==0)return 2;
else if(KEY3==0)return 3;
}else if(KEY1==1&&KEY2==1&&KEY3==1)key_up=1;
return 0;//无按键按下
}
程序可以实现按键输入,并且根据参数mode可以控制是否连按。但是有个缺点就是无法实现两个按键同时按下,并且多个按键互动也比较困难。
改良版
由于一个函数实现多个按键情况比较复杂,所以干脆分开写
GPIO初始化就不放了
key.h
#define KEY1(a) KEY_Scan(0,a,GPIOG,GPIO_Pin_4)
#define KEY2(a) KEY_Scan(1,a,GPIOG,GPIO_Pin_5)
#define KEY3(a) KEY_Scan(2,a,GPIOG,GPIO_Pin_6)
#define KEY4(a) KEY_Scan(3,a,GPIOG,GPIO_Pin_7)
#define KEY5(a) KEY_Scan(4,a,GPIOC,GPIO_Pin_0)
#define KEY6(a) KEY_Scan(5,a,GPIOC,GPIO_Pin_1)
//a是参数mode,1为可连按,0为不可连按
key.c
uint8_t key_up[6] = {1,1,1,1,1,1};//按键长按标志
//参数mode:0,不支持连按;1,支持连按
//参数key 是按键的读取按键电位
uint8_t KEY_Scan(uint8_t index,uint8_t mode,GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin)
{
if(mode)key_up[index]=1; //支持连按
if(key_up[index]&&GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == 0)
{
delay_ms(10);//去抖动
key_up[index]=0;
if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == 0)return 1;
}else if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) != 0)key_up[index]=1;
return 0;//无按键按下
}
main.c
void main(){
CLK_HSICmd(ENABLE); //时钟初始化
key_Init(); //按键初始化
motor_Init(); //电机初始化
uart3_gpio_init(); //串口初始化
for(;;){
if(KEY1(1)==1){ //支持连按
printf("abcd\n"); //如果key1按下就打印abcd
}
}
}
优点:增加或减少按键函数体不用改变,只需要改变宏定义及key_up数组即可;并且每个按键互相独立。
缺点:比上面多用了一个数组