【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);
	}
}

有不好的地方尽情留言

相关推荐
lcj25119 小时前
深入理解指针(4):qsort 函数 & 通过冒泡排序实现
c语言·数据结构·算法
LS_learner9 小时前
树莓派(ARM64 架构)Ubuntu 24.04 (Noble) 系统 `apt update` 报错解决方案
嵌入式硬件
来自晴朗的明天9 小时前
16、电压跟随器(缓冲器)电路
单片机·嵌入式硬件·硬件工程
4311媒体网10 小时前
C语言操作符全解析 C语言操作符详解
java·c语言·jvm
钰珠AIOT10 小时前
在同一块电路板上同时存在 0805 0603 不同的封装有什么利弊?
嵌入式硬件
代码游侠10 小时前
复习——Linux设备驱动开发笔记
linux·arm开发·驱动开发·笔记·嵌入式硬件·架构
二年级程序员10 小时前
一篇文章掌握“顺序表”
c语言·数据结构
傻乐u兔11 小时前
C语言进阶————指针4
c语言·开发语言
历程里程碑11 小时前
Linux22 文件系统
linux·运维·c语言·开发语言·数据结构·c++·算法