打印
[经验分享]

动态数码管

[复制链接]
78|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Puchou|  楼主 | 2025-4-13 07:19 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
一、数码管动态显示概述
LED数码管动态显示接口是单片机中应用最为广泛的一种显示方式之一。
动态驱动是将所有数码管的8个显示笔划(段选端)“a,b,c,d,e,fg,dp”的同名端连在一起,另外为每个数码管的公共极COM增加位选通控制电路,位选通由各自独立的I/O线控制。当单片机输出字形码时,单片机先对位选通COM端电路进行控制,再对段选通进行输出,该位就显示出字形,没有选通的数码管就不会亮。
通过分时轮流控制各个数码管的的COM端,就使各个数码管轮流受控显示,这就是动态驱动。
在轮流显示过程中,每位数码管的点亮时间为1~2ms,由于人的视觉暂留现象及发光二极管的余辉效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示数据,不会有闪烁感,动态显示的效果和静态显示是一样的,能够节省大量的I/O端口,而且功耗更低。
二、动态数码管原理图
(1)原理图





(2)动态数码管如何与芯片相连



(3)“此器件” ——>锁存器74HC573
74HC573的八个锁存器都是透明的D型锁存器,当使能(G)为高时,0输出将随数据(D)输入而变当使能为低时,将输出锁存在已建立的数据电平上。
输出控制不影响锁存器的内部工作,即老数据可以保持,甚至当输出被关闭时,新的数据也可以置入。
这种电路可以驱动大电容或低阻抗负载,可以直接与系统总线接口并驱动总线,而不需要外接口。特别适用于缓冲寄存器,1/0通道,双向总线驱动器和工作寄存器。



Y7C为高电平,a-dp会随着p0变化;Y7C为低电平时,锁存置为低电平的那一刻的数据,不再变化
Y7C和Y6C同时只能有一个为低电平

三、动态数码管显示例程
(1)例程1:两个数码管显示不同内容。本例以第一个数码管显示数字“0”,第二个数码管显示数字“1”为例。
//头文件声明区域
#include <STC15F2K60S2.H>
#include<intrins.h>

//变量声明区域
unsigned int i = 0;

//函数声明区域
void Delay(int ms);



//程序主体
void main()
{
        P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;//初始化程序  

        while(1)
        {
                P2=0XC0;P0=0X01;//打开控制数码管位选的锁存器,然后选中第一个数码管
                P2=0XFF;P0=0XC0;//大家控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay(1);
               
                P2=0XC0;P0=0X02;//打开控制数码管位选的锁存器,然后选中第二个数码管
                P2=0XFF;P0=0XF9;//打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay(1);
               
               
        }       
               
}


//函数定义区域
void Delay(int ms)                //@11.0592MHz
{
        unsigned char i, j;
        for(i = 0;i < ms;i++)
        {
                _nop_();
        _nop_();
        _nop_();
        i = 11;
        j = 190;
        do
        {
                while (--j);
        } while (--i);
                               
        }
       
}

(2)例程2:多个数码管显示不同内容(二)。注:创建数码管显示子函数。
#include <STC15F2K60S2.H>
#include<intrins.h>

void Delay_MS(unsigned int MS);

void main(void)
{
        IO_Init();
       
        P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;                //初始化程序,后期详解;
       
        while(1)
        {
                P2=0XC0;P0=0X01;         //打开控制数码管位选的锁存器,然后选中第一个数码管
                P2=0XFF;P0=0XC0;        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);
               
                P2=0XC0;P0=0X02;         //打开控制数码管位选的锁存器,然后选中第二个数码管
                P2=0XFF;P0=0XF9;        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);
               
                P2=0XC0;P0=0X04;         //打开控制数码管位选的锁存器,然后选中第三个数码管
                P2=0XFF;P0=0XF9;        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);
               
                P2=0XC0;P0=0X08;         //打开控制数码管位选的锁存器,然后选中第四个数码管
                P2=0XFF;P0=0XF9;        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);
               
                P2=0XC0;P0=0X10;         //打开控制数码管位选的锁存器,然后选中第五个数码管
                P2=0XFF;P0=0XF9;        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);
               
                P2=0XC0;P0=0X20;         //打开控制数码管位选的锁存器,然后选中第六个数码管
                P2=0XFF;P0=0XF9;        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);
               
                P2=0XC0;P0=0X40;         //打开控制数码管位选的锁存器,然后选中第七个数码管
                P2=0XFF;P0=0XF9;        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);
               
                P2=0XC0;P0=0X80;         //打开控制数码管位选的锁存器,然后选中第八个数码管
                P2=0XFF;P0=0XF9;        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);
        }
}

