四、数码管

LED数码管:数码管是一种简单、廉价的显示器,是由多个发光二极管封装在一起组成“8”字型的器件

 

 一、数码管引脚定义

         在右边的两张图上,分别为两种数码管的连接方式,上面那种为共阴极连接,下面这种为共阳极连接。左下方这两张图第一张标注了数码管段的定义,第二张则为数码管连接的引脚口。在右图中可以看到引脚口的排布很乱,但是根据左图可知数码管上的各led灯段都和最近的引脚相连,就近引出。

         如果我们想要在数码管上点亮一个数字6,需要将对应段上的LED灯点亮,由于开发板为共阴极连接,所以阴极已经全置为0,我们需要在阳极上给各个I/O口置1才能将对应的LED灯点亮。所以要将A、C、D、E、F、G点亮,需要给7、4、2、1、9、10置1,也就是将对应的段码置为1。

        开发板上的为4位一体的开发板,他们的每一位各自的共阴极都引出去了,他们的位选段都接在一起,例如所有的A都接在11上面,如果想在第三个地方显示1,其他地方不亮,则将其他数码管的共阴极置1,接在阳极上,三号位数码管则置0,接阴极上,再将B、C置为1,则三号位置显示数字1。

        但是这种公用引脚的数码管的缺点在于,只可以同时点亮一个数码管,或者点亮多个显示一样的数码管,但是这种共用引脚可以节省单片机的I/O口,操作时用更少的引脚。

        那我们怎么样让他不同的数码管显示内容不一样呢?这样则需要利用人眼视觉暂存和LED的余晖现象。例如很快的让第一个数码管显示1,第二个数码管显示2,第三个数码管显示3,在快速的扫描,这样就能看到3个数字同时显示了

二、原理图

        数码管的LED1~8接在了138译码器的输出端,138译码器能够使右边Y0~Y7八个端口变成右边A、B、C三个端口控制的,左下角三个引脚是使能端,相当于开关,如果使能电平有效的话,138译码器才工作,没有效的话就不工作。这个开关需要把G1接上高电平1,G2A、G2B接上低电平0,才能工作,在原理图中,G1是接在正极上,G2A、G2B是接在负极上,所以138译码器上电就工作。

138译码器的工作原理: 

C

B

A

Y

0

0

0

Y0

0

0

1

Y1

0

1

0

Y2

0

1

1

Y3

1

0

0

Y4

1

0

1

Y5

1

1

0

Y6

1

1

1

Y7

        在左边A、B、C三个端口中,C为最高位,A为最低位,将这三个端口的高低电平信号组成的二进制数翻译为10进制数得到的数字就表示对应的数码管I/O口置为0,而其他的则置为1。 

 

 

        在我使用的51单片机中,数码管为共阴极连接,而在上图中可以看到,数码管的阳极连接着一个74HC245芯片,这个芯片的称为双向数据缓冲器,他的作用是用来提高驱动能力的,由于单片机功率较小,所以一般情况低电平驱动能力强,高电平驱动能力弱,如果CPU的I/O口直接连在数码管的引脚上会导致效果不明显或者看不到效果,但是有双向数据缓冲器后,CPU过来的电流就变成了一种电信号,只要很微弱就能有效,再由双向数据缓冲器用自己芯片上接的正极电流给到数码管,这个过程也成为弱电控制强电

        芯片上的OE的作用也是使能,低电平的时候该芯片工作,高电平的时候,该芯片不工作,所以OE接在地上,DIR(Direction Port)是方向端口。它是一种数字输入输出口,通常用于控制电机、步进电机、LED灯等设备的方向。用DIR的值来判断是将左边的数据传输到右边还是把右边的数据读到左边。因为数码管的数据不需要读回来,只需要传输过去就好,所以DIR口接在LE上,LE上接了个跳线帽使他短路,接在了VCC上使得LE一直为高电平(在新版中,DIR则是直接接在VCC正极上)。

        在电源正极vcc上接着一个电容C22,他的作用是滤波。

电容的大小和电阻的大小看法一致,104的含义代表着10x10^4,也就是100 000pF。一般读为一百千。

