清翔零基础教你学51单片机_个人学习笔记(5)_数码管静态和动态显示

说明

本人使用的是清翔的51单片机开发板,如果型号相同最方便,但是如果型号不同也可以参考,因为芯片都是一样的,只是外设不同而已,使用时只需要对照自己的开发板原理图稍微修改下引脚即可。

本次笔记对应清翔视频教程的第16、17、18集 数码管静态显示和动态显示(理论+编程)

一、什么是数码管

1.1 数码管的构成

1位数码管清翔零基础教你学51单片机_个人学习笔记(5)_数码管静态和动态显示_第1张图片

多位数码管清翔零基础教你学51单片机_个人学习笔记(5)_数码管静态和动态显示_第2张图片 

 

数码管内部由8个LED组层,排列成8字形,点亮对应的LED,熄灭其他的LED,即可显示想要的数组/字母

1.2 数码管的使用原理

清翔零基础教你学51单片机_个人学习笔记(5)_数码管静态和动态显示_第3张图片

 b图左侧是共阴极数码管,b图右边是共阳极数码管(把阳极或者阴极接在一起,就叫做共阳/阴极数码管)

比如我想显示1,那么只需要把bc点亮,其余熄灭,就可以了

二、数码管部分原理图

清翔零基础教你学51单片机_个人学习笔记(5)_数码管静态和动态显示_第4张图片

 清翔零基础教你学51单片机_个人学习笔记(5)_数码管静态和动态显示_第5张图片

根据原理图我们发现,如果我想显示1,那么只需要把ABCDEFGH电平变成0110 0000,根据连接关系,发现A连接的是P0端口的低位,H是P0端口的高位,也就是说P0端口应该是0000 0110 ,也就是0x06

单片机引脚网络

清翔零基础教你学51单片机_个人学习笔记(5)_数码管静态和动态显示_第6张图片

 三、静态显示和动态显示的含义

静态显示
LED显示器工作方式有两种:静态显示方式和动态显示方式。静态显示的特点是每个数码管的段选必须接一个8位数据线来保持显示的字形码。当送入一次字形码后,显示字形可一直保持,直到送入新字形码为止。
动态显示
动态显示的特点是将所有位数码管的段选线并联在一起,由位选线控制是哪位数码管有效。选亮数码管采用动态扫描显示。所谓动态扫描显示即轮流向各位数码管送出字形码和相应的位选,利用发光管的余辉和人眼视觉暂留作用,使人的感觉好像各位数码管同时都在显示。

四、74HC573锁存器

直接上图,清晰明了

 清翔零基础教你学51单片机_个人学习笔记(5)_数码管静态和动态显示_第7张图片

 简单来说,OE接地,当LE = 1,左右两侧是通的,当LE = 0;左右两侧断开,右侧数据保持断开前的状态不变

两个锁存器的OE引脚,位选接在P2^7,段选接在P2^6,因此可以控住这两个位的高低电平来决定P0端口数据是段选还是位选

五、静态显示代码

5.1 创建工程

复制一份工程模板,并改名为“5.数码管静态显示”,打开项目工程

5.2 位定义

sbit DU = P2^6; //数码管段选
sbit WE = P2^7; //数码管位选

5.3 让第一个数码管显示1

5.3.1 思路

  1. 关闭段选,打开位选,选择第一个数码管,关闭位选
  2. 打开段选,传入数字1对应的信号,关闭段选

这样锁存器就会把第一个数码管以及数字1锁住

5.3.2 代码

原理图再放一下

清翔零基础教你学51单片机_个人学习笔记(5)_数码管静态和动态显示_第8张图片

#include 

typedef unsigned char uchar;
typedef unsigned int uint;

sbit DU = P2^6; //数码管段选
sbit WE = P2^7; //数码管位选
void main()
{
    DU = 0;     //关闭段选
    WE = 1;     //打开位选
    P0 = 0xfe;  //位选,选中第一个数码管11111110
    WE = 0;     //关闭位选                         HGFE DCBA
    P0 = 0x06;  //在开启段选之前,先把段选数据设置好 0000 0110
    DU = 1;     //开启段选
    DU = 0;     //关闭段选
    while(1)
    {
        
    }
}

 开发板上的是共阴极数码管,所以在位选中等于0的数码管才会被选中。在段选中,等于1的段才会点亮。

 5.3.3 编译下载程序

打开stc-isp软件,点击“打开程序文件”,在弹出的文件浏览窗口中进入“2.LED闪烁”,在Objects文件夹下选中.hex文件,再点击下载即可,详见清翔零基础教你学51单片机_个人学习笔记(1)_点亮开发板上的LED灯

3.3 点击编译 3.4 下载 这两个章节的内容

5.3.4 现象

清翔零基础教你学51单片机_个人学习笔记(5)_数码管静态和动态显示_第9张图片

 5.4 让第1,2个数码管显示3

5.4.1 代码

#include 

typedef unsigned char uchar;
typedef unsigned int uint;