void Delay_MS(unsigned int MS)
{
        unsigned char i, j;
        for(i = 0;i < ms;i++)
        {
                _nop_();
        _nop_();
        _nop_();
        i = 11;
        j = 190;
        do
        {
                while (--j);
        } while (--i);
                               
        }
       
}



(3)例程3:多个数码管显示不同内容(二)。注:创建数码管显示子函数。
①法一:
//头文件声明区域
#include <STC15F2K60S2.H>
#include<intrins.h>

//变量声明区域
unsigned int i = 0;
unsigned char DSEG[]= {0X00,0X01,0X02,0X04,0X08,0X10,0X20,0X40,0X80};
unsigned char code SEG[] = {0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};

//函数声明区域
void Delay(int ms);
void DSED_Display(unsigned char dseg,unsigned char seg);



//程序主体
void main()
{
        P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;//初始化程序  
       
        while(1)
        {
         DSED_Display(1,1);
   DSED_Display(2,2);
         DSED_Display(3,3);
         DSED_Display(4,4);
         DSED_Display(5,5);
   DSED_Display(6,6);
         DSED_Display(7,7);
         DSED_Display(8,8);

               
               
        }       
               
}


//函数定义区域
void Delay(int ms)                //@11.0592MHz
{
        unsigned char i, j;
        for(i = 0;i < ms;i++)
        {
                _nop_();
        _nop_();
        _nop_();
        i = 11;
        j = 190;
        do
        {
                while (--j);
        } while (--i);
                               
        }
       
}

void DSED_Display(unsigned char dseg,unsigned char seg)
{
        P0 = 0XFF;//消影
        P2=0XC0;P0=DSEG[dseg];//打开控制数码管位选的锁存器,然后选中第一个数码管
        P2=0XFF;P0=SEG[seg];
        Delay(1);
       
       
}

②法二:

#include <STC15F2K60S2.H>
#include<intrins.h>

unsigned char tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
//unsigned char code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};

unsigned char SEG1,SEG2,SEG3,SEG4,SEG5,SEG6,SEG7,SEG8;

void Delay(int ms);
void SEG_Display(unsigned char yi,unsigned char er,unsigned char san,unsigned char si,unsigned char wu,unsigned char liu,unsigned char qi,unsigned char ba);

void main(void)
{
       
        P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;                //初始化程序,后期详解;

       
        while(1)
        {
                SEG1=1,SEG2=2,SEG3=3,SEG4=4,SEG5=5,SEG6=6,SEG7=7,SEG8=8;
                SEG_Display(SEG1,SEG2,SEG3,SEG4,SEG5,SEG6,SEG7,SEG8);
        }
}

void SEG_Display(unsigned char yi,unsigned char er,unsigned char san,unsigned char si,unsigned char wu,unsigned char liu,unsigned char qi,unsigned char ba)
{
                P0=0XFF;
                P2=0XC0;P0=0X01;         //打开控制数码管位选的锁存器,然后选中第一个数码管
                P2=0XFF;P0=tab[yi];        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);
               
                P0=0XFF;
                P2=0XC0;P0=0X02;         //打开控制数码管位选的锁存器,然后选中第二个数码管
                P2=0XFF;P0=tab[er];        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);
               
                P0=0XFF;
                P2=0XC0;P0=0X04;         //打开控制数码管位选的锁存器,然后选中第三个数码管
                P2=0XFF;P0=tab[san];        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);
               
                P0=0XFF;
                P2=0XC0;P0=0X08;         //打开控制数码管位选的锁存器,然后选中第四个数码管
                P2=0XFF;P0=tab[si];        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);
               
                P0=0XFF;
                P2=0XC0;P0=0X10;         //打开控制数码管位选的锁存器,然后选中第五个数码管
                P2=0XFF;P0=tab[wu];        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);
               
                P0=0XFF;
                P2=0XC0;P0=0X20;         //打开控制数码管位选的锁存器,然后选中第六个数码管
                P2=0XFF;P0=tab[liu];        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);
               
                P0=0XFF;
                P2=0XC0;P0=0X40;         //打开控制数码管位选的锁存器,然后选中第七个数码管
                P2=0XFF;P0=tab[qi];        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);
               
                P0=0XFF;
                P2=0XC0;P0=0X80;         //打开控制数码管位选的锁存器,然后选中第八个数码管
                P2=0XFF;P0=tab[ba];        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);       
}

