矩阵键盘原理图 (2)
简易计算器(1602加矩阵键盘)

一、原理图:二、程序#include<reg51.h> //包含单片机寄存器的头文件#include<intrins.h> //包含_nop_()函数定义的头文件#include<math.h>sbit RS=P2^0; //寄存器选择位,将RS位定义为P2.0引脚sbit RW=P2^1; //读写选择位,将RW位定义为P2.1引脚sbit E=P2^2; //使能信号位,将E位定义为P2.2引脚sbit BF=P1^7; //忙碌标志位,#define NO_KEY_PRESS 0xff/********************************************************************************************************/unsigned char code tab[]={0xb7,0xee,0xde,0xbe,0xed,0xdd,0xbd,0xeb,0xdb,0xbb};unsigned long num1,num2,alg;unsigned char flag;void delay1ms(){unsigned char i,j;for(i=0;i<10;i++)for(j=0;j<15;j++);}/********************************************************************************************************/void delay(unsigned char n){unsigned char i;for(i=0;i<n;i++)delay1ms();}/*****************************************************函数功能:判断液晶模块的忙碌状态返回值:result。
4×4矩阵式键盘按键

一、实验目的1.掌握4×4矩阵式键盘程序识别原理2.掌握4×4矩阵式键盘按键的设计方法二、设计原理(1)如图14.2所示,用单片机的并行口P3连接4×4矩阵键盘,并以单片机的P3.0-P3.3各管脚作输入线,以单片机的P3.4-P3.7各管脚作输出线,在数码管上显示每个按键“0-F”的序号(2)键盘中对应按键的序号排列如图14.1所示三、参考电路740)this.width=740" border=undefined>图14.2 4×4矩阵式键盘识别电路原理图740)this.width=740" border=undefined>图14.1 4×4键盘0-F显示740)this.width=740" border=undefined>图14.3 4×4矩阵式键盘识别程序流程图四、电路硬件说明(1)在“单片机系统”区域中,把单片机的P3.0-P3.7端口通过8联拨动拨码开关JP3连接到“4×4行列式键盘”区域中的M1-M4,N1-N4端口上(2)在“单片机系统”区域中,把单片机的P0.0-P0.7端口连接到“静态数码显示模块”区域中的任何一个a-h端口上;要求:P0.0对应着a,P0.1对应着b,……,P0.7对应着h五、程序设计内容(1)4×4矩阵键盘识别处理(2)每个按键都有它的行值和列值,行值和列值的组合就是识别这个按键的编码矩阵的行线和列线分别通过两并行接口和CPU通信键盘的一端(列线)通过电阻接VCC,而接地是通过程序输出数字“0”实现的键盘处理程序的任务是:确定有无键按下,判断哪一个键按下,键的功能是什么?还要消除按键在闭合或断开时的抖动两个并行口中,一个输出扫描码,使按键逐行动态接地;另一个并行口输入按键状态,由行扫描值和回馈信号共同形成键编码而识别按键,通过软件查表,查出该键的功能六、程序流程图(如图14.3所示)七、汇编源程序;;;;;;;;;;定义单元;;;;;;;;;;COUNT EQU 30H;;;;;;;;;;入口地址;;;;;;;;;;ORG 0000HLJMP STARTORG 0003HRETIORG 000BHRETIORG 0013HRETIORG 001BHRETIORG 0023HRETIORG 002BHRETI;;;;;;;;;;主程序入口;;;;;;;;;;ORG 0100HSTART: LCALL CHUSHIHUA LCALL PANDUANLCALL XIANSHILJMP START ;;;;;;;;;;初始化程序;;;;;;;;;; CHUSHIHUA: MOV COUNT#00H RET;;;;;;;;;;判断哪个按键按下程序;;;;;;;;;; PANDUAN: MOV P3#0FFHCLR P3.4MOV A P3ANL A#0FHXRL A#0FHJZ SW1LCALL DELAY10MSJZ SW1MOV A P3ANL A#0FHCJNE A#0EH K1MOV COUNT#0LJMP DKK1: CJNE A#0DH K2MOV COUNT#4LJMP DKK2: CJNE A#0BH K3 MOV COUNT#8 LJMP DKK3: CJNE A#07H K4 MOV COUNT#12K4: NOPLJMP DKSW1: MOV P3#0FFH CLR P3.5MOV A P3ANL A#0FHXRL A#0FHJZ SW2LCALL DELAY10MS JZ SW2MOV A P3ANL A#0FHCJNE A#0EH K5 MOV COUNT#1 LJMP DKK5: CJNE A#0DH K6 MOV COUNT#5 LJMP DKK6: CJNE A#0BH K7 MOV COUNT#9 LJMP DKK7: CJNE A#07H K8 MOV COUNT#13K8: NOPLJMP DKSW2: MOV P3#0FFH CLR P3.6MOV A P3ANL A#0FHXRL A#0FHJZ SW3LCALL DELAY10MS JZ SW3MOV A P3ANL A#0FHCJNE A#0EH K9 MOV COUNT#2 LJMP DKK9: CJNE A#0DH KA MOV COUNT#6 LJMP DKKA: CJNE A#0BH KB MOV COUNT#10 LJMP DKKB: CJNE A#07H KC MOV COUNT#14 KC: NOPLJMP DKSW3: MOV P3#0FFH CLR P3.7MOV A P3ANL A#0FHXRL A#0FHJZ SW4LCALL DELAY10MSJZ SW4MOV A P3ANL A#0FHCJNE A#0EH KDMOV COUNT#3LJMP DKKD: CJNE A#0DH KE MOV COUNT#7LJMP DKKE: CJNE A#0BH KF MOV COUNT#11LJMP DKKF: CJNE A#07H KG MOV COUNT#15KG: NOPLJMP DKSW4: LJMP PANDUAN DK: RET ;;;;;;;;;;显示程序;;;;;;;;;; XIANSHI: MOV A COUNT MOV DPTR#TABLE MOVC A@A+DPTRMOV P0 ALCALL DELAYSK: MOV A P3ANL A#0FHXRL A#0FHJNZ SKRET ;;;;;;;;;;10ms延时程序;;;;;;;;;;DELAY10MS: MOV R6#20D1: MOV R7#248DJNZ R7$DJNZ R6D1RET;;;;;;;;;;200ms延时程序;;;;;;;;;;DELAY: MOV R5#20LOOP: LCALL DELAY10MSDJNZ R5LOOPRET;;;;;;;;;;共阴码表;;;;;;;;;;TABLE: DB 3FH06H5BH4FH66H6DH7DH07H DB 7FH6FH77H7CH39H5EH79H71H ;;;;;;;;;;结束标志;;;;;;;;;;END八、C语言源程序#include<AT89X51.H>unsigned char code table[]={0x3f0x660x7f0x390x060x6d0x6f0x5e0x5b0x7d0x770x790x4f0x070x7c0x71};void main(void){ unsigned char i j k key;while(1){ P3=0xff; //给P3口置1//P3_4=0; //给P3.4这条线送入0//i=P3;i=i&0x0f; //屏蔽低四位//if(i!=0x0f) //看是否有按键按下//{ for(j=50;j>0;j--) //延时//for(k=200;k>0;k--);if(i!=0x0f) //再次判断按键是否按下//{ switch(i) //看是和P3.4相连的四个按键中的哪个// { case 0x0e:key=0;break;case 0x0d:key=1;break;case 0x0b:key=2;break;case 0x07:key=3;break;}P0=table[key]; //送数到P0口显示//}}P3=0xff;P3_5=0; //读P3.5这条线//i=P3;i=i&0x0f; //屏蔽P3口的低四位//if(i!=0x0f) //读P3.5这条线上看是否有按键按下// { for(j=50;j>0;j--) //延时//for(k=200;k>0;k--);i=P3; //再看是否有按键真的按下//i=i&0x0f;if(i!=0x0f){ switch(i) //如果有显示相应的按键//{ case 0x0e:key=4;break;case 0x0d:key=5;break;case 0x0b:key=6;break;case 0x07:key=7;break;}P0=table[key]; //送入P0口显示//}}P3=0xff;P3_6=0; //读P3.6这条线上是否有按键按下// i=P3;i=i&0x0f;if(i!=0x0f){ for(j=50;j>0;j--)for(k=200;k>0;k--);i=P3;i=i&0x0f;if(i!=0x0f){ switch(i){ case 0x0e:key=8;break;key=9;break;case 0x0b:key=10;break;case 0x07:key=11;break;}P0=table[key];}}P3=0xff;P3_7=0; //读P3.7这条线上是否有按键按下// i=P3;i=i&0x0f;if(i!=0x0f){ for(j=50;j>0;j--)for(k=200;k>0;k--);i=P3;i=i&0x0f;if(i!=0x0f){ switch(i){ case 0x0e:key=12;break;case 0x0d:key=13;break;key=14;break;case 0x07:key=15;break;}P0=table[key];}}}}九、注意事项在硬件电路中,要把8联拨动拨码开关JP2拨下,把8联拨动拨码开关JP3拨上去。
矩阵按键原理图

