第二次学蓝桥杯32板子 看了几个视频 来总结一下 几种独立按键的配置,希望能够帮到有疑惑的同学。
第一种就是刚开始学的正点原子的那 种方法。
这种方法 可以很好地 控制是否支持长按。
u8 KEY_Scan(u8 mode)
{
static u8 key_up=1;//按键按松开标志
if(mode)key_up=1; //支持连按
if(key_up&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1))
{
delay_ms(10);//去抖动
key_up=0;
if(KEY0==0)return KEY0_PRES;
else if(KEY1==0)return KEY1_PRES;
else if(KEY2==0)return KEY2_PRES;
else if(WK_UP==1)return WKUP_PRES;
}else if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0)key_up=1;
return 0;// 无按键按下
}
{
key=KEY_Scan(0); //得到键值
if(key)
{
switch(key)
{
case WKUP_PRES: //控制蜂鸣器
BEEP=!BEEP;
break;
case KEY2_PRES: //控制LED0翻转
LED0=!LED0;
break;
case KEY1_PRES: //控制LED1翻转
LED1=!LED1;
break;
case KEY0_PRES: //同时控制LED0,LED1翻转
LED0=!LED0;
LED1=!LED1;
break;
}
}else delay_ms(10);
}
这种方法 可以很好地 控制是否支持连续按。
第二种方法是
uint8_t key_scan(void)
{
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0)==0)return 1;
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1)==0)return 2;
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2)==0)return 3;
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0)==0)return 4;
else return 0;
}
void key_SScan(void)
{
if((uwTick-uwTick_old)<100) return;
uwTick_old=uwTick;//保证100ms 扫描一次
key_val=key_scan();
key_down=key_val&(key_val^key_old);
//第一次按下1
//key_val 0000 0001
//key_old 0000 0000
//key_down 0000 00001&(0000 0001^0000 0000)=0000 0001
//key_up 1111 1110&(0000 0001^0000 0000)=0000 0000
//key_old 0000 0001
//按下1没有松开时
//key_val 0000 0001
//key_down 0000 0001 &(0000 0001^0000 0001)=0000 0000
//key_up 1111 1110&(0000 0001^0000 0001)=0000 0000
//key_old 0000 0001
//按下1之后松开时
//key_val 0000 0000
//key_down 0000 00000&(0000 0000^0000 0000)=0000 0000
//key_up 1111 1111&(0000 0000^0000 0001)=0000 0001
//key_old 0000 0000
//可以巧妙的发现 key_old在按下期间一直是非0 所以可以根据这个来 记录按下的时长 从而实现长短按
//(key_val^key_old)保证两次的状态不一样,才会把值给了down
//从而保证了不会触发连按并且与keyup结合起来 可以判断按下的时长
key_up=~key_val&(key_val^key_old);
key_old=key_val;//可以保证每一次按之前 key_old都是0000 0000
if(key_old!=0)key_js++;
if(key_js<40)
{
if(key_up==1)ucled=0x01;//里边只能用up了因为只有松手时 才能知道 是长按还是短按
if(key_up==2)ucled=0x02;
if(key_up==3)ucled=0x04;
if(key_up==4)ucled=0x08;
}
if(key_js>=40)
{
if(key_up==1)ucled=0x01<<4;
if(key_up==2)ucled=0x02<<4;
if(key_up==3)ucled=0x04<<4;
if(key_up==4)ucled=0x08<<4;
}
if(key_old==0)key_js=0;
}
第三种 外部中断
可以用外部中断触发的 方式
配置好中断 当按键按下时,是上升沿或者下降沿触发后,去对应的中断服务函数中,处理按键所实现的功能即可
这种方式不占用cpu资源。就是配置有点麻烦,有需要的可以自行配置。
第四种方法 采用adc (硬件有特殊要求)
即按下的每个键所采集到的电压 不同 从而区别出是哪个按键被按下了
一路ADC采集即可实现。
第五种 矩阵键盘(这属于没有方法瞎凑形式)
有时间了 再把代码粘贴过来
如果有时间 也会把第三种的代码
以及第四种的 方法粘贴出来的。。。