4×4矩阵键盘原理及其在单片机中的简单应用(基Proteus仿真)
实验四4×4键盘输入

实验四: 4 × 4键盘输入实验一、实验目的:1.学习非编码键盘的工作原理和键盘的扫描方式。
2.学习键盘的去抖方法和键盘应用程序的设计。
二、实验原理:键盘是单片机应用系统接受用户命令的重要方式。
单片机应用系统一般采用非编码键4*4矩阵盘,需要由软件根据键扫描得到的信息产生键值编码,以识别不同的键。
本板采用键盘,行信号分别为P1.0-P1.3 ,列信号分别为P1.4-P1.7 。
具体电路连接见下图对于键的识别一般采用逐行(列)扫描查询法,判断键盘有无键按下,由单片机I/O口向键盘送全扫描字,然后读入列线状态来判断。
程序及流程图:ORG 0000HAJMP MAINORG 0000HAJMP MAINORG 0030HMAIN:MOV P2,#0F7HMOV P1,#0F0HMOV R7,#100DJNZ R7,$MOV A,P1ANL A,#0F0HXRL A,#0F0HJZ MAINLCALL D10MSMOV A,#00HMOV R0,AMOV R1,AMOV R2,#0FEH SKEY0:MOV A,R2MOVP1,AMOVR7,#10DJNZ R7,$MOVA,P1ANLA,#0F0HXRLA,#0F0HJNZ LKEYINC R0MOVA,R2RL AMOVR2,AMOVA,R0CJNE A,#04H,SKEY0AJMP MAIN LKEY:JNB ACC,4,NEXT1MOVA,#00HMOVR1,AAJMP DKEYNEXT1:JNB ACC.5,NEXT2MOVA,#01HMOVR1,AAJMP DKEYNEXT2:JNB ACC.6,NEXT3MOVA,#02HMOVR1,AAJMP DKEYNEXT3:JNB ACC.7,MAINMOVA,#03HMOVR1,AAJMP DKEY DKEY:MOV A,R0MOVB,#04HMULABADDA,R1AJMP SQRSQR:MOVDPTR,#TABMOVC A,@A+DPTRMOVP0,AAJMP MAINTAB:DB0C0H,0F9H,0A4H,0B0H,99H, 92H, 82H, 0F8H DB 80H, 90H, 88H, 83H, 0C6H,0A1H,86H, 8EH D10MS:MOV R6,#10L1:MOV R5,#248DJNZ R5,$DJNZ R6,L1RETEND流程图:结束三、思考题:总结 FPGA是如何识别按键的?与单片机读取键值有何不同?答:FPGA的所有 I/O 控制块允许每个 I/O 引脚单独配置为输入口 , 不过这种配置是系统自动完成的。
(整理)自己写的单片机矩阵键盘显示程序及仿真

