找回密码
 立即注册
查看: 336|回复: 2

Ai8051U学习之旅(3)- 数码管显示

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:9
  • 最近打卡:2025-02-28 11:44:43
已绑定手机

4

主题

21

回帖

100

积分

注册会员

积分
100
发表于 2025-2-22 11:04:12 | 显示全部楼层 |阅读模式
一、前言
数码管显示是常见的显示器件,最常用的是家电、消费电子上,学会数码管驱动,对于理解数字显示、定时器运用、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,如下图:
截图202502221054568993.jpg
图1 数码管电路图
   74HC595是一个8位串行输入、平行输出的位移缓存器:平行输出为三态输出。在SCK的上升沿,单行数据由SDL输人到内部的8位位移缓存器,并由Q7‘输出,而平行输出则是在LCK的上升沿将在8位位移缓存器的数据存人到8位平行输出缓存器。当串行数据输人端OE的控制信号为低使能时,平行输出端的输出值等于平行输出缓存器所存储的值。而当OE为高电位,也就是输出关闭时,平行输出端会维持在高阻抗状态。串行输入,并行输出。
截图202502221055153411.jpg
表1 74HC595引脚定义
三、软件设计
       知道了驱动原理,接下来就是根据原理写程序,也就是如果让HC595发数据,如果让数据管显示。先简单的显示12345678
   3.1 数码管驱动
   Dev_Segled.c
  1. /*----------------------------------------------------------------------------------------------------------------------
  2. * Copyright(c) 2024, Mark Xu Work Studio R&D Department. All rights reserved.
  3. * 文件名称 : Dev_Segled.c
  4. * 文件版本 : V1.0.0
  5. * 功能描述 : 数码管应用模块
  6. * 创建人员 : Mark Xu
  7. * 创建日期 : 2025/02/17
  8. ----------------------------------------------------------------------------------------------------------------------*/
  9. #include "Dev_Segled.h"                        
  10. //----------------------------------------------------------------------------------------------------------------------
  11. // 配置文件                                         
  12. //----------------------------------------------------------------------------------------------------------------------
  13. #define SEG_COM_MAX                                (8)                //8位数码管
  14. //----------------------------------------------------------------------------------------------------------------------
  15. // 类型重定义                                         
  16. //----------------------------------------------------------------------------------------------------------------------
  17. //----------------------------------------------------------------------------------------------------------------------
  18. // 常量、宏   
  19. //----------------------------------------------------------------------------------------------------------------------
  20. U8C segCode[] = {                       //标准字库
  21. //   0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F
  22.     0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
  23. //black  -     H    J    K    L    N    o   P    U     t    G    Q    r   M    y
  24.     0x00,0x40,0x76,0x1E,0x70,0x38,0x37,0x5C,0x73,0x3E,0x78,0x3d,0x67,0x50,0x37,0x6e,
  25.     0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x46};    //0. 1. 2. 3. 4. 5. 6. 7. 8. 9. -1
  26. U8C segCom[SEG_COM_MAX] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};      //位码
  27. //----------------------------------------------------------------------------------------------------------------------
  28. // 局部变量
  29. //----------------------------------------------------------------------------------------------------------------------
  30. static U8  s_u8DisBuff[SEG_COM_MAX] = {1, 2, 3, 4, 5, 6, 7, 8};                //显示缓存
  31. static U8  s_u8ComLoopCnt = 0;                                        //轮询值
  32. //----------------------------------------------------------------------------------------------------------------------
  33. // 全局变量
  34. //----------------------------------------------------------------------------------------------------------------------
  35. //----------------------------------------------------------------------------------------------------------------------
  36. // 本地函数声明
  37. //----------------------------------------------------------------------------------------------------------------------
  38. /*----------------------------------------------------------------------------------------------------------------------
  39. * 函数名称 :void Segled_Init(void)
  40. * 功能描述 :数码管程序初始化
  41. * 入口参数 :无
  42. * 出口参数 :无
  43. * 备注说明 :无
  44. ----------------------------------------------------------------------------------------------------------------------*/
  45. void Segled_Init(void)
  46. {
  47. }
  48. /*----------------------------------------------------------------------------------------------------------------------
  49. * 函数名称 :void HC595_SendDat(U8 i_Dat)
  50. * 功能描述 :传输数据
  51. * 入口参数 :i_Dat - 要传输的8位数据
  52. * 出口参数 :无
  53. * 备注说明 :无
  54. ----------------------------------------------------------------------------------------------------------------------*/
  55. void HC595_SendDat(U8 i_Dat)
  56. {
  57.         U8 i;
  58.         for (i=0; i<8; i++)
  59.         {
  60.                 if (i_Dat & 0x80)        //先传输高位        
  61.                 {
  62.                         HC595_DAT_HI();
  63.                 }
  64.                 else
  65.                 {
  66.                         HC595_DAT_LO();
  67.                 }
  68.                 i_Dat <<= 1;
  69.                 HC595_SRCLK_HI();
  70.                 HC595_SRCLK_LO();
  71.         }
  72. }
  73. /*----------------------------------------------------------------------------------------------------------------------
  74. * 函数名称 :void Segled_AllOff(void)
  75. * 功能描述 :关闭数码管
  76. * 入口参数 :无
  77. * 出口参数 :无
  78. * 备注说明 :无
  79. ----------------------------------------------------------------------------------------------------------------------*/
  80. void Segled_AllOff(void)
  81. {
  82.         U8 i = 0;
  83.         for (i=0; i<SEG_COM_MAX; i++)
  84.         {
  85.                 s_u8DisBuff[i] = 0x00;
  86.         }
  87. }
