产品选型

51单片机code 基于proteus的51单片机开发实例24-矩阵键盘(行列式键盘)

小编 2024-10-24 产品选型 23 0

基于proteus的51单片机开发实例24-矩阵键盘(行列式键盘)

1. 基于proteus的51单片机开发实例24-矩阵键盘

1.1. 实验目的

图1 矩阵键盘电路

本实例我们来学习矩阵键盘(行列式键盘)的电路设计、编程实现。目的是通过较少的I/O口来识别多个按键。

1.2. 设计思路

我们在前面已经学习过独立按键,在独立按键电路中,一个按键连接单片机的一位I/O端口。这样通过检测I/O的状态就能很方便的识别该按键是否按下。这种电路的优点是:电路简单,程序简单,缺点是一个按键就要占用一个I/O口。我们知道,51单片机总共只有4个8位I/O口,如果外部电路功能较多,I/O口就会不够用,例如如果电路中接了一个8位数码管,又接了16个按键,那么即使数码管采用动态扫描法 也需要占用16个I/O口(8位I/O口用于连接数码管8个段,另8位I/O口用于控制8位数码管的每一位),这时如果按键还是采用独立按键的接法,每个按键接一位I/O口,那么又要占用16个I/O口,这样就把单片机的I/O口全部占完了,如果这时候想加一个蜂鸣器,就没有多余的I/O口了。所以很与必要考虑如何用较少的I/O口实现更多的功能。

矩阵键盘就是基于用较少I/O口连接更多按键的思路实现的。通常将多个按键排列成矩阵形式,这也是矩阵键盘名称的由来,编程时,是按照矩阵的行、列组合判断是那个按键被按下的,因此又称为行列式键盘。

1.3. 基础知识

最常见的矩阵键盘是4*4键盘,其实现方法是将16个按键按照4x4矩阵方式连接,如下图所示。从连接方式来看,有4根行线和4根列线。每个行线和列线的交汇处就是一个按键位。这样总共有8根线就可以实现16个按键的检测,比一个按键连接一个I/O口节省了一半的I/O端口。

图2 矩阵键盘结构

矩阵键盘的工作原理

一般矩阵键盘都会将按键按照一定的规律赋予不同的标号(例如按照从左到右的顺序,或者从上到下的顺序),当检测到有按键按下后,根据被按下的按键序号赋予一定的键值。程序中就可以根据键值进行相应的处理。

在51单片机中,对于矩阵键盘的处理方法是:使用行列扫描法,将键盘的行线和列线分别连接到单片机的I/O口线上,然后按照如下步骤操作:

第一步:判断是否有按键按下

将行线全部输出低电平,全部列线输出高电平,然后将列线置为输入状态,检测列线的状态,只要有一根列线为低电平 ,就表示矩阵键盘中有按键被按下了。

第二步:按键消除抖动

在第一步中如果检测到有按键按下,则使用软件消抖的方法延时20ms左右,再次判断是否有列线为低电平,如果仍有列线为低电平,则认为确实有按键被按下,则进入到第三步处理,否则,认为是抖动,不予识别,继续回到第一步重新开始按键检测。

第三步:按键识别

确认有按键被按下后,接下来就是最关键的内容:确定那个按键被按下。这需要用逐行扫描的方法来确定。先扫描第一行,即将第一行对应的端口输出低电平,然后读每一列的电平,当出现某一列为低电平,说明该列与第一行的交叉点的按键被按下,如果所有列都是高电平,说明第一行的按键都未被按下,那么开始扫描第二行,以此类推,直到找到被按下的键所在的行与列的交叉点。

第四步:键值确定

在第三步中,当确定有按键被按下,则按照事先确定好的按键序号,根据行与列的交叉位置确定键值。简直一般按照一定的规律排列,例如1,2,3,4....。例如确定第一行第一列的交叉点按键为1号按键,第一行与第二列交叉点的按键为2号按键....第四行与第四列的交叉点的按键为16号按键。

1.4. 电路设计

本实例电路图如图1所示。矩阵键盘电路与单片机的P3口的8额I/O连接,P0口连接一个共阳极数码管,用于演示按键序号,指示那个按键被按下。

1.5. 程序设计

本实例程序代码如下。

为了能让大家更为直观的理解矩阵键盘的扫描原理,本例的代码非常详细的列出了整个矩阵键盘的行列扫描过程,没有采用更简洁的编程方法。

#include<AT89X51.h> //

sbit P34=P3^4; //端口引脚定义

sbit P35=P3^5; //

sbit P36=P3^6; //

sbit P37=P3^7; //

//共阳极数码管段码表,0~9,A,b,c,d,E,F,H,P