sbit DU = P2^6; //数码管段选
sbit WE = P2^7; //数码管位选
void main()
{
    DU = 0;     //关闭段选
    WE = 1;     //打开位选
    P0 = 0xfc;  //位选,选中第一个数码管11111100
    WE = 0;     //关闭位选
    P0 = 0x4f;  //在开启段选之前,先把段选数据设置好 0100 1111
    DU = 1;     //开启段选
    DU = 0;     //关闭段选
    while(1)
    {
        
    }
}

5.4.2 现象

清翔零基础教你学51单片机_个人学习笔记(5)_数码管静态和动态显示_第10张图片

 六、数码管动态显示

6.1 动态显示原理

静态显示只能让不同的数码管显示一样的数字,动态显示却能做到让不同的数码管显示不同的数字。

利用的原理就是先开启位选,选择某一个位之后关闭位选,再打开段选传输要显示的数字,传输完成再关闭段选锁存,如此快速变换,就可以让人眼感觉不同的数码管都在发光,并且由于送给不同数码管的显示数据不同,不同数码管的显示也不同。

6.2 让第1,2位数码管分别显示3和7

void main()
{
    while(1)
    {
        DU = 0;     //关闭段选
        P0 = 0XFE;  //选择第1个数码管 1111 1110
        WE = 1;     //开启位选
        WE = 0;     //关闭位选
        
        P0 = 0X4F;  //传输显示数据 3  01001111
        DU = 1;     //开启段选
        DU = 0;     //关闭段选
        delay(1);
        
        P0 = 0XFD;  //选择第2个数码管  11111101
        WE  = 1;    //开启位选
        WE = 0;     //关闭位选
        
        P0 = 0X07;  //传输显示数据 7  0111
        DU = 1;     //开启段选
        DU = 0;     //关闭段选
        delay(1);
        
    }
}

延时的作用是清除残影,如果残影比较严重,可以增加延时

6.3 现象

清翔零基础教你学51单片机_个人学习笔记(5)_数码管静态和动态显示_第11张图片

 

6.4 把数码管显示函数封装一下

6.4.1 数组

数组是一组有序数据的集合,数组中每一个数据都是同一数据类型。数组中的元素可以用数组名和下标来唯一确定,

C 语言支持数组数据结构,它可以存储一个固定大小的相同类型元素的顺序集合。数组是用来存储一系列数据,但它往往被认为是一系列相同类型的变量。

数组的声明并不是声明一个个单独的变量,比如 runoob0、runoob1、...、runoob99,而是声明一个数组变量,比如 runoob,然后使用 runoob[0]、runoob[1]、...、runoob[99] 来代表一个个单独的变量。——选自菜鸟教程

详细的知识点可以参考C语言中文网-什么是数组

一般格式:数据类型 数组名[元素个数] = {元素};,当然数组也有二维数组等高维数组,这里不过多介绍。有时数组元素个数不确定,[元素个数]里面的元素个数也可省略,编译器会自动根据数组初始化的结果分配内存

6.4.2 代码

#include 

typedef unsigned char uchar;
typedef unsigned int uint;
void delay(unsigned int i);

sbit DU = P2^6; //数码管段选
sbit WE = P2^7; //数码管位选
//code它告诉编译器将数组中的数据存储在程序存储器中,而不是存储在数据存储器(RAM)中。
uchar code we[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};
uchar code du[]={ 
                0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F,  //"9"
                0x77,  //"A"
                0x7C,  //"B"
                0x39,  //"C"
                0x5E,  //"D"
                0x79,  //"E"
                0x71,  //"F"
                0x76,  //"H"
                0x38,  //"L"
                0x37,  //"n"
                0x3E,  //"u"
                0x73,  //"P"
                0x5C,  //"o"
                0x40,  //"-"
                0x00,  //熄灭
                0x00  //自定义
                         };

void SEG_DIS(uchar position, uchar number)
{
    DU = 0;
    WE = 0;
    P0 = we[position - 1];
    WE = 1;
    WE = 0;
    
    P0 = du[number];
    DU = 1;
    DU  = 0;
    delay(1);
}

void main()
{
    while(1)
    {
        SEG_DIS(1,3);
        SEG_DIS(2,7);
    }
}

void delay(unsigned int i)
{
    unsigned int j;
    for (; i > 0; i--)
        for (j = 114; j > 0; j--);
}

现象跟刚才一样,在第一个数码管显示3,同时在第2个数码管显示7

 6.4.3 显示三位数

显示3位数只需要把刚才的再给封装一下就行了

首先定义一个函数

void SEG_DIS3(uchar i)
{
    SEG_DIS(1, i / 100);
    SEG_DIS(2, i % 100 / 10);
    SEG_DIS(3, i % 10);
}

然后再在main函数里面调用

void main()
{
    while(1)
    {
        SEG_DIS3(137);
    }
}

这样数码管前三位就会显示1, 3 ,7,非常方便

本次笔记对应清翔视频教程的第16、17、18集 数码管静态显示和动态显示(理论+编程),到此结束。下一个笔记将对应视频教程的19、20集 独立键盘(理论+实践)

你可能感兴趣的:(清翔51学习笔记,51单片机,学习,笔记)