4x4矩阵键盘电路连接图和快速扫描完整程序
实验07:4X4键盘阵列扫描输入.pdf
键盘阵列扫描输入一、实验目的1. 进一步学习并掌握Quartus II设计的方法及步骤;2. 熟悉VHDL语言电路设计方法;3. 熟悉EACF型FPGA开发板,参见6.1节;4. 学习并掌握利用VHDL描述并设计电路的方法及步骤;5. 学习并掌握键盘阵列的扫描输入的方法及实现过程。
二、实验原理键盘阵列是一个由4×4的按键开关组成的阵列,可实现16种状态的输入。
4×4按键阵列的硬件连接原理如下图所示。
4X4键盘阵列其中VCC3.3为3.3V的正电源;BUTTON为4×4共16个按键,R为电阻。
而K_H_1、K_H_2、K_H_3、K_H_4为4×4按键阵列连接到FPGA通用IO引脚的行信号;K_V_1、K_V_2、K_V_3、K_V_4为4×4按键阵列连接到FPGA通用IO引脚的列信号,如下图所示。
键盘阵列与FPGA的连接另外,连接到FPGA的行列信号圴为3.3V的LVTTL电平标准:即电压小于0.8V为低电平,高于2.0V为高电平。
通过上述4×4按键阵列的硬件连接原理图可看出,行和列信号都通过10K的电阻上拉到3.3V的电源,也就是说如果FPGA通过对应的IO引脚来读取4×4按键阵列的行和列信号,得到的全部为高电平“1”,即使按键按下时,读到的依然是高电平“1”。
那么如何在FPGA中判断4×4按键阵列中的哪个键按下呢?当然我们要实现按键输入的功能,就不能全部读取行和列的信号。
而应通过不断地输出扫描行(或列),再通过读取列(或行)的信号来判断哪个按键按下。
即:通过对4×4键盘阵列的4个行(或列)控制信号循环输出”1110、1101、1011、0111”,来驱动键盘阵列,紧接着读取相应的4个列(或行)信号。
通过读取的数据或状态来判断16个按键中哪个键被按下,并对其状态做编码输出。
此电路不停的工作,以便实时准确地获取键盘的输入状态,以供其它电路使用,从而实现了键盘阵列的扫描输入。
4×4键盘扫描程序开启原理及实例(精心整理)
4×4键盘扫描程序开启原理及实例(精心整理)单片机4*4键盘扫描程序时如何开启的?按照行顺序,一行一行的开启,如下图:4*4共16键,假设P0.0-P0.3为H0-H3,P0.4-P0.7为L0-L3(列) L0 L1 L2 L3(行) H0 0 1 2 3H1 4 5 6 7H2 8 9 A BH3 C D E F首先让H0 = 0,然后依次检测L0-L3,看那个键按下了,则对应的L0-L3为0,这样第一行检测结束。
比如扫描H0行时第一个键按下了,则L0=0,获得的P0=0xee,你也可以返回一个值,比如就是0,来代表第一个键(0)被按下,这样依次检测就扫描满16个键就行了。
4*4键盘扫描程序#include //包含头文件#define uchar unsigned char#define uint unsigned intunsigned char const dofly[]={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=dofly[0];break;//0 按下相应的键显示相对应的码值case 0x7d:P0=dofly[1];break;//1case 0x7b:P0=dofly[2];break;//2case 0x77:P0=dofly[3];break;//3case 0xbe:P0=dofly[4];break;//4case 0xbd:P0=dofly[5];break;//5case 0xbb:P0=dofly[6];break;//6case 0xb7:P0=dofly[7];break;//7case 0xde:P0=dofly[8];break;//8case 0xdd:P0=dofly[9];break;//9case 0xdb:P0=dofly[10];break;//acase 0xd7:P0=dofly[11];break;//bcase 0xee:P0=dofly[12];break;//ccase 0xed:P0=dofly[13];break;//dcase 0xeb:P0=dofly[14];break;//ecase 0xe7:P0=dofly[15];break;//f}}}uchar keyscan(void)//键盘扫描函数,使用行列反转扫描法{uchar cord_h,cord_l;//行列值P3=0x0f; //行线输出全为0cord_h=P3&0x0f; //读入列线值if(cord_h!=0x0f) //先检测有无按键按下{delay(100); //去抖if(cord_h!=0x0f){cord_h=P3&0x0f; //读入列线值P3=cord_h|0xf0; //输出当前列线值cord_l=P3&0xf0; //读入行线值return(cord_h+cord_l);//键盘最后组合码值}}return(0xff); //返回该值}void delay(uint i)//延时函数{while(i--);}以下为详细解释:假设按下的是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 //包含头文件#define uchar unsigned char#define uint unsigned intunsigned char const table[]={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--);}在P3口做的键盘你的去抖检测没有做好通过电平输入来引发中断,必须是由P3.2或P3.3引脚输入,这样才能触发中断。
4X4键盘扫描程序
4X4键盘扫描程序,采用查表方式,适用于AVR单片机。
此处为4X4键盘软件部分,硬件部分设计请参照:4X4键盘扫描电路分析。
此程序对应的键盘电路为:键盘状态扫描函数/*键盘扫描函数读取当前键盘的状态有按键按下返回相应按键值无按键按下返回"0x00"*/unsigned char key_read(void){unsigned char i;DDRA = 0x00;/*获取列地址*/PORTA = 0x0F;DDRA = 0xF0;此处应加入几uS延时;i = PINA;DDRA = 0x00;/*获取行地址*/PORTA = 0xF0;DDRA = 0x0F;此处应加入几uS延时;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;}}键盘读取函数/*按键获取函数获取按键信号,其中包含有状态记录及按键去颤抖。
4×4矩阵式键盘的课程设计
“电子创新设计与实践”课程期中课题设计报告姓名:张思源,学:20102121026,年级:2010,专业:电信报告内容设计一个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所示。
二、参考电路图14.2 4×4矩阵式键盘识别电路原理图图14.1 4×4键盘0-F显示图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 001BHRETIRETIORG 002BHRETI;;;;;;;;;;主程序入口;;;;;;;;;;ORG 0100HSTART: LCALL CHUSHIHUALCALL PANDUANLCALL XIANSHILJMP START;;;;;;;;;;初始化程序;;;;;;;;;; CHUSHIHUA: MOV COUNT,#00HRET;;;;;;;;;;判断哪个按键按下程序;;;;;;;;;; PANDUAN: MOV P3,#0FFHCLR P3.4MOV A,P3ANL A,#0FHXRL A,#0FHJZ SW1LCALL DELAY10MSJZ SW1ANL A,#0FHCJNE A,#0EH,K1 MOV COUNT,#0LJMP DKK1: CJNE A,#0DH,K2 MOV COUNT,#4LJMP DKK2: CJNE A,#0BH,K3 MOV COUNT,#8LJMP DKK3: CJNE A,#07H,K4 MOV COUNT,#12K4: NOPLJMP DKSW1: MOV P3,#0FFH CLR P3.5MOV A,P3ANL A,#0FHXRL A,#0FHJZ SW2LCALL DELAY10MSMOV A,P3ANL A,#0FHCJNE A,#0EH,K5 MOV COUNT,#1LJMP DKK5: CJNE A,#0DH,K6 MOV COUNT,#5LJMP DKK6: CJNE A,#0BH,K7 MOV COUNT,#9LJMP DKK7: CJNE A,#07H,K8 MOV COUNT,#13K8: NOPLJMP DKSW2: MOV P3,#0FFH CLR P3.6MOV A,P3ANL A,#0FHXRL A,#0FHJZ SW3LCALL DELAY10MSJZ SW3MOV A,P3ANL A,#0FHCJNE A,#0EH,K9 MOV COUNT,#2LJMP DKK9: CJNE A,#0DH,KA MOV COUNT,#6LJMP 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,KEMOV COUNT,#7LJMP DKKE: CJNE A,#0BH,KFMOV COUNT,#11LJMP DKKF: CJNE A,#07H,KGMOV COUNT,#15KG: NOPLJMP DKSW4: LJMP PANDUANDK: 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,07HDB 7FH,6FH,77H,7CH,39H,5EH,79H,71H ;;;;;;;;;;结束标志;;;;;;;;;;END八、C语言源程序#include<AT89X51.H>unsigned 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];}}}}参考文献:百度百科。
4X4矩阵键盘
题目名称:4×4矩阵式键盘队员:伍星刘晓峰陈仁凤摘要:本系统采用AT89S52为控制核心。
采用4X4键盘,通过8位数码管显示动态扫描0—F 16个数字。
关键词:AT89S52键盘数码管显示Abstract: This system USES AT89S52 devices as control ing 4X4 keyboard, through eight digital tube display dynamic scan 0-16 F.Keyword: AT89S52 Keyboard LED Display目录1 方案论证与比较 (3)1.1采样方法方案论证 (3)1.2处理器的选择方案论证................................................. 错误!未定义书签。
1.3周期性判别与测量方法方案论证................................. 错误!未定义书签。
2 系统设计 (3)2.1总体设计 (3)2.2单元电路设计 (5)2.2.1 前级阻抗匹配和放大电路设计 (5)2.2.2 AD转换及控制模块电路设计 (6)2.2.3 功率谱测量单元电路设计 (6)3 软件设计 (7)4系统测试 (8)5 结论 (9)参考文献: (9)附录: (9)附1:元器件明细表: (9)附2:仪器设备清单 (9)附3:电路图图纸 (10)附4:程序清单 (11)1.方案论证与比较1.1采样方法比较与选择方案一:采用FPGA作为系统主控器。
FPGA可实现各种复杂逻辑功能,规模大,集成度高,体积小,稳定性好,IO资源丰富、易于进行功能扩展,处理速度快,但适用于大规模实时性要求较高的系统,价格高,编程实现难度大。
用液晶显示器进行键盘扫描,价格偏高,程序复杂,故不选择此方案方案二: 采用Atmel公司的AT89S52单片机作为主控制器。
AT89S52是一个低功耗、高性能8位单片机,片内含8 KB Flash片内程序存储器,256 Bytes RAM,32个外部双向输入/输出(I/O)口,5个中断优先级,2层中断嵌套中断等。
单片机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拨上去。
机电单片机课程设计--4乘4矩阵键盘-汇编语言
目录1 引言 (2)2 4×4矩阵键盘控制LED工作原理及软硬件设计、仿真调试 (2)2.1 4×4矩阵式键盘识别显示系统概述 (2)2.2 4×4矩阵式键盘原理 (3)2.3 4×4矩阵式键盘控制LED显示方法 (3)2.4 电路设计及电路图 (3)2.5 4×4矩阵式键盘软件编程 (6)2.6 4×4矩阵式键盘软件仿真调试分析 (9)3 结论 (10)4参考文献 (10)1 引言随着现代科技日新月异的发展,作为新兴产业,单片机的应用越来越广。
单片机以其体积小、重量轻、功能强大、功耗低等特点而备受青睐。
键盘作为一种最为普遍的输入工具在单片机项目应用上显得尤为重要。
用MCS51系列的单片机并行口P1接4×4矩阵键盘,以P1.0-P1.3 作输入线,以P1.4-P1.7作输出线;在数码管上显示每个按键的0-F序号。
2 4×4矩阵键盘控制LED工作原理及软硬件设计、仿真调试2.1 4×4矩阵式键盘识别显示系统概述矩阵式键盘模式以4个端口连接控制4*4个按键,实时在LED数码管上显示按键信息。
显示按键信息,省下了很多的I/O端口为他用,相反,独立式按键虽编程简单,但占用I/O口资源较多,不适合在按键较多的场合应用。
矩阵式键盘简介:矩阵式键盘又称行列键盘,它是用4条I/O线作为行线,4条I/O线作为列线组成的键盘。
在行线和列线的每个交叉点上设置一个按键。
这样键盘上按键的个数就为4*4个。
这种行列式键盘结构能有效地提高单片机系统中I/O口的利用率。
最常见的键盘布局如图1所示。
一般由16个按键组成,在单片机中正好可以用一个P 口实现16个按键功能,这也是在单片机系统中最常用的形式,本设计就采用这个键盘模式。
2.2 4×4矩阵式键盘原理在占用相同的I/O端口的情况下,行列式键盘的接法会比独立式接法允许的按键数量多。
STM32-矩阵键盘程序4×4课件.doc
/*--------------------------------------------------------------------------------------* 矩阵键盘驱动* 文件: keyboard.c* 编写人:LiuHui* 描述:扫描4x4 矩阵键盘输入,并返回键值* 适用范围:驱动采用ST3.5 库编写,适用于STM32F10x 系列单片机* 所用引脚:PA0-PA7* 编写时间:2014 年5 月20 日--------------------------------------------------------------------------------------*/#include "stm32f10x.h"#include "keyboard.h"#include "dealy.h"/*-------------------------------- 矩阵键盘初始化----------------------------------------* 功能:初始化stm32 单片机GPIO //PA0-PA7* 参数传递:* 输入:无* 返回值:无--------------------------------------------------------------------------------------*/void KeyBoard_Init(void){GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_SetBits(GPIOA, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3);GPIO_ResetBits(GPIOA, GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7);}/*------------------------------ 矩阵键盘扫描--------------------------------------------* 功能:扫描矩阵键盘,并返回键值* 参数:* 输入:无* 返回:有键按下返回该键值* 无键按下时则返回0--------------------------------------------------------------------------------------*/u8 Read_KeyValue(void){u8 KeyValue=0;if((GPIO_ReadInputData(GPIOA)&0xff)!=0x0f){Delay_ms(10);if((GPIO_ReadInputData(GPIOA)&0xff)!=0x0f){GPIO_SetBits(GPIOA, GPIO_Pin_0);GPIO_ResetBits(GPIOA, GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3);switch(GPIO_ReadInputData(GPIOA)&0xff){case 0x11: KeyValue = 1; break;case 0x21: KeyValue = 5; break;case 0x41: KeyValue = 9; break;case 0x81: KeyValue = 13;break;}GPIO_SetBits(GPIOA, GPIO_Pin_1);GPIO_ResetBits(GPIOA, GPIO_Pin_0 | GPIO_Pin_2 | GPIO_Pin_3);switch(GPIO_ReadInputData(GPIOA)&0xff){case 0x12: KeyValue = 2; break;case 0x22: KeyValue = 6; break;case 0x42: KeyValue = 10;break;case 0x82: KeyValue = 14;break;}GPIO_SetBits(GPIOA, GPIO_Pin_2);GPIO_ResetBits(GPIOA, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_3);switch(GPIO_ReadInputData(GPIOA)&0xff){case 0x14: KeyValue = 3; break;case 0x24: KeyValue = 7; break;case 0x44: KeyValue = 11;break;case 0x84: KeyValue = 15;break;}GPIO_SetBits(GPIOA, GPIO_Pin_3);GPIO_ResetBits(GPIOA, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2);switch(GPIO_ReadInputData(GPIOA)&0xff){case 0x18: KeyValue = 4; break;case 0x28: KeyValue = 8; break;case 0x48: KeyValue = 12;break;case 0x88: KeyValue = 16;break;}GPIO_SetBits(GPIOA, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3); GPIO_ResetBits(GPIOA, GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 |GPIO_Pin_7);while((GPIO_ReadInputData(GPIOA)&0xff)!=0x0f);return KeyValue;}}return 0;}/*--------------------------------THE END--------------------------------------------*//*--------------------------------------------------------------------------------------* 矩阵键盘驱动* 文件: keyboard.h* 编写人:LiuHui* 描述:扫描4x4 矩阵键盘输入,并返回键值* 适用范围:驱动为ST3.5 库编写,适用于STM32F10x 系列单片机* 所用引脚:PA0-PA7* 编写时间:2013 年11 月22 日* 版本: 1.0--------------------------------------------------------------------------------------*/#ifndef __KEYBOARD_H#define __KEYBOARD_Hvoid KeyBoard_Init(void);u8 Read_KeyValue(void);#endif/*----------------------------------THE END------------------------------------------*#include "stm32f10x.h"void KeyBoard_Init(void){GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_SetBits(GPIOB, GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6);GPIO_ResetBits(GPIOB, GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10);}//3?ê?? ˉPA,PBvoid Delay_ms(int time){int i=0;while(time--){i=12000;while(i--);}}u8 Read_KeyValue(void){u8 KeyValue=1;if((GPIO_ReadInputData(GPIOB)&0xff)!=0x0f){Delay_ms(10);if((GPIO_ReadInputData(GPIOB)&0xff)!=0x0f){GPIO_SetBits(GPIOB, GPIO_Pin_3);GPIO_ResetBits(GPIOB, GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6); switch(GPIO_ReadInputData(GPIOB)&0xff){case 0x11: KeyValue = 7; break;case 0x21: KeyValue = 4; break;case 0x41: KeyValue = 1; break;case 0x81: KeyValue = 0; break;}GPIO_SetBits(GPIOB, GPIO_Pin_4);GPIO_ResetBits(GPIOB, GPIO_Pin_3 | GPIO_Pin_5 | GPIO_Pin_6); switch(GPIO_ReadInputData(GPIOB)&0xff){case 0x12: KeyValue = 8; break;case 0x22: KeyValue = 5; break;case 0x42: KeyValue = 2; break;case 0x82: KeyValue = 0; break;}GPIO_SetBits(GPIOB, GPIO_Pin_5);GPIO_ResetBits(GPIOB, GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_6);switch(GPIO_ReadInputData(GPIOB)&0xff){case 0x14: KeyValue = 9; break;case 0x24: KeyValue = 6; break;case 0x44: KeyValue = 3; break;case 0x84: KeyValue = 0; break;}GPIO_SetBits(GPIOB, GPIO_Pin_6);GPIO_ResetBits(GPIOB, GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5);switch(GPIO_ReadInputData(GPIOB)&0xff){case 0x18: KeyValue = 0; break;case 0x28: KeyValue = 0; break;case 0x48: KeyValue = 0;break;case 0x88: KeyValue = 0;break;}GPIO_SetBits(GPIOB, GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6); GPIO_ResetBits(GPIOB, GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10);//while((GPIO_ReadInputData(GPIOB)&0xff)!=0x0f);return KeyValue;}}return 0;}uint16_t table[]={0xEB,0x28,0xB3,0xBA,0x78,0xDA,0xDB,0xA8,0xFB,0xFA};int main(){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);KeyBoard_Init();int keyvalue=Read_KeyValue();GPIO_Write(GPIOA, table[keyvalue]);/*while(1){int i;for(i=0;i<10;i++){GPIO_Write(GPIOA, table[i]);Delay_ms(500);}}*//*u8 keyvalue;for(int i=0;;i++){KeyBoard_Init();keyvalue=Read_KeyValue();GPIO_Write(GPIOA,table[keyvalue]);Delay_ms(500);}*/}#include "stm32f10x.h"void KeyBoard_Init(void){GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_SetBits(GPIOB, GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6);GPIO_ResetBits(GPIOB, GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10);}void Delay_ms(int time){int i=0;while(time--){i=12000;while(i--);}}u8 Read_KeyValue(void){if((GPIO_ReadInputData(GPIOB)&0xff)!=0x73)// 在这个程序下为什么无论是GPIO_ReadInputData(GPIOB)&0xff)!=0x73 还是GPIO_ReadInputData(GPIOB)&0xff)==0x73 都能往下运行,而在屏蔽Delay_ms(10) 后则只能运行一种,是因为这个Delay_ms(10) 对if 里的判断有影响吗?{Delay_ms(10);GPIO_Write(GPIOA,0x33);}return 0;}int main(){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);KeyBoard_Init();Read_KeyValue();}。
单片机键盘程序(4×4矩阵式)
单片机键盘程序(4×4矩阵式)
1.实验任务
如图4.14.2 所示,用AT89S51 的并行口P1 接4 乘以4 矩阵键盘,以
P1.0-P1.3 作输入线,以P1.4-P1.7 作输出线;在数码管上显示每个按键的
0-F 序号。
对应的按键的序号排列如图4.14.1 所示
图4.14.1
2.硬件电路设计原理图
图4.14.2
3.系统板上硬件连线设计
(1.把单片机系统区域中的P3.0-P3.7 端口用8 芯排线连接到4X4 行列式键盘区域中的C1-C4R1-R4 端口上;
(2.把单片机系统区域中的P0.0/AD0-P0.7/AD7 端口用8 芯排线连接到四路静态数码显示模块区域中的任一个a-h 端口上;要求:P0.0/AD0 对应着a,P0.1/AD1 对应着b,,P0.7/AD7 对应着h。
4.程序设计内容
(1.4 乘以4 矩阵键盘识别处理
(2.每个按键有它的行值和列值,行值和列值的组合就是识别这个按键的编码。
矩阵的行线和列线分别通过两并行接口和CPU 通信。
每个按键的状
态同样需变成数字量0 和1,开关的一端(列线)通过电阻接VCC,而接地是通过程序输出数字0 实现的。
键盘处理程序的任务是:确定有无键按下,判断。
单片机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,#0FHXRL A,#0FHJZ SW1LCALL DELAY10MSJZ SW1MOV A,P3ANL A,#0FHCJNE A,#0EH,K1 MOV COUNT,#0LJMP DKK1: CJNE A,#0DH,K2 MOV COUNT,#4LJMP DKK2: CJNE A,#0BH,K3 MOV COUNT,#8LJMP DKK3: CJNE A,#07H,K4 MOV COUNT,#12K4: NOPLJMP DKSW1: MOV P3,#0FFH CLR P3.5MOV A,P3ANL A,#0FHXRL A,#0FHJZ SW2LCALL DELAY10MSJZ SW2MOV A,P3ANL A,#0FHCJNE A,#0EH,K5 MOV COUNT,#1LJMP DKK5: CJNE A,#0DH,K6 MOV COUNT,#5LJMP DKK6: CJNE A,#0BH,K7 MOV COUNT,#9LJMP DKK7: CJNE A,#07H,K8 MOV COUNT,#13K8: NOPLJMP DKSW2: MOV P3,#0FFH CLR P3.6MOV A,P3ANL A,#0FHXRL A,#0FHJZ SW3LCALL DELAY10MSJZ SW3MOV A,P3ANL A,#0FHCJNE A,#0EH,K9 MOV COUNT,#2LJMP DKK9: CJNE A,#0DH,KA MOV COUNT,#6LJMP 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,KD MOV COUNT,#3LJMP DKKD: CJNE A,#0DH,KE MOV COUNT,#7LJMP DKKE: CJNE A,#0BH,KFLJMP DKKF: CJNE A,#07H,KGMOV COUNT,#15KG: NOPLJMP DKSW4: LJMP PANDUANDK: 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,#20DJNZ R7,$DJNZ R6,D1RET;;;;;;;;;;200ms延时程序;;;;;;;;;;DELAY: MOV R5,#20LOOP: LCALL DELAY10MSDJNZ R5,LOOPRET;;;;;;;;;;共阴码表;;;;;;;;;;TABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07HDB 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: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: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;{ 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;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阵列键盘键信号检测电路设计
4X4阵列键盘键信号检测电路设计
1 设计任务及要求
使用Cyclone III芯片对4X4阵列键盘发出扫描信号,获得结果,并处理输出键值,并以此为基础改进出两个16位二进制数字的加减乘除计算器。
2设计原理及总体框图
1.使用分频器把20MHZ的晶振输出降至800HZ作为系统使用的时钟
2.扫描键盘获取键值
3.应用去抖模块滤除抖动的按键信号
4.使用转换模块将4位二进制数转换为16位二进制数
5.使用存储模块存储2个16位二进制数
6.使用计算模块计算值并输出
7.使用计算符号模块输出计算符号
3 程序设计。
4×4键盘扫描程序
键盘程序假设P2.0-P2.3为H0-H3,P2.4-P2.7为L0-L3 (列) L0 L1 L2 L3(行) H0 0 1 2 3H1 4 5 6 7H2 8 9 A BH3 C D E F首先,行为P2口的低四位,而列为高四位。
P0口为数码管输出口。
第一种思路就是逐行逐列判断法。
#include<reg51.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned charuchar code table[17] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf};//八段数码管对应0-F值. uchar temp;void Delay_1ms(uint i)//1ms延时{uint 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,row,col;temp=P2&0xf0;for(i=0; i<4; i++){if(!(temp&(0x10<<i)))row=i;}P2=0x0f;temp=P2&0x0f;for(j=0; j<4; j++){if(!(temp&(0x01<<j)))col=j;}return (row+col*4);}void Main(void){uchar Key_Value=16; //读出的键值uchar i=0;while(1){P2 = 0xf0;temp=P2;if(temp != 0xf0){Delay_1ms(80); //按键消抖if(temp != 0xf0){Key_Value = Keyscan();}Delay_1ms(350); //按键消抖}P0 = table[Key_Value];//P0口输出数据到数码管}次读取结果组合起来就可以得到当前按键的特征编码。
4×4键盘扫描电路设计
设计项目成绩评定表设计报告书目录一、设计目的 (3)二、设计思路 (3)三、设计内容 (4)3.1、原理分析 (4)3.1 1、4* 4键盘的扫描 (4)3.1.2、扫描结果的显示 (5)3.1.3、电路符号 (5)3.1.4、数码管地址选择控制信号 (6)3.2、程序设计 (6)3.3、管脚分配 (10)四、系统调试与结果 (11)五、主要元器件与设备 (12)六、课程设计体会 (13)七、参考文献 (13)一、设计目的1、掌握常用的输入设备—行列式键盘接口电路的实现方法。
2、学习较复杂的数字系统设计方法。
二、设计思路如下图所示为“4 * 4键盘”模拟图。
行“kbrow”有四行:kbrow0、kbrow1、kbrow2、kbrow3。
列“kbcol”有四列:kbcol0、kbcol1、kbcol2、kbcol3 通过给四行赋值循环地对每行进行扫描,例如:通过行线赋值为“1000”时,这样就使得第0行“0键、1键、2键、3键”处在高电平的状态下。
此时如果0键被按下,那么就有第0列输出为高电平。
即四位kbcol输出为“1000”,获取键值为“0”然后在7段数码管上显示出来。
图1 4 * 4键盘三、设计内容3.1、原理分析在数字系统设计中,4*4矩阵键盘是一种常见的输入装置,通常作为系统的输入模块。
对应于键盘上每一个键的识别,一般采用扫描的方法来实现。
下面介绍一种用列信号进行扫描时的基本原理和流程,如图2所示。
当进行列扫描时,扫描信号由列引脚进入键盘,以1000、0100、0010、0001的顺序每次扫描不同的一列,然后读取行引脚的点评信号,以此可以判断是哪个按键被按下。
例如,当扫描行信号独处的值为“0000”时,表示正在扫描“89AB”一列,如果该列没有按键被按下,则由行信号读出的值为“0000”;反之,如果按键“9”被按下时,则该行信号读出的值为“0110”。
图2 4 * 4键盘及行列代码3.1 1、4* 4键盘的扫描在这一部分中,利用时钟信号进行扫描和频率计数器的计数来完成对键盘的扫描。
4x4键盘(任意同时按键按下有效)扫程序-数码管显示键值
}
}
void main()
{
unsigned char i, key_key[16];
while(1)
{
for(i=0;i<16;i++)
{
key_4x4();
duan_xuan();_xuan();
}
}
for(i=x;i>0;--i)
for(j=114;j>0;--j);
}
void duan_xuan()
{
wr=0; //时钟输入端WR置低电平
cs1=0;//cs1为低电平选通段码锁存IC
wr=1; //时钟输入端WR置高电平,WR得到上升沿
cs1=1;//cs1为高电平,段码锁存IC锁存输出保持不变
case 4:if(col3==0) key=3;n=5;break;
case 5:row1=0;row0=1;if(col0==0) key=4;n=6;break;
case 6:if(col1==0) key=5;n=7;break;
case 7:if(col2==0) key=6;n=8;break;
{
static unsigned char n=1;
// P2=0XFF;
switch(n)
{
case 1:row0=0;row3=1;if(col0==0) key=0;n=2;break;
case 2:if(col1==0) key=1;n=3;break;
case 3:if(col2==0) key=2;n=4;break;
4×4矩阵式键盘识别技术
14.4×4矩阵式键盘识别技术1.实验任务如图4.14.2所示,用AT89S51的并行口P1接4×4矩阵键盘,以P1.0-P1.3作输入线,以P1.4-P1.7作输出线;在数码管上显示每个按键的“0-F”序号。
对应的按键的序号排列如图4.14.1所示错误!48C159D26AE37BF图4.14.12.硬件电路原理图图4.14.23.系统板上硬件连线(1.把“单片机系统“区域中的P3.0-P3.7端口用8芯排线连接到“4X4行列式键盘”区域中的C1-C4 R1-R4端口上;(2.把“单片机系统”区域中的P0.0/AD0-P0.7/AD7端口用8芯排线连接到“四路静态数码显示模块”区域中的任一个a-h端口上;要求:P0.0/AD0对应着a,P0.1/AD1对应着b,……,P0.7/AD7对应着h。
4.程序设计内容(1.4×4矩阵键盘识别处理(2.每个按键有它的行值和列值,行值和列值的组合就是识别这个按键的编码。
矩阵的行线和列线分别通过两并行接口和CPU通信。
每个按键的状态同样需变成数字量“0”和“1”,,而接地是通过程序输出数开关的一端(列线)通过电阻接VCC字“0”实现的。
键盘处理程序的任务是:确定有无键按下,判断哪一个键按下,键的功能是什么;还要消除按键在闭合或断开时的抖动。
两个并行口中,一个输出扫描码,使按键逐行动态接地,另一个并行口输入按键状态,由行扫描值和回馈信号共同形成键编码而识别按键,通过软件查表,查出该键的功能。
5.程序框图错误!P3=FFH,P3.0=0有键按下吗?延时10ms真得有键按下吗?根据当前状态识别按键P3=FFH,P3.1=0有键按下吗?延时10ms真得有键按下吗?根据当前状态识别按键P3=FFH,P3.2=0有键按下吗?延时10ms真得有键按下吗?根据当前状态识别按键P3=FFH,P3.3=0有键按下吗?延时10ms真得有键按下吗?根据当前状态识别按键图4.14.3 6.汇编源程序KEYBUF EQU 30HORG 00HSTART: MOV KEYBUF,#2WAIT:MOV P3,#0FFHCLR P3.4MOV A,P3ANL A,#0FHXRL A,#0FHLCALL DELY10MS MOV A,P3ANL A,#0FHXRL A,#0FHJZ NOKEY1MOV A,P3ANL A,#0FHCJNE A,#0EH,NK1 MOV KEYBUF,#0 LJMP DK1NK1: CJNE A,#0DH,NK2 MOV KEYBUF,#1 LJMP DK1NK2: CJNE A,#0BH,NK3 MOV KEYBUF,#2 LJMP DK1NK3: CJNE A,#07H,NK4 MOV KEYBUF,#3 LJMP DK1NK4: NOPDK1:MOV A,KEYBUFMOV DPTR,#TABLE MOVC A,@A+DPTR MOV P0,ADK1A: MOV A,P3ANL A,#0FHJNZ DK1A NOKEY1:MOV P3,#0FFHCLR P3.5MOV A,P3ANL A,#0FHXRL A,#0FHJZ NOKEY2LCALL DELY10MS MOV A,P3ANL A,#0FHXRL A,#0FHJZ NOKEY2MOV A,P3ANL A,#0FHCJNE A,#0EH,NK5 MOV KEYBUF,#4 LJMP DK2NK5: CJNE A,#0DH,NK6 MOV KEYBUF,#5 LJMP DK2NK6: CJNE A,#0BH,NK7 MOV KEYBUF,#6 LJMP DK2NK7: CJNE A,#07H,NK8 MOV KEYBUF,#7 LJMP DK2NK8: NOPDK2:MOV A,KEYBUFMOV DPTR,#TABLE MOVC A,@A+DPTR MOV P0,ADK2A: MOV A,P3ANL A,#0FHXRL A,#0FHJNZ DK2ANOKEY2:MOV P3,#0FFHCLR P3.6MOV A,P3ANL A,#0FHXRL A,#0FHJZ NOKEY3LCALL DELY10MS MOV A,P3ANL A,#0FHXRL A,#0FHJZ NOKEY3MOV A,P3ANL A,#0FHCJNE A,#0EH,NK9 MOV KEYBUF,#8LJMP DK3NK9: CJNE A,#0DH,NK10 MOV KEYBUF,#9LJMP DK3NK10: CJNE A,#0BH,NK11 MOV KEYBUF,#10 LJMP DK3NK11: CJNE A,#07H,NK12 MOV KEYBUF,#11 LJMP DK3NK12: NOPDK3:MOV A,KEYBUFMOV DPTR,#TABLE MOVC A,@A+DPTR MOV P0,ADK3A: MOV A,P3ANL A,#0FHXRL A,#0FHJNZ DK3ANOKEY3:MOV P3,#0FFHCLR P3.7MOV A,P3ANL A,#0FHXRL A,#0FHJZ NOKEY4LCALL DELY10MS MOV A,P3ANL A,#0FHXRL A,#0FHMOV A,P3ANL A,#0FHCJNE A,#0EH,NK13 MOV KEYBUF,#12 LJMP DK4NK13: CJNE A,#0DH,NK14 MOV KEYBUF,#13 LJMP DK4NK14: CJNE A,#0BH,NK15 MOV KEYBUF,#14 LJMP DK4NK15: CJNE A,#07H,NK16 MOV KEYBUF,#15 LJMP DK4NK16: NOPDK4:MOV A,KEYBUFMOV DPTR,#TABLE MOVC A,@A+DPTR MOV P0,ADK4A: MOV A,P3ANL A,#0FHXRL A,#0FHJNZ DK4ANOKEY4:LJMP WAITDELY10MS:D1: MOV R7,#248DJNZ R7,$DJNZ R6,D1RETTABLE: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07HDB 7FH,6FH,77H,7CH,39H,5EH,79H,71HEND7.C语言源程序#include <AT89X51.H>unsigned char code table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; unsigned char temp;unsigned char key;unsigned char i,j;void main(void){while(1){P3=0xff;P3_4=0;temp=P3;temp=temp & 0x0f;if (temp!=0x0f){for(i=50;i>0;i--)for(j=200;j>0;j--);temp=P3;temp=temp & 0x0f;if (temp!=0x0f){temp=P3;temp=temp & 0x0f; switch(temp){case 0x0e:key=7;break;case 0x0d:key=8;break;case 0x0b:key=9;break;case 0x07:key=10;break;}temp=P3;P1_0=~P1_0;P0=table[key];temp=temp & 0x0f;while(temp!=0x0f){temp=P3;temp=temp & 0x0f; }}}P3=0xff;P3_5=0;temp=P3;temp=temp & 0x0f;if (temp!=0x0f){for(i=50;i>0;i--)for(j=200;j>0;j--);temp=P3;temp=temp & 0x0f;if (temp!=0x0f){temp=P3;temp=temp & 0x0f;switch(temp){case 0x0e:key=4;break;case 0x0d:key=5;break;case 0x0b:key=6;break;case 0x07:key=11;break;}temp=P3;P1_0=~P1_0;P0=table[key];temp=temp & 0x0f;while(temp!=0x0f){temp=P3;temp=temp & 0x0f; }}}P3=0xff;P3_6=0;temp=P3;temp=temp & 0x0f;if (temp!=0x0f){for(i=50;i>0;i--)for(j=200;j>0;j--);temp=P3;temp=temp & 0x0f;if (temp!=0x0f){temp=P3;temp=temp & 0x0f; switch(temp){case 0x0e:key=1;break;case 0x0d:key=2;break;case 0x0b:key=3;break;case 0x07:key=12;break;}temp=P3;P1_0=~P1_0;P0=table[key];temp=temp & 0x0f; while(temp!=0x0f){temp=temp & 0x0f; }}}P3=0xff;P3_7=0;temp=P3;temp=temp & 0x0f;if (temp!=0x0f){for(i=50;i>0;i--)for(j=200;j>0;j--);temp=P3;temp=temp & 0x0f;if (temp!=0x0f){temp=P3;temp=temp & 0x0f;switch(temp){case 0x0e:key=0;break;case 0x0d:key=13;break;key=14;break;case 0x07:key=15;break;}temp=P3;P1_0=~P1_0;P0=table[key];temp=temp & 0x0f;while(temp!=0x0f){temp=P3;temp=temp & 0x0f; }}}}}。
C语言-4x4键盘扫描程序
C语言 4*4键盘扫描电路模块#include <reg51.h>#define uchar unsigned char //byte#define uint unsigned int //wordvoid keyscan(); //函数声明void fun0(); //定义每个按键的功能函数void fun1();void fun2();void fun3();void fun4();void fun5();void fun6();void fun7();void fun8();void fun9();void fun10();void fun11();void fun12();void fun13();void fun14();void fun15();/**************************************************************************** 主程序****************************************************************************/void main(void){while(1) //循环扫描{keyscan();}}/**************************************************************************** 按键功能函数 fun0~fun15****************************************************************************/ void fun0(void){ P3=0x00; }void fun1(void){ P3=0x01; }void fun2(void){ P3=0x02; }void fun3(void){ P3=0x03; } //fun4~fun15 略/**************************************************************************** 键盘扫描子程序 keyscan(); void keyscan(); //函数声明***** 无返回值,直接执行子函数功能fun0(); void fun0();//函数声明****************************************************************************/void keyscan(void){ unsigned char i,j;unsigned char n;P1=0xfe; n=P1; n&=0xf0; //扫描第一行if(n!=0xf0){ for(i=0;i<20;i++) for(j=0;j<250;j++); //延时P1=0xfe; n=P1; n&=0xf0;if(n!=0xf0){switch(n){case(0x70): fun0(); break;//按键 0 的函数功能 - 替换P3=0x00;case(0xb0): fun1(); break;//按键 1 的函数功能- 替换case(0xd0): fun2(); break;//按键 2 的函数功能- 替换case(0xe0): fun3(); break;//按键 3 的函数功能- 替换}}}P1=0xfd; n=P1; n&=0xf0; //扫描第二行if(n!=0xf0){ for(i=0;i<20;i++) for(j=0;j<250;j++);//延时P1=0xfd; n=P1; n&=0xf0;if(n!=0xf0){switch(n){case(0x70): P3=0x04; break;//按键 4 的函数功能- 替换 P3=0x04;case(0xb0): P3=0x05; break;//按键 5 的函数功能- 替换case(0xd0): P3=0x06; break;//按键 6 的函数功能- 替换case(0xe0): P3=0x07; break;//按键 7 的函数功能- 替换}}}P1=0xfb; n=P1; n&=0xf0; //扫描第三行if(n!=0xf0){ for(i=0;i<20;i++) for(j=0;j<250;j++); //延时P1=0xfb; n=P1; n&=0xf0;if(n!=0xf0){switch(n){case(0x70): P3=0x08; break;//按键 8 的函数功能- 替换P3=0x08;case(0xb0): P3=0x09; break;//按键 9 的函数功能- 替换case(0xd0): P3=0x0A; break;//按键 A 的函数功能- 替换case(0xe0): P3=0x0B; break;//按键 B 的函数功能- 替换}}}P1=0xf7; n=P1; n&=0xf0; //扫描第四行if(n!=0xf0){ for(i=0;i<20;i++) for(j=0;j<250;j++); //延时P1=0xf7; n=P1; n&=0xf0;if(n!=0xf0){switch(n){case(0x70): P3=0x0C; break;//按键 C 的函数功能- 替换 P3=0x0C; case(0xb0): P3=0x0D; break;//按键 D 的函数功能- 替换case(0xd0): P3=0x0E; break;//按键 E 的函数功能- 替换case(0xe0): P3=0x0F; break;//按键 F 的函数功能- 替换}}}}。