复制代码
        Dev_Segled.h
  1. /*----------------------------------------------------------------------------------------------------------------------
  2. * Copyright(c) 2025, Mark Xu Work Studio R&D Department. All rights reserved.
  3. * 文件名称 : Dev_Segled.h
  4. * 文件版本 : V1.0.0
  5. * 功能描述 : 数码管功能头文件
  6. * 创建人员 : Mark Xu
  7. * 创建日期 : 2025/02/17
  8. ----------------------------------------------------------------------------------------------------------------------*/
  9. #ifndef        __DEV_SEGLED_H__
  10. #define        __DEV_SEGLED_H__
  11. #include "includes.h"
  12. //----------------------------------------------------------------------------------------------------------------------
  13. // 常量、宏  
  14. //----------------------------------------------------------------------------------------------------------------------
  15. //----------------------------------------------------------------------------------------------------------------------
  16. // 类型重定义                                      
  17. //----------------------------------------------------------------------------------------------------------------------
  18. //----------------------------------------------------------------------------------------------------------------------
  19. // 全局变量
  20. //----------------------------------------------------------------------------------------------------------------------
  21. //----------------------------------------------------------------------------------------------------------------------
  22. // 全局函数
  23. //----------------------------------------------------------------------------------------------------------------------
  24. #if (DEV_SEGLED_EN)
  25.         extern void Segled_Init(void);
  26.         extern void Segled_DeInit(void);
  27.         extern void Segled_PollProc(void);
  28. #else
  29.         #define Segled_Init()
  30.         #define Segled_DeInit()
  31.         #define Segled_PollProc()
  32. #endif
  33. #endif //#ifndef        __DEV_SEGLED_H__
复制代码
在主程序中调用void Segled_PollProc(void);这个函数即可,如下所示:
截图202502221059098704.jpg







回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:9
  • 最近打卡:2025-02-28 11:44:43
已绑定手机

4

主题

21

回帖

100

积分

注册会员

积分
100
发表于 2025-2-22 11:06:55 | 显示全部楼层
1、为了简单期间,直接在main函数中轮询调用,当然设计了标志,每1ms调用一次
2、存在缺点:如果大循环中存在的事件比较大,浪费的时间比较久,则可能影响数码管的显示效果,这时可能需要抢占式任务或直接在定时器中调用
3、下步计划:试一下RTC,作一个小闹钟,配合按键等,可以直接用
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:9
  • 最近打卡:2025-02-28 11:44:43
已绑定手机

4

主题

21

回帖

100

积分

注册会员

积分
100
发表于 2025-2-22 11:14:30 | 显示全部楼层
今天实验的工程,所有源文件均在工程中,
注意:工程名没有更改,当然这个不影响实验的结果
01-Timer.zip (194.64 KB, 下载次数: 13)
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-6-18 21:28 , Processed in 0.128170 second(s), 59 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表