系列文章目录
提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
引入按键处理的思想过程
样例:按键处理系列,低配初阶最基本方法,按下有效
提示:以下是本篇文章正文内容,下面案例可供参考
一、单按键处理逻辑
1.等待按下
2.按键抖动
2.1 硬件消抖:R-S触发器、RC电路
2.2 软件消抖,延时消抖5-20ms
3.判断为有效按下
4.松开抖动
软件消抖
5.判断为松开按键
unsigned char key_num = 0;//充分考虑是否需要赋初始值0。任何局部变量建立后记得清0。标志法其它位置清0,或者每次进入函数体初始化清0。
if(!KeyIn1)
{
Delay_xms(10); //消抖。缺点:进程占用,复杂程序影响其它时基。后续采用中断定时
if(!KeyIn1)
{
fSW1= 1;
}
while(!KeyIn1);//松手等待,防止主循环内多次触发fStart = 1时带来的逻辑
}
二、多按键处理逻辑
1.判断有按键按下
2.判断具体按键
3.按键标志
if(!KeyIn1 || !KeyIn2 ||!KeyIn3 || !KeyIn4)
{
vKeyDelayCnt++;
if(vKeyDelayCnt > 10) //Delay_Xms(10);
{
vKeyDelayCnt = 0;
if(!KeyIn1 || !KeyIn2 ||!KeyIn3 || !KeyIn4)
{
if(!KeyIn1) //判断具体按键
fSW1 = 1;
if(!KeyIn2)
fSW2 = 1;
if(!KeyIn3)
fSW3 = 1;
if(!KeyIn4)
fSW4 = 1;
}
while(!KeyIn1 || !KeyIn2 || !KeyIn3 || !KeyIn4); //松手等待
}
}
三、矩阵按键处理逻辑
例:4行4列矩阵
方法1:逐行扫描/逐列扫描
#define KeyPort P3
sbit KeyIn4 = P3^7; //第4列
sbit KeyIn3 = P3^6;
sbit KeyIn2 = P3^5;
sbit KeyIn1 = P3^4;
sbit keyOut4 = P3^3; //第4行
sbit keyOut3 = P3^2;
sbit keyOut2 = P3^1;
sbit keyOut1 = P3^0;
其它列执行内容相同,列扫描输出配置4组(4列)–>for循环执行扫描
KeyPort = 0xFE; //第1行扫描
if(!KeyIn1 || !KeyIn2 || !KeyIn3 || !KeyIn4) //按键等待
{
vKeyDelayCnt++;
if(vKeyDelayCnt > 10)
{
vKeyDelayCnt = 0;
if(!KeyIn1 || !KeyIn2 || !KeyIn3 || !KeyIn4) //按键按下
{
if(!KeyIn1) //按键识别
fSW1 = 1;
if(!KeyIn2)
fSW2 = 1;
if(!KeyIn3)
fSW3 = 1;
if(!KeyIn4)
fSW4 = 1;
}while(!KeyIn1 || !KeyIn2 || !KeyIn3 || !KeyIn4);//松手等待
}
}
方法2:线反转识别
原理:同时列(行)输出、行(列)输入 -->确定行号/列号 -->确定具体按键
KeyPort = 0xF0; //In输入,Out输出0
if(KeyPort != 0xF0) //1.按键按下
{
vKeyDelayCnt++;
if(vKeyDelayCnt > 10) //2.消抖10ms
{
vKeyDelayCnt = 0;
if(KeyPort != 0xF0) //3.确定有按键按下
{
tempH = KeyPort & 0xF0; //4.确定列号
KeyPort = 0x0F;
tempL = KeyPort & 0x0F; //5.确定行号
}
while(KeyPort != 0x0F); //6.松手等待
gKey = tempH + tempL;
}
}
转载一个经典的按键处理算法,三行代码搞定:
核心算法:
unsigned char Trg;
unsigned char Cont;
void KeyRead( void )
{
unsigned char ReadData = PINB^0xff; // 1
Trg = ReadData & (ReadData ^ Cont); // 2
Cont = ReadData; // 3
}
样例:trg是一次触发,Cont是长按
if (Trg & KEY_BEEP) // 如果按下的是KEY_BEEP
{
Beep(); // 执行蜂鸣器处理函数
}
void KeyProc(void)
{
if (Trg & KEY_MODE) // 如果按下的是KEY_MODE,而且你常按这按键也没有用,
{ //它是不会执行第二次的哦 , 必须先松开再按下
Mode++; // 模式寄存器加1,当然,这里只是演示,你可以执行你想
// 执行的任何代码
}
if (Cont & KEY_PLUS) // 如果“加”按键被按着不放
{
cnt_plus++; // 计时
if (cnt_plus > 100) // 20ms*100 = 2S 如果时间到
{
Func(); // 你需要的执行的程序
}
}
}