void Delay(int ms)                //@11.0592MHz
{
        unsigned char i, j;
        for(i = 0;i < ms;i++)
        {
                _nop_();
        _nop_();
        _nop_();
        i = 11;
        j = 190;
        do
        {
                while (--j);
        } while (--i);
                               
        }
       
}



③法三

#include <STC15F2K60S2.H>
#include<intrins.h>

//#define uchar unsigned char
//#define uint unsigned int
       
typedef unsigned char uchar ;
typedef unsigned int uint ;

unsigned char tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
//unsigned char code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};

unsigned char SEG1,SEG2,SEG3,SEG4,SEG5,SEG6,SEG7,SEG8;

void Delay(int ms);
void SEG_Display12(uchar yi,uchar er);
void SEG_Display34(uchar san,uchar si);
void SEG_Display56(unsigned char wu,unsigned char liu);
void SEG_Display78(unsigned char qi,unsigned char ba);

void main(void)
{

       
        P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;                //初始化程序,后期详解;

        while(1)
        {
                SEG1=1,SEG2=2,SEG3=3,SEG4=4,SEG5=5,SEG6=6,SEG7=7,SEG8=8;
               
                SEG_Display12(SEG1,SEG2);
                SEG_Display34(SEG3,SEG4);
                SEG_Display56(SEG5,SEG6);
                SEG_Display78(SEG7,SEG8);
        }
}


void SEG_Display12(unsigned char yi,unsigned char er)
{
                P0=0XFF;
                P2=0XC0;P0=0X01;         //打开控制数码管位选的锁存器,然后选中第一个数码管
                P2=0XFF;P0=tab[yi];        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);
               
                P0=0XFF;
                P2=0XC0;P0=0X02;         //打开控制数码管位选的锁存器,然后选中第二个数码管
                P2=0XFF;P0=tab[er];        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);       
}

void SEG_Display34(unsigned char san,unsigned char si)
{
                P0=0XFF;
                P2=0XC0;P0=0X04;         //打开控制数码管位选的锁存器,然后选中第三个数码管
                P2=0XFF;P0=tab[san];        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);
               
                P0=0XFF;
                P2=0XC0;P0=0X08;         //打开控制数码管位选的锁存器,然后选中第四个数码管
                P2=0XFF;P0=tab[si];        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);       
}

void SEG_Display56(unsigned char wu,unsigned char liu)
{
                P0=0XFF;
                P2=0XC0;P0=0X10;         //打开控制数码管位选的锁存器,然后选中第五个数码管
                P2=0XFF;P0=tab[wu];        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);
               
                P0=0XFF;
                P2=0XC0;P0=0X20;         //打开控制数码管位选的锁存器,然后选中第六个数码管
                P2=0XFF;P0=tab[liu];        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);
}
void SEG_Display78(unsigned char qi,unsigned char ba)
{
                P0=0XFF;
                P2=0XC0;P0=0X40;         //打开控制数码管位选的锁存器,然后选中第七个数码管
                P2=0XFF;P0=tab[qi];        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);
               
                P0=0XFF;
                P2=0XC0;P0=0X80;         //打开控制数码管位选的锁存器,然后选中第八个数码管
                P2=0XFF;P0=tab[ba];        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);               
}


void Delay(int ms)                //@11.0592MHz
{
        unsigned char i, j;
        for(i = 0;i < ms;i++)
        {
                _nop_();
        _nop_();
        _nop_();
        i = 11;
        j = 190;
        do
        {
                while (--j);
        } while (--i);
                               
        }
       
}

