C51矩阵键盘的检测
- 格式:ppt
- 大小:226.50 KB
- 文档页数:20
C51矩阵键盘的检测要求:扫描矩阵键盘,并将对应按键的值显示在LED上方法一(传统检测):#include<reg52.h>#define uint unsigned int#define uchar unsigned charsbit dula=P2^6;sbit wela=P2^7;//sbit key1=P3^4;uchar code table[]={//共阳极LED数码管显示数字0~F0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};uchar num,temp,num1;void delay(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}uchar keyscan();void display(uchar aa);void main(){while(1){display(keyscan());}}void display(uchar aa){/*先送数,后选通,延时以后,将所有端口都不选通,这样,拖影就消失了*/ dula=1;P0=table[aa-1];dula=0;wela=1;P0=0x01;wela=0;delay(5);wela=1;P0=0x00;wela=0;}uchar keyscan(){P3=0xfe;temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case0xee:num=1;break;case0xde:num=2;break;case0xbe:num=3;break;case0x7e:num=4;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}P3=0xfd;temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case0xed:num=5;break;case0xdd:num=6;break;case0xbd:num=7;break;case0x7d:num=8;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}P3=0xfb;temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case0xeb:num=9;break;case0xdb:num=10;break;case0xbb:num=11;break;case0x7b:num=12;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}P3=0xf7;temp=P3;temp=temp&0xf0;while(temp!=0xf0){delay(5);temp=P3;temp=temp&0xf0;while(temp!=0xf0){temp=P3;switch(temp){case0xe7:num=13;break;case0xd7:num=14;break;case0xb7:num=15;break;case0x77:num=16;break;}while(temp!=0xf0){temp=P3;temp=temp&0xf0;}}}return num;}方法二(技巧检测):#include<reg51.h>#include<intrins.h>sbit dula=P2^6;sbit wela=P2^7;#define uint unsigned int#define uchar unsigned char//uchar code table[10]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01, 0x09};uchar code table[]={//共阳极LED数码管显示数字0~F0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};uchar Key_Value;void Delay_1ms(uint x){uchar i,j;for(i=0;i<x;i++)for(j=0;j<=148;j++);}void Getkey(){uchar i,j,temp,num,Key_Temp1,Key_Temp2,Buffer[4]={0xfe,0xfd,0xfb, 0xf7};for(j=0;j<4;j++)//循环四次{P3=Buffer[j];_nop_();_nop_();temp=0x10;for(i=0;i<4;i++)//循环四次{if(!(P3&temp)){num=i+j*4;//返回取得的按键值}temp<<=1;//换左边一位}}P3=0xff;Key_Temp1=num;//读入按键if(Key_Temp1<16)//有键按下{Delay_1ms(5);//延时消抖Key_Temp2=num;//再读一次if(Key_Temp1==Key_Temp2)//两次相等Key_Value=Key_Temp1;//就确认下来}}void Display(uchar k){dula=1;P0=table[k];dula=0;wela=1;P0=0x01;wela=0;Delay_1ms(5);wela=1;P0=0x00;wela=0;}void Main(void){while(1){Getkey();Display(Key_Value);//显示键值}}。
51键盘矩阵扫描程序假设按下的是S1键进行如下检测(4*4键盘)先在P3口输出p3 00001111低四位行会有变化cord_h =00001111&00001110 =00001110if !=00001111延时0.1uscord_h=00001110&00001111=00001110if !=00001111P3再输出11111110P3 =00001110|11110000=11111110输出高四位cord_l=P3&0xf0 //此时P3口就是(实际值)输入值01111110 而不是上面的11111110cord_l=01111110&11110000=01110000cord_h+cord_l=00001110+01110000=01111110=0x7e //此编码即为S1的编码#include <reg52.h>//包含头文件#define uchar unsigned char#define uint unsigned intunsigned char consttable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//0-Fuchar keyscan(void);void delay(uint i);void main(){uchar key;P2=0x00;//1数码管亮按相应的按键,会显示按键上的字符while(1){key=keyscan();//调用键盘扫描,switch(key){case 0x7e:P0=table[0];break;//0 按下相应的键显示相对应的码值case 0x7d:P0=table[1];break;//1case 0x7b:P0=table[2];break;//2case 0x77:P0=table[3];break;//3case 0xbe:P0=table[4];break;//4case 0xbd:P0=table[5];break;//5case 0xbb:P0=table[6];break;//6case 0xb7:P0=table[7];break;//7case 0xde:P0=table[8];break;//8case 0xdd:P0=table[9];break;//9case 0xdb:P0=table[10];break;//acase 0xd7:P0=table[11];break;//bcase 0xee:P0=table[12];break;//ccase 0xed:P0=table[13];break;//dcase 0xeb:P0=table[14];break;//ecase 0xe7:P0=table[15];break;//f}}}uchar keyscan(void)//键盘扫描函数,使用行列反转扫描法{uchar cord_h,cord_l;//行列值P3=0x0f; //行线输出全为0cord_h=P3&0x0f; //读入列线值if(cord_h!=0x0f) //先检测有无按键按下{delay(100); //去抖cord_h=P3&0x0f; //读入列线值if(cord_h!=0x0f){P3=cord_h|0xf0; //输出当前列线值cord_l=P3&0xf0; //读入行线值return(cord_h+cord_l);//键盘最后组合码值}}return(0xff); //返回该值}void delay(uint i)//延时函数{while(i--);}。
实验6 矩阵键盘的检测一、实验目的1、掌握七段数码管显示的软件译码方法;2、掌握矩阵键盘的使用。
二、实验内容矩阵键盘来控制数码管显示:实验板上电时,数码管不显示,顺序按下4*4矩阵键盘后,在数码管上依次显示0-F,6个数码管同时静态显示即可。
三、实验方法和手段多媒体教学、演示、讲练结合、软件仿真、实物焊接四、实验条件实验指导书、计算机、Proteus软件、Keil C51软件、耗材、电烙铁五、实验学时2学时六、实验步骤1、Proteus设计电路原理图(1)按照图6-1,在Proteus软件中绘制好电路原理图。
图6-1 电路原理图说明:矩阵键盘行线接P3口低4位(第一行P3.0),列线接P3口高4位(第一列接P3.4)。
(2)电路原理图中所需要的元件见表6-1。
表6-1 元件列表元件名称型号数量Proteus中的名称单片机芯片AT89C51 1个AT89C51 晶振12MHz 1个CRYSTAL电容22PF 2个CAP电解电容22uF/16V 1个CAP-ELEC电阻1K 1个RES排阻1K 1个RESPACK_8 六位一体共阴极数码管1个7SEG-MPX6_CC 锁存芯片74HC573 2个74HC573按键开关16个BUTTON 2、编程控制在Keil软件中进行程序编制,完成目标:顺序按下4*4矩阵键盘后,6个数码管同时静态依次显示0-F。
将下面的参考程序补充完整,也可自行编写新程序。
参考程序代码如下:3、仿真调试将生成的HEX文件加载到Proteus中,进行软件仿真,查看效果。
4、实物调试(1)程序烧制(2)使用焊接成功的电路板,通电调试,查看效果。
七、思考题1、如果采用双数码管显示按键值(0-15),应如何修改程序代码?2、如果行线接P3口低4位,列线接P2口低4位,程序代码如何修改?。
51单⽚机矩阵键盘⾏扫描————————————————————————————————————————————分类:按结构原理分:触点式开关按键⽆触点开关按键接⼊⽅式独⽴式按键矩阵式键盘————————————————————————————————————————————矩阵式键盘识别⽅法(⾏扫描法)检测列线的状态:列线Y4~Y7置⾼电平,⾏线Y0~Y3置低电平。
只要有⼀列的电平为低,则表⽰键盘该列有⼀个或多个按键被按下。
若所有列线全为⾼电平,则键盘中⽆按键按下。
判断闭合按键所在的位置:⾏线置⾼电平,列线置低电平。
检测⾏线的状态。
举例:当按下第⼀⾏第⼀列的按键时⾏扫描,⾏线为低电平,列线为⾼电平,得到 1110 0000列扫描,⾏线为⾼电平,列线为低电平,得到 0000 1110将得到的结果进⾏或运算,得到 1110 1110,对应第⼀⾏第⼀列,⼗六进制为0xEE按键表⾏列bin hex111110 11100xEE121101 11100xDE131011 11100xBE140111 11100x7E211110 11010xED221101 11010xDD231011 11010xBD240111 11010x7D311110 10110xEB321101 10110xDB331011 10110xBB340111 10110x7B411110 01110xE7421101 01110xD7431011 01110xB7440111 01110x77————————————————————————————————————————————矩阵式键盘应⽤实例实现结果:通过4*4矩阵键盘对应数码管显⽰0~F设计思路:当检测到按键被按下时,将此时⾏扫描的结果存⼊临时变量,再进⾏列扫描,得到的结果和临时变量进⾏或运算。
通过数组存放按键和数码管编码,⾏列扫描得到结果后遍历数组,找到对应的编码位置并显⽰数码管编码实现代码:1 #include <reg52.h>2 typedef unsigned char uchar;3 typedef unsigned int uint;4 uchar code KEY_TABLE[] =5 {60xEE, 0xDE, 0xBE, 0x7E,70xED, 0xDD, 0xBD, 0x7D,80xEB, 0xDB, 0xBB, 0x7B,90xE7, 0xD7, 0xB7, 0x7710 };11 uchar code TABLE[] =12 {130x3F, 0x06, 0x5B, 0x4F,140x66, 0x6D, 0x7D, 0x07,150x7F, 0x6F, 0x77, 0x7C,160x39, 0x5E, 0x79, 0x71,17 };18void Delay(uchar m)19 {20 --m;21 }22void main()23 {24 uchar temp, key, i;25while(1)26 {27 P3 = 0xF0;28if (P3 != 0xF0)29 {30 Delay(2000);31if (P3 != 0xF0)32 {33 temp = P3;34 P3 = 0x0F;35 key = temp | P3;36for (i = 0; i < 16; ++i)37if (key == KEY_TABLE[i])38break;39 P2 = TABLE[i];40 }41 }42 }43 }。
ORG 0000HLJMP MAINORG 0100HMAIN: ACALL KEYSCAN ;调用子函数MOV A,30H ;从30H单元取相应的数值MOV DPTR,#TABLEMOVC A,@A+DPTRMOV P2,AACALL DELAY20MSSJMP MAINMOV P1,#0FH ;线反转法MOV A,P1ANL A,#0FHMOV B,AMOV P1,#0F0HMOV A,P1ANL A,#0F0HORL A,BMOV 30H,ACJNE A,#0FFH, MASKVIB ;有键按下转去抖动RETMASKVIB: ACALL DELAY20MSMOV P1,#0FH ;再次检测MOV A,P1ANL A,#0FHMOV B,AMOV P1,#0F0HMOV A,P1ANL A,#0F0HORL A,BCJNE A,30H, QUITKEY;比较两次扫描键值RELEASE: MOV P1,#0FFH ;释放检测MOV A,P1CJNE A,#0FFH, RELEASE ;等待释放KEYPRO: MOV B,30H ;键值处理程序MOV DPTR,#KEYV ALUEMOV R7,#0FFHKEY1: INC R7MOV A,R7MOVC A,@A+DPTRCJNE A,B,KEY2MOV A, R7MOV 30H,A;键码保存SETB 20H ;键值有效标志位RETKEY2: CJNE A,#00H,KEY1 ;扫描键值结束标志QUITKEY: RET ;键扫描无效退出DELAY20MS: ;延时20MS子程序,使用40,41,42单元MOV 40H,#20 ;NEXT1: MOV 41H,#20NEXT2: MOV 42H,#248DJNZ 42H,$DJNZ 41H,NEXT2DJNZ 40H,NEXT1RETKEYV ALUE: DB 77H,7BH,7DH,7EH ;键码表DB 0B7H,0BBH,0BDH,0BEHDB 0D7H,0DBH,0DDH,0DEHDB 0E7H,0EBH,0EDH,0EEHDB 00HTABLE: DB 0C0H,0F9H,0A4H,0B0H ;共阳数码管编码表DB 99H,92H,82H,0F8HDB 80H,90H,88H,83HDB 0C6H,0A1H,86H,8EHEND矩阵键盘扫描子程序,使用P1口。
实验四单片机矩阵键盘检测和液晶仿真实验(4学时)一、实验任务利用51单片机实现4X4矩阵键盘和LCD1602液晶显示人机交互系统,编程实现:(1)按键扫描(1、2、……9、A、B、C、D、E、F)和LCD1602显示按键的键号,格式为:KEYNUM+按键号;(2)LCD1602的第一行显示加1功能,初始数字为980,显示位置自己确定,每次按下某一个按键,数字加1,范围为15---20;二、实验目的1、掌握仿真软件Proteus和单片机联调的方法;2、掌握矩阵键盘扫描检测的原理,并且编程实现键盘按键的检测;3、掌握LCD1602液晶显示的原理,并且编程实现LCD1602的显示功能;4、掌握利用单片机实现键盘检测和液晶显示的功能组合,并掌握独立编程控制的能力。
三、实验设备电脑、Proteus软件、Keil软件四、实验原理(一)矩阵键盘扫描检测原理按照按键结构原理可分为两类,一类是触点式开关按键,如机械式开关、导电橡胶式开关等;另一类是无触点开关按键,如电气式按键、磁感应按键等。
在单片机应用系统中,通过按键实现控制功能和数据输入是非常普遍的。
在所需按键数量不多时,系统常采用独立式按键。
独立式按键是指每个按键单独占有一根I/O口线,且其工作状态不会影响其他I/O口线的工作状态。
这种按键的电路配置灵活,软件结构简单。
不过在实际应用中,由于不同的系统对按键的要求不同,因此,对按键程序的设计要考虑全面,以便更好地完成按键所设定的功能。
在按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式,如图4.1所示。
在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。
这样一个端口(如P1口)就可以构成4×4=16个按键,比直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加一条线就可以构成20键的键盘,而直接用端口线则只能多出1键(共9键)。
由此可见,在需要的键数比较多时,采用矩阵法来做键盘是合理的。
#include <reg51.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intuchar dis_buf; //显示缓存uchar temp;uchar key; //键顺序吗void delay0(uchar x); //x*0.14MS#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};// 此表为LED 的字模0 1 2 3 4 5 6 7 89 a b c d e funsigned char code LED7Code[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};/*************************************************************//* *//* 延时子程序*//* *//*************************************************************/void delay(uchar x){ uchar j;while((x--)!=0){ for(j=0;j<125;j++){;}}}/*************************************************************//* *//* 键扫描子程序(4*4 的矩阵) P2.4 P2.5 P2.6 P2.7为行*//* P2.0 P2.1 P2.2 P2.3为列*//* *//*************************************************************/void keyscan(void){ temp = 0;P2=0xF0; //高四位输入行为高电平列为低电平delay(1);temp=P2; //读P2口temp=temp&0xF0; //屏蔽低四位temp=~((temp>>4)|0xF0);if(temp==1) // p2.4 被拉低key=0;else if(temp==2) // p2.5 被拉低key=1;else if(temp==4) // p2.6 被拉低key=2;else if(temp==8) // p2.7 被拉低key=3;elsekey=16;P2=0x0F; //低四位输入列为高电平行为低电平delay(1);temp=P2; //读P2口temp=temp&0x0F;temp=~(temp|0xF0);if(temp==1) // p2.0 被拉低key=key+0;else if(temp==2) // p2.1 被拉低key=key+4;else if(temp==4) // p2.2 被拉低key=key+8;else if(temp==8) // p2.3 被拉低key=key+12;elsekey=16;dis_buf = key; //键值入显示缓存//dis_buf = dis_buf & 0x0f;}/*************************************************************/ /* */ /*判断键是否按下*/ /* */ /*************************************************************/void keydown(void){P2=0xF0;if(P2!=0xF0) //判断按键是否按下如果按钮按下会拉低P2其中的一个端口{keyscan(); //调用按键扫描程序}}/*************************************************************//* *//* 主程序*//* *//*************************************************************/main(){P0=0xFF; //关段码P1=0x10; //开位码delay(10); //延时while(1){keydown(); //调用按键判断检测程序P0 = LED7Code[dis_buf]; //显示按键的数值}}/************************************************************/。
实验三矩阵键盘识别实验
一、实验目的
掌握单片机I/O口的输入检测的方法、矩阵按键的识别方法、键盘消抖等。
学会实时程序的调试技巧。
二、实验原理
我们在手动按键的时候,由于机械抖动或是其它一些非人为的因素很有可能会造成误识别,一般手动按下一次键然后接着释放,按键两片金属膜接触的时间大约为50ms 左右,在按下瞬间到稳定的时间为5-10ms,在松开的瞬间到稳定的时间也为5-10ms,如果我们在首次检测到键被按下后延时10ms 左右再去检测,这时如果是干扰信号将不会被检测到,如果确实是有键被按下,则可确认,以上为按键识别去抖动的原理。
三、实验内容
实验板上电时,数码管不显示,顺序按下矩阵键盘后,在数码管上依次显示0到F,6个数码管同时静态显示即可。
下图中按键s6-s218条线分别联接p3口相连,p3.0~p3.3控制1~4行,p3.4~p3.7控制1~4列。
图1 实验板键盘电路原理图
四、实验步骤
1、按实验要求在Keil中创建项目,编辑、编译程序。
2、将编译生成的目标码文件(后缀为.Hex)传入实验板中。
3、在实验板上运行程序,观察实验运行结果并记录。