矩阵按键原理图
键盘分编码键盘和非编码键盘。
键盘上闭合键的识别由专用的硬件编码器实现,并产生键编码号或键值的称为编码键盘,如计算机键盘。
而靠软件编程来识别的称为非编码键盘。
在一般嵌入式应用中,用的最多的是非编码键盘,也有用到编码键盘的。
非编码键盘又分为独立键盘和行列式(又称为矩阵式)键盘。
所谓独立式键盘,即嵌入式CPU(或称MCU)的一个GPIO口对应一个按键输入,这个输入值的高低状态就是键值。
矩阵键盘用于采集键值的GPIO是复用的,一般分为行和列采集,例如4*4矩阵键盘就只需要行列各4个按键就可以了,矩阵键盘的控制较独立键盘要复杂得多,本实验未涉及,所以对其原理不做详细介绍。
独立按键一般有2组管脚,虽然市面上我们常常看到有4个管脚的按键,但它们一般是两两导通的,这2组管脚在按键未被按下时是断开的,在按键被按下时则是导通的。
基于此原理,我们一般会把按键的一个管脚接地,另一个管脚上拉到VCC,并且也连接到GPIO。
这样,在按键未被按下时,GPIO的连接状态为上拉到VCC,则键值为1;按键被按下时,GPIO虽然还是上拉到VCC,但同时被导通的另一个管脚拉到地了,所以它的键值实际上是0。
矩阵及下三角键盘

