十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
开发板上的键盘主要分为独立键盘和矩阵键盘两种,通过J5跳线帽切换这两种键盘。开发板上面分别标有KBD和BTN,其中KBD就是key board,键盘的意思(矩阵键盘),BTN表示button,独立按键,知道了这个我们就能很好的记忆。下面为开发板的实物图:
创新互联公司专注于企业成都全网营销、网站重做改版、河池网站定制设计、自适应品牌网站建设、HTML5、商城网站建设、集团公司官网建设、外贸营销网站建设、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为河池等各大城市提供网站开发制作服务。 1.独立键盘当J5跳线帽接2,3的时候为独立键盘,接1,2的时候为矩阵键盘。下图为独立键盘的示意图:
此处的S4,S5,S6,S7四个按键组成了独立键盘,当我们按下S4时,P33与GND接通,此时单片机的P33口读取到的电压为0,那么其它三个端口的电压为多少呢?我们看下面的图片:
我们现在使用的STC15F2K60S2系列的P3口默认都为准双向口,通过上面的图片可以看到,如果端口引脚没有输入的时候,其输入数据会被上拉电阻强行置为高电平。再看最后一句,准双向口读取外部状态前,要先锁存为"1"才可读到外部正确的状态,我们使用的15系列单片机在上电的时候就会把引脚置为高电平,已经默认锁存为1,可以直接读取外部状态。
2.矩阵键盘当J5跳线帽接1,2的时候,此部分就会由独立键盘变为矩阵键盘。
对于按键状态的识别,我们常用的方法有两种:线翻转法和行扫描法。
下面是官方书籍中的介绍(采用行扫描法)行扫描法的工作原理
矩阵式结构的键盘显然比直接法要复杂一些,识别也要复杂一些,列线通过电阻接正电源,并将行线所接的单片机的 I/O 口作为输出端,而列线所接的 I/O 口则作为输入端。这样,当按键没有按下时,所有的输入端都是高电平,代表无键按下。行线输出是低电平,一旦有键按下,则输入线就会被拉低,这样,通过读入输入线的状态就可得知是否有键按下了。 矩阵键盘中按键的识别有行扫描和线翻转两种方法,其中 行扫描法是一种最常用的按键识别方法,过程如下:
(1)逐行输出 0,检查列线是否非全高;
(2)如果某行输出 0 时,查到列线非全高,则该行有按键按下;
(3)根据输出 0 的行线和读入 0 的列线,即可判断按下按键的位置。
P30,P31,P32,P33作为单片机输入引脚,P34,P35,P42,P44作为单片机的输出引脚。当开始工作时,我们把单片机四个输出引脚分别置0,然后在输入引脚处读取数值从而判断到底是哪个按键被按下。
举个栗子:我们假设S9按键被按下。首先,我们将单片机的P44引脚置0,由于S4~S7未有按键按下,因此单片机由于上拉电阻的作用,在输入端读取的数值都为1。然后我们把P44重新置为1,把P42置为0,由于S9被按下,此线路导通,因此P32引脚被置为0,其它为1,由此我们可以得知S9按键被按下了,往后以此类推。
代码原理分析unsigned int Key_New; //16位无符号整数
P44 = 0; P42 = 1; P35 = 1; P34 = 1; // 第 1 列
//此时若有按键按下,则P30~P33对应的引脚置零
Key_New = P3 & 0x0f; //只保留末四位的数据
P44 = 1; P42 = 0; // 第 2 列 切换扫描的行
Key_New = (Key_New<< 4) | (P3 & 0x0f); //先把先前的数据往高四位移动,然后保留末四位数据
P42 = 1; P35 = 0; // 第 3 列
Key_New = (Key_New<< 4) | (P3 & 0x0f);
P35 = 1; P34 = 0; // 第 4 列
Key_New = (Key_New<< 4) | (P3 & 0x0f);
以上为代码的工作原理,按照4位一组,最终的结果为0x0400,对应S9按键被按下。
二、代码编写 1.独立键盘#include "key.h"
unsigned char Key_Read_BTN(void){
unsigned char Key_Value;
if(P30 == 0) Key_Value = 7;
else if(P31 == 0) Key_Value = 6;
else if(P32 == 0) Key_Value = 5;
else if(P33 == 0) Key_Value = 4;
else Key_Value = 0;
return Key_Value;
}
2. 矩阵键盘😋此处代码的switch()里面非常有规律。
// 运行程序时,将 J5 调整为 KBD 模式(1、2 脚短接)
#include "key.h"
unsigned char Key_Read(void){
unsigned int Key_New;
unsigned char Key_Val;
P44 = 0; P42 = 1; P35 = 1; P34 = 1;
Key_New = P3;
P44 = 1; P42 = 0;
Key_New = (Key_New<< 4) | (P3 & 0x0f);
P42 = 1; P35 = 0;
Key_New = (Key_New<< 4) | (P3 & 0x0f);
P35 = 1; P34 = 0;
Key_New = (Key_New<< 4) | (P3 & 0x0f);
switch(~Key_New) {
case 0x8000: Key_Val = 4; break; // S4
case 0x4000: Key_Val = 5; break; // S5
case 0x2000: Key_Val = 6; break; // S6
case 0x1000: Key_Val = 7; break; // S7
case 0x0800: Key_Val = 8; break; // S8
case 0x0400: Key_Val = 9; break; // S9
case 0x0200: Key_Val = 10; break; // S10
case 0x0100: Key_Val = 11; break; // S11
case 0x0080: Key_Val = 12; break; // S12
case 0x0040: Key_Val = 13; break; // S13
case 0x0020: Key_Val = 14; break; // S14
case 0x0010: Key_Val = 15; break; // S15
case 0x0008: Key_Val = 16; break; // S16
case 0x0004: Key_Val = 17; break; // S17
case 0x0002: Key_Val = 18; break; // S18
case 0x0001: Key_Val = 19; break; // S19
default: Key_Val = 0;
}
return Key_Val;
}
三、按键消抖
(纯手画,比例不是很对,按下和松手的抖动时间<10ms,稳定期>数百ms)
1.按键抖动原理通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而在闭合及断开的瞬间均伴随有一连串的抖动,为了不产生这种现象而作的措施就是按键消抖。
2.按键消抖的方法 1)普通软件延时软件延时和松手检测都会占用CPU资源(delay)
while(1) {
if(key==0) {
Delay10ms();
if(key==0) {
//按键按下执行相关功能代码
while(!key);
}
}
}
2)标志位软件延时通过引入按下标志位,省去了while(!KEY)的松手检测,将按下时稳定期的数百ms释放出来,只占用了按下和松手时的共20ms的消抖时间。
3)标志位定时器延时使用定时器进行延时消抖,使用标志位代替松手检测(不会对主函数进行明显干扰)
4)状态机算法成熟但代码量大(设置三种状态)
5)三行代码(位运算)unsigned char Key_Value,Key_Down,Key_Old;//定义全局变量
Key_Value = Key_Read(); //读取10ms更新一次的I/O电平状态,并储存于变量Key_Value
Key_Down = Key_Value & (Key_Old ^ Key_Value); //按下为按键值,其它为0
Key_Old = Key_Value;//把读取到的临时按键值Key_Value更新到Key_Old中,作为下一次旧的按键值
假设S4被按下了:
Key_Old | Key_Value | 对应的按键过程 | Key_Old ^ Key_Value | Key_Down |
0 | 0 | 未按下 | 0 | 0 |
0 | 4 | 按下过程中 | 4 | 4 |
4 | 4 | 按下稳定期间 | 0 | 0 |
4 | 0 | 抬起过程中 | 4 | 0 |
拓展:Key_Up = ~Key_Value & (Key_Old ^ Key_Value);
Key_Old | Key_Value | 对应的按键过程 | Key_Old ^ Key_Value | Key_Up |
0 | 4 | 未按下 | 0 | 0 |
0 | 0 | 按下过程中 | 4 | 0 |
4 | 0 | 按下稳定期间 | 0 | 0 |
4 | 4 | 抬起过程中 | 4 | 4 |
长按:if(Key_Old == 4 {(......)}
双击:设置一个标志位,每次加一
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