51系列单片机学习:数码管


前言

数码管在现实生活中无处不在,如何实现数码管按要求显示是本文的重点。通过本文的学习,你将更清晰的了解数码管的电路结构,掌握如何编写数码管的段码表等技术。


一、数码管是什么?

数码管内部其实就是由多个LED按一定位置进行分布,最终实现数字化显示。数码管分为两种类型,一种是共阴数码管即公共端为GND。另一种为共阳数码管即公共端为VCC。具体的电路如图1所示。其实我们在真正使用的时候,你只需要把他们考虑成普通的LED灯即可,LED灯的正极接哪里,负极接哪里,只要LED灯两端的电压大于导通电压即可点亮。
在这里插入图片描述图1 数码管共阴共阳电路

二、数码管段选

1.对于任何数码管,在计算段码表时,只需要考虑数码管中ABCDEFGdp
的连接和对应数码管PCB封装。如果大家在设计原理图时,未考虑购买的元器件封装的问题,很有可能就需要再次修改段码表,否则容易出现显示问题。比如原理图如图2所示,原理图的A端口在7号引脚,但是PCB的7号引脚是B端口,那么之前按照原理图设计的段码表就需要修改。正确的PCB图应该如图3所示。
在这里插入图片描述
图2 共阳数码管电路图
共阳数码管PCB图
图3 共阳数码管PCB图
3.如何编写段码表
根据数码管的LED灯段选走向,如图4所示。如果要显示数字“0”,则需要abcdef都点亮;如果要显示数字“1”,则需要bc点亮;如果要显示数字“2”,则需要abged点亮。其他数字和字符显示大家有空可以自行排布,这里不过多解释。
数码管LED灯段选
图4.数码管段选
4.由于a~dp的引脚都需要与单片机的IO口进行连接,因此只需要考虑数码管是共阴还是共阳。如果是共阳,那么连接a-dp引脚需要是低电平即可点亮。此处列一些常见的段码表。
unsigned char code smg[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E, 0xBF,0xFF}; //共阳数码管段码表0-F、-、熄灭
unsigned char code smg[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x76,0x40,
0x00}; //共阴数码管段码表0-F、-、熄灭

三、数码管位选

1.对于1位数码管,则不需要考虑位选。
2.对于2位及以上数码管,则需要考虑数码管位选。假设是4位数码管,电路原理图如图5所示,如果段选已经设置好了,但是给哪个数码管则需要由段选来控制了。比如只要显示DIG4处的数码管,则需要让P20所连接的8550三极管导通即可,要使8550PNP管导通,P20只需要低电平即可且P21-23都为高电平。同理,只要显示DIG3处的数码管,则只需要P21为低电平且P20、P22和P23为高电平。其他数码管点亮就不再赘述了。
3.如果我们需要显示4位数,那么需要将4位数拆分成4个1位数,比如4位数拆成千位是多少,百位是多少,十位是多少,个位是多少。接下来写一个for循环,依次点亮即可。
在这里插入图片描述
图5.四位数码管电路图

四、具体代码实现

1.一位数码管循环显示0-9

具体代码如下:

/**
一、硬件连接
1.P0接共阳数码管的数据位

二、功能实现
1.数码管循环显示0-9
*/
#include <REGX52.H>

void delay(unsigned int Xms);//延时函数声明

unsigned char code smg[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,
0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xBF,0xFF}; //共阳数码管段码表

void main()
{
	unsigned char i;
	while(1)
	{
		for(i=0;i<10;i++)
		{
			P0=smg[i];
			delay(1000);			
		}		
	}
}

//延时函数定义
void delay(unsigned int Xms)
{
	unsigned int i,j;
	for(i=Xms;i>0;i--)
		for(j=124;j>0;j--);	
}

2.数码管时钟显示

具体代码如下:

/**
一、硬件连接
1.P0接共阳数码管的数据位
2.P20-P23接4位数码管的位选端
二、功能实现
1.简易时钟
*/
#include <REGX52.H>
#define DataPort P0
#define smg_wei_H_2 P2_3
#define smg_wei_H_1 P2_2
#define smg_wei_Min_2 P2_1
#define smg_wei_Min_1 P2_0

unsigned char time_h,time_min,time_s;

/*共阳数码管段选*/
unsigned char SMG_D[]={0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90,0xff};

/*缓存*/
unsigned char Buff[]={8,8,8,8};

/*函数定义*/
void delay(unsigned int Xms);//延时函数声明
void dispaly_Hour();
void dispaly_Min();

/*定时器初始化*/
void Timer0_Init()
{
	TMOD &= 0xF0;			
	TMOD |= 0x01;	
	TL0=0x23;
	TH0=0xFC;				
	TR0 = 1;					
	ET0=1;
	EA=1;
}

void main()
{	
	Timer0_Init();
	time_h=11;
	time_min=42;
	while(1)
	{		
		Buff[0]=time_h/10;
		Buff[1]=time_h%10;//取余代表取余数,11/10=1;11%10=1;
		dispaly_Hour();
		Buff[2]=time_min/10;
		Buff[3]=time_min%10;//取余代表取余数,42/10=4;42%10=2;
		dispaly_Min();		
	}
}

/*定时器中断*/
void Time0_Routine() interrupt 1
{
	static unsigned int count;
	TL0=0x23;
    TH0=0xFC;
	count++;	
	if(count==1000)
	{
		count=0;
		time_s++;
		if(time_s==60)
		{
			time_s=0;
			time_min++;
			if(time_min==60)
			{
				time_min=0;
				time_h++;
				if(time_h==24)
				{
					time_h=0;
				}
			}
		}
	}
}

//延时函数定义
void delay(unsigned int Xms)
{
	unsigned int i,j;
	for(i=Xms;i>0;i--)
		for(j=124;j>0;j--);	
}

/*数码管显示函数*/
void dispaly_Hour()
{
	DataPort=SMG_D[Buff[0]];//小时十位
	smg_wei_H_1=1;smg_wei_H_2=0;smg_wei_Min_1=1;smg_wei_Min_2=1;
	delay(2);
	
	DataPort=SMG_D[Buff[1]];//小时个位
	smg_wei_H_1=0;smg_wei_H_2=1;smg_wei_Min_1=1;smg_wei_Min_2=1;
	delay(2);
}
void dispaly_Min()
{
	DataPort=SMG_D[Buff[2]];//分钟十位
	smg_wei_Min_1=1;smg_wei_Min_2=0;smg_wei_H_1=1;smg_wei_H_2=1;
	delay(2);
	
	DataPort=SMG_D[Buff[3]];//分钟个位
	smg_wei_Min_1=0;smg_wei_Min_2=1;smg_wei_H_1=1;smg_wei_H_2=1;
	delay(2);
}


总结

以上就是今天要讲的内容,本文详细的介绍了数码管的使用,通过两个简单的案例讲解了数码管的段选如何设置和位选如何调用。案例2中使用了定时器T0,后续会详细讲解定时器的知识点。如果觉得不错记得点个赞哦!谢谢大家。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值