矩阵键盘设计一、原理图图1 4*4矩阵键盘分布图2 4*4键码显示模块图3 下三角键盘分布图3 下三角键盘小写模式显示图3 下三角键盘大写模式显示图3 下三角键盘数字模式显示二、C程序(一) 4*4键盘C程序#include<reg51.h>//51头文件#defineucharunsignedchar#defineuintunsignedint ucharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//0-F字型码voiddelay(ucharz)//延时1ms函数{uinti,j;for(i=z;i>0;i--)for(j=110;j>0;j--);}voidkeyscan()//键盘扫描函数{ucharhang,lie;//定义行列值变量P1=0x0f;//准备读行值hang=P1&0x0f;//读入行值if(hang!=0x0f)//先检测有无按键按下{delay(5);//去抖hang=P1&0x0f;//读入行值if(hang!=0x0f){P1=0xf0;//准备读列值lie=P1&0xf0;//读入列值lie=lie+hang;//确定显示点while(P1!=0xf0);{P1=P1&0xf0;}}}switch(lie){case0x7e:P0=table[0];break;//0显示按键值case0xbe:P0=table[1];break;//1case0xde:P0=table[2];break;//2case0xee:P0=table[3];break;//3case0x7d:P0=table[4];break;//4case0xbd:P0=table[5];break;//5case0xdd:P0=table[6];break;//6case0xed:P0=table[7];break;//7case0x7b:P0=table[8];break;//8case0xbb:P0=table[9];break;//9case0xdb:P0=table[10];break;//acase0xeb:P0=table[11];break;//bcase0x77:P0=table[12];break;//ccase0xb7:P0=table[13];break;//dcase0xd7:P0=table[14];break;//ecase0xe7:P0=table[15];break;//f}}voidmain(){P0=0x00;//初始黑屏while(1){keyscan();//调用键盘扫描,}}(二)下三角键盘C程序#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit rs=P2^6;sbit lcden=P2^7;sbit k2=P3^7;sbit xx=P3^0;sbit dx=P3^1;sbit sz=P3^2;uchar code table[]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q', 'r','s','t','u','v','w','x','y','z', 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q', 'R','S','T','U','V','W','X','Y','Z', '0','1','2','3','4','5','6','7','8','9'} ;uchar data table1[50];uchar num=69,num1,j=0,k1=0,k=0;void delay(uint z){int i,j;for(i=z;i>0;i--)for(j=110;j>0;j--);}void write_com(uchar com)// {rs=0;lcden=0;P0=com;delay(1);lcden=1;delay(1);lcden=0;}void write_date(uchar date)// {rs=1;lcden=0;P0=date;delay(1);lcden=1;delay(1);lcden=0;}uchar keyboard()//{uchar temp;if(k2==0){delay(5);if(k2==0){++k1;while(!k2);//判断键盘是否松开if(k1==3)k1=0;}if(k1==0){xx=1;dx=0;sz=0;}if(k1==1){xx=0;dx=1;sz=0;}if(k1==2){xx=0;dx=0;sz=1;}}if(k1==0){xx=1;P1=0xfe;temp=P1;temp=temp&0xfe;while(temp!=0xfe){delay(5);temp=P1;temp=temp&0xfe;while(temp!=0xfe){temp=P1;switch(temp){// case 0xfc:k1=51;break;case 0xfa:num=0;;break;case 0xf6:num=1;break;case 0xee:num=2;break;case 0xde:num=3;break;case 0xbe:num=4;break;case 0x7e:num=5;break;}while(temp!=0xfe){temp=P1;temp=temp&0xfe;}}}P1=0xfd;temp=P1;temp=temp&0xfd;while(temp!=0xfd){delay(5);temp=P1;temp=temp&0xfd;while(temp!=0xfd){temp=P1;switch(temp){// case 0xfc:k1=51;break;case 0xf9:num=6;break;case 0xf5:num=7;break;case 0xed:num=8;break;case 0xdd:num=9;break;case 0x7d:num=11;break;}while(temp!=0xfd){temp=P1;temp=temp&0xfd;}}}P1=0xfb;temp=P1;temp=temp&0xfb;while(temp!=0xfb){delay(5);temp=P1;temp=temp&0xfb;while(temp!=0xfb){temp=P1;switch(temp){case 0xf3:num=12;break;case 0xeb:num=13;break;case 0xdb:num=14;break;case 0xbb:num=15;break;case 0x7b:num=16;break;}while(temp!=0xfb){temp=P1;temp=temp&0xfb;}}}P1=0xf7;temp=P1;temp=temp&0xf7;while(temp!=0xf7){delay(5);temp=P1;temp=temp&0xf7;while(temp!=0xf7){temp=P1;switch(temp){case 0xe7:num=17;break;case 0xd7:num=18;break;case 0xb7:num=19;break;case 0x77:num=20;break;}while(temp!=0xf7){temp=P1;temp=temp&0xf7;}}}P1=0xef;temp=P1;temp=temp&0xef;while(temp!=0xef){delay(5);temp=P1;temp=temp&0xef;while(temp!=0xef){temp=P1;switch(temp){case 0xcf:num=21;break;case 0xaf:num=22;break;case 0x6f:num=23;break;}while(temp!=0xef){temp=P1;temp=temp&0xef;}}}P1=0xdf;temp=P1;temp=temp&0xdf;while(temp!=0xdf)delay(5);temp=P1;temp=temp&0xdf;while(temp!=0xdf){temp=P1;switch(temp){case 0x9f:num=24;break;case 0x5f:num=25;break;}while(temp!=0xdf){temp=P1;temp=temp&0xdf;}}}P1=0xbf;temp=P1;temp=temp&0xbf;while(temp!=0xbf)delay(5);temp=P1;temp=temp&0xbf;while(temp!=0xbf){temp=P1;switch(temp){case 0x3f:num=69;break;//case 0x5f:num=25;break;}while(temp!=0xbf){temp=P1;temp=temp&0xbf;}}}}if(k1==1){//dx=1;P1=0xfe;temp=P1;temp=temp&0xfe;while(temp!=0xfe){delay(5);temp=P1;temp=temp&0xfe;while(temp!=0xfe){temp=P1;switch(temp){// case 0xfc:k1=51;break;case 0xfa:num=26;;break;case 0xf6:num=27;break;case 0xee:num=28;break;case 0xde:num=29;break;case 0xbe:num=30;break;case 0x7e:num=31;break;}while(temp!=0xfe){temp=P1;temp=temp&0xfe;}}}P1=0xfd;temp=P1;temp=temp&0xfd;while(temp!=0xfd){delay(5);temp=P1;temp=temp&0xfd;while(temp!=0xfd){temp=P1;switch(temp){// case 0xfc:k1=51;break;case 0xf9:num=32;break;case 0xf5:num=33;break;case 0xed:num=34;break;case 0xdd:num=35;break;case 0xbd:num=36;break;case 0x7d:num=37;break;}while(temp!=0xfd){temp=P1;temp=temp&0xfd;}}}P1=0xfb;temp=P1;temp=temp&0xfb;while(temp!=0xfb){delay(5);temp=P1;temp=temp&0xfb;while(temp!=0xfb){temp=P1;switch(temp){case 0xf3:num=38;break;case 0xeb:num=39;break;case 0xdb:num=40;break;case 0xbb:num=41;break;case 0x7b:num=42;break;}while(temp!=0xfb){temp=P1;temp=temp&0xfb;}}}P1=0xf7;temp=P1;temp=temp&0xf7;while(temp!=0xf7){delay(5);temp=P1;temp=temp&0xf7;while(temp!=0xf7){temp=P1;switch(temp){case 0xe7:num=43;break;case 0xd7:num=44;break;case 0xb7:num=45;break;case 0x77:num=46;break;}while(temp!=0xf7){temp=P1;temp=temp&0xf7;}}}P1=0xef;temp=P1;temp=temp&0xef;while(temp!=0xef){delay(5);temp=P1;temp=temp&0xef;while(temp!=0xef){temp=P1;switch(temp){case 0xcf:num=47;break;case 0xaf:num=48;break;case 0x6f:num=49;break;}while(temp!=0xef){temp=P1;temp=temp&0xef;}}}P1=0xdf;temp=P1;temp=temp&0xdf;while(temp!=0xdf)delay(5);temp=P1;temp=temp&0xdf;while(temp!=0xdf){temp=P1;switch(temp){case 0x9f:num=50;break;case 0x5f:num=51;break;}while(temp!=0xdf){temp=P1;temp=temp&0xdf;}}}P1=0xbf;temp=P1;temp=temp&0xbf;while(temp!=0xbf)delay(5);temp=P1;temp=temp&0xbf;while(temp!=0xbf){temp=P1;switch(temp){case 0x3f:num=69;break;}while(temp!=0xbf){temp=P1;temp=temp&0xbf;}}}}if(k1==2){//sz=1;P1=0xfe;temp=P1;temp=temp&0xfe;while(temp!=0xfe){delay(5);temp=P1;temp=temp&0xfe;while(temp!=0xfe){temp=P1;switch(temp){// case 0xfc:k1=51;break;case 0xfa:num=52;;break;case 0xf6:num=53;break;case 0xee:num=54;break;case 0xde:num=55;break;case 0xbe:num=56;break;case 0x7e:num=57;break;}while(temp!=0xfe){temp=P1;temp=temp&0xfe;}}}P1=0xfd;temp=P1;temp=temp&0xfd;while(temp!=0xfd){delay(5);temp=P1;temp=temp&0xfd;while(temp!=0xfd){temp=P1;switch(temp){case 0xf9:num=58;break;case 0xf5:num=59;break;case 0xed:num=60;break;case 0xdd:num=61;break;//case 0xbd:num=62;break;}while(temp!=0xfd){temp=P1;temp=temp&0xfd;}}}}// table1[k]=num;k++;return(num);}/*void display(){ int i,a,b;for(i=0;i<80;i++){a=keyboard();table1[i]=a;write_com(0x80+i);write_date(table[table1[i]]);a=69;delay(100);}}*/void init()//{xx=0;dx=0;sz=0;lcden=0;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);// write_com(0x80);}void main(){ int i=0,j=0;init();while(1){ //table1[k]=keybord();k++;if(k==10)k=0;delay(100);write_com(0x80+0x00);//for(k=0;k<20;k++){write_date(table[keyboard()]);}//for(k=0;k<20;k++)//{write_date(table[table1[k]]);delay(100);}// for(i=0;i<10;i++)/*{ write_date(table[i]);i++;j++;delay(100);}if(i==20)j=0;write_com(0x80+0x40+j);for(k=0;k<20;k++){ write_date(table[i]);i++;j++;delay(100);}if(i==40)j=0;write_com(0x80+0x14+j);for(k=0;k<20;k++){ write_date(table[i]);i++;j++;delay(100);}if(i==60)j=0;write_com(0x80+0x54+j);for(k=0;k<20;k++){ write_date(table[i]);i++;j++;delay(100);}if(i>62)while(1);*/// write_com(0x80+0x40);// for(k=0;k<10;k++)// {write_date(table[keyboard()]);delay(100);}// write_com(0x80+0x40);//for(k=0;k<10;k++)//write_date(table[keyboard()]);// write_com(0x80+0x14);//for(k=0;k<10;k++)//write_date(table[keyboard()]);// write_com(0x80+0x54);//for(k=0;k<10;k++)//write_date(table[keyboard()]);}}此程序对初学者相当有效,且易于学习掌握。
单片机实验报告——矩阵键盘数码管显示

