基于51单片机实现动态数码管显示

控制/MCU

1878人已加入

描述

前言

前面我们已经介绍了如何使用51单片机控制静态数码管显示,在实际应用中通常都需要显示多位数值,如果采用静态数码管显示就不够好,因此就需要采用另外一种显示方式,即数码管动态显示。开发板上板载2 个四位一体的共阴数码管,接下来我们就来介绍下如何使用51 单片机控制动态数码管显示。本教程所要实现的功能是:控制动态数码管从左至右显示数字0-7。学习本节可以参考前面的实验内容。

一、数码管介绍

1.多位数码管简介

多位数码管,即两个或两个以上单个数码管并列集中在一起形成一体的数码管。当多位一体时,它们内部的公共端是独立的,而负责显示什么数字的段线(a-dp)全部是连接在一起的,独立的公共端可以控制多位一体中的哪一位数码管点亮,而连接在一起的段线可以控制这个能点亮数码管亮什么数字,通常我们把公共端叫做“位选线”,连接在一起的段线叫做“段选线”,有了这两个线后,通过单片机及外部驱动电路就可以控制任意的数码管显示任意的数字了。

一般一位数码管有10 个引脚, 二位数码管也是10 个引脚, 四位数码管是12 个引脚,关于具体的引脚及段、位标号大家可以查询相关资料,最简单的办法就是用数字万用表测量,若没有数字万用表也可用5V 直流电源串接1k 电阻后测量,将测量结果记录,通过统计便可绘制出引脚标号。多位数码管有许多是按一定要求设计的,引脚不完全按照一般规则设定,所以需要在使用时查找手册,最直接的办法就是按照数码管上的标示向生产商要求。

我们开发板上使用了2 个四位一体的共阴数码管,这样可在上面同时显示8个数值。

2.数码管动态显示原理

多位数码管依然可以静态显示,但是显示时要么只显示一位数码管,要么多位同时显示相同内容。当多位数码管应用于某一系统时,它们的“位选”是可独立控制的,而“段选”是连接在一起的,我们可以通过位选信号控制哪几个数码管亮,而在同一时刻,位选选通的所有数码管上显示的数字始终都是一样的,因为它们的段选是连接在一起的,送入所有数码管的段选信号都是相同的,所以它们显示的数字必定一样,数码管的这种显示方法叫做静态显示。

而动态显示,就是利用减少段选线,分开位选线,利用位选线不同时选择通断,改变段选数据来实现的。比如在第一次选中第一位数码管时,给段选数据0,下一次位选中第二位数码管时显示1。为了在显示1 的时候,0 不会消失(当然实际上是消失了),必须在人肉眼观察不到的时间里再次点亮第一次点亮的0。而这时就需要记住,人的肉眼正常情况下只能分辨变化超过24ms 间隔的运动。也就是说,在下一次点亮0 这个数字的时间差不得大于24ms。这时就会发现,数码管点亮是在向右或者向左一位一位点亮,形成了动态效果。如果把间隔时间改长就能直接展现这一现象。

数码管动态显示的应用非常多,所以大家一要认真学好数码管的动态显示方法。

二、74HC245 和74HC138 芯片介绍

通过前面内容的介绍我们知道,要使单片机能控制开发板上2 位一体的共阴数码管显示,仅靠单片机IO 口来驱动是不行的,这里就需要增加外部驱动芯片,开发板上使用的是74HC245 芯片。2 个4 位一体的共阴数码管的位选线有8 根,直接让单片机IO 口控制是没有任何问题的,但考虑到51 单片机IO 口资源的限制,通常我们会使用一种IO 扩展芯片,比如74HC138、74HC164、74HC595 芯片等,只需要很少的单片机IO 口就可以扩展出8 个控制口,通过级联方式甚至可扩展出更多的控制口(这个在后面LED 点阵实验章节中会有详细介绍)。我们开发板上使用的是74HC138 译码器芯片,只需单片机3 个IO 口就可以实现8 个位选管脚的控制,节省了芯片的IO 资源。

下面就来看看这两个芯片功能及使用方法:

1.74HC245介绍

74HC245 是一种三态输出、八路信号收发器,主要应用于大屏显示,以及其它的消费类电子产品中增加 驱动

(1)主要特性

①采用CMOS 工艺

②宽电压工作范围:3.0V-5.0V

③双向三态输出

④八线双向收发器

⑤封装形式:SOP20、SOP20-2、TSSOP20、DIP20

(2)管脚功能定义

数码管

数码管

数码管

从上面的管脚功能定义说明及真值表可以知道该芯片使用方法很简单,给OE使能管脚低电平,DIR 管脚为高电平传输方向是A->B 输出,DIR 为低电平传输方向是B->A,至于输出高电平还是输出低电平取决于输入端的状态,如果输入为低电平,输出即为低;输入为高电平,输出即为高。如果OE 使能管脚为高电平,不论DIR 管脚是高还是低,输出是高组态。

通常我们使用74HC245 芯片用作驱动只会让其在一个方向输出,即DIR 管脚为高电平,传输方向是A->B。

2.74HC245介绍

74HC138D 是一种三通道输入、八通道输出译码器,主要应用于消费类电子产品。

(1)主要特性

①采用CMOS 工艺

②低功耗

③工作电压:3.0V-5.0V

④封装形式:SOP16

(2)管脚功能定义

数码管

数码管

数码管

