四位共阳极数码管显示函数_数码管显示

编者按  

 本着简单、准确、可靠、稳定、通用的原则,此次对于数码管进行一个简单的应用,同时可以设计一个电子小时钟,增加趣味性。

    数码管是一种半导体发光器件,其基本单元是发光二极管。能显示4位数字的叫四位数码管,当然也有多位和只有一位的数码管,他们的电气原理相同。数码管按段数分为七段数码管和八段数码管,八段数码管比七段数码管多一个发光二极管单元(多一个小数点显示);按发光二极管单元连接方式分为共阳极数码管和共阴极数码管。共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管。共阳数码管在应用时应将公共极COM接到+5V,当某一字段发光二极管的阴极为低电平时,相应字段就点亮。当某一字段的阴极为高电平时,相应字段就不亮。共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数码管。共阴数码管在应用时应将公共极COM接到地线GND上,当某一字段发光二极管的阳极为高电平时,相应字段就点亮。当某一字段的阳极为低电平时,相应字段就不亮。基于51单片机的电子时钟(数码管显示)

                           原理图

f2100b0762245e8f4062ae7be57546ce.png

首先我们先进行原理图的讲解,这里我们直接使用的开发板,其原理连接图如上:

其中D(0~1)是连接在单片机的P0口上的。

从图中,我们可以看到,第一个74HC573是来控制8个数码管的位选的,就是说我要选种哪个数码管,这里的WE是低电平有效,比如说我想选中最后一个数码管,那么这里我就要将0x7f送到相应的I/O口。第二个74HC573是来控制数码管显示什么的这里0~9的16进制码如下:

0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f;

要想完成电子时钟,我们先要显示一个数值,

这里我们封装两个函数:

wirte_address(unsigned char);

write_date(unsigned int)

第一个函数是用来写地址的,就是用来选中数码管的;

第二个函数是用来写数据的,就是选中的数码管显示什么。

比如我们想在最后一个数码管上显示一个8;

那么则有:

write_address(0x7f);

write_date(0x7f);

这样就能在相应的位置上显示一个8了;

然后我们就要多个位置显示,这里我们硬件的P0口接的是数码管,同时我们要引进相应的延时函数delay(unsigned int);

我们利用发光管的余辉和人眼视觉暂留作用,让人眼无法分辨出来,从而达到“同时显示的效果”。

但是我们需要注意的是消影,在每次写入之前令P0=0xff,这是为了消除上次段选数据,否则会造成,显示混乱。

当我们能显示时,就需要了解定时器,让它来计时,然后将数值取出,进行显示。这里我们的晶振是12MHz,所以一个机械周期时1/12MHz=1us,为了使计时较为精确,我们这里选择定时器0的模式2,8位重装定时器,并且我们100us进入一次中断,定时器的初始化就该如下:

TMOD=0x02;

H0=256-100;

TL0=256-100;

EA=1;

ET0=1;

TR0=1

这样我们再定义一个n用来计数进入中断的次数,当n的10000时,就表示1s到了,所以我们需要对相应的变量进行处理。

那么我们需要对数据进行处理,比如,所得的秒的值,其十位=秒/10,其个位就等于秒%10,其它以此类推。

那么整个的程序代码如下:

#include

#define uint unsigned int

#define uchar unsigned char

uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //数码管位选数据

sbit dula=P2^6;//段选信号,写数码管数据

sbit wela=P2^7;//位选信号,选择数码管

uint miao=0; //秒

uint fen=0; //分

uint shi=0;     //时

uint n=0; //计数

int date[6]={0,0,0,0,0,0};   //定义一个有6个地址的数组,分别存时,分,秒的个位和十位。

void delay(uint z) //延时函数

{

     uint x,y;

for(x=z;x>0;x--)

  for(y=50;y>0;y--);

}

void write_address(uchar address) //写地址函数,选择数码管

{

    wela=1;

P0=address;

wela=0;

}

void write_date(uint n)      //写数据函数,送入段选信号

{    

    dula=1;

P0=table[n];

dula=0;

} //显示函数

void display()

{  

        write_date(date[0]);

        P0=0xff;

        write_address(0x7f);

        delay(1);

        write_date(date[1]);

        P0=0xff

        write_address(0xbf);

        delay(1);

        write_date(date[2]);

        P0=0xff;

        write_address(0xef);

        delay(1);

        write_date(date[3]);

        P0=0xff;

        write_address(0xf7);

        delay(1);

        write_date(date[4]);

        P0=0xff;

        write_address(0xfd);

        delay(1);

        write_date(date[5]);

        P0=0xff;

        write_address(0xfe);

        delay(1);

}

void time_init()    //定时器初始化函数

{

    TMOD=0x02;   //选择方式2

TH0=156;   //重装初值为156

TL0=156;   //运行值为156

EA=1;   //开总中断

ET0=1;   //开定时器0中断

TR0=1;   //开定时器0

}

void main()

{

   dula=0;    //先关闭位选,段选信号。

   wela=0;

   time_init();

   while(1)

   {

       display();

   }   

}

void timer() interrupt 1   //定时器0中断

{

     n++;

if(n==10000) //当n=10000时,表示1s到了

{  

    n=0;

    miao++;

if(miao==60)

{

    miao=0;

     fen++;

if(fen==60)

{

     fen=0;

  shi++;

if(shi==24)

{    

    shi=0;

}    

}

}

date[0]=miao%10;

date[1]=miao/10;

date[2]=fen%10;

date[3]=fen/10;

date[4]=shi%10;

date[5]=shi/10;

}

其效果图如下:

47e0578e1c1124d48480c7f18fc62b10.png

编辑:@陈白凯

责编:@张嘉翮

审核:@葛向阳

03024cbb764d0166980e5e6b75174efc.png

版权声明:本文为weixin_31031155原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。