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

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

- 模块图

在这里插入图片描述

- 显示原理

– 消抖

静态数码管技术 + 人眼视觉停留
显示原理类似于以前的 胶片机放影视,也就是只要我切换的速度足够快你就看不出来其实我是一次次显示的(滑稽)
在这里插入图片描述
影视中为了流畅,我们的最低帧数为24帧,即每秒钟放24张影视图和24张黑屏,那么一张图片的周期为 T = 1s/(24+24) = 20.8ms
而在动态数码管的显示中,假设我们为8数码管,则一张视图应该是8个数码管共同的时间,即应该在原来周期上除以8, T = 1s/(24+24)/8 = 2.6ms

讲了这些能干啥呢?
消抖啊!不然显示出来后就跟影流之主一样。
在这里插入图片描述

– 数码管显示

在这里插入图片描述
段选控制哪个数码管亮,位选控制数码管显示的值。

– 码表

共阴极数码管码表 = ~共阳极数码管码表
1、共阳:
char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
2、共阴:
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;
		}	
	}
}

/*******************************************************************************
* 函数名         : IrInit()
* 函数功能		   : 初始化红外线接收
* 输入           : 无
* 输出         	 : 无
*******************************************************************************/
void IrInit()
{
	IT0=1;//下降沿触发
	EX0=1;//打开中断0允许
	EA=1;	//打开总中断

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

/*******************************************************************************
* 函 数 名         : delay
* 函数功能		   : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(unsigned int i)
{
	while(i--);	
}

/*******************************************************************************
* 函数名         : ReadIr()
* 函数功能		   : 读取红外数值的中断函数
* 输入           : 无
* 输出         	 : 无
*******************************************************************************/
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();
	}
		
}


  • 35
    点赞
  • 222
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
51单片机矩阵键盘动态数码管是一种常见的硬件组合,常用于电子产品中的输入和显示功能。通过使用矩阵键盘和动态数码管,可以实现对用户输入的响应和信息的显示。 矩阵键盘是一种由多个按键组成的输入设备,通过按下不同的按键,可以输出不同的电信号。在51单片机中,可以使用行列扫描的方式读取矩阵键盘上的按键状态。通过设置相应的IO口为输出和输入模式,并循环扫描每一行或列的状态,可以检测到用户按下的按键。 动态数码管是一种用于数字显示的输出设备,通常由多个LED组成。为了实现数字显示,需要按照一定的时间序列依次点亮数码管的各个LED。在51单片机中,可以使用定时器中断和IO口输出控制的方式来实现动态数码管的显示。 具体实现的步骤包括: 1. 设置矩阵键盘的行和列对应的IO口为输入和输出模式。 2. 循环扫描每一行或列,检测按键状态。 3. 根据检测到的按键状态,进行相应的处理,例如触发某个事件或将按键值存储到变量中。 4. 设置动态数码管的各个LED对应的IO口为输出模式。 5. 使用定时器中断来控制数码管的显示,按照一定的时间序列依次点亮LED,显示所需的数字。 以上是基本的实现思路,具体的代码实现会涉及到具体的硬件连接和编程语言。希望可以帮助到你!如果有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值