单片机实验报告信息处理实验实验二矩阵键盘专业:电气工程及其自动化指导老师:***组员:明洪开张鸿伟张谦赵智奇学号:152703117 \152703115\152703118\152703114室温:18 ℃日期:2017 年10 月25日矩阵键盘一、实验内容1、编写程序,做到在键盘上每按一个键(0-F)用数码管将该建对应的名字显示出来。
按其它键没有结果。
二、实验目的1、学习独立式按键的查询识别方法。
2、非编码矩阵键盘的行反转法识别方法。
3、掌握键盘接口的基本特点,了解独立键盘和矩阵键盘的应用方法。
4、掌握键盘接口的硬件设计方法,软件程序设计和贴士排错能力。
5、掌握利用Keil51软件对程序进行编译。
6、会根据实际功能,正确选择单片机功能接线,编制正确程序。
对实验结果能做出分析和解释,能写出符合规格的实验报告。
三、实验原理1、MCS51系列单片机的P0~P3口作为输入端口使用时必须先向端口写入“1”。
2、用查询方式检测按键时,要加入延时(通常采用软件延时10~20mS)以消除抖动。
3、识别键的闭合,通常采用行扫描法和行反转法。
行扫描法是使键盘上某一行线为低电平,而其余行接高电平,然后读取列值,如读列值中某位为低电平,表明有键按下,否则扫描下一行,直到扫完所有行。
行反转法识别闭合键时,要将行线接一并行口,先让它工作在输出方式,将列线也接到一个并行口,先让它工作于输入方式,程序使CPU通过输出端口在各行线上全部送低电平,然后读入列线值,如此时有某键被按下,则必定会使某一列线值为0。
然后,程序对两个并行端口进行方式设置,使行线工作于输入方式,列线工作于输出方式,并将刚才读得的列线值从列线所接的并行端口输出,再读取行线上输入值,那么,在闭合键所在行线上的值必定为0。
这样,当一个键被接下时,必定可以读得一对唯一的行线值和列线值。
由于51单片机的并口能够动态地改变输入输出方式,因此,矩阵键盘采用行反转法识别最为简便。
单片机4×4矩阵键盘设计方案

