【51单片机】数码管的静态与动态显示(含消影)

数码管在现实生活里是非常常见的设备,例如

这些数字的显示都是数码管的应用。

目录

  • 静态数码管:
    • 器件介绍:
      • 数码管的使用:
      • 译码器的使用:
      • 缓冲器:
    • 实现原理:
    • 完整代码:
  • 动态数码管:
    • 消影:
    • 完整代码:

静态数码管:

器件介绍:


注意 :数码管有共阴共阳的区分。

在自己设计电路时,应当选用一种数码管时需要选用相应的译码器(共阴配共阴,共阳同理)


数码管的使用:

数码管其实就是一段一段LED构成的,51单片机使用的是共阴数码管,即图中的上侧表示,其中的标号怎样理解呢?

3和8为一个端子引出去的两个引脚,都是接地,

其余引脚的虽然右图看似杂乱无章,实则有点就近原则的意思,一个引脚控制一段LED,从上侧左图就可以看出。


但是这是一个数码管,51单片基中的数码管是下图这样的

看着复杂,无非就是多了7个共阴端,这时我们就需要译码器来进行选择哪个管子亮,这个过程叫做位选

在学习数电时,会接触到译码器,其中最经典的就是138译码器

译码器的使用:

大概说一下它的功能,

使能端让译码器正常工作情况下(51单片机的译码器可以看到三个使能端已经达到此效果),我们通过输入端A B C来进行控制Y端子的输出,每次输出一位有效,有效的会输出0

正好符合我们共阴的配置,一次可以选择一个数码管的亮灭1


缓冲器:

选择完管子,就轮到每个管子应该输出什么数字了,

这个过程叫做段选

回到这张图片,我们发现每个管子的数字是通过P0端来实现显示数字
74HC245的作用主要是缓冲,增加电流,让灯更亮,
电阻的作用是限流,防止烧坏

实现原理:

元器件的使用知道了,现在就可以操作了

现在梳理一下流程

  1. 通过译码器控制指定的管子亮灭
  2. 控制P0寄存器控制显示的数字

技巧:

在需要一个实现固定功能的代码情况下,可以将其封装成一个函数,使用时更方便,便捷

我们这里就选择将控制第几个灯亮,显示什么数字的功能封装成一个函数

注意:

赋值时应当注意译码器的高低位等器件的高低位,防止最后的结果不符合预期

c 复制代码
#include <REGX52.H>
//延时函数
void Delay(unsigned char xms)		//@11.0592MHz
{
	unsigned char i, j;
	
	while(xms--)
	{
		i = 2;
		j = 199;
		do
		{
			while (--j);
		} while (--i);
	}
}

char arr[] = { 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F };

//loc代表选择灯亮的位置,num代表你要显示的数字
void NixieTube(unsigned char loc, num)
{
	switch(loc)
	{
		case 1:P2_4 = 1; P2_3 = 1; P2_2 = 1; break;
		case 2:P2_4 = 1; P2_3 = 1; P2_2 = 0; break;
		case 3:P2_4 = 1; P2_3 = 0; P2_2 = 1; break;
		case 4:P2_4 = 1; P2_3 = 0; P2_2 = 0; break;
		case 5:P2_4 = 0; P2_3 = 1; P2_2 = 1; break;
		case 6:P2_4 = 0; P2_3 = 1; P2_2 = 0; break;
		case 7:P2_4 = 0; P2_3 = 0; P2_2 = 1; break;
		case 8:P2_4 = 0; P2_3 = 0; P2_2 = 0; break;
	}
	//数字的显示通过数组,我们再控制LED灯时普遍喜欢用数组实现
	P0 = arr[num];
}

完整代码:

c 复制代码
#include <REGX52.H>

void Delay(unsigned char xms)		//@11.0592MHz
{
	unsigned char i, j;
	
	while(xms--)
	{
		i = 2;
		j = 199;
		do
		{
			while (--j);
		} while (--i);
	}
}

char arr[] = { 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F };

void NixieTube(unsigned char loc, num)
{
	switch(loc)
	{
		case 1:P2_4 = 1; P2_3 = 1; P2_2 = 1; break;
		case 2:P2_4 = 1; P2_3 = 1; P2_2 = 0; break;
		case 3:P2_4 = 1; P2_3 = 0; P2_2 = 1; break;
		case 4:P2_4 = 1; P2_3 = 0; P2_2 = 0; break;
		case 5:P2_4 = 0; P2_3 = 1; P2_2 = 1; break;
		case 6:P2_4 = 0; P2_3 = 1; P2_2 = 0; break;
		case 7:P2_4 = 0; P2_3 = 0; P2_2 = 1; break;
		case 8:P2_4 = 0; P2_3 = 0; P2_2 = 0; break;
	}
	P0 = arr[num];
}