电容的单位,pf是最小的电容单位。

1000pf = nF

1000nf = uF

1000uf = mF

1000mf = F

RP4和RP5是4位一体的排阻,作用是限流电阻,防止数码管电流过大

三、静态数码管显示

        现在我们想在LED6上显示一个数字6,由上面介绍可知,需要将译码器P24,P23、P22上的二进制数转化为10进制的5,再段选,将对应的数码段点亮,若要显示6,则b段和dp段不点亮,B0~B7为 1011 1110,I/O口的大段对应着地址的大段,所以转化为16进制时应该为0111 1101,也就是0x7D 

#include <REGX52.H>
void main()
{
        P2_4 = 1;
        P2_3 = 0;
        P2_2 = 1;
        P0 = 0x7D;
        while(1)
        {         
        }
}   

模块化编程:

模块化编程是一种将程序分解为多个模块或子程序的编程方法,每个模块或子程序都负责完成特定的任务或功能。模块化编程具有以下好处:

  1. 代码复用:模块化编程可以使代码更加模块化和可复用,可以在不同的项目中重复使用模块,提高代码的效率和可维护性。

  2. 分工合作:模块化编程可以使多个程序员分工合作,每个程序员负责开发和维护自己的模块,提高开发效率和代码质量。

  3. 可维护性:模块化编程可以使程序结构更加清晰和易于维护,可以更快地定位和修复错误,降低程序维护成本。

  4. 灵活性:模块化编程可以使程序更加灵活和可扩展,可以根据具体需求添加或删除模块,提高程序的适应性和可扩展性。

  5. 测试容易:模块化编程可以使程序的测试更加容易和有效,可以单独测试每个模块,以确保程序的正确性和稳定性。

#include <REGX52.H>

unsigned char nember[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x07,0x7f,0x6f};

void nixie(unsigned char Locating,Number)
{
        switch(Locating)
        {
                case 1: P2_4 = 1; P2_3 = 1; P2_2 = 1;break;        
                case 2: P2_4 = 1; P2_3 = 1; P2_2 = 0;break;        
                case 3: P2_4 = 1; P2_3 = 0; P2_2 = 1;break;        
                case 4: P2_4 = 1; P2_3 = 0; P2_2 = 0;break;        
                case 5: P2_4 = 0; P2_3 = 1; P2_2 = 1;break;        
                case 6: P2_4 = 0; P2_3 = 1; P2_2 = 0;break;        
                case 7: P2_4 = 0; P2_3 = 0; P2_2 = 1;break;                        
                case 8: P2_4 = 0; P2_3 = 0; P2_2 = 0;break;        
        }
        P0 = nember[Number];
}
void main()
{
        nixie(2,2);
        while(1)
        {
                
        }

} 

四、动态数码管显示

有了前面的模块化编程,我们可以很方便的让静态的数码管显示,变成动态的数码管显示,但是在动态显示的过程中,会有显示错乱的情况,这个时候就需要进行消影。

显示错乱的原理:

        在我们进行动态数码管显示时,进行的是,位选 段选 位选 段选 位选 段选,在这个过程中,第二次的段选数据还没有过来时,已经进行了第二次的位选,而将第一次的段选数据给到了第二次的位选上,所以造成了显示错乱的现象。

消影:

        在第二次位选之前,第一次段选之后,将第一次的段选择清零,这样就不会影响到下一个数码管段的显示。

#include <REGX52.H>

unsigned char nember[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x07,0x7f,0x6f};

void Delay1ms()                //@11.0592MHz
{
        unsigned char i, j;
        i = 2;
        j = 199;
        do
        {
           while (--j);
        } while (--i);
}