Protues 电路连接图如下所示:PS:矩阵键盘说明——4×4矩阵从左到右依次编码为1,,3,4,5,6,7,8,9,10,11,12,13,14,15,16 按下某一按键,Led数码管就会显示相应的数字。
Keil C51 程序如下:有点不足望改进。
O(∩_∩)O谢谢!!!////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include <reg51.h>#define uchar unsigned char //宏的定义变量类型uchar 代替unsigned char#define uint unsigned int //宏的定义变量类型uint 代替unsigned intuchar dis_buf; //显示缓存uchar temp;uchar l,h,j; //定义行列void delay0(uchar x); //x*0.14MS// 此表为LED 的字模0 1 2 3 4 5 6 78 9uchar code LED7Code[] = {0xc0,0xf9,~0x5B,~0x4F,~0x66,~0x6D,~0x7D,~0x07,~0x7F,~0x6F};/************************************************************** ** 延时子程序** * *************************************************************/void delay(uchar x){ uchar j;while((x--)!=0) //CPU执行x*12次,x=10{ for(j=0;j<50;j++){;}}}/************************************************************* * * * 键扫描子程序(4*4的矩阵) P1.4 P1.5 P1.6 P1.7为行** P1.0 P1.1 P1.2 P1.3为列** * *************************************************************/void keyscan(void){ temp=0;P1=0xF0; //高四位输入行为高电平列为低电delay(3); //延时temp=P1; //读P1口temp=temp&0xF0;//屏蔽低四位temp=~((temp>>4)|0xF0); //高四位取反无键按下取反应为0xf0if(temp==1) //0001 [1,1] 被拉低h=1;else if(temp==2) //0010[2,1] 被拉低h=2;else if(temp==4) //0100[3,1] 被拉低h=3;else if(temp==8) //1000[4,1] 被拉低h=4;dis_buf = h;dis_buf = (dis_buf<<4) & 0xf0; //行信息现存在第四位delay(10);P1=0x0F; //低四位输入列为高电平行为低电平delay(3); //延时temp=P1; //读P1口temp=temp&0x0F; //屏蔽高四位temp=~(temp|0xF0); //取反if(temp==1) //1列被拉低l=1;else if(temp==2) //2列被拉低l=2;else if(temp==4) //3列被拉低l=3;else if(temp==8) //4列被拉低l=4;l= l & 0x0f;delay(3);dis_buf= l | dis_buf;}/************************************************************** **判断键是否按下** **************************************************************/void keydown(void){P2=0xF0; //显示00P3=0xf0;//将高4位全部置1 低四位全部置0if(P1!=0xF0) //判断按键是否按下如果按钮按下会拉低P1其中的一个端口{keyscan(); //调用按键扫描程序}}void display( ){j=50;while(j){P2= 0x80;P0= LED7Code[0];delay(50);P2=0x01;P0= LED7Code[1];delay(50);P0=0xff;j--;}}void display1( ){j=50;while(j){P2= 0x80;P0= LED7Code[2];delay(50);P2=0x01;P0= LED7Code[1];delay(50);P0=0xff;j--;}}void display2( ){j=50;while(j){P2= 0x80;P0= LED7Code[3];delay(50);P2=0x01;P0= LED7Code[1];delay(50);P0=0xff;j--;}}void display3( ){j=50;while(j){P2= 0x80;P0= LED7Code[4];delay(50);P2=0x01;P0= LED7Code[1];delay(50);P0=0xff;j--;}}void display4( ){j=50;while(j){P2= 0x80;P0= LED7Code[5];delay(50);P2=0x01;P0= LED7Code[1];delay(50);P0=0xff;j--;}}void display5( ){j=50;while(j){P2= 0x80;P0= LED7Code[6];delay(50);P2=0x01;P0= LED7Code[1];delay(50);P0=0xff;j--;}}/************************************************************* * * * 主程序* * * *************************************************************/ void main(){P0=0xc0;delay(20); //延时while(1){ keydown(); //调用按键判断检测程序switch( dis_buf){case 0x11 : P2=0x80; P0= LED7Code[1]; break;case 0x12 : P2=0x80; P0= LED7Code[2]; break;case 0x13 : P2=0x80; P0= LED7Code[3]; break;case 0x14 : P2=0x80; P0= LED7Code[4]; break;case 0x21 : P2=0x80; P0= LED7Code[5]; break;case 0x22 : P2=0x80; P0= LED7Code[6]; break;case 0x23 : P2=0x80; P0= LED7Code[7]; break;case 0x24 : P2=0x80; P0= LED7Code[8]; break;case 0x31 : P2=0x80; P0= LED7Code[9]; break;case 0x32 : display();break;case 0x33 : P2 = LED7Code[1]; P0= LED7Code[1]; break;case 0x34 : display1(); break;case 0x41 : display2(); break;case 0x42 : display3();; break;case 0x43 : display4();; break;case 0x44 : display5();; break;}delay(250);}}//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////。
基于msc51单片机实现的四位4乘4矩阵键盘计算器的C语言程序及其PROTUES电路和仿真

