四乘四键盘显示

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

四乘四键盘显示
一、设计要求
4*4矩阵键盘共16个键,每按一次键,数码管就显示一次按键代表的值。

二、元件选取
单片机:STC89C52RC;电阻:470Ω;发光二极管;4*4键盘;共阳极七段数码管
三、设计思想
本设计硬件上采用STC89C52RC单片机的最小系统,单片机的P1口与键盘相连,P1.0—P1.3管脚分别与键盘的四行连接,P1.4—P1.7管脚分别与键盘的四列相连;P0口P1.0—P1.7管脚与数码管1的a—dp相连,P2口P2.0—P2.7管脚分别与数码管2的a—dp相连,数码管的公共端接+5V电源,控制数码管的显示;发光二极管的阴极与单片机的P3.0管脚连接,阳极与+5V电源连接,低电平有效,控制二极管发光;
程序上采用定时扫描方式,利用定时T0产生50ms定时中断,CPU响应中断后进入Scan_Key()子程序对键盘进行扫描,对P1口初值0xf7扫描第一行,进入延时程序消抖动后,进入switch()语句,屏蔽行的低四位,取列的高四位,检测哪一列有键按下,若有键按下,标志位FLAG0=1,发光二极管的到低电平发光;令P1口的初值右移一位后或0x80进行高位补一,扫描第二行,如此循环右移,四行便全都检测到了。

当有键按下时,m!=0xf0,进入while循环不停地执行m&0xf0语句,使m=0xf0;按键松开后,m=0xf0跳出while循环,执行中断程序,显示按键的值。

如此软件与硬件结合,能合理的完成设计要求,每按一次键,数码管就显示一次按键代表的值。

四、原理图
四、程序流程
五、调试过程
调试过程中,遇到了以下问题:一是数码管不能正常显示,经检查是数码管公共端未接电源,连接后数码管还是不能正常显示,经检查是单片机接触不良,将单片机拔出,对照底座重新插入,然后在仿真数码管显示正常;二是发光二极管在按键按下后不能正常发光,经检查是软件编程存在缺陷,定时时间短,单片机接收不到二极管的低电平,故不发光。

经改进后,将二极管管脚赋低电平的语句嵌入到键盘扫描程序中,二极管工作正常。

六、程序清单
#include<reg52.h>
#define RELOAD_H ( 65536-50000)/256; //定义定时器0重装值
#define RELOAD_L ( 65536-50000)%256;
extern void Timer0_Init(void); //定时器初始化子函数
extern void Delay(unsigned int n);
extern void Scan_Key(void);
unsigned char dispcode[2];
unsigned char dofly[16];
unsigned char ptr,m;
unsigned int t,c;
bit FLAG0=0; //定义是否有键按下
sbit Beep = P3^0; //发光二极管管脚
void main(void)
{
Timer0_Init();
while(1)
{
Scan_Key(); //扫描键盘
void Timer0_Init(void) //定时器0初始化
{
TMOD=0x01; //定时器0,方式1
TL0=RELOAD_L; //TL0定时器0低8位计数器TH0=RELOAD_H; //TH0定时器0高8位计数器TR0=1; //定时器/计数器0启动位.
//TR0=1:开始计时或计数
ET0=1; //定时器/计数器0中断使能
EA=1; //全局中断使能
}
void Timer0_ISR(void) interrupt 1 //定时器0中断服务程序
{
P0=dofly[c];
P2=dofly[t];
TL0=RELOAD_L; //定时器0初值重装
TH0=RELOAD_H;
}
void Delay(unsigned int n) //延时
{
unsigned int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<80;j++);
unsigned char dofly[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //数码管显示程序
void Scan_Key(void) // 键盘扫描程序
{
char a1,i;
bit FLAG0=0;
a1=0xf7; //列扫描初值
ptr=0;
for(i=0;i<4;i++) //键盘4个扫描列
{
P1=a1;
Delay(10);
m=P1;
switch(m&0xf0) //取行的高4位,侦测哪一行有按键被按下
{
case 0x70: ptr=i*4; //第一行被按否? 如有则是tab[i*4]键
FLAG0=1; Beep=0; //表示有按键
break;
case 0xb0: ptr=i*4+1; //第二行被按否? 如有则是tab[i*4+1]键
FLAG0=1; Beep=0;
break;
case 0xd0: ptr=i*4+2; //第三行被按否? 如有则是tab[i*4+2]键
FLAG0=1; Beep=0;
break;
case 0xe0: ptr=i*4+3; //第四行被按否?如有则是tab[i*4+3]键
FLAG0=1; Beep=0;
break;
default:break;
}
a1=(a1>>1)|0x80;
while(m!=0xf0)
{
m=P1;
m=m&0xf0;
}
}
Beep=1;
if(FLAG0)
{
dispcode[0]=ptr % 10; //求个位的数值
dispcode[1]=ptr / 10; //求十位上的数值
c=dispcode[0];
t=dispcode[1];
}
}。

相关文档
最新文档