void nixie(unsigned char Locating,Number)
{
        switch(Locating)
        {
                case 1: P2_4 = 1; P2_3 = 1; P2_2 = 1;break;        
                case 2: P2_4 = 1; P2_3 = 1; P2_2 = 0;break;        
                case 3: P2_4 = 1; P2_3 = 0; P2_2 = 1;break;        
                case 4: P2_4 = 1; P2_3 = 0; P2_2 = 0;break;        
                case 5: P2_4 = 0; P2_3 = 1; P2_2 = 1;break;        
                case 6: P2_4 = 0; P2_3 = 1; P2_2 = 0;break;        
                case 7: P2_4 = 0; P2_3 = 0; P2_2 = 1;break;                        
                case 8: P2_4 = 0; P2_3 = 0; P2_2 = 0;break;        
        }
        P0 = nember[Number];
        Delay1ms();
        P0 = 0x00;
}
void main()
{
        while(1)
        {
               nixie(1,1);
               nixie(2,2);
               nixie(3,3); 
        }

} 

 五、数码管的驱动方式

 

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是DHT11湿度温度传感器和四数码管显示的μVision4代码实现: ``` #include <reg52.h> #define DHT11_DATA P1_0 sbit LSA=P2^2; sbit LSB=P2^3; sbit LSC=P2^4; sbit beep=P2^5; unsigned char code table[]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90 }; //共阴数码管0~9的编码 unsigned char RH,TEMP; //湿度和温度 unsigned char T_DATA_H,T_DATA_L,RH_DATA_H,RH_DATA_L,checkdata; //DHT11数据 void delay(unsigned int time) //延时函数 { unsigned int i,j; for (i=0;i<time;i++) { for (j=0;j<110;j++); } } void delay_us(unsigned int time) //微秒延时函数 { unsigned int i; for (i=0;i<time;i++); } void start_work() //DHT11开始工作 { unsigned char i; DHT11_DATA=0; //主机将总线拉低至少18ms delay(20); DHT11_DATA=1; //发送起始信号,总线由上拉电阻拉高 delay_us(20); //主机延时20~40us DHT11_DATA=0; //主机将总线拉低80us delay_us(80); DHT11_DATA=1; //主机将总线拉高,等待DHT11响应信号 while(DHT11_DATA); while(!DHT11_DATA); while(DHT11_DATA); for (i=0;i<8;i++) //接收湿度整数部分数据 { while(!DHT11_DATA); delay_us(40); RH_DATA_H<<=1; RH_DATA_H|=DHT11_DATA; while(DHT11_DATA); } for (i=0;i<8;i++) //接收湿度小数部分数据 { while(!DHT11_DATA); delay_us(40); RH_DATA_L<<=1; RH_DATA_L|=DHT11_DATA; while(DHT11_DATA); } for (i=0;i<8;i++) //接收温度整数部分数据 { while(!DHT11_DATA); delay_us(40); T_DATA_H<<=1; T_DATA_H|=DHT11_DATA; while(DHT11_DATA); } for (i=0;i<8;i++) //接收温度小数部分数据 { while(!DHT11_DATA); delay_us(40); T_DATA_L<<=1; T_DATA_L|=DHT11_DATA; while(DHT11_DATA); } for (i=0;i<8;i++) //接收校验码 { while(!DHT11_DATA); delay_us(40); checkdata<<=1; checkdata|=DHT11_DATA; while(DHT11_DATA); } } void main() { unsigned char i; while(1) { start_work(); //DHT11开始工作 RH=RH_DATA_H; //湿度整数部分 TEMP=T_DATA_H; //温度整数部分 LSA=0; //选中第一位数码管 P0=table[TEMP/10]; //写入温度整数位 delay(5); LSA=1; //关闭第一位数码管 LSB=0; //选中第二位数码管 P0=table[TEMP%10]; //写入温度小数位 delay(5); LSB=1; //关闭第二位数码管 LSC=0; //选中第三位数码管 P0=table[RH/10]; //写入湿度整数位 delay(5); LSC=1; //关闭第三位数码管 LSA=0; //选中第四位数码管 P0=table[RH%10]; //写入湿度小数位 delay(5); LSA=1; //关闭第四位数码管 } } ``` 注意事项: 1. 本代码中使用的是STC89C51单片机,如果使用其他型号的单片机需要修改对应的IO端口。 2. DHT11需要一定的时间来完成数据读取和校验,因此需要适当的延时,否则会出现读取错误。 3. 数码管显示的部分需要根据具体的电路连接进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值