从上面的管脚功能定义说明及真值表可以知道该芯片使用方法很简单,给E1、E2 使能管脚低电平,E3 管脚为高电平,至于哪个管脚输出有效电平(低电平),要看A0,A1,A2 输入管脚的电平状态。如果A0,A1,A2 都为低电平,则Y0 输出有效电平(低电平),其他管脚均输出高电平。如果A0 为高电平,A1,A2 都为低电平,则Y1 输出有效电平(低电平),其他管脚均输出高电平。其他几种输出大家可以对照真值表查看。如果E1、E2 使能管脚任意一个为高电平或者E3 为低电平,不论输入是什么,输出都为高电平。

这里给大家总结一个方法:A0、A1、A2 输入就相当于3 位2 进制数,A0 是低位,A1 是次高位,A2 是高位。而Y0-Y7 具体哪一个输出有效电平,就看输入二进制对应的十进制数值。比如输入是101(A2,A1,A0),其对应的十进制数是5,所以Y5 输出有效电平(低电平)。

三、硬件设计

本实验使用到硬件资源如下:

(1)动态数码管模块

(2)74HC138

开发板上的动态数码管模块电路如下图所示:

数码管

数码管

从上图中可以看出,该电路是独立的,动态数码管的控制管脚并未直接连接到51 单片机的IO 上,而是段选端连接到J6 端子上,位选端连接到J1 端子上。段选端通过74HC245 芯片驱动这两个共阴数码管的a-dp 段。

如果要想51 单片机控制动态数码管,就必须将单片机管脚通过导线连接到J6 端子和J1 端子上。因此需使用一根8Pin 排线将单片机的管脚与J6 端子顺序连接,使用一根8Pin 排线将38 译码器的输出J10 端子与J1 端子顺序连接,使用3 根杜邦线将单片机的管脚与J9 端子连接。由于动态数码管模块电路是独立的,所以使用任意单片机管脚都可以,为了与我们例程程序配套,这里使用P0口控制数码管段选,使用P2.2、P2.3、P2.4 管脚控制74HC138 译码器输入从而控制数码管位选。

注意 :要保证P0 口的P00 与A 段到P0 口的P07 与DP 段依次顺序连接,单片机的P22、P23、P24 口与38 译码器的A、B、C 连接,38 译码器的输出J10 端子的Y0-Y7 与位选端子J1 的W1-W8 连接,不能交叉,否则使用例程程序就会出错,默认我们已经使用8 个黄色短接片将38 译码器的输出J10 与数码管位选J1短接好。

四、软件设计

本教程所要实现的功能是:控制动态数码管从左至右显示数字0-7。

#include< reg52.h >
typedef unsigned int u16;
typedef unsigned char u8;
#define SMG_A_DP_PORT  P0//宏定义 定义段选
sbit LSA=P2^2;//定义位选
sbit LSB=P2^3;
sbit LSC=P2^4;


u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共阴极数码管


void delay_10us(u16 time_us)
{
    while(time_us--);
}


void smg_display(void)
{
  u8 i=0;
  for(i=0;i< 8;i++)
  {
       switch(i)//位选
    {
      case 0: LSC=0;LSB=0;LSA=0;break;
      case 1: LSC=0;LSB=0;LSA=1;break;
      case 2: LSC=0;LSB=1;LSA=0;break;
      case 3: LSC=0;LSB=1;LSA=1;break;
      case 4: LSC=1;LSB=0;LSA=0;break;
      case 5: LSC=1;LSB=0;LSA=1;break;
      case 6: LSC=1;LSB=1;LSA=0;break;
      case 7: LSC=1;LSB=1;LSA=1;break;
    }
    SMG_A_DP_PORT=gsmg_code[i];//传送段选数据
    delay_10us(100);//延时一段时间,等待显示稳定
    SMG_A_DP_PORT=0x00;//消音
  }
}


void main()
{

    while(1)
  {
     smg_display();
  }
}

其中对于依次输出段选信号时的for循环可以改为如下片段:

void smg_display(void)
{
  u8 i=0;


  for(i=0;i< 8;i++)
  {
       switch(7-i)//位选
    {
      case 0: LSC=1;LSB=1;LSA=1;break;
      case 1: LSC=1;LSB=1;LSA=0;break;
      case 2: LSC=1;LSB=0;LSA=1;break;
      case 3: LSC=1;LSB=0;LSA=0;break;
      case 4: LSC=0;LSB=1;LSA=1;break;
      case 5: LSC=0;LSB=1;LSA=0;break;
      case 6: LSC=0;LSB=0;LSA=1;break;
      case 7: LSC=0;LSB=0;LSA=0;break;
    }
    SMG_A_DP_PORT=gsmg_code[i];//传送段选数据
    delay_10us(100);//延时一段时间,等待显示稳定
    SMG_A_DP_PORT=0x00;//消音
  }
}

main.c 文件内代码非常少也很简单,首先将51 单片机的头文件包含进来,然后定义38 译码器的控制引脚,并将共阴数码管0-F 段码数据使用数组定义好。主函数功能也很简单,直接进入while 循环,在循环体内执行smg_display()数码管动态显示函数。该函数是根据动态数码管显示原理所编写,即选中所要显示的那位数码管,然后发送在该位数码管上所要显示的段码数据,延时一定时间后在将段选口清零即消隐(消除之前的显示),如此循环8 次即可实现8 位数码管显示。在动态显示中,要注意延时时间,只要保证在人肉眼所能感觉时间之内即可,让我们看到所要显示的内容就像是同时显示一样。如果时间过长或者过短都可能会影响数码管的显示效果,大家可以在例程基础上试着修改延时时间观察效果。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分