1、设计原理(1)如图14.2所示,用单片机的并行口P3连接4×4矩阵键盘,并以单片机的P3.0-P3.3各管脚作输入线,以单片机的P3.4-P3.7各管脚作输出线,在数码管上显示每个按键“0-F”的序号。
(2)键盘中对应按键的序号排列如图14.1所示。
2、参考电路图14.2 4×4矩阵式键盘识别电路原理图3、电路硬件说明(1)在“单片机系统”区域中,把单片机的P3.0-P3.7端口通过8联拨动拨码开关JP3连接到“4×4行列式键盘”区域中的M1-M4,N1-N4端口上。
(2)在“单片机系统”区域中,把单片机的P0.0-P0.7端口连接到“静态数码显示模块”区域中的任何一个a-h端口上;要求:P0.0对应着a,P0.1对应着b,……,P0.7对应着h。
4、程序设计内容(1)4×4矩阵键盘识别处理。
(2)每个按键都有它的行值和列值,行值和列值的组合就是识别这个按键的编码。
矩阵的行线和列线分别通过两并行接口和CPU通信。
键盘的一端(列线)通过电阻接VCC,而接地是通过程序输出数字“0”实现的。
键盘处理程序的任务是:确定有无键按下,判断哪一个键按下,键的功能是什么?还要消除按键在闭合或断开时的抖动。
两个并行口中,一个输出扫描码,使按键逐行动态接地;另一个并行口输入按键状态,由行扫描值和回馈信号共同形成键编码而识别按键,通过软件查表,查出该键的功能。
5、程序流程图(如图14.3所示)6、汇编源程序;;;;;;;;;;定义单元;;;;;;;;;;COUNT EQU 30H;;;;;;;;;;入口地址;;;;;;;;;;ORG 0000HLJMP STARTORG 0003HRETIORG 000BHRETIORG 0013HRETIORG 001BHRETIORG 0023HRETIORG 002BHRETI;;;;;;;;;;主程序入口;;;;;;;;;;ORG 0100HSTART: LCALL CHUSHIHUALCALL PANDUANLCALL XIANSHILJMP START;;;;;;;;;;初始化程序;;;;;;;;;;CHUSHIHUA: MOV COUNT,#00HRET;;;;;;;;;;判断哪个按键按下程序;;;;;;;;;;PANDUAN: MOV P3,#0FFHCLR P3.4MOV A,P3ANL A,#0FHJZ SW1LCALL DELAY10MS JZ SW1MOV A,P3ANL A,#0FHCJNE A,#0EH,K1 MOV COUNT,#0 LJMP DKK1: CJNE A,#0DH,K2 MOV COUNT,#4 LJMP DKK2: CJNE A,#0BH,K3 MOV COUNT,#8 LJMP DKK3: CJNE A,#07H,K4 MOV COUNT,#12K4: NOPLJMP DKSW1: MOV P3,#0FFH CLR P3.5MOV A,P3ANL A,#0FHJZ SW2LCALL DELAY10MS JZ SW2MOV A,P3ANL A,#0FHCJNE A,#0EH,K5 MOV COUNT,#1 LJMP DKK5: CJNE A,#0DH,K6 MOV COUNT,#5 LJMP DKK6: CJNE A,#0BH,K7 MOV COUNT,#9 LJMP DKK7: CJNE A,#07H,K8 MOV COUNT,#13K8: NOPLJMP DKSW2: MOV P3,#0FFH CLR P3.6MOV A,P3ANL A,#0FHJZ SW3LCALL DELAY10MS JZ SW3MOV A,P3ANL A,#0FHCJNE A,#0EH,K9 MOV COUNT,#2 LJMP DKK9: CJNE A,#0DH,KA MOV COUNT,#6 LJMP DKKA: CJNE A,#0BH,KB MOV COUNT,#10 LJMP DKKB: CJNE A,#07H,KC MOV COUNT,#14 KC: NOPLJMP DKSW3: MOV P3,#0FFH CLR P3.7MOV A,P3ANL A,#0FHJZ SW4LCALL DELAY10MSJZ SW4MOV A,P3ANL A,#0FHCJNE A,#0EH,KDMOV COUNT,#3LJMP DKKD: CJNE A,#0DH,KE MOV COUNT,#7LJMP DKKE: CJNE A,#0BH,KF MOV COUNT,#11 LJMP DKKF: CJNE A,#07H,KG MOV COUNT,#15KG: NOPLJMP DKSW4: LJMP PANDUAN DK: RET ;;;;;;;;;;显示程序;;;;;;;;;; XIANSHI: MOV A,COUNTMOV DPTR,#TABLEMOVC A,@A+DPTRMOV P0,ALCALL DELAYSK: MOV A,P3ANL A,#0FHXRL A,#0FHJNZ SKRET;;;;;;;;;;10ms延时程序;;;;;;;;;;DELAY10MS: MOV R6,#20D1: MOV R7,#248DJNZ R7,$DJNZ R6,D1RET;;;;;;;;;;200ms延时程序;;;;;;;;;;DELAY: MOV R5,#20LOOP: LCALL DELAY10MSDJNZ R5,LOOPRET;;;;;;;;;;共阴码表;;;;;;;;;;TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H DB 7FH,6FH,77H,7CH,39H,5EH,79H,71H;;;;;;;;;;结束标志;;;;;;;;;;END7、C语言源程序#includeunsigned char code table[]={0x3f,0x66,0x7f,0x39,0x06,0x6d,0x6f,0x5e,0x5b,0x7d,0x77,0x79,0x4f,0x07,0x7c,0x71};void main(void){ unsigned char i,j,k,key;while(1){ P3=0xff; //给P3口置1//P3_4=0; //给P3.4这条线送入0//i=P3;i=i&0x0f; //屏蔽低四位//if(i!=0x0f) //看是否有按键按下//{ for(j=50;j>0;j--) //延时//for(k=200;k>0;k--);if(i!=0x0f) //再次判断按键是否按下//{ switch(i) //看是和P3.4相连的四个按键中的哪个// { case 0x0e:key=0;break;case 0x0d:key=1;break;case 0x0b:key=2;break;case 0x07:key=3;break;}P0=table[key]; //送数到P0口显示//}}P3=0xff;P3_5=0; //读P3.5这条线//i=P3;i=i&0x0f; //屏蔽P3口的低四位//if(i!=0x0f) //读P3.5这条线上看是否有按键按下// { for(j=50;j>0;j--) //延时//for(k=200;k>0;k--);i=P3; //再看是否有按键真的按下//i=i&0x0f;if(i!=0x0f){ switch(i) //如果有,显示相应的按键//{ case 0x0e:key=4;break;case 0x0d:key=5;break;case 0x0b:key=6;break;case 0x07:key=7;break;}P0=table[key]; //送入P0口显示//}}P3=0xff;P3_6=0; //读P3.6这条线上是否有按键按下// i=P3;i=i&0x0f;if(i!=0x0f){ for(j=50;j>0;j--)for(k=200;k>0;k--);i=P3;i=i&0x0f;if(i!=0x0f){ switch(i){ case 0x0e:key=8;break;case 0x0d:key=9;break;case 0x0b:key=10;break;case 0x07:key=11;break;}P0=table[key];}}P3=0xff;P3_7=0; //读P3.7这条线上是否有按键按下//i=P3;i=i&0x0f;if(i!=0x0f){ for(j=50;j>0;j--) for(k=200;k>0;k--); i=P3;i=i&0x0f;if(i!=0x0f){ switch(i){ case 0x0e:key=12;break;case 0x0d:key=13;break;case 0x0b:key=14;break;case 0x07:key=15;break;}P0=table[key];}}}}8、注意事项在硬件电路中,要把8联拨动拨码开关JP2拨下,把8联拨动拨码开关JP3拨上去。
矩阵式键盘实验报告