单片机原理及接口技术课程设计报告设计题目:计算器设计学号:100230205姓名:费博文指导教师:张扬信息与电气工程学院二零一三年七月计算器设计单片机体积小,功耗小,价格低,用途灵活,无处不在,属专用计算机。
是一种特殊器件,需经过专门学习方能掌握应用,应用中要设计专用的硬件和软件。
近年来,单片机以其体积小、价格廉、面向控制等独特优点,在各种工业控制、仪器仪表、设备、产品的自动化、智能化方面获得了广泛的应用。
与此同时,单片机应用系统的可靠性成为人们越来越关注的重要课题。
影响可靠性的因素是多方面的,如构成系统的元器件本身的可靠性、系统本身各部分之间的相互耦合因素等。
其中系统的抗干扰性能是系统可靠性的重要指标。
数学是科技进步的重要工具,数据的运算也随着科技的进步越发变得繁琐复杂,计算器的出现可以大大解放人在设计计算过程中的工作量,使计算的精度、速度得到改善,通过msc51单片机,矩阵键盘和LED数码管可以实现简单的四位数的四则运算和显示,并当运算结果超出范围时予以报错。
注:这一部分主要描述题目的背景和意义,对设计所采取的主要方法做一下简要描述。
字数不要太多,300-500字。
另注:本文要当做模板使用,不要随意更改字体、字号、行间距等,学会使用格式刷。
文中给出的各项内容都要在大家的报告中体现,可采用填空的方式使用本模板。
1. 设计任务结合实际情况,基于AT89C51单片机设计一个计算器。
该系统应满足的功能要求为:(1) 实现简单的四位十进制数字的四则运算;(2) 按键输入数字,运算法则;(3) LED数码管移位显示每次输入的数据和运算结果;(4) 当运算结果超出范围时实现报错。
主要硬件设备:AT89C51单片机、LED数码管、矩阵键盘。
注:这一部分需要写明系统功能需求,用到的主要硬件(参考实验箱的说明书)。
2. 整体方案设计计算器以AT89C51单片机作为整个系统的控制核心,应用其强大的I/O功能和计算速度,构成整个计算器。
单片机c语言程序设计---矩阵式键盘实验报告

单片机c语言程序设计---矩阵式键盘实验报告课程名称:单片机c语言设计实验类型:设计型实验实验项目名称:矩阵式键盘实验一、实验目的和要求1.掌握矩阵式键盘结构2.掌握矩阵式键盘工作原理3.掌握矩阵式键盘的两种常用编程方法,即扫描法和反转法二、实验内容和原理实验1.矩阵式键盘实验功能:用数码管显示4*4矩阵式键盘的按键值,当K1按下后,数码管显示数字0,当K2按下后,显示为1,以此类推,当按下K16,显示F。
(1)硬件设计电路原理图如下仿真所需元器件(2)proteus仿真通过Keil编译后,利用protues软件进行仿真。
在protues ISIS 编译环境中绘制仿真电路图,将编译好的“xxx.hex”文件加入AT89C51。
启动仿真,观察仿真结果。
操作方完成矩阵式键盘实验。
具体包括绘制仿真电路图、编写c源程序(反转法和扫描法)、进行仿真并观察仿真结果,需要保存原理图截图,保存c源程序,总结观察的仿真结果。
完成思考题。
三、实验方法与实验步骤1.按照硬件设计在protues上按照所给硬件设计绘制电路图。
2.在keil上进行编译后生成“xxx.hex”文件。
3.编译好的“xxx.hex”文件加入AT89C51。
启动仿真,观察仿真结果。
四、实验结果与分析void Scan_line()//扫描行{Delay(10);//消抖switch ( P1 ){case 0x0e: i=1;break;case 0x0d: i=2;break;case 0x0b: i=3;break;case 0x07: i=4;break;default: i=0;//未按下break;}}void Scan_list()//扫描列{Delay(10);//消抖switch ( P1 ){case 0x70: j=1;break;case 0xb0: j=2;break;case 0xd0: j=3;break;case 0xe0: j=4;break;default: j=0;//未按下break;}}void Show_Key(){if( i != 0 && j != 0 ) P0=table[ ( i - 1 ) * 4 + j - 1 ];else P0=0xff;}五、讨论和心得。
4乘4矩阵式键盘使用

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。
基于51单片机4乘4矩阵键盘的设计

