您的位置 首页 > 数码极客

如何让每个数码管,如何让数码管显示1


1)实验平台:ALIENTEK NANO STM32F411 V1开发板

2)摘自《正点原子STM32F4 开发指南(HAL 库版》关注官方微信号公众号,获取更多资料:正点原子

第十七章 数码管显示实验

前面几章的实例,均没涉及到显示,这一章,我们将向大家介绍数码管的使用。在本章中,

我们将使用 NANO STM32F4 V1 开发板上的数码管模块,来点亮数码管,并实现字符的显示。

本章分为如下几个部分:

17.1 数码管/74HC595D/74HC138D 简介

17.2 硬件设计

17.3 软件设计

17.4 下载验证

17.1 数码管/74HC595D/74HC138D 简介

1)数码管

数码管,也称 LED 数码管,按发光二极管单元连接方式可分为“共阳极数码管”和“共阴

极数码管”。而开发板板载的数码管为四位共阴极数码管,实物图与内部引脚图,如图 17.1.1

所示:

图 17.1.1 四位数码管实物与内部引脚结构图

共阳极数码管是指将所有发光二极管的阳极接到一起,而共阴极数码管则是发光二极管的

阴极连到一起,连接方式如图 17.1.2 所示:

图 17.1.2 数码管的连接方式

从上图可以看到,数码管为共阴时,当某一字段的发光二极管阳极为高电平时,响应字段

就点亮,为共阳时,当某一字段的发光二极管阴极为低电平时,相应字段则点亮。所以通过点

亮相对应的字段就可以显示我们需要的字符。

数码管要正常显示,就要用驱动电路来驱动数码管的各个端码,从而显示出我们要的字符,

因此根据数码管的驱动方式不同,可以分为“静态式”和“动态式”两类。

静态显示驱动,也称为直流驱动。静态驱动是指每个数码管的每一个端码都有一个单片机

的 I/O 端口进行驱动,或者使用如 BCD 码二-十进制译码进行驱动。静态驱动的优点是编程简

单,显示亮度高,缺点是占用 I/O 端口多,如驱动 5 个数码管静态显示则需要 5×8=40 个 I/O 端

口来驱动,要知道 STM32 单片机可用的 IO 端口是有限的,实际应用时必须增加译码器进行驱

动,但会增加电路的复杂性。

动态显示驱动,是单片机应用中最为广泛的显示方式,动态驱动是将所有数码管的 8 个显

示笔划“a,b,c,d,e,f,g,dp”的同名端连载一起,另外为每个数码管的公共级 COM 增

加位选通控制电路,位选通由各自独立 IO 线控制,当单片机输出字形码时,所有数码管都接

收到相同的字形码,但究竟是哪个数码管会显示出字形,取决于单片机对位选通 COM 端电路

的控制,所有我们只要将需要显示的数码管的选通控制打开,改为就显示出字形,没有选通的

数码管就不会亮。通过分时轮流控制各个数码管的 COM 端,就可以使各个数码管轮流显示。

在轮流显示过程中,每位数码管的点亮时间为 1~2ms,由于人的视觉暂留现象及发光二极管的

余辉效应,尽管实际上各位数码管并非同时点亮,只要扫描的速度够快,给人的印象就是一组

稳定的显示数据,不会有闪烁感,动态显示的效果和静止显示是一样的,能够节省大连的 IO

端口,功耗降低。

本实验我们将使用动态驱动的方式驱动数码管,为了节省 IO,使用到驱动电路,段选数据

使用 74HC595D 串行数据转并行数据输出芯片,位选数据使用 74HC138D 三-八译码器芯片。

下面将介绍这两款芯片。

2)74HC595D

74HC595D 是恩智浦 NXP 公司推出的一款低噪声、低功耗、高速的 CMOS 移位寄存器,

能够驱动 15 个 LS-TTL 的负载。该器件包含一个 8 位串行输入、并行输出的移位寄存器及带有

三态输出控制的 8 位 D 型存储器。74HC595D 的特点如下:

1 、带存储功能的 8 位串行输入,并行输出的移位寄存器

2 、工作电压范围宽:2V-6V

3 、可级联使用

