AVR单片机用PA口的八个按键对应PB口的八个LED灯亮
#include
//端口初始化
void port_init(void) //BCD口使能上拉
{
PORTB = 0XFF;
PORTC = 0XFF;
PORTD = 0XFF;
DDRB = 0X00;
DDRC = 0X00;
DDRD = 0X00;
}
//延时函数:方式一
void Delay(void)
{
unsigned char a, b, c;
for (a = 1; a; a++)
for (b = 1; b; b++)
for (c = 0; c<10; c++) //循环次数=255*255*10
;
}
//延时函数:方式二,1ms延时,准确性较Delay();高
voidDelayMs(unsigned int i)
{
while(i--)
{
unsignedint j;
for(j=1;j<=613;j++)
;
}
}
//键盘扫描函数
voidkey_scan(void)
{
unsigned char key;
DDRB = 0XFF;
DDRA = 0X00; //按键输入
PORTA = 0XFF; //平时为高
if(PINA != 0XFF) //检测A口电平,如果全是高电平则退出
{
DelayMs(20); //防抖
if(PINA != 0XFF ) //再次检测A口电平,如果不全是高电平则继续执行程序{
key = PINA; //读取PINA,将其存放在key中
PORTB = key; //将PINA读出的值赋给B端口,对应LED点亮while(PINA != 0XFF); //当前有按键处于按下状态,再按其他按键时程序维持当前
//状态,不会有对应LED点亮发生
}
}
}
void main(void)
{
port_init();
while(1)
{
key_scan();
}
}
信息工程学院实验报告 课程名称:微机原理与接口技术 实验项目名称:键盘扫描及显示实验 实验时间: 班级: 姓名: 学号: 一、实 验 目 的 1. 掌握 8254 的工作方式及应用编程。 2. 掌握 8254 典型应用电路的接法。 二、实 验 设 备 了解键盘扫描及数码显示的基本原理,熟悉 8255 的编程。 三、实 验 原 理 将 8255 单元与键盘及数码管显示单元连接,编写实验程序,扫描键盘输入,并将扫描结果送数码管显示。键盘采用 4×4 键盘,每个数码管显示值可为 0~F 共 16 个数。实验具体内容如下:将键盘进行编号,记作 0~F ,当按下其中一个按键时,将该按键对应的编号在一个数码管上显示出来,当再按下一个按键时,便将这个按键的编号在下一个数码管上显示出来,数码管上可以显示最近 6 次按下的按键编号。 键盘及数码管显示单元电路图如图 7-1 和 7-2 所示。8255 键盘及显示实验参考接线图如图 7-3 所示。 图 7-1 键盘及数码管显示单元 4×4 键盘矩阵电路图 成 绩: 指导老师(签名):
图 7-2 键盘及数码管显示单元 6 组数码管电路图 图 7-3 8255 键盘扫描及数码管显示实验线路图 四、实验内容与步骤 1. 实验接线图如图 7-3 所示,按图连接实验线路图。
图 7-4 8255 键盘扫描及数码管显示实验实物连接图 2.运行 Tdpit 集成操作软件,根据实验内容,编写实验程序,编译、链接。 图 7-5 8255 键盘扫描及数码管显示实验程序编辑界面 3. 运行程序,按下按键,观察数码管的显示,验证程序功能。 五、实验结果及分析: 1. 运行程序,按下按键,观察数码管的显示。
4X4扫描式矩阵键盘课程设计 课程设计名称: 4_4扫描式矩阵键盘设计 姓名:DUKE 班级:电子1008班 学号:10086 成绩: 日期:2014年1月6日
摘要 随着21世纪的到来,电子信息行业将是人类社会的高科技行业之一,式设施现代化的基础,也是人类通往科技巅峰的直通路。电子行业的发展从长远来看很重要,但最主要的还是科技问题。 矩阵式键盘提高效率进行按键操作管理有效方法,它可以提高系统准确性,有利于资源的节约,降低对操作者本身素质的要求。是它能准时、实时、高效地显示按键信息,以提高工作效率和资源利用率。 矩阵式键盘乃是当今使用最为广泛的键盘模式,该系统以N个端口连接控制N*N个按键,显示在LED数码管上。单片机控制依据这是键盘显示系统,该系统可以对不同的按键进行实时显示,其核心是单片机和键盘矩阵电路部分,主要对按键与显示电路的关系、矩阵式技术及设备系统的硬件、软件等各个部分进行实现。 4*4矩阵式键盘采用AT89C51单片机为核心,主要由矩阵式键盘电路、译码电路、显示电路等组成,软件选用C语言编程。单片机将检测到的按键信号转换成数字量,显示于LED显示器上。该系统灵活性强,易于操作,可靠性高,将会有更广阔的开发前景。
目录 第一章:系统功能要求-------------------------------------------------------- 1.1 4*4 矩阵式键盘系统概述------------------------------------------------ 1.2 本设计任务和主要内容--------------------------------------------------- 第二章:方案论证--------------------------------------------------------------- 第三章:系统硬件电路的设计------------------------------------------------ 3.1 单片机控制系统原理----------------------------------------------------- 3.2 原理图绘制说明---------------------------------------------------------- 3.3 画出流程图---------------------------------------------------------------- 3.4 原理图绘制--------------------------------------------------------------- 第四章:系统程序的设计------------------------------------------------------ 4.1 程序的编写步骤----------------------------------------------------------- 4.2 编写的源程序-------------------------------------------------------------- 第五章:调试及性能分析------------------------------------------------------ 第六章:心得体会--------------------------------------------------------------- 参考文献----------------------------------------------------------------------------
#include
* 输出: 无 ***********************************************************************/ void delay() { _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); } /******************************************************************** * 名称: bit Busy(void) * 功能: 这个是一个读状态函数,读出函数是否处在忙状态 * 输入: 输入的命令值 * 输出: 无 ***********************************************************************/ bit Busy(void) { bit busy_flag = 0; RS = 0; RW = 1; E = 1; delay(); busy_flag = (bit)(P0 & 0x80); E = 0; return busy_flag; } /******************************************************************** * 名称: wcmd(uchar del) * 功能: 1602命令函数 * 输入: 输入的命令值 * 输出: 无 ***********************************************************************/ void wcmd(uchar del) { while(Busy()); RS = 0; RW = 0; E = 0; delay(); P0 = del; delay(); E = 1;
4*4键盘程序readkeyboard: begin: acall key_on jnz delay ajmp readkeyboard delay:acall delay10ms acall key_on jnz key_num ajmp begin key_num:acall key_p anl a,#0FFh jz begin acall key_ccode push a key_off:acall key_on jnz key_off pop a ret key_on: mov a,#00h orl a,#0fh mov p1,a mov a,p1 orl a,#0f0h cpl a ret key_p: mov r7,#0efh l_loop:mov a,r7 mov p1,a mov a,p1 orl a,#0f0h mov r6,a cpl a jz next ajmp key_c next: mov a,r7 jnb acc.7,error rl a mov r7,a ajmp l_loop error:mov a,#00h ret key_c:mov r2,#00h mov r3,#00h mov a,r6
mov r5,#04h again1:jnb acc.0,out1 rr a inc r2 djnz r5, again1 out1: inc r2 mov a,r7 mov r5,#04h again2:jnb acc.4,out2 rr a inc r3 djnz r5,again2 out2: inc r3 mov a, r2 swap a add a,r3 ret key_ccode:push a swap a anl a,#0fh dec a rl a ;行号乘4 rl a mov r7,a pop a anl a,#0fh dec a add a,r7 ret delay10ms: anl tmod,#0f0h orl tmod,#01h mov th0,#0d8h mov tl0,#0f0h setb tr0 wait:jbc tf0,over ajmp wait clr tr0 over:ret 单片机键盘设计 (二)从电路或软件的角度应解决的问题 软件消抖:如果按键较多,硬件消抖将无法胜任,常采用软件消抖。通常采用软件延时的方法:在第一次检测到有键按下时,执行一段延时10ms的子程序后,再确认电平是否仍保持闭合状态电平,如果保持闭合状态电平,则确认真正有键按下,进行相应处理工作,消除了抖动的影响。(这种消除抖动影响的软件措施是切实可行的。)
键盘是单片机常用输入设备,在按键数量较多时,为了节省I/O口等单片机资源,一般采取扫描的方式来识别到底是哪一个键被按下。即通过确定被按下的键处在哪一行哪一列来确定该键的位置,获取键值以启动相应的功能程序。 4*4矩阵键盘的结构如图1(实物参考见万用板矩阵键盘制作技巧)。在本例中,矩阵键盘的四列依次接到单片机的P1.0~P1.3,四行依次接到单片机的P1.4~P1.7;同时,将列线上拉,通过10K电阻接电源。 查找哪个按键被按下的方法为:一个一个地查找。 先第一行输出0,检查列线是否非全高; 否则第二行输出0,检查列线是否非全高; 否则第三行输出0,检查列线是否非全高; 如果某行输出0时,查到列线非全高,则该行有按键按下; 根据第几行线输出0与第几列线读入为0,即可判断在具体什么位置的按键按下。 下面是具体程序:
void Check_Key(void) { unsigned char row,col,tmp1,tmp2; tmp1 = 0x10; //tmp1用来设置P1口的输出,取反后使 P1.4~P1.7中有一个为0 for(row=0;row<4;row++) // 行检测 { P1 = 0x0f; // 先将p1.4~P1.7置高 P1 =~tmp1; // 使P1.4~p1.7中有一个为0 tmp1*=2; // tmp1左移一位 if ((P1 & 0x0f) < 0x0f) // 检测P1.0~P1.3中是否有一位为0,只要有,则说明此行有键按下,进入列检测 { tmp2 = 0x01; // tmp2用于检测出哪一列为0 for(col =0;col<4;col++) // 列检测 { if((P1 & tmp2)==0x00) // 该列如果为低电平则可以判定为该列 { key_val =key_Map[ row*4 +col ]; // 获取键值,识别按键;key_Map为按键的定义表 return; // 退出循环 } tmp2*=2; // tmp2左移一位 } } } } //结束 这是一种比较经典的矩阵键盘识别方法,实现起来较为简单,程序短小精炼。
二、设计内容 1、本设计利用各种器件设计,并利用原理图将8255单元与键盘及数码管显示单元连接,扫描键盘输入,最后将扫描结果送入数码管显示。键盘采用4*4键盘,每个数码管可以显示0-F共16个数。将键盘编号,记作0-F,当没按下其中一个键时,将该按键对应的编号在一个数码管上显示出来,当在按下一个 键时,便将这个按键的编号在下一个数码管上显示,数码管上 可以显示最近6次按下的按键编号。 设计并实现一4×4键盘的接口,并在两个数码管上显示键盘所在的行与列。 三、问题分析及方案的提出 4×4键盘的每个按键均和单片机的P1口的两条相连。若没有按键按下时,单片机P1口读得的引脚电平为“1”;若某一按键被按下,则该键所对应的端口线变为地电平。单片机定时对P1口进行程序查询,即可发现键盘上是否有按键按下以及哪个按键被按下。 实现4×4键盘的接口需要用到单片机并编写相应的程序来识别键盘的十六个按键中哪个按键被按下。因为此题目还要求将被按下的按键显示出来,因此可以用两个数码管来分别显示被按下的按键的行与列
表示任意一个十六进制数)分别表示键盘的第二行、第三行、第四行;0xXE、0xXD、0xXB、0xX7(X表示任意一个十六进制数)则分别表示键盘的第一列、第二列、第三列和第四列。例如0xD7是键盘的第二行第四列的按键 对于数码管的连接,采用了共阳极的接法,其下拉电阻应保证芯片不会因为电流过大而烧坏。 五、电路设计及功能说明 4×4键盘的十六个按键分成四行四列分别于P1端口的八条I/O 数据线相连;两个七段数码管分别与单片机的P0口和P2口的低七 位I/O数据线相连。数码管采用共阳极的接法,所以需要下拉电阻 来分流。结合软件程序,即可实现4×4键盘的接口及显示的设计。 当按下键盘其中的一个按键时,数码管上会显示出该按键在4×4键 盘上的行值和列值。所以实现了数码管显示按键位置的功能 四、设计思路及原因 对于4×4键盘,共有十六个按键。如果每个按键与单片机的一个引脚相连,就会占用16个引脚,这样会使的单片机的接口不够用(即使够用,也是对单片机端口的极大浪费)。因此我们应该行列式的接法。行列式非编码键盘是一种把所有按键排列成行列矩阵的键盘。在这种键若没有按键按下时,单片机从P1口读得的引脚电平为“1”;若某一按键被按下,则该键所对应的端口线变为地电平。因此0xEX(X表示任意4×4键盘的第一行中的某个按键被按下,相应的0xDX、0xBX、0x7X(X 二、实验内容
4x4矩阵键盘识别设计班级:1221201 专业:测控技术与仪器 姓名:涂勇 学号:2012 2012 0110 指导老师:钟念兵 东华理工大学 2016年1月1日
摘要 随着21世纪的到来,电子信息行业将是人类社会的高科技行业之一,电子式设施现代化的基础,也是人类通往科技巅峰的直通路。电子行业的发展从长远来看很重要,但最主要的还是科技问题。 矩阵式键盘提高效率进行按键操作管理有效方法,它可以提高系统准确性,有利于资源的节约,降低对操作者本身素质的要求。是它能准时、实时、高效地显示按键信息,以提高工作效率和资源利用率。 矩阵式键盘乃是当今使用最为广泛的键盘模式,该系统以N个端口连接控制N*N 个按键,显示在LED数码管上。单片机控制依据这是键盘显示系统,该系统可以对不同的按键进行实时显示,其核心是单片机和键盘矩阵电路部分,主要对按键与显示电路的关系、矩阵式技术及设备系统的硬件、软件等各个部分进行实现。 4*4矩阵式键盘采用STM32嵌入式微处理器为核心,主要由矩阵式键盘电路、硬件电路、显示电路等组成,软件选用C语言编程。STM32将检测到的按键信号转换成数字量,显示于LED显示器上。该系统灵活性强,易于操作,可靠性高,将会有更广阔的开发前景。
目录 第一章:系统功能要求--------------------------------------------------------4*4 矩阵式键盘系统概述------------------------------------------------ 本设计任务和主要内容--------------------------------------------------- 第二章:系统硬件电路的设计------------------------------------------------硬件系统主要思路和电路原理图- -------------------------------------- 硬件上键盘规划- --------------------------------------------------------- 第三章:系统程序的设计------------------------------------------------------程序的编写步骤----------------------------------------------------------- 编写的源程序-------------------------------------------------------------- 第四章:心得体会---------------------------------------------------------------
/*----------------------------------------------- 名称:矩阵键盘依次输入控制使用行列逐级扫描 论坛:https://www.doczj.com/doc/9d5923636.html, 编写:shifang 日期:2009.5 修改:无 内容:如计算器输入数据形式相同从右至左使用行列扫描方法 ------------------------------------------------*/ #include
44 键盘扫描实验 实验目的 1、学习HDL程序的基本设计技巧; 2、掌握矩阵键盘的扫描原理和使用方法。 Verilog程序: module hex_keypad(Col,Code,show,show1,count,scan,clock,Row); output[3:0] Code,Col,count; //定义列信号Col、行列信号共同决定的 输出代码Code、以及计数变量count output[7:0] show,show1; //定义七段显示变量show、show1 input[3:0] Row; //定义输入行信号Row input scan; //定义数码管选择信号scan input clock; //定义时钟信号clock reg[3:0] Col,Code,count; //将输出信号定义为reg型 reg[7:0] show,show1; reg[1:0] cn; //定义reg型变量cn,用于计数 reg reset,count_up,count_down; //定义变量reset用于计数清零,count_up 开始加计数,count_down开始减计数reg[15:0] times1,times2; //定义变量times1、times2用于决定开 始计数的时间 assign scan=1'b1; //将数码管选择信号赋值为1
always@(posedge clock) //产生列信号 if(cn==4)cn<=0; else cn<=cn+1; always@(cn) case(cn) 2'b00:Col=4'b1110; 2'b01:Col=4'b1101; 2'b10:Col=4'b1011; 2'b11:Col=4'b0111; endcase always@(posedge clock) //行列信号共同决定输出代码Code case({Row,Col}) 8'b1110_1110:Code=4'h0; 8'b1110_1101:Code=4'h1; 8'b1110_1011:Code=4'h2; 8'b1110_0111:Code=4'h3; 8'b1101_1110:Code=4'h4; 8'b1101_1101:Code=4'h5;
C语言 4*4键盘扫描电路模块 #include
经典的矩阵键盘扫描程序 查找哪个按键被按下的方法为:一个一个地查找。 先第一行输出0,检查列线是否非全高; 否则第二行输出0,检查列线是否非全高; 否则第三行输出0,检查列线是否非全高; 如果某行输出0时,查到列线非全高,则该行有按键按下; 根据第几行线输出0与第几列线读入为0,即可判断在具体什么位置的按键按下。 下面是具体程序: void Check_Key(void) { unsigned char row,col,tmp1,tmp2; tmp1 = 0x10; //tmp1用来设置P1口的输出,取反后使 P1.4~P1.7中有一个为0 for(row=0;row<4;row++) // 行检测 { P1 = 0x0f; // 先将p1.4~P1.7置高 P1 =~tmp1; // 使P1.4~p1.7中有一个为0 tmp1*=2; // tmp1左移一位 if ((P1 & 0x0f) < 0x0f) // 检测P1.0~P1.3中是否有一位为0,只要有,则说明此行有键按下,进入列检测 { tmp2 = 0x01; // tmp2用于检测出哪一列为0 for(col =0;col<4;col++) // 列检测
{ if((P1 & tmp2)==0x00) // 该列如果为低电平则可以判定为该列 { key_val =key_Map[ row*4 +col ]; // 获取键值,识别按键;key_Map为按键的定义表 return; // 退出循环 } tmp2*=2; // tmp2左移一位 } } } } //结束 这是一种比较经典的矩阵键盘识别方法,实现起来较为简单,程序短小精炼。 4*4矩阵键盘扫描程序 /* 设置行线为输入线,列线为输出线 */ uchar KeyScan(); //按键扫描子程序 void delay10ms(); //延时程序 uchar key_free(); //等待按键释放程序 void key_deal(); //键处理程序 //主程序 void main() { while(1) { KeyScan(); key_free(); key_deal(); } } //按键扫描子程序 uchar KyeScan() { unsigned char key,temp; P1=0xF0; if(P1&0xF0!=0xF0) { delay10ms(); //延时去抖动 if(P1&0xF0!=0xF0) { P1=0xFE; //扫描第一列
#include
feng=1; break; case 0xeb: led4=~led4; feng=0; delay1(100); feng=1; break; } while(templ!=0xf0) { templ=P3; templ=templ&0xf0; } } } P3=0xfe; templ=P3; templ=templ&0xf0; while(templ!=0xf0) { delay1(10); templ=P3; templ=templ&0xf0; while(templ!=0xf0) { templ=P3; switch(templ) { case 0xbe: led8=~led8; feng=0; delay1(100); feng=1; break; case 0xee: led2=~led2; feng=0;
4*4矩阵键盘电路连接图和快速扫描完整程序 #include
P0=wei[x]; while(b--); LE1=0; } //////////////////////////////////////////////////////////////////// //4*4矩阵扫描,键值保存在key中 void key_4x4() { P1=temp; //初值uchar temp=0xfe; sm=P1; sm=sm&0xf0; //取P1口高四位的值,如果为0就表示无键按下if(sm!=0xf0) { switch(sm) { case 0x70:{key=0+4*beis;break;} case 0xb0:{key=1+4*beis;break;} case 0xd0:{key=2+4*beis;break;} case 0xe0:{key=3+4*beis;break;} default :{key=10+4*beis;break;} } } else { if(temp==0xf7) { temp=0xfe; } else { temp=_crol_(temp,1); } beis++; if(beis==4)beis=0; } } ////////////////////////////////////////////////////////////////////
以下假设你懂C语言,因为纯粹的C语言描述,所以和处理器平台无关,你可以在MCS-51,AVR,PIC,甚至是ARM平台上面测试这个程序性能。以下以AVR的MEGA8作为平台讲解,没有其它原因,因为我手头上只有AVR的板子而已没有51的。用51也可以,只是芯片初始化部分不同,还有寄存器名字不同而已。 核心算法: unsigned char Trg; unsigned char Cont; void KeyRead( void ) { unsigned char ReadData = PINB^0xff; // 1 Trg = ReadData & (ReadData ^ Cont); // 2 Cont = ReadData; // 3 } 下面是程序解释:Trg(triger)代表的是触发,Cont(continue)代表的是连续按下。 1:读PORTB的端口数据,取反,然后送到ReadData 临时变量里面保存起来。(端口值与0XFF 按位异或,有按键按下为0,异或后相应的位就为1,相当于将读取的端口值取反) 2:算法1,用来计算触发变量的。一个位与操作,一个异或操作,我想学过C语言都应该懂吧?Trg为全局变量,其它程序可以直接引用。 3:算法2,用来计算连续变量。 看到这里,有种“知其然,不知其所以然”的感觉吧?代码很简单,但是它到底是怎么样实现我们的目的的呢?好,下面就让我们绕开云雾看青天吧。 我们最常用的按键接法如下:AVR是有内部上拉功能的,但是为了说明问题,我是特意用外部上拉电阻。(STM32可以将端口设置为输入上拉模式)那么,按键没有按下的时候,读端口数据为1,如果按键按下,那么端口读到0。下面就看看具体几种情况之下,这算法是怎么一回事。 (1)没有按键的时候 端口为0xff,ReadData读端口并且取反,很显然,就是 0x00 了。(0XFF^0XFF=0X00)Trg = ReadData & (ReadData ^ Cont); (初始状态下,Cont也是为0的)很简单的数学计算,因为ReadData为0,则它和任何数“相与”,结果也是为0的。 Cont = ReadData; 保存Cont 其实就是等于ReadData,为0; 结果就是: ReadData = 0; Trg = 0; Cont = 0; (2)第一次PB0按下的情况 端口数据为0xfe,ReadData读端口并且取反,很显然,就是 0x01 了。(0XFE^0XFF=0X01)Trg = ReadData & (ReadData ^ Cont); 因为这是第一次按下,所以Cont是上次的值,应为为0。那么这个式子的值也不难算,也就是 Trg = 0x01 & (0x01^0x00) = 0x01 Cont = ReadData = 0x01; 结果就是: ReadData = 0x01; Trg = 0x01;Trg只会在这个时候对应位的值为1,其它时候都为0 Cont = 0x01;
本资源为网上搜集而来,如果该程序涉及或侵害到您的版权请立即写信通知我
键盘扫描 键盘是由按键构成,是单片机系统里最常用的输入设备。我们可以通过键盘输入数据或命令来实现简单的人-机通信。 1.按键及键抖动 按键是一种常开型按钮开关。平时,按键的两个触点处于断开状态,按下按键时两个触点才闭合(短路)。如图1-1所示,平常状态下,当按键K未被按下时,按键断开,PA0输入口的电平为高电平;当按键K被按下时,按键闭合,PA0输入口的电平为低电平。 图1-1 按键电路 图1-2 按键抖动 一般的按键所用开关都是机械弹性开关,由于机械触点的弹性作用,按键开
关在闭合时不会马上稳定地连接,在断开进也不会马上完全的断开,在闭合和断开的瞬间均有一连串的抖动。按键按下的电压信号波形图如图1-2所示,从图中可以看出按键按下和松开的时候都存在着抖动。抖动时间的长短因按键的机械特性不同而有所不同,一般为5ms~10ms。 如果不处理键抖动,则有可能引起一次按键被误读成多次,所以为了确保能够正确地读到按键,必须去除键抖动,确保在按键的稳定闭合和稳定断开的时候来判断按键状态,判断后再做处理。按键在去抖动,可用硬件或软件两种方法消除。由于使用硬件方法消除键抖动,一般会给系统的成本带来提高,所以通常情况下都是使用软件方法去除键抖动。 常用的去除键抖动的软件方法有很多种,但是都离不开基本的原则:就是要么避开抖动的时候检测按键或是在抖动的时候检测到的按键不做处理。这里说明一下常用的两种方法: 第一种方法是检测到按键闭合电平后先执行一个延时程序,做一个12ms~24ms的延时,让前抖动消失后再一次检测按键的状态,如果仍是闭合状态的电平,则认为真的有按键按下;若不是闭合状态电平,则认为没有键按下。若是要判断按键松开的话,也是要在检测到按键释放电平之后再给出12ms~24ms的延时,等后抖动消失后再一次检测按键的状态,如果仍为断开状态电平,则确认按键松开。这种方法的优点是程序比较简单,缺点是由于延时一般采用跑空指令延时,造成程序执行效率低。 第二种方法是每隔一个时间周期检测一次按键,比如每5ms扫描一次按键,要连续几次都扫描到同一按键才确认这个按键被按下。一般确认按键的扫描次数由实际情况决定,扫描次数的累积时间一般为50ms~60ms。比如,以5ms为基本时间单位去扫描按键的话,前后要连续扫描到同一个按键11次而达到50ms 来确认这个按键。按键松开的检测方法也是一样要连续多次检测到按键状态为断开电平才能确认按键松开。这种方法的优点是程序执行效率高,不用刻意加延时指令,而且这种方法的判断按键抗干扰能力要更好;缺点是程序结构较复杂。 在以下的介绍中,我们将使用第二种方法来去除键抖动。 2.键盘结构及工作原理 键盘一般有独立式和行列式(矩阵式)两种。当然还有其它的结构,比如交互式结构等等,不过其它的结构比较少用,在这里就不介绍了。在中颖的单片机中,有些单片机的LCD驱动引脚的SEGMENT口可以共享按键扫描口,当选择为按键扫描口时,可以使用这些口来扫描按键,所以在外部电路可以连接LCD和按键矩阵,采用分时扫描进行处理,下面也将介绍这个特殊应用的方法和注意的地方。 独立式键盘结构
4*4键盘程序 readkeyboard: begin: acall key_on jnz delay ajmp readkeyboard delay:acall delay10ms acall key_on jnz key_num ajmp begin key_num:acall key_p anl a,#0FFh jz begin acall key_ccode push a key_off:acall key_on jnz key_off pop a ret key_on: mov a,#00h orl a,#0fh mov p1,a mov a,p1 orl a,#0f0h cpl a ret key_p: mov r7,#0efh l_loop:mov a,r7 mov p1,a mov a,p1 orl a,#0f0h mov r6,a cpl a jz next ajmp key_c next: mov a,r7 jnb acc.7,error rl a mov r7,a ajmp l_loop error:mov a,#00h ret key_c:mov r2,#00h mov r3,#00h mov a,r6 mov r5,#04h again1:jnb acc.0,out1 rr a inc r2 djnz r5, again1 out1: inc r2 mov a,r7 mov r5,#04h again2:jnb acc.4,out2 rr a inc r3 djnz r5,again2 out2: inc r3 mov a, r2 swap a add a,r3 ret key_ccode:push a swap a anl a,#0fh dec a rl a ;行号乘 4 rl a mov r7,a pop a anl a,#0fh dec a add a,r7 ret delay10ms: anl tmod,#0f0h orl tmod,#01h mov th0,#0d8h mov tl0,#0f0h setb tr0 wait:jbc tf0,over ajmp wait clr tr0 over:ret 单片机键盘设计 (二)从电路或软件的角度应解决的问题 软件消抖:如果按键较多,硬件消抖将无法胜任,常采用软件消抖。通常采用软件延时的方法:在第一次检测到有键按下时,执行一段延时10ms的子程序后,再确认电平是否仍保持闭合状态电平,如果保持闭合状态电平,则确认真正有键按下,进行相应处理工作,消除了抖动的影响。(这种消除抖动影响的软件措施是切实可行的。) 2.采取串键保护措施。串键:是指同时有一个以上的键按下,串键会引起CPU错误响应。 通常采取的策略:单键按下有效,多键同时按下无效。 3.处理连击。连击:是一次按键产生多次击键的效果。要有对按键释放的处理,为了消除连击,使得一次按键只产生一次键功能的执行(不管一次按键持续的时间多长,仅采样一个数据)。否则的话,键功能程序的执行次数将是不可预知,由按键时间决定。连击是可以利用的。连击对于用计数法设计的多功能键特别有效。 三、键盘工作方式 单片及应用系统中,键盘扫描只是CPU的工作内容之一。CPU忙于各项任务时,如何兼顾键盘的输入,取决于键盘的工作方式。考虑仪表系统中CPU任务的份量,来确定键盘的工作方式。 键盘的工作方式选取的原则是:既要保证能及时响应按键的操作,又不过多的占用CPU的工作时间。 键盘的工作方式有:查询方式(编程扫描,定时扫描方式)、中断扫描方式。