I/O输出——实例2:数码管静态驱动


一、实例目的
      通过本实例,我们应:
      1. 了解数码管的内部结构和工作原理;
      2. 掌握单片机I/O驱动单个数码管显示。
   
二、数码管结构及工作原理
      数码管又称七段式数码管,被广泛应用在电子数字钟、电子仪表等设备中用来显示数值信息。
      1位数码管和多位数码管分别如下图所示。
                    I/O输出——实例2:数码管静态驱动       I/O输出——实例2:数码管静态驱动
                    图1  1位数码管                                                        图2  4位数码管
    注:图1和图2来源自Wikipedia,原文链接:https://en.wikipedia.org/wiki/Seven-segment_display

    下面介绍7段数码管的内部结构和工作原理。 
     数码管符号如图3左边所示。 按结构,数码管分为共阴极数码管和共阳极数码管两种,分别见图3(a)、图3(b)。
     共阴极数码管中发光二极管的负极(阴极,cathod )连接在一起形成公共端(COMMON),正极为段控制端(a~h)。数码管工作时,共阴极数码管的COM要接地(或低电平),则段是否点亮由对应段的电平决定,高电平-亮(on),低电平则灭(on)。
     共阳极数码管中发光二极管的正极(阳极, anode)连接在一起形成公共端(COMMON),负极为段控制端(a~h)。数码管工作时,共阳极数码管的COM要接电源(或高电平),则段是否点亮由对应段的电平决定,低电平-亮(on),高电平则灭(on)。
I/O输出——实例2:数码管静态驱动
                                                图3  数码管符号和内部结构

     因此,可以通过控制段的亮灭来使数码管显示数字。例如,为了让阳极数码管显示数字,则要求dp、f和c不亮,其它段都亮,如表1所示。 假设dp为高位,a为低位,则2对应的段码为0xA4.
     
    表1  共阳极数码管显示数字2对应的段状态
dp
g
f
e
d
c
b
a
段码
状态
off
on
off
on
on
off
on
on
-
段电平
1
0
1
0
0
1
0
0
0xA4
同理可以得到其它数字对应的码段。共阳极/共阴极数码管的显示数字与段码关系见表2。

                                                        表2  共阴极/共阳极数码管段码表
                    I/O输出——实例2:数码管静态驱动
     编写数码管驱动程序时,一般将数码管段码按照0~9,A-F存在一个一维数组里, 通过0~16即可获得对应码段。
三、1位数码管驱动电路设计
1位共阴极数码管的驱动电路如图4所示。 74HC573锁存器用来驱动1位七段数码管,除能够为数码管提供驱动电流外,还可以锁存显示数字。 显示内容锁存后,作为段控制I/O的P0口可以分时复用为其它功能,如访问外扩的E2PROM等。如P0口只驱动数码管,则LE可以直接连接到电源。
I/O输出——实例2:数码管静态驱动
                                           图4 1位数码管驱动电路


四、数码管静态显示程序设计
设要求1位数码管循环顺序显示0~9,A-F,间隔1s。程序如下,说明见注释:

#include<reg52.h>
#define led_seg P0        //段控制I/O,gfedcba<>P0.6~P0.0
sbit led_refresh = P2^0; //wiring to LE pin of 74HC573
////共阳极段码:Anode mode code table for 0-9,A-F, and off
//unsigned char LED_CODE[] = {0xC0,0xF9,0xA4,0xB0,0x99,    //数字0~4
//                0x92,0x83,0xF8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xFF};    //数字5~9;

//共阴极段码:Cathod code table for 0-9,A-F, and off
unsigned char LED_CODE[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
                          0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00};

void delayMS(unsigned int ms)
{
  unsigned int i,j;
  for(i=0;i<ms;i++)
   for(j=0;j<150;j++);
}
void main()
{
   unsigned char i;
   while(1)
   {  
      for(i=0;i<16;i++)
         {
           led_seg = LED_CODE[i]; //准备数码管显示数字
           led_refresh = 1;       //刷新数码管显示
           led_refresh = 0;       //锁存显示数字,P0口可以分时作其它用途
           P0 = 0xFF;             //例如,P0输出其它数据,不会改变数码管显示
           delayMS(2000);
         }
    }
}

Proteus仿真:
I/O输出——实例2:数码管静态驱动











相关文章: