51单片机入门——动态数码管显示详解

   日期:2020-08-31     浏览:198    评论:0    
核心提示:51单片机:动态数码管显示- 模块图- 显示原理– 消抖静态数码管技术 + 人眼视觉停留显示原理类似于以前的 胶片机放影视,也就是只要我切换的速度足够快你就看不出来其实我是一次次显示的(滑稽)影视中为了流畅,我们的最低帧数为24帧,即每秒钟放24张影视图和24张黑屏,那么一张图片的周期为 T = 1s/(24+24) = 20.8ms。而在动态数码管的显示中,假设我们为8数码管,则一张视图应该是8个数码管共同的时间,即应该在原来周期上除以8, T = 1s/(24+24)/8 = 2.6m

51单片机:动态数码管显示

- 模块图

- 显示原理

– 消抖

静态数码管技术 + 人眼视觉停留
显示原理类似于以前的 胶片机放影视,也就是只要我切换的速度足够快你就看不出来其实我是一次次显示的(滑稽)

影视中为了流畅,我们的最低帧数为24帧,即每秒钟放24张影视图和24张黑屏,那么一张图片的周期为 T = 1s/(24+24) = 20.8ms
而在动态数码管的显示中,假设我们为8数码管,则一张视图应该是8个数码管共同的时间,即应该在原来周期上除以8, T = 1s/(24+24)/8 = 2.6ms

讲了这些能干啥呢?
消抖啊!不然显示出来后就跟影流之主一样。

– 数码管显示


段选控制哪个数码管亮,位选控制数码管显示的值。

– 码表

共阴极数码管码表 = ~共阳极数码管码表
共阴极数码管码表:
unsigned char code table[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

话不多说,上代码:

#include "reg52.h"
#include "intrins.h"

//38译码器A、B、C
sbit sA = P1^0;
sbit sB = P1^1;
sbit sC = P1^2;

//位选控制码表
unsigned char code table[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

//延迟1ms
void delay500us(void)   //误差 0us
{
    unsigned char a,b;
    for(b=71;b>0;b--)
        for(a=2;a>0;a--);
}



//显示八数码管
void showDigital()
{
	int i;
	for(i=0;i<8;i++)
	{
		switch(i)
		{
			case(0):
				sA = 0;sB = 0;sC = 0;break;
			case(1):
				sA = 1;sB = 0;sC = 0;break;
			case(2):
				sA = 0;sB = 1;sC = 0;break;
			case(3):
				sA = 1;sB = 1;sC = 0;break;
			case(4):
				sA = 0;sB = 0;sC = 1;break;
			case(5):
				sA = 1;sB = 0;sC = 1;break;
			case(6):
				sA = 0;sB = 1;sC = 1;break;
			case(7):
				sA = 1;sB = 1;sC = 1;break;
		}
		P0 = table[i+1];
		delay500us();
		P0 = 0x00;
	}
}

void main()
{
	while(1)
		showDigital();
}


稍微再加点小功能:用红外遥控显示静态数码管



#include "reg52.h"
#include "intrins.h"

//38译码器A、B、C
sbit sA = P1^0;
sbit sB = P1^1;
sbit sC = P1^2;

//中断0
sbit IRIN = P3^2;

//接收到的4组数据
unsigned char IrValue[4];
unsigned char Time;

//位选控制码表
unsigned char code table[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

//延迟1ms
void delay500us(void)   //误差 0us
{
    unsigned char a,b;
    for(b=71;b>0;b--)
        for(a=2;a>0;a--);
}



//显示八数码管
void showDigital()
{
	int i;
	if(IrValue[2] == 0x44)
	{
		for(i=0;i<8;i++)
		{
			switch(i)
			{
				case(0):
					sA = 0;sB = 0;sC = 0;break;
				case(1):
					sA = 1;sB = 0;sC = 0;break;
				case(2):
					sA = 0;sB = 1;sC = 0;break;
				case(3):
					sA = 1;sB = 1;sC = 0;break;
				case(4):
					sA = 0;sB = 0;sC = 1;break;
				case(5):
					sA = 1;sB = 0;sC = 1;break;
				case(6):
					sA = 0;sB = 1;sC = 1;break;
				case(7):
					sA = 1;sB = 1;sC = 1;break;
			}
			P0 = table[i+1];
			delay500us();
			P0 = 0x00;
		}
	}
	else if(IrValue[2] == 0x45)
	{
		for(i=0;i<8;i++)
		{
			switch(i)
			{
				case(0):
					sA = 0;sB = 0;sC = 0;break;
				case(1):
					sA = 1;sB = 0;sC = 0;break;
				case(2):
					sA = 0;sB = 1;sC = 0;break;
				case(3):
					sA = 1;sB = 1;sC = 0;break;
				case(4):
					sA = 0;sB = 0;sC = 1;break;
				case(5):
					sA = 1;sB = 0;sC = 1;break;
				case(6):
					sA = 0;sB = 1;sC = 1;break;
				case(7):
					sA = 1;sB = 1;sC = 1;break;
			}
			P0 = table[6];
			delay500us();
			P0 = 0x00;
		}	
	}
	else
	{
		for(i=0;i<8;i++)
		{
			switch(i)
			{
				case(0):
					sA = 0;sB = 0;sC = 0;break;
				case(1):
					sA = 1;sB = 0;sC = 0;break;
				case(2):
					sA = 0;sB = 1;sC = 0;break;
				case(3):
					sA = 1;sB = 1;sC = 0;break;
				case(4):
					sA = 0;sB = 0;sC = 1;break;
				case(5):
					sA = 1;sB = 0;sC = 1;break;
				case(6):
					sA = 0;sB = 1;sC = 1;break;
				case(7):
					sA = 1;sB = 1;sC = 1;break;
			}
			P0 = table[0];
			delay500us();
			P0 = 0x00;
		}	
	}
}


void IrInit()
{
	IT0=1;//下降沿触发
	EX0=1;//打开中断0允许
	EA=1;	//打开总中断

	IRIN=1;//初始化端口
}


void delay(unsigned int i)
{
	while(i--);	
}


void ReadIr() interrupt 0
{
	unsigned char j,k;
	unsigned int err;
	Time=0;					 
	delay(700);	//7ms
	if(IRIN==0)		//确认是否真的接收到正确的信号
	{	 
		
		err=1000;				//1000*10us=10ms,超过说明接收到错误的信号
			
		while((IRIN==0)&&(err>0))	//等待前面9ms的低电平过去 
		{			
			delay(1);
			err--;
		} 
		if(IRIN==1)			//如果正确等到9ms低电平
		{
			err=500;
			while((IRIN==1)&&(err>0))		 //等待4.5ms的起始高电平过去
			{
				delay(1);
				err--;
			}
			for(k=0;k<4;k++)		//共有4组数据
			{				
				for(j=0;j<8;j++)	//接收一组数据
				{

					err=60;		
					while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去
					{
						delay(1);
						err--;
					}
					err=500;
					while((IRIN==1)&&(err>0))	 //计算高电平的时间长度。
					{
						delay(10);	 //0.1ms
						Time++;
						err--;
						if(Time>30)
						{
							return;
						}
					}
					IrValue[k]>>=1;	 //k表示第几组数据
					if(Time>=8)			//如果高电平出现大于565us,那么是1
					{
						IrValue[k]|=0x80;
					}
					Time=0;		//用完时间要重新赋值 
				}
			}
		}
		if(IrValue[2]!=~IrValue[3])
		{
			return;
		}
	}			
}

void main()
{
	IrInit();
	while(1)
	{
		showDigital();
	}
		
}


 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服