74HC595D 广泛应用于点阵屏和主控 IO 较少数据串行转并行的场合,74HC595D 的框图如

图 17.1.1 所示:

图 17.1.1 74HC595D 框图

1,引脚说明

74HC595D 的引脚说明如表 17.1.2 所示:

表 17.1.2 74HC595 引脚说明

我们使用的 74HC595D 采用 SO16 封装,总共 16 个脚,其中包括 8 个三态输出 IO 口、1

个串行数据输出端,1 个移位寄存器清零端,1 个数据输入时钟,1 个输出存储器锁存时钟,1

个输出使能端,1 个串行数据输入端,等其他引脚。下面我们分别以数据端和控制端讲解下引

脚的作用:

数据端:

Q0-Q7:八位并行数据输出端,可以直接控制数码管的 8 个段。

Q7’:级联输出端。它可接入下一个 74HC595 的 DS 端。

DS:串行数据输入端,级联的话接上一级的 Q7’。

控制端:

/MR(10 脚):低电平时将移位寄存器的数据清零。一般情况下接 VCC。

SH_CP(11 脚):上升沿时数据寄存器的数据移位。传输方向:Q0->Q1->Q2->Q3->...->Q7;

下降沿移位寄存器数据不变。

ST_CP(12 脚):上升沿时移位寄存器的数据进入数据存储器,下降沿时存储器数据不变。

通常将 ST_CP 置为低电平,当移位结束后,在 ST_CP 端产生一个正脉

冲,更新显示数据。

/OE(13 脚):高电平时禁止输出(高组态)。可以用一个引脚控制它,可以方便地产生

闪烁和熄灭效果。

2,时序图

数据的串行输入需要按照规定的时间才能正常写入,根据上面讲解,我们要知道的是

SH_CP 上升沿高电平和 ST_CP 正脉冲保持的时间,如图 17.1.3 所示:

图 17.1.3 SHCP 和 STCP 时序图

从上图可以看到时序的时间都是 ns 级别的,在写软件时我们只需要几 us 的时间就可以了。

通过 74HC595D 的使用,我们就可以以串行数据输入,并行数据输出控制数码管的端选段,

从而显示对应的字符。

3)74HC138D

74HC138D 是恩智浦 NXP 公司推出的一款高速 CMOS、低功耗的 3-8 译码器。通过三个地

址的输入设置,可选择对应八种的状态输出。74HC138D 的特点如下:

1)低功耗。

2)工作电压范围宽:3V-5V。

74HC138D 广泛应用于消费类电子产品,74HC138D 的框图如图 17.1.4 所示:

图 17.1.4 74HC138D 引脚和功能框图

1,引脚说明

74HC138D 的引脚说明如表 17.1.5 所示:

图 17.1.6 74HC138D 真值表

从图可以看到,当/E1、/E2、E3 使能端使能后,设置 A0、A1、A2 的输入(高电平有效),

/Y0~/Y7 都会有对应的状态输出(低电平),例如 A0、A1、A2 设置的是(A2=0,A1=1,A2=1),

根据 BCD-421 码的换算,代表是 3,则 Y3 输出有效电平 L,其他的都输出为无效电平 H。设

置(A2=1,A1=1,A0=1),代表是 7,则 Y7 输出有效电平 L,其他的都输出为无效电平 H。

通过 74HC138D 的使用,我们就可以控制对应数码管的位选端了。

17.2 硬件设计

本实验用到的硬件资源有:

1) 指示灯 DS0

2) 74HC595D、74HC138D

3) 数码管

数码管、74HC595D、74HC138D 电路连接如图 17.2.1-1 和图 17.2.1-2 所示:

图 17.2.1-1 开发板连接示意图

图 17.2.1-2 开发板连接示意图

原理图中 74HC595D 芯片标的引脚标号名称可能与芯片手册标的有点不一样,以下是引脚

对应标号关系,如表 17.2.2 所示:

表 17.2.2 引脚标号关系

从图 17.2.1 原理图可以看到,74HC138D 的使能端引脚默认已上拉或下拉硬件使能,

74HC595D 的 RST 复位引脚与开发板的复位线相连接,当按下开发板的复位按键或首次上电即

