单片机4X4矩阵键盘中断处理程序(1)
- 格式:docx
- 大小:12.12 KB
- 文档页数:2
4*4 键盘程序readkeyboard: orl a,#0f0h mov a, r2begin: acall key_on mov r6,a swap a jnz delay cpl a add a,r3ajmp readkeyboard jz next retdelay:acall delay10ms ajmp key_c key_ccode:push a acall key_on next: mov a,r7 swap ajnz key_num jnb acc.7,error anl a,#0fhajmp begin rl a dec akey_num:acall key_p mov r7,a rl a ; 行号乘anl a,#0FFh ajmp l_loop 4jz begin error:mov a,#00h rl aacall key_ccode ret mov r7,apush a key_c:mov r2,#00h pop akey_off:acall key_on mov r3,#00h anl a,#0fh jnz key_off mov a,r6 dec apop a mov r5,#04h add a,r7ret again1:jnb acc.0,out1retkey_on: mov a,#00h rr a delay10ms: orl a,#0fh inc r2 anl tmod,#0f0h mov p1,a djnz r5, again1 orl tmod,#01h mov a,p1 out1: inc r2 mov th0,#0d8h orl a,#0f0h mov a,r7 mov tl0,#0f0h cpl a mov r5,#04h setb tr0ret again2:jnb acc.4,out2wait:jbc tf0,overkey_p: mov r7,#0efh rr a ajmp waitl_loop:mov a,r7 inc r3 clr tr0 mov p1,amov a,p1 djnz r5,again2out2: inc r3 单片机键盘设计over:ret二)从电路或软件的角度应解决的问题软件消抖:如果按键较多,硬件消抖将无法胜任,常采用软件消抖。
4乘4矩阵式键盘在单片机中的应用--C语言下图为4*4键盘的结果图,用单片机的P1口接4×4矩阵键盘,接法如图所示,用数码管显示按键的值,按下键S1,数码管显示0,按下S2,数码管显示1,按下S16,显示F。
先看程序代码:#include<reg51.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned charuchar code table[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//八段数码管对应0—F值。
void Delay_1ms(uint i)//1ms延时{uchar x, j;for(j=0;j<i;j++)for(x=0;x<=148;x++);}void delay()//消除按键抖动延时{int i,j;for(i=0; i<=10; i++)for(j=0; j<=2; j++);}uchar Keyscan(void){uchar i,j, temp, Buffer[4] = {0xfe, 0xfd, 0xfb, 0xf7};for(j=0; j<4; j++){P1 = Buffer[j];delay();temp = 0x10;for(i=0; i<4; i++){if(!(P1 & temp)){return (i+j*4);}temp <<= 1;}}}void Main(void){uchar Key_V alue; //读出的键值while(1){P1 = 0xf0;if(P1 != 0xf0){Delay_1ms(15); //按键消抖if(P1 != 0xf0){Key_Value = Keyscan();}}P0 = table[Key_V alue];//P0口输出数据到数码管}}代码分析:程序从Main开始执行,Key_V alue用来存放Keyscan();的返回值,Key_V alue为1,则数码管会显示1。
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拨上去。
单片机驱动4X4矩阵式键盘输入程序(1)单片机驱动4X4矩阵式键盘输入程序 (1)用AT89S51单片机的并行口P1接4×4矩阵键盘,以P1.0-P1.3作输入线,以P1.4-P1.7作输出线;在数码管上显示每个按键的“0-F”序号。
实现键盘输入的识别。
我将给大家提供c和汇编两个版本的4X4矩阵式键盘输入程序。
如汇编语言源程序:KEYBUF EQU 30HORG 00HSTART: MOV KEYBUF,#2WAIT:MOV P3,#0FFHCLR P3.4MOV A,P3ANL A,#0FHXRL A,#0FHJZ NOKEY1LCALL DELY10MSMOV A,P3ANL A,#0FHXRL A,#0FHJZ NOKEY1MOV A,P3ANL A,#0FHCJNE A,#0EH,NK1MOV KEYBUF,#0LJMP DK1NK1: CJNE A,#0DH,NK2MOV KEYBUF,#1LJMP DK1NK2: CJNE A,#0BH,NK3 MOV KEYBUF,#2LJMP DK1NK3: CJNE A,#07H,NK4 MOV KEYBUF,#3LJMP DK1NK4: NOPDK1:MOV A,KEYBUFMOV DPTR,#TABLE MOVC A,@A+DPTRMOV P0,ADK1A: MOV A,P3ANL A,#0FHXRL A,#0FHJNZ DK1ANOKEY1:MOV P3,#0FFHCLR P3.5MOV A,P3ANL A,#0FHXRL A,#0FHJZ NOKEY2LCALL DELY10MSMOV A,P3ANL A,#0FHXRL A,#0FHJZ NOKEY2MOV A,P3ANL A,#0FHCJNE A,#0EH,NK5MOV KEYBUF,#4LJMP DK2NK5: CJNE A,#0DH,NK6 MOV KEYBUF,#5LJMP DK2NK6: CJNE A,#0BH,NK7 MOV KEYBUF,#6LJMP DK2NK7: CJNE A,#07H,NK8 MOV KEYBUF,#7LJMP DK2NK8: NOPDK2:MOV A,KEYBUFMOV DPTR,#TABLE MOVC A,@A+DPTRMOV P0,ADK2A: MOV A,P3ANL A,#0FHXRL A,#0FHJNZ DK2ANOKEY2:MOV P3,#0FFHCLR P3.6MOV A,P3ANL A,#0FHXRL A,#0FHLCALL DELY10MSMOV A,P3ANL A,#0FHXRL A,#0FHJZ NOKEY3MOV A,P3ANL A,#0FHCJNE A,#0EH,NK9MOV KEYBUF,#8LJMP DK3NK9: CJNE A,#0DH,NK10 MOV KEYBUF,#9LJMP DK3NK10: CJNE A,#0BH,NK11 MOV KEYBUF,#10LJMP DK3NK11: CJNE A,#07H,NK12 MOV KEYBUF,#11LJMP DK3NK12: NOPDK3:MOV A,KEYBUFMOV DPTR,#TABLEMOVC A,@A+DPTRMOV P0,ADK3A: MOV A,P3ANL A,#0FHXRL A,#0FHJNZ DK3AMOV P3,#0FFHCLR P3.7MOV A,P3ANL A,#0FHXRL A,#0FHJZ NOKEY4LCALL DELY10MSMOV A,P3ANL A,#0FHXRL A,#0FHJZ NOKEY4MOV A,P3ANL A,#0FHCJNE A,#0EH,NK13MOV KEYBUF,#12LJMP DK4NK13: CJNE A,#0DH,NK14 MOV KEYBUF,#13LJMP DK4NK14: CJNE A,#0BH,NK15 MOV KEYBUF,#14LJMP DK4NK15: CJNE A,#07H,NK16 MOV KEYBUF,#15LJMP DK4NK16: NOPDK4:MOV A,KEYBUFMOV DPTR,#TABLEMOVC A,@A+DPTRMOV P0,ADK4A: MOV A,P3ANL A,#0FHXRL A,#0FHJNZ DK4ANOKEY4:LJMP WAITDELY10MS:MOV R6,#10D1: MOV R7,#248DJNZ R7,$DJNZ R6,D1RETTABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H DB 7FH,6FH,77H,7CH,39H,5EH,79H,71HEND。
4×4矩阵键盘原理及其在单片机中的简单应用基于Proteus仿真1、4×4矩阵键盘的工作原理如下图所示,4×4矩阵键盘由4条行线和4条列线组成,行线接P3.0-P3.3,列线接P3.4-P3.7,按键位于每条行线和列线的交叉点上。
按键的识别可采用行扫描法和线反转法,这里采用简单的线反转法,只需三步。
第一步,执行程序使X0~X3均为低电平,此时读取各列线Y0~Y3的状态即可知道是否有键按下。
当无键按下时,各行线与各列线相互断开,各列线仍保持为高电平;当有键按下时,则相应的行线与列线通过该按键相连,该列线就变为低电平,此时读取Y0Y1Y2Y3的状态,得到列码。
第二步,执行程序使Y0~Y3均为低电平,当有键按下时,X0~X3中有一条行线为低电平,其余行线为高电平,读取X0X1X2X3的状态,得到行码。
第三步,将第一步得到的列码和第二步得到的行码拼合成被按键的位置码,即Y0Y1Y2Y3X0X1X2X3(因为行线和列线各有一条为低电平,其余为高电平,所以位置码低四位和高四位分别只有一位低电平,其余为高电平)。
当0键按下时,行线X0和列线Y0为低电平,其余行列线为高电平,于是可以得到0键的位置码Y0Y1Y2Y3X0X1X2X3为0111 0111,即0X77。
当5键按下时,行线X1和列线Y1为低电平,其余行列线为高电平,于是可得到5键的位置码Y0Y1Y2Y3X0X1X2X3为1011 1011,即0XBB。
全部矩阵键盘的位置码如下:2、4×4矩阵键盘在单片机的简单应用举例(一)如下图所示,运行程序时,按下任一按键,数码管会显示它在矩阵键盘上的序号0~F,并且蜂鸣器发出声音,模拟按键的声音。
此处采用线反转法识别按键。
C程序如下:#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit buzzer=P1^0;uchar code dis[]= //0~9,A~F的共阳显示代码{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0X88,0X83,0XC6,0XA1,0X86,0X8E};uchar code tab[]= //矩阵键盘按键位置码{0x77,0xb7,0xd7,0xe7,0x7b,0xbb,0xdb,0xeb,0x7d,0xbd,0xdd,0xed,0x7e,0xbe,0xde,0xee};void delay(uint x) //延时函数{uchar i;while(x--)for(i=0;i<120;i++);}uchar scan() //矩阵键盘扫描函数,得到按键号,采用线反转法{uchar a,b,c,i;P3=0XF0; //P3口输出11110000a=P3; //读取列码delay(10); //防抖延时10msP3=0X0F; //P3口输出00001111b=P3; //读取行码c=a+b; //得到位置码for(i=0;i<16;i++)if(c==tab[i])return i; //查表得到按键序号并返回return -1; //无按键,则返回-1}void beep() //蜂鸣器发出声音,模拟按键的声音{ uchar i;for(i=0;i<100;i++){buzzer=~buzzer;delay(1);}buzzer=0;}void main(){uchar key;buzzer=0; //关闭蜂鸣器while(1){key=scan(); //得到按键号if(key!=-1) //有按键则显示,并且蜂鸣器发出声音{P0=dis[key];beep();delay(100);}}}Proteus仿真运行结果如下:3、4×4矩阵键盘在单片机的简单应用举例(二)如下图所示,运行程序时,按下的按键键值越大,点亮的LED灯越多,例如,按下1号键时,点亮一只LED灯,按下2号键时,点亮两只LED灯,按下16号键时,点亮全部LED 灯。
4*4#include<reg52.h>#include<intrins.h>#define ulong unsigned long 宏定义#define uint unsigned int#define uchar unsigned char#define ajk P1 //定义按键口#define xsk P0 //定义显示口sbit e=P2^7; //显示控制口sbit cs2=P2^6;sbit cs1=P2^5;uint jm,shi=0x0b,ge=0x0b,dxkz=0xff,wxkz=0xfe,z;uchar code tab1[]={0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77,}; uchar code tab2[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0xff,};void anjjc(); //按键处理void delay(uint z); //申明/***************主程序******************/void main(){TMOD=0x01; //中断初始化TH0=(65536-500)/256;TL0=(65536-500)%256;EA=1;ET0=1;TR0=1;while(1){anjjc(); //调用按键扫描}}/****************矩阵扫描*****************/ void anjjc(){uchar aa;ajk=0xf0; //列为1横为0aa=ajk;if(aa!=0xf0) //判断是否按下{delay(5); //去抖动ajk=0xf0;aa=ajk;if(aa!=0xf0) //在判断是否按下{uchar j,i=0,k,ajkkz=0xfe;for(k=4;k>0;k--) //逐行为0控制{ajk=ajkkz;aa=ajk;for(j=4;j>0;j--){if(aa==tab1[i]) //逐列查数组是否相等jm=i; //相等则i就是键码i++; //不等加1}ajkkz=_crol_(ajkkz,1); //左移使下一行为0,在查}}shi=jm/10; // 十位数据处理ge=jm%10; //个位数据处理}}/*************数码管控制********************/void xst0() interrupt 1 //中断显示{switch(wxkz) //位选控制段选数值{case 0xfe:dxkz=ge;break;case 0xfd:dxkz=shi;break;}e=0;cs2=0;xsk=0xff;e=1;cs2=1;e=0;cs1=0;xsk=tab2[dxkz];e=1;cs1=1;e=0;cs2=0;xsk=wxkz;e=1;cs2=1;wxkz=_crol_(wxkz,1); //位选控制if(wxkz==0xfb) //显示位数控制wxkz=0xfe;TH0=(65536-500)/256;TL0=(65536-500)%256;}/*************延时程序********************/ void delay(uint z) //延时{uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}。
目录摘要 (2)第一章硬件部分 (3)第一节AT89C51 (3)第二节4*4矩阵式键盘 (6)第三节LED数码管 (8)第四节硬件电路连接 (10)第二章软件部分 (12)第一节所用软件简介 (12)第二节程序流程图 (14)第三节程序 (17)第三章仿真结果 (19)心得体会 (21)参考文献 (22)摘要电子信息行业将是人类社会的高科技行业之一,是设施现代化的基础,也是人类通往科技巅峰的直通车。
电子行业的发展很重要,而计算机技术是现代科技发展的重要组成部分。
矩阵式键盘控制系统可以提高效率,是进行按键操作管理的有效方法,它可以提高系统准确性,有利于资源的节约,降低对操作者本身的要求。
并能正确、实时、高效地显示按键信息,以提高工作效率和资源利用率。
矩阵式键盘是当今使用最为广泛的键盘模式,该系统以N个端口连接控制N*N个按键,并通过单片机,显示在LED数码管上。
单片机控制键盘显示系统,可以对不同的按键进行实时显示,其核心是单片机、键盘矩阵电路和数码管显示电路。
4*4矩阵式键盘以AT89C51单片机为核心,主要由矩阵式键盘电路、显示电路等组成,软件选用C语言编程。
单片机将检测到的按键信号转换成数字量,显示于LED显示器上。
该系统灵活性强,易于操作,可靠性高,广泛应用于各种场合。
第一章硬件部分第一节AT89C51AT89C51是一种带4K字节FLASH存储器(FPEROM—Flash Programmable and Erasable Read Only Memory)的低电压、高性能CMOS 8位微处理器,俗称单片机。
AT89C51单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。
引脚如图所示AT89C51图1 AT89C51管脚图AT89C51其具有以下特性:与MCS-51 兼容4K字节可编程FLASH存储器寿命:1000写/擦循环数据保留时间:10年全静态工作:0Hz-24MHz三级程序存储器锁定128×8位内部RAM32可编程I/O线两个16位定时器/计数器5个中断源可编程串行通道低功耗的闲置和掉电模式片内振荡器和时钟电路特性概述:AT89C51 提供以下标准功能:4k 字节Flash 闪速存储器,128字节内部RAM,32 个I/O 接口,两个16位定时/计数器,一个5向量两级中断结构,一个全双工串行通信口,片内振荡器及时钟电路。
51单片机4×4矩阵按键程序(汇编)ORG 0000HLJMP MAIN ;跳转至主程序ORG 0100HMAIN: LCALL KEY_INMOV P0,ALCALL DELAJMP MAIN;======================;判断有无按键,无按键直接返回;KEY_IN: MOV P1,#0F0H ;置行线为低电平,读列线状态(在高4位,无按键则全为1); MOV A,P1; ANL A,#0F0H ;屏蔽低四位; MOV B,A; MOV P1,#0FH ;置列线为低电平,读行线状态(在低4位,无按键则全为1); MOV A,P1; ANL A,#0FH; ORL A,B ;高四位与低四位重新组合; CJNE A,#0FFH,KEYSCAN ;0FFH为末按键; RET;==========================================;//=============键盘扫描程序============================================== ;KEYSCAN:KEY_IN: MOV R1,#0 ;初始化列地址MOV R3,#11110111B ;初始化扫描码LOOP:MOV A,R3RL AMOV R3,A ;保留扫描码MOV P1,A ;送扫描码MOV A,P1 ;读键盘ORL A,#0F0H ;屏蔽高四位CJNE A,#0FFH,NEXT31 ;A不等于FFH,说明该列有按键动作INC R1 ;列地址加1,准备扫描下一列CJNE R1,#4,LOOP ;列地址不等于4,扫描下一列SJMP EXIT ;没有按键,退出;//=============按键判断对应位等于零,说明该行有按键按下==================NEXT31:JB ACC.0,NEXT32MOV R2,#0 ;第0行有按键SJMP NEXT5NEXT32:JB ACC.1,NEXT33MOV R2,#1 ;第1行有按键SJMP NEXT5NEXT33:JB ACC.2,NEXT34MOV R2,#2 ;第2行有按键SJMP NEXT5NEXT34:MOV R2,#3 ;第3行有按键NEXT5: ;计算按键地址MOV A,R1RL ARL A ;列地址乘4(每列对应4行) ADD A,R2 ;加行地址MOV DPTR,#KEYTABMOVC A,@A+DPTREXIT:; MOV P1,#0FFH ;置键盘接口高电平RET;延时子程序,1s延时DEL: MOV R7,#10DEL1: MOV R6,#200DEL2: MOV R5,#248HERE: DJNZ R5,HEREDJNZ R6,DEL2DJNZ R7,DEL1RET;//=============按键名称表================================================ KEYTAB:DB 3fH ;扫描码0*****************************************DB 06H ;扫描码1 **DB 5bH ;扫描码2 I/O口 P1.0 P1.1 P1.2 P1.3 ** DB 4fH ;扫描码3 **DB 66H ;扫描码4 P1.4 0 1 2 3 **DB 6dH ;扫描码5 **DB 7dH ;扫描码6 P1.5 4 5 6 7 **DB 07H ;扫描码7 **DB 7fH ;扫描码8 P1.6 8 9 A B **DB 6fH ;扫描码9 **DB 77H ;扫描码A P1.7 C D E F **DB 7cH ;扫描码B **DB 39H ;扫描码C***************************************** DB 5eH ;扫描码DDB 79H ;扫描码EDB 71H ;扫描码FDB 00HDB 00HEND。
;******************************************************;*标题: 51单片机4×4矩阵式键盘识别汇编程序;*******************************************************; 0 1 2 3 ---P20; 4 5 6 7 ---P21; 8 9 10 11 ---P22; 12 13 14 15 ---P23; | | | |; P24 P25 P26 P27;******************************************************************ORG 0000hAJMP MAINORG 0030hMAIN:MOV DPTR,#TAB ;将表头放入DPTRLCALL KEY;调用键盘扫描程序MOVC A,@A+DPTR ;查表后将键值送入ACCMOV P0,A;将Acc值送入P0口CLR P1.3 ;开显示LJMP MAIN ;返回调用子程序反复循环显示;----------------------------------------------------------------------KEY:LCALL KS ;调用检测按键子程序JNZ K1 ;有键按下继续LCALL DELAY2 ;无键按下调用延时去抖动程序AJMP KEY;返回继续检测有无按键按下K1:LCALL DELAY2LCALL DELAY2 ;有键按下继续延时去抖动LCALL KS ;再一次调用检测按键程序JNZ K2 ;确认有按下进行下一步AJMP KEY;无键按下返回继续检测K2:MOV R2,#0EFH ;将扫描值送入R2暂存MOV R4,#00H ;将第一列的列值00H送入R4暂存,R4用于存放列值。
K3:MOV P2,R2 ;将R2的值送入P1口L6:JB P2.0,L1 ;P1.0等于1跳转到L1MOV A,#00H ;将第一行的行值00H送入ACCAJMP LK ;跳转到键值处理程序JB P2.1,L2 ;P1.1等于1跳转到L2MOV A,#04H ;将第二行的行值送入ACCAJMP LK ;跳转到键值理程序进行键值处理L2:JB P2.2,L3 ;P1.2等于1跳转到L3MOV A,#08H ;将第三行的行值送入ACCAJMP LK ;跳转到键值处理程序L3:JB P2.3,NEXT ;P1.3等于1跳转到NEXT处MOV A,#0cH ;将第四行的行值送入ACCLK:ADD A,R4 ;行值与列值相加后的键值送入APUSH ACC ;将A中的值送入堆栈暂存K4:LCALL DELAY2 ;调用延时去抖动程序LCALL KS ;调用按键检测程序JNZ K4 ;按键没有松开继续返回检测POP ACC ;将堆栈的值送入ACCRETNEXT:INC R4 ;将列值加一MOV A,R2 ;将R2的值送入AJNB ACC.7,KEY;扫描完成跳至KEY处进行下一回合的扫描RL A;扫描未完成将A中的值右移一位进行下一列的扫描MOV R2,A;将ACC的值送入R2暂存AJMP K3 ;跳转到K3继续KS:MOV P2,#0FH ;将P1口高四位置0低四位值1MOV A,P2 ;读P1口XRL A,#0FH ;将A中的值与A中的值相异或RET ;子程序返回DELAY2: ;40ms延时去抖动子程序8*FA*2=40ms MOV R5,#08HL7:MOV R6,#0FAHL8:DJNZ R6,L8DJNZ R5,L7RETDB 0C0H;0DB 0F9H;1DB 0A4H;2DB 0B0H;3DB 099H;4DB 092H;5DB 082H;6DB 0F8H;7DB 080H;8DB 090H;9DB 088H;ADB 083H;bDB 0C6H;CDB 0A1H;dDB 086H;EDB 08EH;F END。
MSP430f2272单片机中断控制4X4键盘程序#include "msp430f2272.h"intyu[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};int i,j,k,temp,dat,ms;void delay(int ms){ while(ms--) for(i=0;i<2;i++);}int main( void ){ // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; P1DIR |=0x0f; P2DIR =0xff;P1IE |=0xf0;P1IES |=0xf0;P2OUT=yu[0];P1IFG =0x00; _EINT(); temp=0xfe; while(1) { temp=0xfe;P1OUT=temp;delay(5);temp=0xfd;P1OUT=temp;delay(5);temp=0xfb;P1OUT=temp;delay(5);temp=0xf7;P1OUT=temp;delay(5); }}#pragmavector=PORT1_VECTOR__interrupt void Port_ISR(void) {switch(temp){case 0xfe:{if(P1IFG==BIT4)dat=0;if(P1IFG==BIT5)dat=1;if(P1IFG==BIT6)dat=2;if(P1IFG==BIT7)dat=3;P2OUT =~yu[dat];P1IFG=0x00;break;}case 0xfd:{if(P1IFG==BIT5)dat=5; if(P1IFG==BIT6)dat=6; if(P1IFG==BIT7)dat=7; P2OUT =~yu[dat];P1IFG=0x00;break;}case 0xfb:{if(P1IFG==BIT4)dat=8; if(P1IFG==BIT5)dat=9; if(P1IFG==BIT6)dat=10; if(P1IFG==BIT7)dat=11; P2OUT =~yu[dat];P1IFG=0x00;break;}case 0xf7:{if(P1IFG==BIT4)dat=12; if(P1IFG==BIT5)dat=13;if(P1IFG==BIT7)dat=15;P2OUT =~yu[dat];P1IFG=0x00;break;}default:break;}}/****************************************** ***************/#include "msp430f2272.h"intyu[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};int i,j,k,temp,dat,ms;void delay(int ms){ while(ms--) for(i=0;i<2;i++);}int main( void ){ // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; P1DIR |=0x0f;P2DIR =0xff;P1REN |=0xf0; P1IE |=0xf0;P1IES |=0xf0;P2OUT=~yu[6];P1IFG =0x00; _EINT(); temp=0xfe; while(1) {temp=0xfe;P1OUT=temp;delay(5);temp=0xfd;P1OUT=temp;delay(5);temp=0xfb;P1OUT=temp;delay(5);temp=0xf7;P1OUT=temp;delay(5); }}#pragmavector=PORT1_VECTOR__interrupt void Port_ISR(void) {switch(temp){case 0xfe:{if((P1IFG|0xef)==0xff)dat=0;if((P1IFG|0xdf)==0xff)dat=1;if((P1IFG|0xbf)==0xff)dat=2;if((P1IFG|0x7f)==0xff)dat=3; P2OUT =~yu[dat];P1IFG=0x00;break;}case 0xfd:{if((P1IFG|0xef)==0xff)dat=4; if((P1IFG|0xdf)==0xff)dat=5; if((P1IFG|0xbf)==0xff)dat=6; if((P1IFG|0x7f)==0xff)dat=7; P2OUT =~yu[dat];P1IFG=0x00;break;}case 0xfb:{if((P1IFG|0xef)==0xff)dat=8; if((P1IFG|0xdf)==0xff)dat=9; if((P1IFG|0xbf)==0xff)dat=10; if((P1IFG|0x7f)==0xff)dat=11; P2OUT =~yu[dat];P1IFG=0x00;break;}case 0xf7:{if((P1IFG|0xef)==0xff)dat=12; if((P1IFG|0xdf)==0xff)dat=13; if((P1IFG|0xbf)==0xff)dat=14; if((P1IFG|0x7f)==0xff)dat=15; P2OUT =~yu[dat];P1IFG=0x00;break;}default:break;}}#include "msp430f2272.h"intyu[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};int i,j,k,temp,dat,ms;void delay(int ms){ while(ms--) for(i=0;i<2;i++);}int main( void ){ // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; P1DIR |=0x0f; P2DIR =0xff;P1REN |=0xf0; P1IE |=0xf0; P1IES |=0xf0;P2OUT=~yu[6];P1IFG =0x00; _EINT(); temp=0xfe; while(1) { temp=0xfe;P1OUT=temp;delay(5);temp=0xfd;P1OUT=temp;delay(5);temp=0xfb;P1OUT=temp;delay(5);temp=0xf7;P1OUT=temp;delay(5); }}#pragmavector=PORT1_VECTOR__interrupt voidPort_ISR(void) {if(temp==0xfe){if((P1IFG|0xef)==0xff)dat=0;if((P1IFG|0xdf)==0xff)dat=1; if((P1IFG|0xbf)==0xff)dat=2; if((P1IFG|0x7f)==0xff)dat=3; P2OUT =~yu[dat];P1IFG=0x00;}if(temp==0xfd){if((P1IFG|0xef)==0xff)dat=4; if((P1IFG|0xdf)==0xff)dat=5; if((P1IFG|0xbf)==0xff)dat=6; if((P1IFG|0x7f)==0xff)dat=7; P2OUT =~yu[dat];P1IFG=0x00;}if(temp==0xfb){if((P1IFG|0xef)==0xff)dat=8; if((P1IFG|0xdf)==0xff)dat=9; if((P1IFG|0xbf)==0xff)dat=10; if((P1IFG|0x7f)==0xff)dat=11;P2OUT =~yu[dat];P1IFG=0x00;}if(temp==0xf7){if((P1IFG|0xef)==0xff)dat=12; if((P1IFG|0xdf)==0xff)dat=13; if((P1IFG|0xbf)==0xff)dat=14; if((P1IFG|0x7f)==0xff)dat=15; P2OUT =~yu[dat];P1IFG=0x00;}}。
MSP430 4x4阵列按键程序作者:cxjr 摘自:匠人的百宝箱采用P1口4x4阵列参考电路例程://******************************************************************* **********#include <msp430x14x.h>//******************************************************************* **********//IO初始化程序void Init_Port(void){//将P1口所有的管脚在初始化的时候设置为输入方式P1DIR = 0;//将P1口所有的管脚设置为一般I/O口P1SEL = 0;// 将P1.4 P1.5 P1.6 P1.7设置为输出方向P1DIR |= BIT4;P1DIR |= BIT5;P1DIR |= BIT6;P1DIR |= BIT7;//先输出低电平P1OUT = 0x00;// 将中断寄存器清零P1IE = 0;P1IES = 0;P1IFG = 0;//打开管脚的中断功能//对应的管脚由高到低电平跳变使相应的标志置位P1IE |= BIT0;P1IES |= BIT0;P1IE |= BIT1;P1IES |= BIT1;P1IE |= BIT2;P1IES |= BIT2;P1IE |= BIT3;P1IES |= BIT3;_EINT();//打开中断return;}void Delay(void){int i;for(i = 100;i--;i > 0) ;//延时一点时间}//******************************************************************* **********//键处理程序int KeyProcess(void){int nP10,nP11,nP12,nP13;int nRes = 0;//P1.4输出低电平P1OUT &= ~(BIT4);nP10 = P1IN & BIT0;if (nP10 == 0) nRes = 13;nP11 = P1IN & BIT1;if (nP11 == 0) nRes = 14;nP12 = P1IN & BIT2;if (nP12 == 0) nRes = 15;nP13 = P1IN & BIT3;if (nP13 == 0) nRes = 16;//P1.5输出低电平P1OUT &= ~(BIT4);nP10 = P1IN & BIT0;if (nP10 == 0) nRes = 9;nP11 = P1IN & BIT1;if (nP11 == 0) nRes = 10;nP12 = P1IN & BIT2;if (nP12 == 0) nRes = 11;nP13 = P1IN & BIT3;if (nP13 == 0) nRes = 12;//P1.6输出低电平P1OUT &= ~(BIT4);nP10 = P1IN & BIT0;if (nP10 == 0) nRes = 5;nP11 = P1IN & BIT1;if (nP11 == 0) nRes = 6;nP12 = P1IN & BIT2;if (nP12 == 0) nRes = 7;nP13 = P1IN & BIT3;if (nP13 == 0) nRes = 8;//P1.7输出低电平P1OUT &= ~(BIT4);nP10 = P1IN & BIT0;if (nP10 == 0) nRes = 1;nP11 = P1IN & BIT1;if (nP11 == 0) nRes = 2;nP12 = P1IN & BIT2;if (nP12 == 0) nRes = 3;nP13 = P1IN & BIT3;if (nP13 == 0) nRes = 4;P1OUT = 0x00;//恢复以前值。