一、实验目的
- 理解数码管动态显示工作原理并掌握数码管动态显示编程方法
- 理解单片机检测按键的工作原理并掌握检测键盘的编程方法
二、实验要求
设计并调试矩阵键盘程序:实现一个4×4矩阵键盘,编号顺序为先行后列,即1行1列为0号键,1行2列为1号键……依次类推,共15号键。检测到按键后,两位数码管显示键号。如:按下第2行第1列键,数码管显示04。
电路图如下:
实验分析
该实验用的是矩阵键盘来控制动态数码管显示的数字,标号0-15的按键对应两位数码管上0-15的数字。
首先我先创建了一个GETNUMBER的的头文件,对于获取数字的函数声明,再在相应的.c文件中进行定义。由上图,我是将P1口的第四位来控制行的开关,再由P1的高四位来控制列的开关,当行列同时输入0导通时,该开关被按下并接通。
这里的MatrixKey中return KeyNumber的值。
如上图,先将P1全置1阻塞,然后打开第一行的开关,再依次执行四个导通列开关的语句,依次控制同一行上的四个按键。同理,第二,三,四行都像第一行这样子来操作,最后返回KeyNumber的值,这里的Delay函数起到消影的作用。然后再在main函数当中定义一个KeyNum = MatrixKey(),来接收KeyNumber的值。再在main.c的运行文件中建立一个test函数,在此之前我们再设置一个table数组,里面依次是用十六进制表示的0-9的数字。我们可以用table[KeyNum/10]来表示十位数,table[KeyNum%10]来表示动态数码管上的个位数,从而实现了动态数码管上的数字显示。
我们再从图中的观察一下74HC573这个锁存器,标号为U2的74HC573锁存器是控制数码管的段选,是用来表示具体数字的。而标号为U3的74HC573孙存其是控制数码管的位选,用来选择接通哪个位。P3_2口接的是段选,P3_3口接的是位选,可以给他们取个别名。
再来介绍一下74HC573这个锁存器及其作用。
由真值表中可以看出,Output Enable为高电平时,无论Latch Enable与D端为何种电平状态,其输出都为高阻态,此时芯片处于不可控状态。所以在设计电路是我们直接将Output Enable接地,也就是74HC573一直处于使能状态。
当Output Enable为低电平,且Latch Enable为高电平时,D与Q同时为H或L。当Latch Enable为低电平时,无论D为何种电平,Q都保持上一次的数据状态。
锁存器就是把当前的状态锁存起来,使输入的数据在接口电路的输出端保持一段时间锁存后状态不再发生变化,直到解除锁存。锁存引脚高电平表示直通状态,为低电平表示锁存状态,可以通过控制锁存引脚,控制74HC573后端输出数据。
在第一个数码管显示中,这里的dula=1,接通段选位,给段选位输入段选位的值,再dula=0将其锁存起来。再wela=1接通位选,P2=0XFE,是把第一个数码管接通,存入P2的值,再wela=0,保存P2的数值到十位数。这里的wela=1,P2=0XFF,wela=0的操作是用来消影的。
完整代码如下:
main.c
#include <REGX52.H> #include "DELAY.H" #include"GetKeyNum.h" sbit dula=P3^2; //P3_2与P3_3两个引脚会高收益两片74HC573本次显示数据是给他们谁的 sbit wela=P3^3; //谁能到使能信号谁就接受本次的显示数 unsigned char table[]={ 0X3F, 0X06, 0X5B, 0X4F, 0X66, 0X6D, 0X7D, 0X07, 0X7F, 0X6F }; unsigned char KeyNum=0; void test01() { KeyNum = MatrixKey(); //第一个数码管 dula=1; //p3_2 P2=table[KeyNum/10]; dula=0; wela=1; //P3_3 P2=0XFE; //1111 1110选中第一个数码管 wela=0; Delay1ms(1); wela=1; P2=0XFF;//消影 wela=0; //第二个数码管 dula=1; P2=table[KeyNum%10]; dula=0; wela=1; P2=0XFd; //1111 1101选中第二个数码管 wela=0; Delay1ms(1); wela=1; P2=0XFF;//消影 wela=0; } void main() { while(1) { test01(); } }
Delay.c
#include "DELAY.H" void Delay1ms(unsigned int xms) //@12.000MHz { unsigned char i, j; while(xms--) { i = 2; j = 239; do { while (--j); } while (--i); } }
Delay.h
#ifndef __DELAY_H__ #define __DELAY_H__ #include <REGX52.H> void Delay1ms(unsigned int xms); #endif
GetKeyNum.h
unsigned char MatrixKey();
GetKeyNum.c
#include"DELAY.H" #include"GetKeyNum.h" unsigned char MatrixKey() { unsigned char KeyNumber=0; P1=0XFF; P1_0=0; if(P1_4==0){Delay1ms(20);KeyNumber=0;} if(P1_5==0){Delay1ms(20);KeyNumber=1;} if(P1_6==0){Delay1ms(20);KeyNumber=2;} if(P1_7==0){Delay1ms(20);KeyNumber=3;} P1=0XFF; P1_1=0; if(P1_4==0){Delay1ms(20);KeyNumber=4;} if(P1_5==0){Delay1ms(20);KeyNumber=5;} if(P1_6==0){Delay1ms(20);KeyNumber=6;} if(P1_7==0){Delay1ms(20);KeyNumber=7;} P1=0XFF; P1_2=0; if(P1_4==0){Delay1ms(20);KeyNumber=8;} if(P1_5==0){Delay1ms(20);KeyNumber=9;} if(P1_6==0){Delay1ms(20);KeyNumber=10;} if(P1_7==0){Delay1ms(20);KeyNumber=11;} P1=0XFF; P1_3=0; if(P1_4==0){Delay1ms(20);KeyNumber=12;} if(P1_5==0){Delay1ms(20);KeyNumber=13;} if(P1_6==0){Delay1ms(20);KeyNumber=14;} if(P1_7==0){Delay1ms(20);KeyNumber=15;} return KeyNumber; }
我也是新手小白,若哪里有错,还请大佬指点一下。也请大家帮忙点点赞,阿里嘎多。