void main()
{
	NixieTube(1, 1);
	
	while(1)
	{	
	}
}

动态数码管:

先来科普一下:

动态数码管不是动态的显示数字(表面理解),而是一次显示多个数字

有了以上的基础,动态数码管可谓是信手拈来

我们将封装好的函数放在while(1)循环中,在循环中放入你想控制的位置与数字

消影:

运行后发现会有重影的现象
产生原因:

我们静态显示一个数码管时是位选-->段选,最后死循环完成的,

但是动态的显示的顺序是 位选 -->段选-->位选-->段选-->位选 这样循环,而问题就出现在段选-->位选这里,因单片机的速度非常快,导致上一次的段选与下一次的位选相结合,造成了重影

消影方法:

对封装好的函数进行一点改进,

现状态稳定1ms,在次状态开始前进行清0的操作

c 复制代码
void NixieTube(unsigned char loc, num)
{
	switch(loc)
	{
		case 1:P2_4 = 1; P2_3 = 1; P2_2 = 1; break;
		case 2:P2_4 = 1; P2_3 = 1; P2_2 = 0; break;
		case 3:P2_4 = 1; P2_3 = 0; P2_2 = 1; break;
		case 4:P2_4 = 1; P2_3 = 0; P2_2 = 0; break;
		case 5:P2_4 = 0; P2_3 = 1; P2_2 = 1; break;
		case 6:P2_4 = 0; P2_3 = 1; P2_2 = 0; break;
		case 7:P2_4 = 0; P2_3 = 0; P2_2 = 1; break;
		case 8:P2_4 = 0; P2_3 = 0; P2_2 = 0; break;
	}
	P0 = arr[num];
	Delay(1);
	P0 = 0x00;
}

完整代码:

c 复制代码
#include <REGX52.H>

void Delay(unsigned char xms)		//@11.0592MHz
{
	unsigned char i, j;
	
	while(xms--)
	{
		i = 2;
		j = 199;
		do
		{
			while (--j);
		} while (--i);
	}
}

char arr[] = { 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F };

void NixieTube(unsigned char loc, num)
{
	switch(loc)
	{
		case 1:P2_4 = 1; P2_3 = 1; P2_2 = 1; break;
		case 2:P2_4 = 1; P2_3 = 1; P2_2 = 0; break;
		case 3:P2_4 = 1; P2_3 = 0; P2_2 = 1; break;
		case 4:P2_4 = 1; P2_3 = 0; P2_2 = 0; break;
		case 5:P2_4 = 0; P2_3 = 1; P2_2 = 1; break;
		case 6:P2_4 = 0; P2_3 = 1; P2_2 = 0; break;
		case 7:P2_4 = 0; P2_3 = 0; P2_2 = 1; break;
		case 8:P2_4 = 0; P2_3 = 0; P2_2 = 0; break;
	}
	P0 = arr[num];
	Delay(1);
	P0 = 0x00;
}

void main()
{
	while(1)
	{	
		NixieTube(1, 1);
		NixieTube(2, 2);
		NixieTube(3, 3);
	}
}

有不好的地方尽情留言

相关推荐
森旺电子23 分钟前
51单片机仿真摇号抽奖机源程序 12864液晶显示
单片机·嵌入式硬件·51单片机
爱吃西瓜的小菜鸡2 小时前
【C语言】判断回文
c语言·学习·算法
不过四级不改名6772 小时前
蓝桥杯嵌入式备赛教程(1、led,2、lcd,3、key)
stm32·嵌入式硬件·蓝桥杯
小A1593 小时前
STM32完全学习——SPI接口的FLASH(DMA模式)
stm32·嵌入式硬件·学习
Rorsion3 小时前
各种电机原理介绍
单片机·嵌入式硬件
FeboReigns4 小时前
C++简明教程(文章要求学过一点C语言)(1)
c语言·开发语言·c++
FeboReigns4 小时前
C++简明教程(文章要求学过一点C语言)(2)
c语言·开发语言·c++
_小柏_5 小时前
C/C++基础知识复习(43)
c语言·开发语言·c++
yoyobravery5 小时前
c语言大一期末复习
c语言·开发语言·算法
善 .6 小时前
单片机的内存是指RAM还是ROM
单片机·嵌入式硬件