【51单片机】(三)数码管(原理,静态、动态显示)


一.数码管基础知识

四位一体数码管:
在这里插入图片描述
数码管电路原理:
在这里插入图片描述
与之有关的元件——“138译码器”:
在这里插入图片描述
①想要点亮一个数码管并让其显示数字,我们需要操作两个端口,给两个端口不同的电平。我们的单片机数码管上端是共阴极的,所以发光的条件是上端赋予低电平,下端赋予高电平
【通俗理解:上方LED端口选择要点亮哪一个数码管;下方abcdefg端口确定点亮什么数字。】

(1)数码管上方有8个接口LED1~8,分别对应接到“译码器”的右输出端。译码器的左端连接单片机的3个P2口。(具体如何用三个P2口控制8个LED输出口,后面会单独讲解)
(2)每一体数码管下方引出abcdefg和dp共八个接口,分别对应点亮一个LED长条(图中有标注)或是小数点,点亮几个就可以组合成一个数字。这八个接口接到74HC245缓冲器的右输出端,而74HC245的左端连接单片机的8个P0口。74HC245左右端一一对应(A0-B0,A1-B1……)。
(缓冲器是用来提高单片机驱动能力的一个元件,VCC可以增强信号强度)

比如我现在想让LED6数码管发出“3”的数字。那么,上方接口所赋予的电平情况应该是(从左往右)1101 1111;下方接口接通abcdg,应该是(从左往右)1111 0010。但是,

我们在缓冲器左端传入的二进制必须从高位往低位读取。

比如,现在从左往右端口是1111 0010,但是P0输入端输入的是0100 1111,也就是P0=0x4F。
在这里插入图片描述 在这里插入图片描述
为了方便,这里总结数码管段码表:
在这里插入图片描述

数码管静态显示时,只能让其中一个数码管发光。也就是说,在同一时间,上端接口只能保证有一个输入0。(具体原因见“译码器”工作方法)

译码器工作方法:

左端输入端输入的信号按CBA排序,组成一个三位的二进制数,再将这个二进制数转化为十进制数,这个十进制数对应右端输出端的下标,这个输出端将会输出低电平。

比如输入:A : 0 、B : 1 、C : 1,排序为110,转十进制为6,Y6口(对应LED7)将会输出低电平,其他端口均输出高电平。


二.数码管静态显示

根据之前的讲解,不难写出代码了:
这个代码可以让数码管LED3显示数字“3”。

#include<regx52.h>
void main()
{
	    P2_4=0; P2_3=1; P2_2=0; //CBA:010
		P0=0x4F;  //OUTPUT 3:abcdg -> 1111 0010 -> 0100 1111 -> 0x4F
		while(1)
		{
		}
}

为了方便操作,我们将数码管每一个位置的数字显示封装在函数中。
①首先,使用段码表,初始化一个数组NixieTable,后面可以直接调用,显示数字。
②其次用分支语句写出所有数码光发光的情况。(P2端口)

void Nixie(int LED,int number)   
{
		char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00}
		switch(LED)   //CBA
		{	
			case 1: P2_4=0; P2_3=0; P2_2=0; break;
			case 2: P2_4=0; P2_3=0; P2_2=1; break;
			case 3: P2_4=0; P2_3=1; P2_2=0; break;
			case 4: P2_4=0; P2_3=1; P2_2=1; break;
			case 5: P2_4=1; P2_3=0; P2_2=0; break;
			case 6: P2_4=1; P2_3=0; P2_2=1; break;
			case 7: P2_4=1; P2_3=1; P2_2=0; break;
			case 8: P2_4=1; P2_3=1; P2_2=1; break;
		}
		
		P0=NixieTable[number];
}

当然,我们可以把函数改的人性化一些。内部LED1~8序号是从右往左的,我们在写函数的时候,可以反一反。


三.数码管动态显示

由于数码管在同一时间只能静态显示一个数字,那么如果我们让多个数字同时显示,该怎么办呢?

