• MicroPython-On-ESP8266——8x8LED点阵模块(2)使用74HC595驱动


    MicroPython-On-ESP8266——8x8LED点阵模块(2)使用74HC595驱动

    1. 使用74HC595驱动的原理

    1.1. 基础回顾

    上篇我们学习了8x8LED点阵屏的电路基础知识和驱动的原理,见

    8x8LED点阵模块(1)驱动原理

    里面也提到了,咱们nodemcu开发板的GPIO引脚不够,只能借助74HC595、MAX7219此类IC来完成点阵屏的驱动。这里咱们先从74HC595开始来实验。

    数码管的使用,2片HC595驱动四位数码管

    595芯片的基础原理前面文章也有做过介绍,这里还是再笼统回顾一下。

    1.2. 74HC595如何使用

    595输入端只需要3个GPIO,却可以输出8个GPIO状态,其实咱们就理解为把GPIO管脚扩充了。

    在这里插入图片描述
    动画演示595工作原理

    注:
    1、这个动图不是我做的,也不清楚来源,但确实很形象。如有侵权请私信通知删除,感谢原作者!
    2、图上有个错误的地方,大家要留意。DS串行口推入数据的次序是Q0 -> Q1 -> Q2 -> Q3 -> Q4 -> Q5 -> Q6 -> Q7 -> Q7S(溢出位) 。如果只送了8位过去,第一个移入的位状态最终会移到Q7,最后一个移入的状态位最终停留在Q0。也就是先送高位。上图锁存器对应的引脚顺序要反向过来才对。

    实际使用时,时钟引脚每跳变(先变成高电平再变回低电平)一次,就把输入数据引脚DS的状态送入位移寄存器,想送入多少个随自己定。送完位移数据后,让锁存引脚跳变一下,把位移寄存器的值整体推入锁存器,从而让输出GPIO能保持住想要的状态。

    仔细品味一下上面的动图,一定要理解串入并出是怎么实现的。^_^

    1.3. 多个74HC595级联使用

    既然一个595能有8个GPIO输出,那咱们要控制8x8LED点阵的16个引脚,就只需要两片595就行了。595还能无限级联实现串行,本片先入先出的状态值会经过Q0位移到Q7再溢出到Q7S管脚,把Q7S接入到下一片595的DS输入数据引脚作为输入端,就能实现级联了。

    在这里插入图片描述

    不管级联了多少片,把每片的时钟引脚和锁存引脚都短接在一起,这样咱们在开发板上指定两个GPIO引脚统一进行位移跳变和锁存跳变。

    也就是说按照上图来说我想要一次性控制4片75HC595的输出状态,相对于在最左侧给DS(SER)引脚要输入4*8=32个状态位,每一个状态位输入完中间进行一下位移引脚跳变,所有状态位向右移动一次。

    • 第一个状态位,经历过32次位移后,电平状态移动到了第4片74HC595的QH(Q7)位移寄存器
    • 第二个状态位,经历过32-1次位移后,电平状态移动到了第4片74HC595的QG(Q6)位移寄存器
    • 依次。。。
    • 最后一个(第32个)状态位,位移1次,输出到了第1片74HC595的QA(Q0)位移寄存器

    大家排队往前走,32个小伙伴都就位后,锁存引脚跳变一下。大家集体上位进入对应的锁存寄存器,

    2. 74HC595实操接线

    基本电路图:

    在这里插入图片描述

    电路图比较简洁,因为把led的16个管脚用标签的形式来对应了,没有直接进行连线,要不然会交叉的很厉害,没法看。

    锁存GPIO位与点阵管脚连接顺序表:

    锁存IC管脚控制对象点阵屏管脚
    U1QA行1
    U1QB行2
    U1QC行3
    U1QD行4
    U1QE行5
    U1QF行6
    U1QG行7
    U1QH行8
    U2QAl列1
    U2QB列2
    U2QC列3
    U2QD列4
    U2QE列5
    U2QF列6
    U2QG列7
    U2QH列8

    来个模拟连接图:
    在这里插入图片描述

    实际的接线图有点乱,下面是我接的,光接线就搞了好久(欲哭无泪):
    在这里插入图片描述
    这里接线一定要有耐心,接完还要反复检查确保没有接错。

    3. 代码逻辑

    3.1. 图案取模

    在这里插入图片描述
    取模这里在上篇介绍点阵屏原理时已经介绍过了,这里只吧图放过来回顾。

    3.2. 代码编写

    关键点:
    1). 连线方式是QA(Q0)连到了行/列1,QH(Q7)连接到了行/列8。
    2). 取模方式是逆向(低位在前)
    3). 前面说了向74HC595位移数据时,高位在先,也就是第1个移入的数据最终写入QH(Q7)
    4). 也就是说控制74HC595寄存器时,我们取模出来的数据是要从低位到高位依次送入位移寄存器

    有点绕,我也不知道有没有解释清楚,自己实操体会吧。。。 =_=!

    看代码吧,基本上都配了注释,外面就不再过多解释了。

    from machine import Pin
    
    # 准备数据引脚
    pin_sclk = Pin(4, Pin.OUT); pin_sclk.off()  # D2,时钟,上升跳变时数据位移锁存
    pin_rlck = Pin(0, Pin.OUT); pin_rlck.off()  # D3,上升跳变时,数据全部推入锁存
    pin_dio = Pin(2, Pin.OUT); pin_dio.off()    # D4,待移入的数据
    
    # 行引脚控制
    row = [
        0x7F,  # 01111111
        0xBF,  # 10111111
        0xDF,  # 11011111
        0xEF,  # 11101111
        0xF7,  # 11110111
        0xFB,  # 11111011
        0xFD,  # 11111101
        0xFE,  # 11111110
    ]
    
    col = [
        0x00,  # 00000000
        0x66,  # 01100110
        0x99,  # 10011001
        0x81,  # 10000001
        0x42,  # 01000010
        0x24,  # 00100100
        0x18,  # 00011000
        0x00,  # 00000000
    ]
    
    def jump_up(pin):
        pin.on()  # 产生跳变
        pin.off()  # 保持一段时间后关闭
    
    def send_data(position, is_row=True):
        '向位移寄存器送数据'
        value = row[position] if is_row else col[position]  # 取行码或列码对应位置的值
        for i in range(8):
            pin_dio.value((value >> i) & 0x01)  # 从最低位开始送数据
            jump_up(pin_sclk)  # 位移到下一个寄存器
    
    while True:
        for n in range(8):
            send_data(n, is_row=False)  # 先推列码 
            send_data(n, is_row=True)   # 再推行码
            jump_up(pin_rlck)  # 全部数据推入锁存
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    3.2. 代码运行效果

    在这里插入图片描述

    4. 作业

    借助74HC595用动态扫描的方式在8x8LED点阵屏上显示一个固定图案,这步已经实现了。这篇就介绍这么多吧。

    最后来个拓展小作业,在点阵屏上切换显示多个图案,如下效果:

    在这里插入图片描述

    温馨提示:
    1、轮换显示了3个图案,那对应取模时要取3个是必然的了;
    2、定时切换多个图案,中间用time.sleep是行不通的,可以自行实验一下。

  • 相关阅读:
    循环神经网络-简洁实现
    FreeRTOS_空闲任务
    如何用Java编写代码来等待一个线程join()??
    蓝牙协议栈&BLE
    基于51单片机光照强度检测智能窗帘Proteus仿真
    2023.10.02
    【Java】poi-tl实现导出Word模板并动态渲染数据
    Frustum PointNets for 3D Object Detection from RGB-D Data(2018)
    栈——算法专项刷题(六)
    网络原理~初识
  • 原文地址:https://blog.csdn.net/fatway/article/details/127931848