实现思路
开始时四列均输出高电平,键盘处于检测状态。检测到按键按下(读IO口值不为0)转去执行读取输入字符子程序。
为避免按键抖动引起干扰,引入按键消抖。如果按键确实按下,读IO口的值不为0,对读取的IO口值进行译码。如果同时按下多个同一列按键,键盘不确定按下的是什么键,返回’?’,否则返回输入的字符。由于一次按下时间较长(相对处理器执行速度),避免重复读键盘导致干扰呼吸灯主程序执行,需要在主程序中引入一个bool型变量press,平时不按下按键时置false ,检测到按下并且不是误触发则读取字符后置true,误触发仍置false,并且整个检测块被if块保护,在同一次按键主程序又执行到检测按键处时不会重复扫描和分析按键,避免降低MPU处理速度从而影响呼吸灯闪烁频率。最终调试发现效果很好。虽然没有使用中断机制,但是键盘检测模块的执行效果就像是使用中断机制一样,对主程序的执行没有任何影响。
键盘按键映射图
| C1 | C2 | C3 | C4 | |
|---|---|---|---|---|
| R1 | 1 | 2 | 3 | A |
| R2 | 4 | 5 | 6 | B |
| R3 | 7 | 8 | 9 | C |
| R4 | * | 0 | # | D |
硬件接线
R1--------PC0
R2--------PC1
R3--------PC2
R4--------PC3
C1--------PA0
C2--------PA1
C3--------PA4
C4--------PB0
PA5-------PA8
源代码
#include "mbed.h"
#define IOS (0x0F) // PC_0+PC_1+PC_2+PC_3
//R1-R4: PC0-PC3, C1:PA0, C2:PA1, C3:PA4, C4:PB0
PortIn myIOs(PortC, IOS);
DigitalOut led(LED1);
DigitalOut C1(PA_0);
DigitalOut C2(PA_1);
DigitalOut C3(PA_4);
DigitalOut C4(PB_0);
PwmOut pwm(PA_8);
char keyboardInputHandler();
int main() {
myIOs.mode(PullDown);
float i = 0.5; //dc
bool flag = true;
bool press = false;
pwm.period_ms(10);
char input;
while(1)
{
led.write(PA_8);
C1=1,C2=1,C3=1,C4=1;
if(myIOs.read()!=0)
{/*键盘扫描程序*/
if(!press)
{
input = keyboardInputHandler();
if(input != '\0')
{
printf("Input content is character %c.\r\n",input);
press=true;
}
else press=false;
}
}
else press=false;
pwm.write(i);
if(flag)
{
i+=0.01;
if(i>=1.0) flag=false;
}
else {
i-=0.01;
if(i<=0) flag=true;
}
wait_ms(10);
}
}
char keyboardInputHandler()
{
int i;
char a;
C1=1,C2=1,C3=1,C4=1;
if(myIOs.read()==0) return '\0';
for(i=1;i<5;i++)
{
if(i==1) {
C1=1,C2=0,C3=0,C4=0;
if(myIOs.read()!=0)
{
wait_ms(20);
if(myIOs.read()!=0)
{
if(myIOs.read()==0b0001)
a='1';
else if(myIOs.read()==0b0010)
a='4';
else if(myIOs.read()==0b0100)
a='7';
else if(myIOs.read()==0b1000)
a='*';
else a='?';
break;
}
else a='\0';
}
else a='\0';
}
else if(i==2) {
C1=0,C2=1,C3=0,C4=0;
if(myIOs.read()!=0)
{
wait_ms(20);
if(myIOs.read()!=0)
{
if(myIOs.read()==0b0001)
a='2';
else if(myIOs.read()==0b0010)
a='5';
else if(myIOs.read()==0b0100)
a='8';
else if(myIOs.read()==0b1000)
a='0';
else a='?';
break;
}
else a='\0';
}
else a='\0';
}
else if(i==3) {
C1=0,C2=0,C3=1,C4=0;
if(myIOs.read()!=0)
{
wait_ms(20);
if(myIOs.read()!=0)
{
if(myIOs.read()==0b0001)
a='3';
else if(myIOs.read()==0b0010)
a='6';
else if(myIOs.read()==0b0100)
a='9';
else if(myIOs.read()==0b1000)
a='#';
else a='?';
break;
}
else a='\0';
}
else a='\0';
}
else {
C1=0,C2=0,C3=0,C4=1;
if(myIOs.read()!=0)
{
wait_ms(20);
if(myIOs.read()!=0)
{
if(myIOs.read()==0b0001)
a='A';
else if(myIOs.read()==0b0010)
a='B';
else if(myIOs.read()==0b0100)
a='C';
else if(myIOs.read()==0b1000)
a='D';
else a='?';
break;
}
else a='\0';
}
else a='\0';
}
}
return a;
}
本文介绍了一种在不使用中断机制的情况下实现键盘检测和呼吸灯控制的方法。通过检测按键按下并消除按键抖动,确保了主程序执行不受干扰。同时,通过引入bool型变量press避免重复读取键盘,保持了MPU处理速度,实现了良好的呼吸灯闪烁频率。
412

被折叠的 条评论
为什么被折叠?



