51单片机数码管静态与动态显示

数码管简述

在这里插入图片描述
这是一个数码管内部电路原理图,ah每个数字代表一个发光二极管,v是公共端,可以接地或者电源,对应共阴极和共阳极接法。ag段数码管用来显示数字,h显示小数点。为了便于封装,数码管的外部一共10个引脚,5和10连在一起接公共端,其余各对应一个发光二极管:
在这里插入图片描述
例如,如果我们想显示数字“0”,那么就需要a~f这六个数码管亮;如果显示数字“1”,那么就需要b、c两个数码管点亮,以此类推。一般情况下,单片机的IO口和数码管的连接方式如下:
在这里插入图片描述
如果我们将数码管接到P1口上,显示数字“0”的话,那么P1口的八个引脚电平(共阴极数码管)应为:0011 1111转换成二进制就是P1=0x3f,如果是共阳极数码管,则P1=~0x3f,按位取反就可以。如果我们想让小数点显示出来,那么应该将P0.7置1(共阴极),对应引脚电平为1000 0000,二进制0x80,为了简便,我们直接参与按位或的方式,即:
P1=(0x3f|0x80) 共阴极 P1=~(0x3f|0x80) 共阳极
设计实例(数码管静态显示)
Proteus中的数码管有几种形式:内置编码器的数码管、七段数码管(共阴极、共阳极)、八段数码管(共阴极、共阳极),我们分别看一下:
1、 带有编码器的数码管:
在这里插入图片描述
一共四个引脚,最右边是低位,最左边是高位,直接将对应数据的16进制输入即可,例如我们将上图数码管四个管脚由右边到左边依次接P1.0~P.3,如果我们想显示0的话,P1=0x00,显示1的话P1=0x01以此类推。这种数码管使用方便,但是没有使能端,一般只用作静态显示。
2、 七段数码管(共阴极为例)
在这里插入图片描述
七段数码管一共七个数据端口,还有一个公共使能端,也叫做位选端。对于共阴极数码管,当公共端接低电平时候,数码管才可以正常工作。七个数据端口上为最低为、下边为高位,接单片机的IO口。例如,单片机的P1.0~P1.1依次接数码管的七个数据端,如果显示0,那么P1=0x3f,以此类推。
3、 八段数码管(以共阳极为例)
在这里插入图片描述
Proteus中八段数码管如图,有八个数据位(第七位同七段数码管,第八位为小数点),由一个位选端。如果想显示数字0,我们没有必要去推导每一位,直接按照共阴极按位取反,即P1=0x3f,即为共阳极数码管显示数字0的方法。如果想显示小数点,直接按位或0x80,即P1=(0x3f|0x80),此时显示的即为数字0加小数点。
小福利
共阴极七段数码管0~F的编码:

unsigned char code t_display[]={      
0x3F, 0x06, 0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};

实例2 数码管动态显示
不知道大家看完上边的例子有没有想过,一个数码管需要单片机一个IO口的7~8个引脚,那么两个、三个呢,如果这么算,一个单片机只能驱动四个数码管,除此之外什么也干不了,那你可就小看单片机了,接下来就介绍一下51单片机数码管的动态显示。
首先看一下Proteus中的数码管:
在这里插入图片描述
四个数码管的段选端口是连接在一起的(AG,DP端口是小数点的显示);1、2、3、4是位选信号。如果我们将段选信号输入到端口,那么所有的数码管显示的数字是一样的,这不是我们想要的效果,所以就需要用到位选信号14,每次只让一个位选信号使能,其他三个就禁止。可是这样你会觉得,每次只有一个数码管显示啊,对的,每个时刻确实只有一个数码管显示,但是下一时刻我们就切换要显示的数字,然后换一个数码管显示,这样的效果就是看到四个数码管轮流显示,每次显示的数字不一样,还不是我们想要的效果。那如果我们将每个数码管切换的时间间隔缩小呢,比如,10ms,这个间隔肉眼是无法分辨出来的,这就是数码管动态显示的原理!我们直接上干活:
数码管动态显示Proteus仿真电路图:
在这里插入图片描述
然后是代码,有详细注释哦~

#include <reg51.h>
unsigned char num,num2=0;//num用于计数,刷新数码管,num2用于选择要显示的数字
unsigned char code display[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//数码
unsigned char com[]={0x01,0x02,0x04,0x08};//位选地址

void main()
{
	TMOD=0x01;//设置定时器0工作方式1
	TH0 = (65536-917)/256;		//1ms延时初值计算
	TL0 = (65536-917)%256;;		
	EA=1;//开总中断
	ET0=1;//定时器0中断
	TR0=1;//开始计时
	while(1){
		if(num==10){  //定时器中断10次,也就是10ms
			num=0;  //清零
			P1=~com[num2];//送入位选信号
		  P2=0xff;//消影
		  P2=display[num2];//送入段选信号
			num2++; //num2=0~3,四个数码管轮流显示。
			if(num2>=4)
			num2=0;
		}
	}
}

void Timer0() interrupt 1  //定时器中断
{
  TH0 = (65536-917)/256;	//重新赋值
TL0 = (65536-917)%256;;	
num++;//
}

然后就是一个使用点的例子,实现59s的计时,电路图和上边是一样的,直接上代码:

#include <reg51.h>

unsigned char code display[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
unsigned char com[]={0x01,0x02,0x04,0x08};

unsigned char num,num2=0,time[4];
unsigned int num3;


void main()
{
	TMOD=0x01;
	TH0 = (65536-917)/256;		
	TL0 = (65536-917)%256;;		
	EA=1;
	ET0=1;
	TR0=1;
	time[0]=0;
	time[1]=0;
	time[2]=0;
	time[3]=0;
	while(1){
		if(num==10){		
			num=0;
			P1=~com[num2];
		  P2=0xff;
		  P2=display[time[num2]];
			num2++;
			if(num2>=4)
			num2=0;	
		}
	   	
			if(num3==1000)//计数1000次,计时1s
			{
				time[3]++;//更新第四位
				if(time[3]>=10)
				{
					time[3]=0;
					time[2]++;//更新第三位
					if(time[2]>=6)
						time[2]=0;
				}
				num3=0;
			}
	}
}

void Timer0() interrupt 1
{
  TH0 = (65536-917)/256;		
	TL0 = (65536-917)%256;;	
	num++;
	num3++;
}

主要程序和上边是一样的,多了一部分计时1s的程序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值