一、前言 数码管显示是常见的显示器件,最常用的是家电、消费电子上,学会数码管驱动,对于理解数字显示、定时器运用、IO操作都有帮助,今天就先整理一下数码管学习笔记。 二、硬件电路2.1 数码管2.1.1 数码管的基本结构1) 七段数码管: ü 最常见的类型,包含7个LED段(a-g),排列成“日”字形。 ü 额外的小数点(DP)段,共8个控制引脚。 ü 每个段对应一个LED,通过通电点亮。 2) 共阳(Common Anode)与共阴(Common Cathode): ü 共阳:所有LED的阳极连接在一起,接高电平(VCC),阴极分别控制。 ü 共阴:所有LED的阴极连接在一起,接地(GND),阳极分别控制。 2.1.2 工作原理1)显示原理: ü 通过给不同段通电组合显示数字(如数字“0”需要a、b、c、d、e、f段亮)。 ü 需配合限流电阻(通常100-500Ω)保护LED。 2)编码方式: ü 每个数字对应一个二进制或十六进制编码(段码表)。 ü 例如,共阴数码管显示“0”的段码为 0x3F(二进制 00111111)。 2.1.3 驱动方式1、静态驱动: n 每个数码管独立连接控制引脚,适合少量显示。 n 优点:亮度稳定;缺点:占用引脚多。 2、动态扫描(多路复用): n 多个数码管共用段引脚,通过快速切换公共端分时显示。 n 优点:节省引脚;缺点:需较高刷新频率(>60Hz)避免闪烁。 2.2 数码管驱动电路正常情况下,MCU的驱动电路没有那么大或IO不够多时,就需要外围驱动IC来做数码管的驱动电路,最常用的是串转并芯片,AI8051U开发板上用的是经典的74HC595,如下图: 图1 数码管电路图 74HC595是一个8位串行输入、平行输出的位移缓存器:平行输出为三态输出。在SCK的上升沿,单行数据由SDL输人到内部的8位位移缓存器,并由Q7‘输出,而平行输出则是在LCK的上升沿将在8位位移缓存器的数据存人到8位平行输出缓存器。当串行数据输人端OE的控制信号为低使能时,平行输出端的输出值等于平行输出缓存器所存储的值。而当OE为高电位,也就是输出关闭时,平行输出端会维持在高阻抗状态。串行输入,并行输出。 表1 74HC595引脚定义 三、软件设计 知道了驱动原理,接下来就是根据原理写程序,也就是如果让HC595发数据,如果让数据管显示。先简单的显示12345678 3.1 数码管驱动 Dev_Segled.c
- /*----------------------------------------------------------------------------------------------------------------------
- * Copyright(c) 2024, Mark Xu Work Studio R&D Department. All rights reserved.
- * 文件名称 : Dev_Segled.c
- * 文件版本 : V1.0.0
- * 功能描述 : 数码管应用模块
- * 创建人员 : Mark Xu
- * 创建日期 : 2025/02/17
- ----------------------------------------------------------------------------------------------------------------------*/
-
- #include "Dev_Segled.h"
-
- //----------------------------------------------------------------------------------------------------------------------
- // 配置文件
- //----------------------------------------------------------------------------------------------------------------------
- #define SEG_COM_MAX (8) //8位数码管
-
- //----------------------------------------------------------------------------------------------------------------------
- // 类型重定义
- //----------------------------------------------------------------------------------------------------------------------
-
- //----------------------------------------------------------------------------------------------------------------------
- // 常量、宏
- //----------------------------------------------------------------------------------------------------------------------
- U8C segCode[] = { //标准字库
- // 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
- //black - H J K L N o P U t G Q r M y
- 0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
- 0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46}; //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1
-
- U8C segCom[SEG_COM_MAX] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //位码
-
- //----------------------------------------------------------------------------------------------------------------------
- // 局部变量
- //----------------------------------------------------------------------------------------------------------------------
- static U8 s_u8DisBuff[SEG_COM_MAX] = {1, 2, 3, 4, 5, 6, 7, 8}; //显示缓存
- static U8 s_u8ComLoopCnt = 0; //轮询值
- //----------------------------------------------------------------------------------------------------------------------
- // 全局变量
- //----------------------------------------------------------------------------------------------------------------------
-
- //----------------------------------------------------------------------------------------------------------------------
- // 本地函数声明
- //----------------------------------------------------------------------------------------------------------------------
-
-
- /*----------------------------------------------------------------------------------------------------------------------
- * 函数名称 :void Segled_Init(void)
- * 功能描述 :数码管程序初始化
- * 入口参数 :无
- * 出口参数 :无
- * 备注说明 :无
- ----------------------------------------------------------------------------------------------------------------------*/
- void Segled_Init(void)
- {
-
- }
-
-
- /*----------------------------------------------------------------------------------------------------------------------
- * 函数名称 :void HC595_SendDat(U8 i_Dat)
- * 功能描述 :传输数据
- * 入口参数 :i_Dat - 要传输的8位数据
- * 出口参数 :无
- * 备注说明 :无
- ----------------------------------------------------------------------------------------------------------------------*/
- void HC595_SendDat(U8 i_Dat)
- {
- U8 i;
- for (i=0; i<8; i++)
- {
- if (i_Dat & 0x80) //先传输高位
- {
- HC595_DAT_HI();
- }
- else
- {
- HC595_DAT_LO();
- }
-
- i_Dat <<= 1;
-
- HC595_SRCLK_HI();
- HC595_SRCLK_LO();
- }
- }
-
- /*----------------------------------------------------------------------------------------------------------------------
- * 函数名称 :void Segled_AllOff(void)
- * 功能描述 :关闭数码管
- * 入口参数 :无
- * 出口参数 :无
- * 备注说明 :无
- ----------------------------------------------------------------------------------------------------------------------*/
- void Segled_AllOff(void)
- {
- U8 i = 0;
- for (i=0; i<SEG_COM_MAX; i++)
- {
- s_u8DisBuff[i] = 0x00;
- }
- }
复制代码
Dev_Segled.h - /*----------------------------------------------------------------------------------------------------------------------
- * Copyright(c) 2025, Mark Xu Work Studio R&D Department. All rights reserved.
- * 文件名称 : Dev_Segled.h
- * 文件版本 : V1.0.0
- * 功能描述 : 数码管功能头文件
- * 创建人员 : Mark Xu
- * 创建日期 : 2025/02/17
- ----------------------------------------------------------------------------------------------------------------------*/
- #ifndef __DEV_SEGLED_H__
- #define __DEV_SEGLED_H__
-
- #include "includes.h"
-
- //----------------------------------------------------------------------------------------------------------------------
- // 常量、宏
- //----------------------------------------------------------------------------------------------------------------------
-
- //----------------------------------------------------------------------------------------------------------------------
- // 类型重定义
- //----------------------------------------------------------------------------------------------------------------------
-
- //----------------------------------------------------------------------------------------------------------------------
- // 全局变量
- //----------------------------------------------------------------------------------------------------------------------
-
- //----------------------------------------------------------------------------------------------------------------------
- // 全局函数
- //----------------------------------------------------------------------------------------------------------------------
- #if (DEV_SEGLED_EN)
- extern void Segled_Init(void);
- extern void Segled_DeInit(void);
- extern void Segled_PollProc(void);
- #else
- #define Segled_Init()
- #define Segled_DeInit()
- #define Segled_PollProc()
- #endif
-
- #endif //#ifndef __DEV_SEGLED_H__
-
复制代码
在主程序中调用void Segled_PollProc(void);这个函数即可,如下所示:
|