矩阵键盘实验报告佘成刚学号2010302001班级08041202时间2016.01.20一、实验目的1.学习矩列式键盘工作原理;2.学习矩列式接口的程序设计。
二、实验设备普中HC6800ESV20开发板三、实验要求要现:用4*4矩阵键盘,用按键形式输入学号,在数码管上显示对应学号。
四、实验原理工作原理:矩阵式由行线和列线组成,按键位于行、列的交叉点上。
如图所示,一个4*4 的行、列结构可以构成一个由16 个按键的键盘。
很明显,在按键数量较多的场合,矩阵式键盘与独立式键盘相比,要节省很多的I/0 口。
(1)矩阵式键盘工作原理按键设置在行、列交节点上,行、列分别连接到按键开关的两端。
行线通过下拉电阻接到GND 上。
平时无按键动作时,行线处于低电平状态,而当有按键按下时,行线电平状态将由与此行线相连的列线电平决定。
列线电平如果为低,行线电平为高,列线电平如果为高,则行线电平则为低。
这一点是识别矩阵式键盘是否被按下的关键所在。
因此,各按键彼此将相互发生影响,所以必须将行、列线信号配合起来并作适当的处理,才能确定闭合键的位置。
(2)按键识别方法下面以3 号键被按下为例,来说明此键是如何被识别出来的。
前已述及,键被按下时,与此键相连的行线电平将由与此键相连的列线电平决定,而行线电平在无键按下时处于高电平状态。
如果让所有列线处于高电平那么键按下与否不会引起行线电平的状态变化,始终是高电平,所以,让所有列线处于高电平是没法识别出按键的。
现在反过来,让所有列线处于低电平,很明显,按下的键所在行电平将也被置为低电平,根据此变化,便能判定该行一定有键被按下。
但我们还不能确定是这一行的哪个键被按下。
所以,为了进一步判定到底是哪—列的键被按下,可在某一时刻只让一条列线处于低电平,而其余所有列线处于高电平。
当第1 列为低电平,其余各列为高电平时,因为是键3 被按下,所以第1 行仍处于高电平状态;当第2 列为低电平,其余各列为高电平时,同样我们会发现第1 行仍处于高电平状态,直到让第4 列为低电平,其余各列为高电平时,因为是3 号键被按下,所以第1 行的高电平转换到第4 列所处的低电平,据此,我们确信第1 行第4 列交叉点处的按键即3 号键被按下。
4X4矩阵键盘及显示电路设计

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段数码管的译码显示。