4位8段数码管的基本介绍与在80c51单片机上使用4位8段数码管显示数字。

4位8段数码管

简介

在Proteus中有着4种4位8段数码管,主要分为共阴极和共阳极两种。4位8段数码管右侧的8个引脚是各位数码管共用的,左侧的4个引脚分别是每位数码管的公共阴极。

特性

根据上述介绍,得出4位8段数码管的特性如下:

在同一时刻,每位数码管只能显示相同的数字。

每位数码管在同一时刻是否导通是相互独立的。

4位8段数码管的使用

在80c51单片机上使用4位8段数码管显示数字1234。

因为4位8段数码管特性的原因,无法在同一时刻显示1234,因此可以利用人的视觉暂留(Persistence of vision)现象(余晖效应)来实现类似的效果。即在短时间内,分别在第1、2、3、4位数码管显示1、2、3、4来使人在视觉上看到数码管显示1234。

原理图部分

数码管左侧8个引脚接P0口,P0口做一般I/O口时需要外接电阻,数码管右侧4个引脚接P2口的低4位。

原理图

代码部分

程序逻辑主要包括:

  1. 获取数据的每一位
  2. 在数码管逐个显示数据的每一位

获取数据的每一位

该操作通过如下公式实现:

千位:(data%10000)/1000

百位:(data%1000)/100

十位:(data%100)/10

个位:(data%10)/1

根据该公式很容易可以写出代码。

显示数据

4位8段数码管显示数据可以重用在上一篇博文所使用的编码函数。

上一篇博文:

完整代码

代码太过繁杂,后续想办法进行优化。

第一版

#include <reg51.h>

#define bool bit
#define true 1
#define false 0

//4位数码管结构体
struct Dts{
    char DT1;
    char DT2;
    char DT3;
    char DT4;
};

//编码函数
char DT_Convert(char numb){
    switch(numb){
        case 0:
            return 0x3F;
        case 1:
            return 0x06;
        case 2:
            return 0x5B;
        case 3:
            return 0x4F;
        case 4:
            return 0x66;
        case 5:
            return 0x6D;
        case 6:
            return 0x7D;
        case 7:
            return 0x07;
        case 8:
            return 0x7F;
        case 9:
            return 0x6F;
        case 10:
            return 0x77;
        case 11:
            return 0x7C;
        case 12:
            return 0x39;
        case 13:
            return 0x5E;
        case 14:
            return 0x79;
        case 15:
            return 0x71;
        default:
            return 0x00;
    }
}

//填充结构体
bool Set_Dts(int dat,struct Dts* dtsp){
    if(dat>9999||dat<-999){
        return false;
    }
    if(dat<0){
        dtsp->DT1=0x40;
        dat=-dat;
    }
    else{
        dtsp->DT1=DT_Convert((dat%10000)/1000);
    }
    dtsp->DT2=DT_Convert((dat%1000)/100);
    dtsp->DT3=DT_Convert((dat%100)/10);
    dtsp->DT4=DT_Convert((dat%10)/1);
    
    return true;
}

//延时
void Delay(){
    unsigned int i=100;
      while(--i);
}

//显示4位数码管(短时间)
bool DT_Show(struct Dts* dtsp){
    P2=0x0E;
    P0=dtsp->DT1;
    Delay();
    P0=0x00;
    
    P2=0x0D;
    P0=dtsp->DT2;
    Delay();
    P0=0x00;
    
    P2=0x0B;
    P0=dtsp->DT3;
    Delay();
    P0=0x00;
    
    P2=0x07;
    P0=dtsp->DT4;
    Delay();
    P0=0x00;
    
    return true;
}

//显示4位数码管(长时间)
void Show(unsigned int max,int numb){
    struct Dts dts={0,0,0,0};
    unsigned int i=0;
    
    Set_Dts(numb,&dts);
    while(i<max){
        DT_Show(&dts);
    }
}

void main(){
    while(1)
    {
        Show(100000,1234);
    }
}

第二版

#include <reg51.h>

#define bool bit
#define true 1
#define false 0

//4位数码管结构体
struct Dts{
    char DT1;
    char DT2;
    char DT3;
    char DT4;
};

//共阴数码管编码表
char Code_Table[16]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};

//填充结构体
bool Set_Dts(int dat,struct Dts* dtsp){
    if(dat>9999||dat<-999){
        return false;
    }
    if(dat<0){
        dtsp->DT1=0x40;
        dat=-dat;
    }
    else{
        dtsp->DT1=Code_Table[(dat%10000)/1000];
    }
    dtsp->DT2=Code_Table[(dat%1000)/100];
    dtsp->DT3=Code_Table[(dat%100)/10];
    dtsp->DT4=Code_Table[(dat%10)/1];
    
    return true;
}

bool DT_Show(struct Dts* dtsp){
    unsigned int i=1;
    char* p=&dtsp->DT1;
    for(;i<16;i*=2,p++){
        P0=0x00;
        P2=~i;
        P0=*p;
    }
    return true;
}

void Show(unsigned int max,int numb){
    struct Dts dts={0,0,0,0};
    unsigned int i=0;
    
    Set_Dts(numb,&dts);
    while(i<max){
        DT_Show(&dts);
    }
}

void main(){
    while(1){
        Show(100000,1234);
    }
}

结语

目前代码实现的是能显示在9999~-999的任意整数,难点主要是对每位数码管时序的控制,以及利用视觉暂留现象,需要尽量让亮的时间大于灭的时间。

Last modification:May 18th, 2020 at 11:00 am