51单片机Proteus仿真+Keil工程-实验2-按键-数码管
程序员文章站
2022-06-21 20:54:18
实验2-单片机数码管按键实验(Proteus仿真+Keil工程):51单片机连接4x4矩阵按键外设,使用矩阵反转扫描方法,按下不同按键,在8段数码管上面显示0~F,十六个按键值。...
实验2-单片机数码管和按键实验
之前做的一次实验,51单片机通过按键控制单个数码管。如有问题欢迎指正。
实验目标:
通过建立4x4矩阵按键在8段数码管上面显示0~F,十六个按键值。
Proteus原理图
选择元器件:
DEVICES | 说明 |
---|---|
7SEG-COM-ANODE | 1位共阳极数码管 |
AT89C51 | MCU |
BUTTON | 按键 |
CAP | 普通电容 |
CAP-ELEC | 电解电容 |
CRYSTAL | 晶振 |
LED-BLUE | 蓝色LED灯 |
RES | 电阻 |
RESPACK-8 | 排阻 |
51单片机的P0口做IO口使用时是漏极开路输出,其引脚一般需要在片外接一定阻值的上拉电阻,此时端口不存在高阻抗的悬浮状态,因此它是一个准双向口。同时,P0口每一位的驱动能力是P1~P3口的两倍,每位可以驱动8个LSTTL(Low-power Schottky TTL,即低功耗肖特基TTL)输入,89C51等单片机任何一个端口想要获得较大的驱动能力,必须采用低电平输出。
时钟晶体振荡频率为
时钟周期相当于
复位电路的话通过给89C51等单片机的复位引脚RST加上大于2个机器周期的高电平(即24个时钟振荡周期)就可以使单片机复位。
KEIL工程:
主函数:
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define SegPort P0
#define KeyPort P1
#define TIME 1000 /*延时常量(ms)*/
#define SHAKING_TIME 10 /*消抖时间(ms)*/
uchar code seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};/*0123456789abcdef*/
void delay(uint i);
void display_digitron(uchar num);
uchar KeyScan(void);/*键盘扫描函数1*/
uchar KeyPro(void); /*键值返回函数1*/
void main(void)
{
uchar num;
while(1)
{
/*使用函数1*/
num=KeyPro();
if(num!=0xff)
{
display_digitron(num);
}
/*使用函数2:存在问题*/
}
}
void delay(uint i)
{
uchar t;
while(i--)
{
for(t=0;t<120;t++);
}
}
我使用了两种控制方法,分别是矩阵反转扫描,行扫描,状态量扫描(有bug),放上了比较简洁的矩阵反转扫描。
数码管显示函数:
void display_digitron(uchar num)
{
SegPort=seg[num];
}
键盘扫描函数:
/*键盘扫描函数,使用行列反转扫描法*/
uchar KeyScan(void)
{
unsigned char cord_h,cord_l;//行列值中间变量
KeyPort=0x0f; //行线输出全为0
cord_h=KeyPort&0x0f; //读入列线值
if(cord_h!=0x0f) //先检测有无按键按下
{
delay(SHAKING_TIME); //去抖
if((KeyPort&0x0f)!=0x0f)
{
cord_h=KeyPort&0x0f; //读入列线值
KeyPort=cord_h|0xf0; //输出当前列线值
cord_l=KeyPort&0xf0; //读入行线值
while((KeyPort&0xf0)!=0xf0);//等待松开并输出
return(cord_h+cord_l);//键盘最后组合码值
}
}return(0xff); //返回该值
}
按键处理函数:
/*按键处理函数1,返回键值*/
uchar KeyPro(void)
{
switch(KeyScan())
{
case 0x7e:return 0;break;//0 按下相应的键显示相对应的码值
case 0x7d:return 4;break;//4
case 0x7b:return 8;break;//8
case 0x77:return 12;break;//c
case 0xbe:return 1;break;//1
case 0xbd:return 5;break;//5
case 0xbb:return 9;break;//9
case 0xb7:return 13;break;//d
case 0xde:return 2;break;//2
case 0xdd:return 6;break;//6
case 0xdb:return 10;break;//a
case 0xd7:return 14;break;//e
case 0xee:return 3;break;//3
case 0xed:return 7;break;//7
case 0xeb:return 11;break;//b
case 0xe7:return 15;break;//f
default:return 0xff;break;
}
}
参考文献
1.《单片机原理与接口技术》张毅刚
返回目录
本文地址:https://blog.csdn.net/qq_43353985/article/details/107939728