可对 74HC595D 的芯片的数据清零,以到达复位的作用。由于没有做级联的功能,SDO 引脚上

做了悬空处理。而使能端引脚也同样做了默认硬件使能。

在数码管中,两个数码管的 A~DOT 段选段都与 74HC595D 芯片的 QA~QH 相连接,而数

码管的 CH1~CH4 位选端则单独分别与 74HC138D 芯片的 Y0~Y7 引脚相连接。通过控制

74HC595D 输出的段码和控制 74HC138D 输出的位选就可以实现选择点亮数码管。

本节,我们将实现 8 位数码管的动态显示,通过 TIMER3 定时器 2ms 时间来刷新显示,1S

时间更新显示字符,下面我们开始软件设计。

17.3 软件设计

我们直接打开数码管显示实验可以发现 HARDWARE 下面有一个 和 timer 文件,同

时包含了头文件 和 。

文件下的代码,是关于定时器的初始化配置,在第十三章定时器中断实验我们有比

较详细的讲解,这里就不做介绍了。这里我们主要讲解下 的代码,首先是 LED_SMG_Init

函数,该函数比较简单,对使用到的 IO 口初始化,LED_SMG_Init 函数代码如下:

//数码管驱动 IO 初始化

void LED_SMG_Init(void)

{

GPIO_InitTypeDef GPIO_Initure;

__HAL_RCC_GPIOB_CLK_ENABLE(); //开启 GPIOB 时钟

__HAL_RCC_GPIOC_CLK_ENABLE(); //开启 GPIOC 时钟

//74HC595 DS-PB3 LCLK-PB4 SCK-PB5

GPIO_Ini|GPIO_PIN_4|GPIO_PIN_5;//PB3~5

GPIO_Ini;

//推挽输出

GPIO_Ini;

//上拉

GPIO_Ini;

//高速

HAL_GPIO_Init(GPIOB,&GPIO_Initure);

//74HC138 A0-PC10 A1-PC11 A2-PC12

GPIO_Ini|GPIO_PIN_11|GPIO_PIN_12;//PC10~12

HAL_GPIO_Init(GPIOC,&GPIO_Initure);

HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_RESET);

HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET);

HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_SET);

HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10,GPIO_PIN_RESET);

HAL_GPIO_WritePin(GPIOC,GPIO_PIN_11,GPIO_PIN_RESET);

HAL_GPIO_WritePin(GPIOC,GPIO_PIN_12,GPIO_PIN_RESET);

}

接着,要介绍的是 LED_Wei 函数。这函数实现控制 74HC138D 的 A0~A2 地址,将入口参

数通过转换设置 LED_A0~LED_A2 的宏定义 IO 位带操作,LED_Wei 函数代码如下:

//74HC138 驱动

//数码管位选

//num:要显示的数码管编号 0-7(共 8 个数码管)

void LED_Wei(u8 num)

{

LED_A0=num&0x01;

LED_A1=(num&0x02)>>1;

LED_A2=(num&0x04)>>2;

}

LED_Write_Data 函数,该函数实现了段码数据以 8 个上升沿的时钟先低位后高位的串行输

入 形 式 , 传 输 给 74HC595D, 然 后 调 用 LED_Wei 函 数 控 制 位 选 需 要 显 示 的 数 码 管 ,

LED_Write_Date 函数代码如下:

//74HC595 驱动

//数码管显示

//duan:显示的段码

//wei:要显示的数码管编号 0-7(共 8 个数码管)

void LED_Write_Data(u8 duan,u8 wei)

{

u8 i;

for( i=0;i<8;i++)//先送段

{

LED_DS=(duan>>i)&0x01;

LED_SCK=0;

delay_us(5);

LED_SCK=1;

}

LED_Wei(wei);//后选中位

}

最后要介绍的是 LED_Refresh 函数,该函数实现对 74HC595D 串行输入的数据,进行刷新

输出给数码管,LED_Refresh 函数如下:

//74HC595 驱动

//数码管刷新显示

void LED_Refresh(void)

{

LED_LCLK=1;

delay_us(5);

LED_LCLK=0;

}