unsigned char code Tab[ ]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,

0x88,0x83,0xc6,0xa1,0x86,0x8e,0x89}; //

//定义键值的全局变量

unsigned char keyval;

//延时函数

void led_delay(void)

{

unsigned char j;

for(j=0;j<200;j++)

;

}

//数码管显示键值

void display(unsigned char k)

{

P0=Tab[k]; //键值送数码管显示

led_delay(); //延时

}

// void delay20ms(void)

{

unsigned char i,j;

for(i=0;i<100;i++)

for(j=0;j<60;j++)

;

}

void main(void)

{

EA=1; //总中断开启

ET0=1; //定时器T0中断开启

TMOD=0x01; //定时器T0工作方式1

TH0=(65536-500)/256; //定时器初值

TL0=(65536-500)%256; //定时器初值

TR0=1; //开启定时器

keyval=0x00; //键值初始化为0

P2=0xFC;//数码管公共端打开,允许显示

while(1)

{

display(keyval); //数码管显示键值

}

}

//定时器T0中断服务程序

void time0_interserve(void) interrupt 1 using 1

{

TR0=0; //进中断后,先关闭定时器

P3=0xf0; //行线电平全部置低电平,列线全部置高电平

if((P3&0xf0)!=0xf0) //如果列线中有低电平,说明有键被按下

delay20ms(); //延时,消除按键抖动

if((P3&0xf0)!=0xf0) //消抖后仍有列线为低电平,则认为确实有按键按下

{

//扫描第一行

P3=0xfe; //行线第一行置低电平,

if(P34==0) //第一列为低电平,则第一行第一列的按键按下

keyval=1; //按下的按键的键值

if(P35==0) //第二列为低电平,则第一行第二列按键按下

keyval=2; //键值

if(P36==0) //第三列为低电平,则第一行第三列按键按下

keyval=3;

if(P37==0) //第四列为低电平,则第一行第四列按键按下

keyval=4; //

//扫描第二行

P3=0xfd;

if(P34==0)

keyval=5;

if(P35==0)

keyval=6;

if(P36==0)

keyval=7;

if(P37==0)

keyval=8;

//扫描第三行

P3=0xfb;

if(P34==0)

keyval=9;

if(P35==0)

keyval=10;

if(P36==0)

keyval=11;

if(P37==0)

keyval=12;

//扫描第四行

P3=0xf7;

if(P34==0)

keyval=13;

if(P35==0)

keyval=14;

if(P36==0)

keyval=15;

if(P37==0)

keyval=16;

}

TR0=1; //重启定时器

TH0=(65536-500)/256; //定时器赋初值

TL0=(65536-500)%256; //

}

1.6. 实例仿真

编写程序代码,编译生成HEX文件,将HEX文件装载到proteus电路的单片机中,开始仿真,通过按下不同的按键观察数码管显示的键值。

1.7. 总结

通过本实例,我们了解了如何用较少的按键实现矩阵键盘的按键识别。这为我们以后学习如何节约I/O端口打下了基础。

单片机编程好学吗?单片机初学者怎样看懂代码?

单片机在很多人看来好像门槛很高,在某些人看来很简单。

所以,单片机编程好不好学,这取决于谁去学,有没有基础,有没有兴趣。

我自己是通过自学学会的,我个人认为相对java那些纯软件,单片机比较好学。

单片机编程只需要学习C语言,很多人也会把汇编也学了,但是实际产品开发汇编一般用的还是比较少。

反正我从来没用汇编做过项目,所以只需要学习C语言就可以了。

至于单片机嘛,入门51的单片机也很简单,就是看手册配置单片机的寄存器而已。

就像你买一个冰箱,它配一个说明书给你,教你怎么用。

学习编程的过程才是最枯燥,连续看1个月视频,敲一个月的代码,只能在屏幕前显示冷冰冰一些字符。

而单片机则有趣得多,你只要会C语言入门语句,再加一点单片机寄存器配置就能点亮电路板上的一个灯。

这个时候你会更有成就感,感觉你学的东西可以很快看到成果,很快你天马行空的脑袋就会去思考,我怎么用程序控制家里的灯打开和关闭。

有了这些想法以后,你就更有动力去学习,把自己的想法变现。

所以很多时候,我经常对学员说,只要你有兴趣,其实最后你是玩会单片机的

就像我们玩游戏,只要有兴趣,我相信一个小学生都能玩得很好。

单片机初学者怎么看懂代码?

在看代码之前,我们首先要背下C语言的一些关键词和语句都有什么作用,这是基础,这一步没做到,不要想着能看懂代码。

那是不是知道C语言所有关键词和语句就一定能看懂代码呢?