我们可以让这些LED按顺序以极高的频率快速闪烁,在人眼看来就是同时显示。

有了这样的方法,我们先付诸实践:(略去函数部分)

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

但是,实际上的效果却是:虽然显示了321,但是每个数字不该点亮的灯条会有一些模糊的光泛出:
在这里插入图片描述
这显然是不符合我们的预期的。原因是单片机在操作“段选->位选”的时候,速度很快,可能会篡位,导致顺序错乱。

于是,我们在数码管动态显示时,还必须完成一步“消影”操作。

在Nixie函数中,每一次“位选->段选”操作完,在极短的时间之内,完成将P0清零(P0=0x00;)的操作。

void Nixie(int LED,int number)   
{
		char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00};
		switch (LED)   //CBA
		{	
			case 1: P2_4=0; P2_3=0; P2_2=0; break;
			case 2: P2_4=0; P2_3=0; P2_2=1; break;
			case 3: P2_4=0; P2_3=1; P2_2=0; break;
			case 4: P2_4=0; P2_3=1; P2_2=1; break;
			case 5: P2_4=1; P2_3=0; P2_2=0; break;
			case 6: P2_4=1; P2_3=0; P2_2=1; break;
			case 7: P2_4=1; P2_3=1; P2_2=0; break;
			case 8: P2_4=1; P2_3=1; P2_2=1; break;
		}
		
		P0=NixieTable[number];
		Delay(100);   //<----------------------
		P0=0x00;     //<-----------------------
}

这样执行之后,就不会出现残影了。
在这里插入图片描述

  • 16
    点赞
  • 84
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C51单片机数码管动态显示单片机基础教学中比较经典的一个实验,该实验可以通过单片机控制数码管的显示,实现数字的动态滚动、计时、计数等功能。下面是该实验的总结。 一、实验原理 数码管动态显示是通过单片机的高速刷新来实现的。数码管的显示是静态的,即只有一次性地将数码管的显示数据送入数码管的存储器中,而动态显示则是通过不断地刷新数码管的显示数据,使其看上去是在不停地变化。单片机控制数码管的显示,需要通过端口输出控制信号,将位选和段选信号送入数码管中,从而实现数码管动态显示。 二、实验器材 1. C51单片机开发板 2. 74HC595移位寄存器 3. 共阴数码管 4. 面包板、杜邦线等 、实验步骤 1. 将数码管的阳极连接到单片机的P2口,将数码管的阴极连接到74HC595移位寄存器的输出端Q0~Q7。 2. 将74HC595移位寄存器的SCK、RCK、SDA分别连接到单片机的P3.5、P3.6、P3.7口。 3. 在程序中设置数码管的显示数据,将其存入74HC595移位寄存器中。 4. 设置位选信号,将控制信号送入数码管中,实现数码管动态显示。 四、实验代码 以下是C语言编写的数码管动态显示的实验代码: ``` #include <reg52.h> #define uchar unsigned char #define uint unsigned int uchar code table[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90}; //数码管显示表 void delay(uint x) { uint i, j; for (i = x; i > 0; i--) for (j = 110; j > 0; j--); } void main() { uchar i = 0; while (1) { P3 = 0xFF; //清零P3口 P1 = table[i++]; //设置数码管显示数据 if (i == 10) i = 0; //循环显示0~9 P3 = ~(1 << i); //设置位选信号,显示第i个数码管 delay(1); //延时一段时间 } } ``` 五、实验结果 实验成功后,数码管应该可以进行动态滚动、计时、计数等功能的实现。通过对程序进行修改,还可以实现更多有趣的功能,如闪烁、渐变等。 六、实验结论 通过本次实验,我们掌握了单片机控制数码管动态显示原理和方法,了解了74HC595移位寄存器的使用方法。在实验中,我们不仅学会了如何通过单片机控制数码管的显示,还锻炼了编程能力和动手能力。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值