要正确显示数码管,需要正确的段码,接下来,我们介绍一个数码管段码查询的软件,该

软件的界面如图 17.3.1 所示:

图 17.3.1 数码管段码查询软件界面

该软件设置很简单,只要设置段码的排列顺序、数码管的极性,通过选择点击区,就可以

输出段码了。该软件也提供了一些常用的字符给我们选择。

根据我们开发板 74HC595D 驱动数码管的方式,极性选择“共阴”,排列的顺序选择“a-dp”,

如图 17.3.1 所示:

图 17.3.2 软件配置

根据软件的配置,设置了 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,.(点号),全灭,共 18 个显示字符段

码,分别是 0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,0xee,0x3e,0x9c,0x7a,0x9e,0x8e,

0x01,0x00。

文件下的代码我们就介绍完了,接下来看看 ,代码如下:

#ifndef _LED_SMG_H

#define _LED_SMG_H

#include ";

////74HC138 操作线

#define LED_A0 PCout(10) //A0 地址线

#define LED_A1 PCout(11) //A1 地址线

#define LED_A2 PCout(12) //A2 地址线

////74HC595 操作线

#define LED_DS

PBout(3) //数据线

#define LED_LCLK PBout(4) //锁存时钟线

#define LED_SCK

PBout(5) //时钟线

void LED_SMG_Init(void);

void LED_Refresh(void);

void LED_Write_Data(u8 duan,u8 wei);

#endif

该部分比较简单,就是一些 IO 的宏定义和函数的定义。

最后说一下 main,c,该部分代码如下:

//共阴数字数组

//0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F, .,全灭

u8 smg_num[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,

0xf6,0xee,0x3e,0x9c,0x7a,0x9e,0x8e,0x01,0x00};

int main(void)

{

HAL_Init();

//初始化 HAL 库

Stm32_Clock_Init(96,4,2,4);

//设置时钟,96Mhz

delay_init(96);

//初始化延时函数

uart_init(115200);

//初始化串口 115200

LED_Init();

//初始化 LED

LED_SMG_Init();

//数码管初始化

TIM3_Init(20-1,9600-1);

//2ms 定时显示

while(1)

{

}

}

u8 smg_wei=0;//数码管位选

u8 smg_duan=0;//数码管段选

u16 t=0;

//回调函数,定时器中断服务函数调用

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

{

if(htim==(&TIM3_Handler))

{

LED_Write_Data(smg_num[smg_duan],smg_wei);//数码管显示

LED_Refresh();//刷新显示

smg_wei++;

if(smg_wei==8) smg_wei=0;

t++;

if(t==500)//数码管每秒更新

{

t=0;

LED0=!LED0;

smg_duan++;

if(smg_duan==18) smg_duan=0;

}

}

}

代码比较简单,对数码管等其他外设初始化,控制数码管动态显示的定时器设置为 2ms 中

断,在定时器中断中每 2ms 刷新显示 1 位数码管,每 1S 时间更新显示数码管段码,字符从 0

开始不停的循环显示,同时 DS0 闪烁。然后我们编译此工程,直到编译成功为止。

代码比较简单,对数码管等其他外设初始化,控制数码管动态显示的定时器设置为 2ms 中

断,在定时器中断中每 2ms 刷新显示 1 位数码管,每 1S 时间更新显示数码管段码,字符从 0

开始不停的循环显示,同时 DS0 闪烁。至此,我们的软件设计就完成了。

17.4 下载验证

将代码下载到开发板后,可以看到 8 位数码管以 1S 时间更新显示,同时 DS0 不停的闪烁,

数码管显示如图 17.4.1 所示:

图 17.4.1 数码管显示效果

通过这一章的学习,我们学会了数码管的使用,在以后需要显示程序的编写,大家可以好

好利用。

责任编辑: 鲁达

1.内容基于多重复合算法人工智能语言模型创作,旨在以深度学习研究为目的传播信息知识,内容观点与本网站无关,反馈举报请
2.仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证;
3.本站属于非营利性站点无毒无广告,请读者放心使用!

“如何让每个数码管,如何让数码管显示1,如何让数码管闪烁,如何让数码管显示3,如何让数码管显示”边界阅读