当前位置: 移动技术网 > 网络运营>网络>协议 > 51单片机Proteus仿真+Keil工程-实验2-按键-数码管

51单片机Proteus仿真+Keil工程-实验2-按键-数码管

2020年08月12日  | 移动技术网网络运营  | 我要评论
实验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等单片机任何一个端口想要获得较大的驱动能力,必须采用低电平输出。
  时钟晶体振荡频率为fosc=12MHZf_{osc}=12MHZ
  时钟周期相当于Tosc=1fosc83.33nsT_{osc}=\frac{1}{f_{osc}} \approx 83.33ns
  复位电路的话通过给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

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网