学习目标

  1. 理解数码管电路原理
  2. 理解74HC595移位寄存器原理
  3. 了解74HC595移位寄存器电路设计
  4. 加强二进制操作
  5. 驱动74HC595移位寄存器控制数码管

    学习内容

    数码管结构

    共阴与共阳

    共阳数码管是指将所有发光二极管的阳极接到一起,形成公共阳极(COM)的数码管,共阳数码管在应用的时候,应该将 COM 端口接到正极,当某一段发光二极管的阴极为低电平的时候,相对应的段就点亮,当某一字段的阴极为高电平的时候,相对应段就不亮。

    1位数码管

    微信截图_20221128105958.png
    微信截图_20221128115607.png

    2位数码管

    微信截图_20221128105822.png
    微信截图_20221128120713.png

    4位数码管

    微信截图_20221128105410.png
    微信截图_20221128121600.png

移位寄存器

74HC595 是一款 8 位 CMOS 移位寄存器。8 位并行输出端口为可控的三态输出,一 个串行输出端口,可以实现多级芯片串行控制,组成 8n 位(n 为芯片数量)并行输 。
优点:通过逻辑操作来控制LED的状态,少量的引脚控制更多的状态。
微信截图_20221128105958.png微信截图_20221128132522.png

原理图

image.png

移位寄存器数据流程

移位寄存器的引脚:

  1. LATCH_CLOCK: 锁存时钟
  2. SHIFT_CLOCK: 移位时钟
  3. A: 数据输入信号管脚
  4. QA~QH: 数据信号转化出来的高低电平
  5. SQH: 串行数据输出管脚

63.png
上图帮我们认识了几个管脚的作用:

  • A:数据信号输入
  • QA~QH: 高低电平输出

同时再次加深了我们对74HC595功能的理解:将数据转换为高低电平的一个工具

移位寄存器控制流程

数量流程中,数据变成高低电平过程清楚了。但是数据是给到芯片的,这个过程是比较讲究的。
也就是我们传统说法,要按照规矩来传递数据。数据传递是要通过协议的。
我们通过 数据输入信号管脚(原理图上标记为A)来输入数据。我们必须清楚的知道,一个引脚给数据,其实就是给高低电平信号,一个高低电平信号只能表示一个bit,而我们又8给输出口,理论上需要给8次高低电平才能满足8个端口的输出要求。但是如何去界定8给高低电平呢,就需要用时间去界定。提供了两个引脚:

  1. LATCH_CLOCK: 锁存时钟引脚
  2. SHIFT_CLOCK: 移位时钟引脚

image.png

移位:由低电平变为高电平,表示记录一个位的电平。
锁存:由低电平变为高电平,表示将记录的数据应用到电路中。

移位寄存器串联

image.png
本案例中是有两个移位寄存器U1U2的。分别关注两个移位寄存器的ASQH.
image.png
通过流程我们可以明确以下结论:

  1. 移位寄存器通过A输入数据
  2. 移位寄存器通过SQH输出数据
  3. 两个移位寄存器通过将一个的SQH输出到另外一个的输入A口,两个移位寄存器就串联了
  4. 末端的移位寄存器输出口悬空表示不输出
  5. 数据会传递到末端,也就是数据会先填充的是末端。

串联后控制流程需要有所改变,改变如下:
image.png

image.png

  • Logic分析仪

image.png

  • Digtals

image.png

实现数码管显示

  1. #include "Config.h"
  2. #include "GPIO.h"
  3. #include "Delay.h"
  4. #define NIXIE_DI P44 // 数据输入
  5. #define NIXIE_SCK P42 // 移位寄存器
  6. #define NIXIE_RCK P43 // 锁存寄存器
  7. void GPIO_config(void) {
  8. GPIO_InitTypeDef GPIO_InitStructure; //结构定义
  9. GPIO_InitStructure.Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4; //指定要初始化的IO,
  10. GPIO_InitStructure.Mode = GPIO_PullUp; //指定IO的输入或输出方式,GPIO_PullUp,GPIO_HighZ,GPIO_OUT_OD,GPIO_OUT_PP
  11. GPIO_Inilize(GPIO_P4, &GPIO_InitStructure);//初始化
  12. }
  13. #define GET_BIT_VAL(byte, pos) (byte & (1 << pos))
  14. int main() {
  15. char i;
  16. u8 a_dat = 0x12; // 0001 0010 字母位 5.
  17. //&1000 0000
  18. u8 b_idx = 0x1F; // 0001 1111 数字位
  19. GPIO_config();
  20. // 显示 7.
  21. // 0111 1000
  22. // 先发字母位 (控制显示的内容)
  23. // 8bit,先发出去的会作为高位
  24. for(i = 7; i >= 0; i--){ // 0点亮
  25. NIXIE_DI = GET_BIT_VAL(a_dat, i);
  26. // 寄存器的移位操作
  27. NIXIE_SCK = 0;
  28. NOP2();
  29. NIXIE_SCK = 1;
  30. NOP2();
  31. }
  32. // 再发数字位 (控制显示哪几个)
  33. // 1111 1011
  34. // 7.7.空7. 7.7.7.7. -------------------与二级制是反向
  35. for(i = 7; i >= 0; i--){ // 只要不是0,就是高电平
  36. NIXIE_DI = GET_BIT_VAL(b_idx, i);
  37. // 寄存器的移位操作
  38. NIXIE_SCK = 0;
  39. NOP2();
  40. NIXIE_SCK = 1;
  41. NOP2();
  42. }
  43. // 锁存操作
  44. NIXIE_RCK = 0;
  45. NOP2();
  46. NIXIE_RCK = 1;
  47. NOP2();
  48. while(1) {
  49. }
  50. }

练习题

  1. 实现数码管数字显示
  2. 通过串口控制数码管显示(串口指令,两个字节,一个控制显示,一个控制哪一个灯显示)