[整理]4x4键盘
- 格式:doc
- 大小:60.50 KB
- 文档页数:8
4X4矩阵键盘控制数码管显示按键值4X4矩阵键盘控制数码管显示按键值一、设计内容与要求用80C51单片机控制系统显示按键值0~F。
二、设计目的意义2.1 设计目的1、了解单片机系统中实现LED动态显示的原理及方法;2、详细了解8051芯片的性能及编程方法;3、了解单片机系统基本原理,了解单片机控制原理;4、掌握AT89C51输入/输出接口电路设计方法;5、掌握AT89C51程序控制方法;6、掌握单片机汇编编程技术中的设计和分析方法;7、掌握使用PROTEUS软件进行仿真的方法。
8、学会使用并熟练掌握电路绘制软件Protel99SE;9、掌握电路图绘制及PCB图布线技巧。
2.2 设计意义1、在系统掌握单片机相应基础知识的前提下,熟悉单片机应用系统的设计方法及系统设计的基本步骤。
2、完成所需单片机应用系统原理图设计绘制的基础上完成系统的电路图设计。
3、完成系统所需的硬件设计制作,在提高实际动手能力的基础上进一步巩固所学知识。
4、进行题目要求功能基础上的软件程序编程,会用相应软件进行程序调试和测试工作。
5、用AT89C51设计出题目所要求的数码管动态循环显示,并针对实际设计过程中软、硬件设计方面出现的问题提出相应解决办法。
6、通过单片机应用系统的设计将所学的知识融会贯通,锻炼独立设计、制作和调试单片机应用系统的能力;领会单片机应用系统的软、硬件调试方法和系统的研制开发过程,为进一步的科研实践活动打下坚实的基础。
三、系统硬件电路图3.1 Proteus软件简介以及仿真电路图Proteus是世界上著名的EDA工具(仿真软件),从原理图布图、代码调试到单片机与外围电路协同仿真,一键切换到PCB设计,真正实现了从概念到产品的完整设计。
是目前世界上唯一将电路仿真软件、PCB设计软件和虚拟模型仿真软件三合一的设计平台,其处理器模型支持8051、HC11、PIC10/12/16/18/24/30/DsPIC33、AVR、1ARM、8086和MSP430等,2010年即将增加Cortex和DSP系列处理器,并持续增加其他系列处理器模型。
4*4键盘程序readkeyboard:begin: acall key_onjnz delayajmp readkeyboard delay:acall delay10msacall key_onjnz key_numajmp beginkey_num:acall key_panl a,#0FFhjz beginacall key_ccodepush akey_off:acall key_onjnz key_offpop aretkey_on: mov a,#00horl a,#0fhmov p1,amov a,p1orl a,#0f0hcpl aretkey_p: mov r7,#0efhl_loop:mov a,r7mov p1,amov a,p1orl a,#0f0hmov r6,acpl ajz nextajmp key_cnext: mov a,r7jnb acc.7,errorrl amov r7,aajmp l_looperror:mov a,#00hretkey_c:mov r2,#00hmov r3,#00hmov a,r6mov r5,#04hagain1:jnb acc.0,out1rr ainc r2djnz r5, again1out1: inc r2mov a,r7mov r5,#04hagain2:jnb acc.4,out2rr ainc r3djnz r5,again2out2: inc r3mov a, r2swap aadd a,r3retkey_ccode:push aswap aanl a,#0fhdec arl a ;行号乘4rl amov r7,apop aanl a,#0fhdec aadd a,r7retdelay10ms:anl tmod,#0f0horl tmod,#01hmov th0,#0d8hmov tl0,#0f0hsetb tr0wait:jbc tf0,overajmp waitclr tr0over:ret单片机键盘设计(二)从电路或软件的角度应解决的问题软件消抖:如果按键较多,硬件消抖将无法胜任,常采用软件消抖。
4X4键盘扫描程序,采用查表方式,适用于AVR单片机。
此处为4X4键盘软件部分,硬件部分设计请参照:4X4键盘扫描电路分析。
此程序对应的键盘电路为:键盘状态扫描函数/*键盘扫描函数读取当前键盘的状态有按键按下返回相应按键值无按键按下返回"0x00"*/unsigned char key_read(void){unsigned char i;DDRA = 0x00;/*获取列地址*/PORTA = 0x0F;DDRA = 0xF0;i = PINA;DDRA = 0x00;/*获取行地址*/PORTA = 0xF0;DDRA = 0x0F;i |= PINA;DDRA = 0x00;/*输出复位*/PORTA = 0xFF;switch (i) {/*将按键码转换成键值*/case 0x00: return 0x00;case 0xEE: return '1';case 0xDE: return '2';case 0xBE: return '3';case 0x7E: return 'A';case 0xED: return '4';case 0xDD: return '5';case 0xBD: return '6';case 0x7D: return 'B';case 0xEB: return '7';case 0xDB: return '8';case 0xBB: return '9';case 0x7B: return 'C';case 0xE7: return '*';case 0xD7: return '0';case 0xB7: return '#';case 0x77: return 'D';default : return 0x00;}键盘读取函数/*按键获取函数获取按键信号,其中包含有状态记录及按键去颤抖。
多数示例提供完整源程序KX2C5F+系统提供的大量电子设计自主创新演示项目于宽领域大深度培养能力、启迪智慧、激励创新杭州康芯公司实验3基本8052 IP核的4X4键盘、字符型液晶应用、CPU双向口设置及等精度频率计设计--全国大学生电子设计决赛赛题,一个典型的SOC系统设计K X康芯科技锁相环输出240MHz32位计数器输出作为频率计的测试信号样本等精度频率计硬件采样模块P3口信号作为液晶显示器显示控制信号8KB 程序ROM240MHz 输出作为频率计的测试信号样本锁相环输出40MHz注意程序路径程序ROM设置为8KB单片机程序文件作此ROM的配置文件取名为RM1K X 康芯科技单片机复位键测频显示4X4键盘待测频率输入口:P18测频键测脉宽键测占空比键字符液晶测试键按复位键后再按此键测脉宽测得脉宽3276.80us按复位键后再按此键测试含中文字库的液晶屏等精度频率采样模块FTEST功能与时序测试SOC结构模块KX康芯科技等精度测频专用芯片等精度测频FTEST模块电路结构KX康芯科技FPGA‘1’ D C Q D C Q D C Q SS1 Q2 END Q3 PL (EEND)MUX21 ‘0’ BENA ‘1’ (BCLK) (SPUL) SPUL2选1多路选择器 (START) BZH BCLK 32 BENA CLR BZQ 64-8多路选择器(CL) (TCLK) (CLR)D CQENA32位标准频率计数器 8 DATA TF TCLK 32 ENA TSQ (DATA)SS1的逻辑功能为: 当Q2=‘1’,Q3=‘0’ 则PUL=‘1’,否则 PUL=‘0’ SEL 3 当Q2=‘1’,Q3=‘1’ 则EEND=‘1’,否则 EEND=‘0’带括号的信号为端口信号(SEL)CLR 32位待测频率计数器等精度频率计设计在此完成的设计项目可达到的指标为:KX康芯科技(1)频率测试功能:测频范围0.1Hz~100MHz。
单片机实践实验报告课题:4x4键盘保险箱密码锁院系:机械工程系班级:姓名:学号:指导老师:1.实验功能描述——4x4键盘密码锁【功能要求】能描述如下:用4x4键盘上的按键设定好数字0~9,密码有初始程序给定,由键盘输入6位数字密码,正确指示灯亮,错误蜂鸣响5下报警。
2.硬件及原理说明本实验利用6位数码管显示、4x4键盘实现输入。
说明:ON:1(0x01);TW:2(0x02);TH:3(0x04);FO:4(0x11);FI:5(0x12);SI:6(0x14);SET:开始输入密码(0x18);SE:7(0x21);EI:8(0x22);NI:9(0x24);ZE:0(0x28);OK:确定(0x38)。
本实验利用状态转移法依次输入数字的原理示意图:键盘位于实验仪08区,四行四列,PC口低四位接列、高四位接行,电路连接图如下:3.C51程序摘要及简述1.本次实验的主要功能为键盘功能,即模块3,所以本次报告的摘要以模块3的为主:#define SET 0x18 //对从0x18到0x38的键盘地址进行定义#define ON 0x01#define TW 0x02#define TH 0X04#define FO 0x11#define FI 0x12#define SI 0x14#define SE 0x21#define EI 0x22#define NI 0x24#define ZE 0x28#define OK 0x38#include<reg51.h>extern unsigned char one,two,three,four,five,six; //声明调用在模块1定义的密码的6位数字变量extern unsigned char code table[16]; //声明调用在模块1定义的数码管字型码用于DisplayEdit函数显示extern unsigned char DispBuf[6];extern void Ring(int n); //声明调用在模块1定义的报警函数unsigned char Editone,Edittwo,Editthree,Editfour,Editfive,Editsix; //声明密码6位数字编辑变量extern unsigned char KeyVal;unsigned char CurKey,LastKey;unsigned char KeySts;extern unsigned char Point;sbit lamp=P1^1; //指示灯使用P1.1 sbit ring=P1^2; //报警蜂鸣器使用P1.2 void DisplayEdit(){DispBuf[5]=table[Editone];DispBuf[4]=table[Edittwo];DispBuf[3]=table[Editthree];DispBuf[2]=table[Editfour];DispBuf[1]=table[Editfive];DispBuf[0]=table[Editsix];DispBuf[6-KeySts] &=0x7F;}void Check () //密码检查正误函数{if (one==1 && two==2 && three==3 && four==4 && five==5 && six==6){ring = 1;lamp = 0;}else{Ring(5);lamp = 1;}}void KeyPro(void){unsigned char KeyPressed;LastKey=CurKey;CurKey=KeyVal;KeyPressed=CurKey^LastKey; //上次残留变量遗存键值与新键值异或if(KeyPressed==0) return; //结果为0,表示没有按键,返回主程序if(CurKey==0x0F) return; //有键变化但不是压下而是松开,返回主程序KeyPressed=KeyPressed+(Point<<4);switch(KeySts) //有键压下,分状态处理{case 0:if(KeyPressed==SET){KeySts++; //按下SET键,状态转移,可以开始输入密码Editone=one;Edittwo=two;Editthree=three;Editfour=four;Editfive=five;Editsix=six;}break;case 1: //状态1,对应数码管左第一位数字switch(KeyPressed){case ZE: Editone=0; //若按下ZE键,将数字0赋给Editone,下同break;case ON: Editone=1;break;case TW: Editone=2;break;case TH: Editone=3;break;case FO: Editone=4;case FI: Editone=5;break;case SI: Editone=6;break;case SE: Editone=7;break;case EI: Editone=8;break;case NI: Editone=9;break;case OK: one=Editone; //当按下OK键,将Editone的值赋给one,即确认第一位数字的键输入KeySts++; //状态转移,表示第一位数字输入完毕并开始第二位数字的键输入break;}break;case 2:switch(KeyPressed){case ZE: Edittwo=0;break;case ON: Edittwo=1;break;┋┋//case 2至case 5语句功能大致同case 1,故此省略,不再赘述┋case 6:switch(KeyPressed){case ZE: Editsix=0;break;case ON: Editsix=1;break;case TW: Editsix=2;break;case TH: Editsix=3;break;case FO: Editsix=4;break;case FI: Editsix=5;break;case SI: Editsix=6;break;case SE: Editsix=7;case EI: Editsix=8;break;case NI: Editsix=9;break;case OK: six=Editsix;KeySts++;Check(); //与前5个函数不同的在于第六位输入完毕后即开始检查输入的密码正误break;}break;default :KeySts=0;}DisplayEdit();}2.数码管的显示需反序赋值,否则会导致密码显示高地位反序,因为人们习惯上输入的密码高位对应于显示管的地位,正好是反序:void Displaymima(){DispBuf[5]=table[one];DispBuf[4]=table[two];DispBuf[3]=table[three];DispBuf[2]=table[four];DispBuf[1]=table[five];DispBuf[0]=table[six];}。
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; //定义输入行信号Rowinput scan; //定义数码管选择信号scaninput clock; //定义时钟信号clockreg[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; //将数码管选择信号赋值为1always@(posedge clock) //产生列信号if(cn==4)cn<=0; elsecn<=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;endcasealways@(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;8'b1101_1011:Code=4'h6;8'b1101_0111:Code=4'h7;8'b1011_1110:Code=4'h8;8'b1011_1101:Code=4'h9;8'b1011_1011:Code=4'hA;8'b1011_0111:Code=4'hB;8'b0111_1110:Code=4'hC;8'b0111_1101:Code=4'hD;8'b0111_1011:Code=4'hE;8'b0111_0111:Code=4'hF;endcasealways@(posedge clock) //由输出Code决定数码管的显示,七段用十六进制数表示case(Code[3:0])4'h0:show=8'hFC;4'h1:show=8'h60;4'h2:show=8'hDA;4'h3:show=8'hF2;4'h4:show=8'h66;4'h5:show=8'hB6;4'h6:show=8'h3E;4'h7:show=8'hE0;4'h8:show=8'hFE;4'h9:show=8'hE6;4'hA:show=8'hEE;4'hB:show=8'hCE;4'hC:show=8'h9C;4'hD:show=8'h7A;4'hE:show=8'h9E;4'hF:show=8'h8E;endcasealways@(posedge clock) //加减计数case(Code)4'h0:begin reset=1;count_up=0;count_down=0;end //按0键时清零4'hE:begin count_up=1;count_down=0;end //按E键加计数4'hF:begin count_down=1;count_up=0;end //按F键减计数default: begin count_down=0;count_up=0;reset=0; end //按其它键不计数endcasealways@(posedge clock)if(times1==1000) times1<=101; else if (count_up) times1<=times1+1;always@(posedge clock)if(times2==1000) times2<=101; else if (count_down) times2<=times2+1; always@(posedge clock)if(reset)count<=4'h0; elseif (times1>100&&Code==4'hE) //加计数begincount<=count+4'b1;if (count==4'h9) count<=4'h0;endelseif (times2>100&&Code==4'hF) //减计数begincount<=count-4'b1;if (count==4'h0) count<=4'h9;endalways@(posedge clock) //计数显示case(count[3:0])4'h0:show1=8'hFC;4'h1:show1=8'h60;4'h2:show1=8'hDA;4'h3:show1=8'hF2;4'h4:show1=8'h66;4'h5:show1=8'hB6;4'h6:show1=8'h3E;4'h7:show1=8'hE0;4'h8:show1=8'hFE;4'h9:show1=8'hE6;endcaseendmodule仿真波形:Col、Row、Code、show、show[17..10]为十六进制显示,times1、times2、count为十进制显示当Code为F(即按F键)时,show显示8E即F,表明此时按下的是F 键。
4X4矩阵键盘与显示电路设计FPGA在数字系统设计中的广泛应用,影响到了生产生活的各个方面。
在FPGA 的设计开发中,VHDL语言作为一种主流的硬件描述语言,具有设计效率高,可靠性好,易读易懂等诸多优点。
作为一种功能强大的FPGA数字系统开发环境,Altera公司推出的Quar-tUSⅡ,为设计者提供了一种与结构无关的设计环境,使设计者能方便地进行设计输入、快速处理和器件编程,为使用VHDL语言进行FPGA设计提供了极大的便利。
矩阵键盘作为一种常用的数据输入设备,在各种电子设备上有着广泛的应用,通过7段数码管将按键数值进行显示也是一种常用的数据显示方式。
在设计机械式矩阵键盘控制电路时,按键防抖和按键数据的译码显示是两个重要方面。
本文在QuartusⅡ开发环境下,采用VHDL语言设计了一种按键防抖并能连续记录并显示8次按键数值的矩阵键盘与显示电路。
一、矩阵键盘与显示电路设计思路矩阵键盘与显示电路能够将机械式4×4矩阵键盘的按键值依次显示到8个7段数码管上,每次新的按键值显示在最右端的第O号数码管上,原有第0~6号数码管显示的数值整体左移到第1~7号数码管上显示,见图1。
总体而言,矩阵键盘与显示电路的设计可分为4个局部:(1)矩阵键盘的行与列的扫描控制和译码。
该设计所使用的键盘是通过将列扫描信号作为输入信号,控制行扫描信号输出,然后根据行与列的扫描结果进行译码。
(2)机械式按键的防抖设计。
由于机械式按键在按下和弹起的过程中均有5~10 ms的信号抖动时间,在信号抖动时间内无法有效判断按键值,因此按键的防抖设计是非常关键的,也是该设计的一个重点。
(3)按键数值的移位存放。
由于该设计需要在8个数码管上依次显示前后共8次按键的数值,因此对已有数据的存储和调用也是该设计的重点所在。
(4)数码管的扫描和译码显示。
由于该设计使用了8个数码管,因此需要对每个数码管进行扫描控制,并根据按键值对每个数码管进行7段数码管的译码显示。
4x4键盘的程序有扫描法与线反法,但我个人认为用线反法较好,用扫描法得依次扫描所有行或列,如果用线反法就简单多了。
先使键盘的行置为低、列置为高(或列置为高、行置为低),接着读回端口的值。
比如:如果使用P0为键盘接口就先使低四位为低、高四位为高即P0=0xf0然后就读回P0口的值赋给一个变量,a=P0;紧接就给行列赋相反的值行置为高、列置为低(或列置为低、行置为高)即P0=0x0f然后就读回再与a运算就能得到唯一的识别码下面的程序就是用线反写一个4x4键盘识别程序:#include<AT89X52.H>#include<delay.h>#define KEY_SCAN P1#define uchar unsigned char//char num;/********************************//*函数名称:KEY_DOWN() *//*函数功能:延时子函数 *//*参数:无 *//*返回:返回1或0 *//*备注:1表示有键按下,0则无*//********************************/bit KEY_DOWN(){KEY_SCAN=0x0f; //先给键盘口赋个初值if(KEY_SCAN!=0x0f) //判断是有按键按下,即KEY_SCAN不等于初值时有键按下{delayms(10); //消抖if(KEY_SCAN!=0x0f) //再次判断是否真有键按下return 1; //真有就返回1没有返回零elsereturn 0;}elsereturn 0;}/********************************//*函数名称:SCAN_GET() *//*函数功能:键盘值函数 *//*参数:无 *//*返回:返回1或0 *//*备注:无 *//********************************/uchar SCAN_GET(){char button;uchar key_code;button=KEY_SCAN;KEY_SCAN=0xf0;button=(button|KEY_SCAN);while(KEY_SCAN!=0xf0);delayms(10);switch(button){case 0xd7: key_code='1';break;case 0xdb: key_code='2';break;case 0xdd: key_code='3';break;case 0xb7: key_code='4';break;case 0xbb: key_code='5';break;case 0xbd: key_code='6';break;case 0x77: key_code='7';break;case 0x7b: key_code='8';break;case 0x7d: key_code='9';break;case 0xeb: key_code='0';break;case 0xee: key_code=0xee;break;default : break;}return key_code;}////////////////////////////////////////////////////////////// //此程序是上两个程序结合的/********************************//*函数名称:Key_Get() *//*函数功能:键盘扫描函数 *//*参数:无 *//*返回:无 *//*备注:无 *//********************************/void Key_Get(){char button;KEY_SCAN=0x0f;if(KEY_SCAN!=0x0f){delayms(5);if(KEY_SCAN!=0x0f)button=KEY_SCAN;KEY_SCAN=0xf0;button=(button|KEY_SCAN);while(KEY_SCAN!=0xf0);switch(button){case 0xd7: num='1';P0=0x00;break; case 0xdb: num='2';P0=0x0f;break; case 0xdd: num='3';break;case 0xb7: num='4';break;case 0xbb: num='5';break;case 0xbd: num='6';break;case 0x77: num='7';break;case 0x7b: num='8';break;case 0x7d: num='9';break;case 0xeb: num='0';break;case 0xe7: num='a';break;case 0xed: num='b';break;case 0xee: num='c';break;case 0xde: num='d';break;case 0xbe: num='e';break;case 0x7e: num='f';break;default : break;}}}}qinglei120713的分享分享矩阵键盘C51程序(4*4)(来自互联网) 1111111111111111111111111111111111111111111111 11111111111111111111111111111111111111#include <reg51.h>#include <intrins.h>#define key_port P0 //键盘接口定义sbit key_port_0=key_port^0;sbit key_port_1=key_port^1;sbit key_port_2=key_port^2;sbit key_port_3=key_port^3;/*******************************STC89C59 单片机一毫秒延时函数*******************************/void delay_ms(unsigned int ms){unsigned int i,j;for( i=0;i<ms;i++)for(j=0;j<332;j++); //1947是STC89C58在22.1184MHz晶振下,通过软件仿真反复实验得到的数值}/**************************串口发送一个字符**************************/void com_send_dat( unsigned char dat){SBUF=dat;while (TI== 0);TI= 0 ;}/**************************串口初始化**************************/void init_com( void ){SCON=0x50 ; //SCON: serail mode 1, 8-bit UART, enable ucvr //UART为模式1,8位数据,允许接收TMOD|=0x20 ; //TMOD: timer 1, mode 2, 8-bit reload //定时器1为模式2,8位自动重装TH1=0xfa ; //Baud:19200 fosc="22.1184MHzTL1=0xfa;PCON|=0x80; //SMOD=1;波特率加倍;ES=1; //Enable Serial InterruptTR1 = 1 ; // timer 1 run}/**************************键盘扫描函数**************************/unsigned char keyscan(void){unsigned char key,i;unsigned char co de key_table[16]={0xee,0xed,0xeb,0xe7,0xde,0xdd,0xdb,0xd7,0xbe,0xbd,0x bb,0xb7,0x7e,0x7d,0x7b,0x77};key_port=0x0f; //确定行列位置if(key_port==0x0f)return(0);//无键按下返回0delay_ms(10); //调用延时函数,目的是去前沿键抖。
单片机实训教材
单片机的应用
键盘扫描程序FY:江西华忆电子工业中等学校
键盘扫描程序设计
一,实训教学目的
1,了解键盘的组成及接线方法
2,了解编码键盘和非编码键盘的组成
3,学习非编码键盘的扫描方法步骤
4,编写程序实现简单键盘设计和矩阵键盘的编程。
二,主要元件的介绍。
1,CPU AT89S51
AT89S51是一款低功耗,高性能的8位微处理器,有4KBZ可在系统编程(ISP) Flash闪速存储器,1000次擦写周期,它与工业标准的80C51和80C52的指令集及输出PIN脚完全兼容。
128X8-bit片内RAM,32个可编程I/O脚,2个16-位定时/计数器,5个中断源,可编程全双工串行口,低功耗空闲模式和掉电模式。
3,键盘原理
1)独立式键盘的接线原理
独立式键盘是由若干个机械触点开关构成的,把它与单片机的I/O口县连接起来,通过读I/O口的电平状态,即可识别出相应的按键是否被按下,看下面的电路图:如果按键不被按下,其端口就为高电平,如果相应的按键被按下,则端口变为低电平。
在这种键盘的连接方法中,我们通常采用上拉电阻接法,即各按键开关一端接低电平,另一端接单片机I/O口线并通过上拉电阻与VCC相连,这是为了保证在按键断开时,各I/O口线有确定的高电平,如果端口内部已经有上拉电阻,则外电路的上拉电阻就可以省去,想想看,哪几个并行口内部有上拉电阻呢?
通常我们用来做键盘的有触点式和非触点式两种,单片机中应用的一般是由机械触点构成的触点式微动开关,这种开关具有结构简单,使用可靠的优点,但当我
们按下按键或释放按键的时候它有一个特点,就是会产生抖动,看上图的按键脉冲波形,这种抖动对于人来说是感觉不到的,但对单片机来说,则是完全可以感应到的,因为计算机处理的速度是在微秒级的,而机械抖动的时间至少是毫秒级,对计算机而言,这已是一个很“漫长”的过程了,
按键区抖动原则和方法常用的有两种:硬件方法和软件方法。
硬件去抖动方法很多,这不在我们的讨论范围。
单片机中常用软件去抖动方法,软件法其实很简单,就是在单片机获得端口低电平信息后,不是立即认定按键已被按下,而是在延时
10ms或更长时间后再次检查该端口,如果仍为低,说明此键确实被按下了,这实际上是避开了按键按下时的抖动时间;而在检测到按键释放后(端口电平为高电平时)再延时5-10ms,消除后沿的抖动,然后再对按键进行处理,不过一般情况下,我们通常不对按键释放后沿进行处理,实践证明,也能满足通常的要求。
2)矩阵式键盘的连接方法和工作原理:
什么是矩阵式键盘?当键盘中按键数量较多时,为了减少I/O口线的占用,通常将按键排列成矩阵式,在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。
这样做有什么好处呢?大家看下面的电路图,一个并行口可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍多,而且线数越多,区别就越明显。
比如再多加一条线就可以构成20键的键盘,而直接用端口线则只能多出一个键(9键)。
由此可见,在需要的按键数量比较多的时候,采用矩阵法莱连接键盘是非常合理的。
矩阵式结构的键盘显然比独立式键盘复杂些,识别也要复杂一些,在上图中,列线通过电阻接电源,并将行线索接的单片机4个I/O口作为输出端,而列线所接的I/O 口则作为输入端,这样,当按键没有被按下时,所有的输出端都是高电平,代表无按键按下,行线输出是低电平;一旦有键按下,输入线就会被拉低,这样,通过读入输入线的状态就可以得知是否有键按下了,具体的识别及编程方法如下所述:识别方法:确定矩阵式键盘上任何一个键被按下通常采用“行扫描法”或“行反转法”。
行扫描法又称为逐行(或列)扫描查询法,它是一种最常用的多按键识别方法。
因此我们就以“行扫描法”为例来说明矩阵式键盘的工作原理;
a.判断键盘中有无键按下
将全部的行线X0-X3置低电平,然后检测列线的状态,只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平线与4根行线相交叉的4
个按键之中;若所有列线均为高电平,则表示键盘中无键按下。
b.判断闭合键所在的位置
在确认有键按下后,即可进入确定具体闭合键的过程。
其方法是:依次将行线
置为低电平(即置某根行线为低电平时,其他线为高电平),当确定某根行线
为低电平后,再逐行检测各列线的电平状态,若某列为低,则该列线与置为低
电平的行线交叉处的按键就是闭合的按键。
c.去抖动
当检测到有键按下后,延时一段时间后再做下一次的检测判断,若仍有键按下,应识别出是哪一个键闭合,方法是对键盘的行线进行扫描,在每组行输出时读取列线,然后可采用计算法或查表法计算出闭合键的行值和列值转换成所定义的键值。
为了保证按键每闭合依次CPU仅作一次处理,必须去除键释放的抖动。
按键扫描子程序程序算法,
1)一行一行扫描,如果有按键,则下一步,否则,跳到5步。
2)与以前的按键码比较,如果相同,则执行下一步,否则跳到4步。
3)确定有键按下,设置按键按下标志(keyDown),结束
4)保存当前按键码key(行码和列码拼起来)结束。
5)当前没有按键,检查是否同一行,是则执行下一步,否则结束。
6)检查以前是否有按键按下,如果有,则执行下一步,否则跳到8步。
7)以前有按键,那么现在按键松开了,设置按键松开标志(keyUp),结束。
8)清除按键keyDown标志。
按键处理子程序
分2种情况,一种是确定有按键了即检查keyDown为1就处理,另一种是检查
到按键松开即keyUp为1就处理,下面以keyDown来说明
1)如果keyDown不为1,则结束,否则继续下一步。
2)清除keyDown标志,使之只被处理一次。
3)将当前扫描的键码key与码表依次比较,如果是表中的某个值则将这个处理该按键,否则认为是错误的按键。
结束
4)
三,实训工作制作指导
1,学习使用Proteus仿真软件画出原理图。
2,熟悉汇编语言程序设计,学习使用Keil 51进行源代码编写3,学习程序调试的方法
四,电路原理图
五,工作原理
8051系列单片机定时器系统的工作过程大体是这样:首先由软件设定好定时/计数器的工作方式及计数初值,然后启动它工作,定时器/计数器将按照设定好的工作方式,从计数初值开始,对指定的加1操作,此时不占用CPU的时间,只有当定时器/计数器计满溢出时,才向CPU发出中断请求信号,CPU通过中断或查询方式处理溢出后的服务。
溢出后,定时器/计数器继续进行加1操作,每次溢出都会申请中断。
定时器方式1是按16位加1计数器工作的,该计数器由高8位TH和低8位TL组成。
使用定时器方式2时,定时器被拆成一个8位寄存器TH和一个8位计数器TL,CPU对它们初始化时必须送相同的定时初值。
当定时器启动后,TL按8位加1计数器计数,每当它计数满回零时一方面向CPU发出溢出中断请求和另一方面从TH中重新获得初值并启动计数。
利用这个方式作为波特
率生成器。
六,物料表
七,
八,实训步骤
1.熟悉CPU的工作原理及电路结构。
2.
3.根据原理图准备所需元器件。
4.熟悉单片机引脚功能及工作原理。
5.按照原理图组装好电路板。
6.
7.准备电路工作时所需电源。
8.
9.用万用表检查电路板是否正常工作。
10.
11.接上电源,注意电源极性,简单的方法是接上电源的瞬间
手摸CPU,如果发热应立即切断电源。
12.
13.根据设计好的算法写出汇编语言程序。
14.将设计好的程序在软件上进行仿真调试,
15.调试通过后再将程序烧录到程序存储器中进行测试
九,仪器准备
5伏直流稳压电源1台
示波器1台
万表用1只
十,问答题
1.将程序烧录到程序存储器中,上电后,LED灯不闪烁,蜂
鸣器不叫的原因。
附程序源码:
ORG 00h
LJMP Main
ORG 100h
MAIN:
MOV SP, #5FH
MOV A, #0FEH LOOP:
MOV P1, A
MOV R7, #100
MOV R6, #50
ACALL DELAY
RL A
SJMP LOOP DELAY:
DJNZ R5, $
DJNZ R7, DELAY
MOV R7, #100
DJNZ R6, DELAY
RET
END。