答案肯定是不一定的,一段代码就是一个功能,如果你不了解功能的情况下看代码,你会越看越迷茫。

一般我看代码的正确流程是:

1. 先搞懂功能原理,然后思考如果是我的话,我会怎么去写,我会先尝试着用自己的思维去实现一下代码,只有写的时候你才会发现问题。

2. 抱着这些问题去研究别人的代码,看下别人的实现思路。

3. 如果有条件,可以尝试改改别人的代码,调试一下会有什么反应。

做到以上三步,基本上你就能吃透别人的代码。

学会看懂别人的代码是一项非常重要的能力,我的编程水平都是这样去提升的。

很多时候虽然你重写代码也能实现同样的功能,但是其中涉及到2个东西会直接影响整个产品的稳定性和效率。

1.代码架构

2.代码算法

代码架构 决定你的程序移植性和可扩展性,同时也会影响做出来产品的稳定性。

关于程序架构这块,一般需要经过大量的实际项目沉淀,才能知道实际产品开发当中的痛点,才会理解架构的重要性。

所以我在19年录制了一套专门针对单片机C语言的程序架构,架构采取模块化编程,内核文件负责任务调度,并提供任务创建和管理接口。

还有就是队列算法,回调函数等等,通过使用c语言高级语法的一些技巧来解决产品可扩展性和移植性的问题。

这个教程也是无偿给大家看的,需要的找无际单片机编程领取。

如果对大家有帮助的话,就给我来个鼓励(赞)就行了,不然下次没什么动力分享这些有价值的东西了,浪费时间又没好处对吧?哈哈哈。

代码算法 决定你的程序执行的效率,举个例子,右移运算也能当除法去,并且执行的机器周期比除法运算短。

这两个概念主要体现在中大型的项目上,如果你的项目是51单片机级别的,基本上可以忽略,因为芯片的资源有限,你想做出好的架构,芯片的ROM都不够用。

相关问答

请以 51单片机 内部三总线详细描述一下STM32 D- Code I- Code 总线区别以及是怎么工作的并解释APB AHB工作原理?

强劲。...其实,这些东西怎么工作的,原理是怎么样,怎么使用更高效等等这些问题,都不需要我们关心。毕竟这么核心的东西,除非厂家将要放弃这款架构的研究,然后...

code 是什么数据?

code是keilC51里面的关键字,一般用于定义常量数组,意思是告诉编译说把这个数组放在ROM存储。code的作用是告诉单片机,定义的数据要放在ROM(程序存储区)里...

c 51 的数据类型""idata, code ,xdata,pdata""各对应at89s 51单片机 的哪些存储空间?

idata对应于内部RAM00H~FFHcode对应于程序存储器的0000H~1FFFH(8K)如果扩展可寻址64K。使用MOVCxdata对应于外部RAM0000H~FFFFH(需要...

code 正确使用方法?

在单片机使用C语言进行编程的时候,经常使用到code。code是keilC51(也就是说,在其它的编译器中可能是其它形式,例如IAR中的CODE)里面的关键字,一般用于定义...

51单片机 串口通讯代码和校验怎么弄,最好有现成的程序我参考一下?

可以用串口通讯模式3来收发。这是9位数据的收发模式,第九位可以作为奇偶校验位。发送如下:SPOUT:MOVC,P;奇偶位送CMOVTB8,C;送发送位MOVSBUF,A;发...

51单片机 编程方法?

1.定义的变量不要太多。低128位为用户定义变量的存放区域(默认时),也可以把变量放在高128位,但容易出错,尽量少放,最好不放。通过*.M51可以查看内存变量的存...

51单片机 定时器代码怎么写?

51单片机定时器代码要根据具体需求来编写。原因解释:1.51单片机定时器可以定时触发中断请求,为外设或者执行特定程序提供时间标准,而具体编写的代码要根据实...

51单片机 所有伪指令?

MCS-51单片机常用伪指令一)符号定义伪指令符号定义名用法说明EQU为常量,符号名...MCS-51单片机常用伪指令一)符号定义伪指令符号定义名...

51单片机 怎么将hex代码下载去单片机?

回答如下:要将hex代码下载到51单片机中,需要使用一个编程器,如STC-ISP、USBISP等。下面是一些大致的步骤:1.将编程器与电脑连接,并安装驱动程序。2.将51...

51单片机 C语言 如何写代码。控制2个LED的亮和灭。

[最佳回答]比如你的8个灯连在P0口,如果是阴极的你只要先定义sbitP0^0=LED0;.....一定定义下去然后再定义一个按钮比如P1.1sbitP1^1=key;代码里写12...

猜你喜欢