【手把手教你51单片机】数码管的学习

注:本文章转载自《手把手教你学习51单片机》!因转载需要原文链接,故无法选择转载!
如若侵权,请联系我进行删除!上传至网络博客目的为了记录自己学习的过程的同时,同时能够帮助其他一同学习的小伙伴!

数码管的学习

LED小灯是一种简单的LED,只能通过亮和灭来表达简单的信息。而本节我们要学一种能够表达更复杂信息的器件——LED数码管。

数码管的基本介绍

先给大家提供一张原理图看一下,如图5-3所示。
20230116_1
这是比较常见的数码管的原理图,我们板子上一共有6个数码管。前边有了LED小灯的学习,数码管学习就会轻松很多。从图5-3可以看出来,数码管一共有a,b,c,d,e,f,g,dp这么8个段,而实际上,这8个段每一段都是一个LED小灯,所以一个数码管就是由8个LED小灯组成的。我们看一下数码管内部结构的示意图,如图5-4.
20230116_2
数码管分为共阳极和共阴极两种,共阴数码管就是8只LED小灯的阴极是连接在一起的,阴极是公共端,由阳极来控制单个小灯的亮灭。同理,共阳数码管就是阳极连接在一起,大家可以认真研究下图5-4.细心的同学会发现,图5-3的数码管上边有2个com,这就是我们数码管的公共端。为什么有两个呢?一方面是两个可以起到对称的效果,刚好是10个引脚,另外一个方面,公共端通过的电流较大,我们初中就学过,并联电路电流之和等于总电流,用2个com可以把公共电流平均到2个引脚上去,降低单条电路所承受的电流。
从我们开发板的电路图上可以看出来,我们所用的数码管都是共阳数码管,一共有6个,如图5-5所示:
20230116_3
6个数码管的com都是接到了正极上,当然了,和LED小灯电路一样,也是由74HC138控制三极管的导通来控制整个数码管的使能。先来看最右边的DS1这个数码管,原理图上可以看出,控制DS1的三极管是Q17,控制Q17的引脚是LEDS0,对应到74HC138上边就是U3的Y0输出,如图5-6所示:
20230116_4
我们现在的目的是让LEDS0这个引脚输出低电平,相信大家现在可以根据前边学过的知识独立把ADDR0,ADDR1,ADDR3,ADDR4这4个所需输入的值写出来了,现在大家不要偷懒,根据74HC138的手册去写一下,不需要你记住这些结论,但是遇到就写依次,锻炼过几次之后,遇到同类芯片自己就知道如何去解决问题了。
数码管通常是用来显示数字的,我们板子上有6个数码管,习惯上称之为6位,那控制位选择的就是74HC138了。而数码管内部的8个LED小灯我们称之为数码管的段,那么数码管的段选择(即该段的亮灭)是通过P0口控制,经过74HC245驱动。

数码管的真值表

数码管的8个段,我们直接当成8个LED小灯来控制,那就是a,b,c,d,e,f,g,dp一共8个LED小灯。我们通过图5-3可以看出,如果点亮b和c这两个小灯,也就是数码管的b段和c段,其他的所有的段都熄灭的话,就可以让数码管显示出数字1,那么这个时候实际上P0的值就是0b11111001,十六进制就是0xF9.那么我们写一个程序进去,去看一看数码管显示的效果。

#include <reg52.h>

sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;

void main(void)
{
    ENLED = 0;//使能U3,选择数码管DS1
    ADDR3 = 1;
    ADDR2 = 0;
    ADDR1 = 0;
    ADDR0 = 0;
    P0 = 0xF9;  //点亮数码管段b和c
    while(1);
}

大家把这个程序编译一下,并下载到单片机中,就可以看到程序运行的结果是在最右侧的数码管上显示了一个数字1.
用同样的方法,我们可以把其他的数字字符在数码管上显示出来,而数码管显示的数字字符对应给P0赋值,我们叫做数码管的真值表。 我们来列一下我们这个电路图的数码管真值表,注意,这个真值表里显示的数字都不带小数点的,如表5-7.
20230116_5
我们可与把上边那个用数码管显示数字1程序中的P0赋值随便修改成表5-7真值表中的数值,看看显示数字的效果。

数码管的静态显示

在前面的章节我们学习了74HC138.了解到74HC138在同一时刻只能让一个输出口为低电平,也就是说在同一时刻内我们只能使用一个数码管,并根据我们给出的P0的值来改变这个数码管显示的字符,我们可以将此理解为数码管的静态显示。
数码管静态显示是对应动态显示而言的,静态显示对于一两个数码管还行,多个数码管,静态显示实现的意义就没有了。这节课我们先利用一个数码管的静态显示来实现一个简单的秒表,为下节课的动态显示打下基础。
先来介绍一下51单片机的关键字

code

我们前面课程定义变量时,一般用到unsigned char 或者 unsigned int 这两个关键字,这样定义的变量都是放在我们的单片机的RAM中,我们在程序中可以随意去改变这些变量的值。但是还有一种数据,我们在程序中要使用,但是却不会改变它们的值,定义这种数据时可以加一个code 关键字修饰一下,这个数据就会存储到我们的程序空间Flash中,这样可以大大节省单片机的RAM的使用量,毕竟我们的单片机RAM空间比较小,而程序空间则大得多。那么现在要使用的数码管真值表,我们只会使用它们的值,而不需要改变它们,就可以用code 关键字把它们放入Flash中了,具体代码如下:

#include <reg52.h>

sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;

//用数组来存储数码管的真值表,数组将在下一章节详细介绍
unsigned char code LedChar[] = {
    0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
    0x80,0x90,0x88,0x83,0xC6,0xA1,0x860x8E
}
void main()
{

    unsigned char cnt = 0;  //记录T0中断次数
    unsigned char sec = 0;  //记录经过的秒数

    ENLED = 0;  //使能U3,选择数码管DS1
    ADDR3 = 1;
    ADDR2 = 0;
    ADDR1 = 0;
    ADDR0 = 0;
    TMOD = 0x01;//设置T0为模式1
    TH0 = 0xB0;
    TL0 = 0x00;
    TR0 = 1;    //启动T0

    while(1)
    {
        if(TF0 == 1)//判断T0是否溢出
        {
            TF0 = 0;    //T0溢出后,清零中断标志
            TH0 = 0xB0; //并重新赋初值
            TL0 = 0x00; 
            cnt++;
            if(cnt>=50)
            {
                cnt = 0;//达到50次之后计数值清零
                P0 = LedChar[sec];//当前秒数对应的真值表中的值送到P0口
                sec++;
                if(sec>=16)
                {
                    sec = 0;
                    
                }
            }
        }
    }

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值