(4)例程4:多位数码管倒计时。本例以第6、7、8位数码管显示255→0的倒计时为例,其他数码管保持熄灭。
#include <STC15F2K60S2.H>
#include<intrins.h>

#define uchar unsigned char
#define uint unsigned int

unsigned char tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
//unsigned char code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};

unsigned char SEG1,SEG2,SEG3,SEG4,SEG5,SEG6,SEG7,SEG8;
unsigned char Num = 255 ;
unsigned char Num_Refresh = 0 ;

void Delay(uint MS);
void SEG_Display12(uchar yi,uchar er);
void SEG_Display34(uchar san,uchar si);
void SEG_Display56(unsigned char wu,unsigned char liu);
void SEG_Display78(unsigned char qi,unsigned char ba);

void main(void)
{
       
        P2=0XA0;P0=0X00;P2=0X80;P0=0XFF;                //初始化程序,后期详解;
        P2=0XC0;P0=0X01;P2=0XFF;P0=0XFF;                //打开第一个数码管,后期详解;
       
        SEG1=11,SEG2=11,SEG3=11,SEG4=11,SEG5=11;
        SEG6=2,SEG7=5,SEG8=5;
        while(1)
        {               
               
          if(++Num_Refresh==125)
                {
                        Num_Refresh = 0 ;
                        Num = Num -1; //Num--;
                        SEG6=Num/100,SEG7=Num%100/10,SEG8=Num%10;
                }
               
                SEG_Display12(SEG1,SEG2);
                SEG_Display34(SEG3,SEG4);
                SEG_Display56(SEG5,SEG6);
                SEG_Display78(SEG7,SEG8);
        }
}


void SEG_Display12(unsigned char yi,unsigned char er)
{
                P0=0XFF;
                P2=0XC0;P0=0X01;         //打开控制数码管位选的锁存器,然后选中第一个数码管
                P2=0XFF;P0=tab[yi];        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);
               
                P0=0XFF;
                P2=0XC0;P0=0X02;         //打开控制数码管位选的锁存器,然后选中第二个数码管
                P2=0XFF;P0=tab[er];        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);       
}

void SEG_Display34(unsigned char san,unsigned char si)
{
                P0=0XFF;
                P2=0XC0;P0=0X04;         //打开控制数码管位选的锁存器,然后选中第三个数码管
                P2=0XFF;P0=tab[san];        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);
               
                P0=0XFF;
                P2=0XC0;P0=0X08;         //打开控制数码管位选的锁存器,然后选中第四个数码管
                P2=0XFF;P0=tab[si];        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);       
}

void SEG_Display56(unsigned char wu,unsigned char liu)
{
                P0=0XFF;
                P2=0XC0;P0=0X10;         //打开控制数码管位选的锁存器,然后选中第五个数码管
                P2=0XFF;P0=tab[wu];        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);
               
                P0=0XFF;
                P2=0XC0;P0=0X20;         //打开控制数码管位选的锁存器,然后选中第六个数码管
                P2=0XFF;P0=tab[liu];        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);
}
void SEG_Display78(unsigned char qi,unsigned char ba)
{
                P0=0XFF;
                P2=0XC0;P0=0X40;         //打开控制数码管位选的锁存器,然后选中第七个数码管
                P2=0XFF;P0=tab[qi];        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);
               
                P0=0XFF;
                P2=0XC0;P0=0X80;         //打开控制数码管位选的锁存器,然后选中第八个数码管
                P2=0XFF;P0=tab[ba];        //打开控制数码管段选的锁存器,然后给上述打开的数码管输出码值
                Delay_MS(1);               
}


void Delay(uint MS)        //@11.0592MHz
{
        unsigned char i, j;
        for(i = 0;i < ms;i++)
        {
                _nop_();
        _nop_();
        _nop_();
        i = 11;
        j = 190;
        do
        {
                while (--j);
        } while (--i);
                               
        }





————————————————

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

原文链接:https://blog.csdn.net/La_gloire/article/details/136304399

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

29

主题

80

帖子

0

粉丝