case 0x7d:KEY=7;break;
case 0xeb:KEY=8;break;
case 0xdb:KEY=9;break;
case 0xbb:KEY=10;break;
case 0x7b:KEY=11;break;
case 0xe7:KEY=12;break;
控制任务:
编程实现4乘4的矩阵键盘控制连接在P0口和P1口上的16个LED,当按下某键并释放后只有对应的LED灯亮,例如按S0后D0亮,按S1后D1亮。
程序及仿真:
#include<reg51.h>
unsigned char code led[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
b=P2;
a=a|b;
switch(a)
{
case 0xee:KEY=0;break;
case 0xde:KEY=1;break;
case 0xbe:KEY=2;break;
case 0x7e:KEY=3;break;
case 0xed:KEY=4;break;
case 0xdd:KEY=5;break;
{
P0=0xff;
P1=led[n-8];
}}
int main(void)
{
whilsplay(KEY);
}
return 0;
}
更多资源,请关注微博“风竹弈星”,私聊。
unsigned char KEY=0xff;
void keyscan(void)
{
unsigned char a,b;
P2=0xf0;//高四位作为输入(高电平),低四位输出低电平
自己写的单片机矩阵键盘显示程序及仿真

Protues 电路连接图如下所示:PS:矩阵键盘说明——4×4矩阵从左到右依次编码为1,,3,4,5,6,7,8,9,10,11,12,13,14,15,16按下某一按键,Led数码管就会显示相应的数字。
Keil C51 程序如下:有点不足望改进。
O(∩_∩)O谢谢!!!/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////#include <reg51.h>#define uchar unsigned char //宏的定义变量类型 uchar 代替 unsigned char#define uint unsigned int //宏的定义变量类型 uint 代替 unsigned intuchar dis_buf; //显示缓存uchar temp;uchar l,h,j; //定义行列void delay0(uchar x); //x*0.14MS// 此表为 LED 的字模 0 1 2 3 4 5 6 78 9uchar code LED7Code[] = {0xc0,0xf9,~0x5B,~0x4F,~0x66,~0x6D,~0x7D,~0x07,~0x7F,~0x6F};/************************************************************* * ** 延时子程序 ** **************************************************************/void delay(uchar x){ uchar j;while((x--)!=0) //CPU执行x*12次,x=10{ for(j=0;j<50;j++){;}}}/************************************************************* * * * 键扫描子程序 (4*4的矩阵) P1.4 P1.5 P1.6 P1.7为行 * * P1.0 P1.1 P1.2 P1.3为列 ** * *************************************************************/void keyscan(void){ temp=0;P1=0xF0; //高四位输入行为高电平列为低电delay(3); //延时temp=P1; //读P1口temp=temp&0xF0;//屏蔽低四位temp=~((temp>>4)|0xF0); //高四位取反无键按下取反应为0xf0if(temp==1) //0001 [1,1] 被拉低h=1;else if(temp==2) //0010[2,1] 被拉低h=2;else if(temp==4) //0100[3,1] 被拉低h=3;else if(temp==8) //1000[4,1] 被拉低h=4;dis_buf = h;dis_buf = (dis_buf<<4) & 0xf0; //行信息现存在第四位delay(10);P1=0x0F; //低四位输入列为高电平行为低电平delay(3); //延时temp=P1; //读P1口temp=temp&0x0F; //屏蔽高四位temp=~(temp|0xF0); //取反if(temp==1) //1列被拉低l=1;else if(temp==2) //2列被拉低l=2;else if(temp==4) //3列被拉低l=3;else if(temp==8) //4列被拉低l=4;l= l & 0x0f;delay(3);dis_buf= l | dis_buf;}/************************************************************** **判断键是否按下 ** **************************************************************/void keydown(void){P2=0xF0; //显示00P3=0xf0;//将高4位全部置1 低四位全部置0if(P1!=0xF0) //判断按键是否按下如果按钮按下会拉低P1其中的一个端口{keyscan(); //调用按键扫描程序}}void display( ){j=50;while(j){P2= 0x80;P0= LED7Code[0];delay(50);P2=0x01;P0= LED7Code[1];delay(50);P0=0xff;j--;}}void display1( ){j=50;while(j){P2= 0x80;P0= LED7Code[2];delay(50);P2=0x01;P0= LED7Code[1];delay(50);P0=0xff;j--;}}void display2( ){j=50;while(j){P2= 0x80;P0= LED7Code[3];delay(50);P2=0x01;P0= LED7Code[1];delay(50);P0=0xff;j--;}}void display3( ){j=50;while(j){P2= 0x80;P0= LED7Code[4];delay(50);P2=0x01;P0= LED7Code[1];delay(50);P0=0xff;j--;}}void display4( ){j=50;while(j){P2= 0x80;P0= LED7Code[5];delay(50);P2=0x01;P0= LED7Code[1];delay(50);P0=0xff;j--;} }void display5( ){j=50;while(j){P2= 0x80;P0= LED7Code[6];delay(50);P2=0x01;P0= LED7Code[1];delay(50);P0=0xff;j--;}}/************************************************************** ** 主程序 ** **************************************************************/ void main(){P0=0xc0;delay(20); //延时while(1){ keydown(); //调用按键判断检测程序switch( dis_buf){case 0x11 : P2=0x80; P0= LED7Code[1]; break;case 0x12 : P2=0x80; P0= LED7Code[2]; break;case 0x13 : P2=0x80; P0= LED7Code[3]; break;case 0x14 : P2=0x80; P0= LED7Code[4]; break;case 0x21 : P2=0x80; P0= LED7Code[5]; break;case 0x22 : P2=0x80; P0= LED7Code[6]; break;case 0x23 : P2=0x80; P0= LED7Code[7]; break;case 0x24 : P2=0x80; P0= LED7Code[8]; break;case 0x31 : P2=0x80; P0= LED7Code[9]; break;case 0x32 : display();break;case 0x33 : P2 = LED7Code[1]; P0= LED7Code[1]; break;case 0x34 : display1(); break;case 0x41 : display2(); break;case 0x42 : display3();; break;case 0x43 : display4();; break;case 0x44 : display5();; break;}delay(250);}}/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////(注:本资料素材和资料部分来自网络,仅供参考。
Proteus使用笔记之51单片机4x4矩阵按键

uchar key; while(1) { key=keyscan(); delayMS(50); } } void delayMS(unsigned int z) { unsigned i,j; for(i=z;i>;0;i--) for(j=122;j>;0;j--); } uchar keyscan(void) { uchar scode,scode1,scode2,k; P1=0xf0;
Proteus 使用笔记之 51 单片机 4x4 矩阵按 键
采用反转法判断按键坐标,即行号与列号获得按键码。 写完后发现 Proteus 一个问题:直接使用这样的 if(P1&0xf0!=0xf0)语句时,调不出来,当用了一个中间 变量过渡时,就调出来了,害我花了一个上午的时间,现 在暂时不知道 Proteus 为什么要这样,实际中是不需要的。
case 0x42: k=10;break; case 0x44: k=11;break; case 0x48: k=12;break; case 0x81: k=13;break; case 0x82: k=14;break; case 0x84: k=15;break; case 0x88: k=16;break; default: k=0;break; }
scode1=P1&0xf0; if(scode1!=0xf0) { delayMS(10); scode1=P1&0xf0; if(scode1!=0xf0) { scode1=P1^0xf0; //行号 P1=0x0f; scode2=P1^0x0f; //列号 scode=scode1+scode2; switch(scode) { case 0x11: k=1;break; case 0x12: k=2;break; case 0x14: k=3;break; case 0x18: k=4;break; case 0x21: k=5;break; case 0x22: k=6;break; case 0x24: k=7;break; case 0x28: k=8;break; case 0x41: k=9;break;
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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为01110111,即0X77。
当5键按下时,行线X1和列线Y1为低电平,其余行列线为高电平,于是可得到5键的位置码Y0Y1Y2Y3X0X1X2X3为10111011,即0XBB。
全部矩阵键盘的位置码如下:
2、4×4矩阵键盘在单片机的简单应用举例(一)
如下图所示,运行程序时,按下任一按键,数码管会显示它在矩阵键盘上的序号0~F,并且蜂鸣器发出声音,模拟按键的声音。
此处采用线反转法识别按键。
C程序如下:
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit 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口输出11110000
a=P3; //读取列码
delay(10); //防抖延时10ms
P3=0X0F; //P3口输出00001111
b=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 灯。
这里仍然采用线反转法识别按键。
C程序如下:
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
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;
P1=0XF0;
a=P1;
delay(10);
P1=0X0F;
b=P1;
c=a+b;
for(i=0;i<16;i++)
if(c==tab[i])return i; //有按键,则返回按键号
return -1; //无按键,则返回-1
}
void main()
{uchar key,i,led3,led2;
while(1)
{key=scan();
if(key!=-1)
{led3=0xff;
led2=0xff;
for(i=0;i<=key;i++) //这里假设key=3,因为key是从0开始算起,所以是4号键,应该{if(i<8) //点亮4只LED灯,执行4次for循环后,led3=00001111,所以点亮led3>>=1; //了4只LED灯。
else
led2>>=1;
}
P2=led2;
P3=led3;
}
}
}
Proteus仿真运行结果如下:
4、参考文献
[1]彭伟.单片机C语言程序设计实训100例.北京:电子工业出版社.2009
[2]贾振国,许琳.智能化仪器仪表原理及应用.北京:中国水利水电出版
社.2011。