MicroPython-On-ESP8266——8x8LED点阵模块(3)使用MAX7219驱动

22 篇文章 1 订阅
19 篇文章 1 订阅

MicroPython-On-ESP8266——8x8LED点阵模块(3)使用MAX7219驱动

1. 新主角登场

手上有块8x8LED点阵屏,咱们已经了解了点阵屏的基础电路与驱动原理,并用两片74HC595锁存IC成功驱动点阵屏显示需要的图案。

MicroPython-On-ESP8266——8x8LED点阵模块(1)驱动原理

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

今天咱们来试试用一片MAX7219来驱动这个LED点阵屏。

在这里插入图片描述

2. MAX7219介绍与驱动点阵屏原理

2.1. MAX7219驱动IC介绍

MAX7219驱动IC,官方文档:
https://datasheets.maximintegrated.com/cn/ds/MAX7219-MAX7221_cn.pdf

文档里面有引脚图和典型驱动数码管的接线示例(这就给力了)

在这里插入图片描述
且不论芯片如何工作起来,单单从标注的引脚和典型驱动数码管的接线图来看,要用本芯片来驱动8x8
LED,需要先建立一个基础的对照关系:

  • DIG_0 ~ DIG_7,这8个引脚用来控制数码管的位码,我们驱动8x8点阵屏就对应来控制8个管脚;
  • SEG_A ~ SEG_G,SEG_DP,这8个段码的引脚,驱动8x8点阵屏就对应来控制8个管脚。

2.2. 驱动原理

这里我们不用按官方文档详细去解读,我只把核心知识点罗列出来。

2.2.1. 知识点1:这是一个串入并出的芯片

MAX7219内部有一个16位的寄存器,外部数据通过串行的方式逐个输入,按照D0 -> D1 -> D2 -> … -> D15的顺序依次填入到该16为寄存器内。

如果外部串行输入16次状态值,第一个输入的值最终被位移至D15位,第二个位移到D14,最后一个进入的状态值只位移到D0位。

串入位移的动作和最终并出的结果是通过以下管脚实现的:

引脚作用
DIN输入引脚。外部给定的电平状态,等待被移入到寄存器内部的D0位
CLK时钟引脚。初始是低电平,当时钟引脚电平向上跳变一次时,DIN输入引脚的状态值可以位移进寄存器了
LOAD锁存引脚。初始低电平。输入引脚和时钟引脚配合,完成想要位移的状态值后,本锁存引脚需要向上跳变一次,完成寄存器所有位状态的锁定,也就是具备了对外输出指定结果的能力
DOUT溢出数据引脚。状态值位移到寄存器D15后,如果还有DIN值位移进寄存器,那D15的值就溢出到DOUT引脚。这样把DOUT引脚接入到下一片MAX7219的DIN脚,就实现了多个芯片级联的效果了

位移逻辑图:
在这里插入图片描述

注:
LOAD锁存引脚进行跳变以确认最终值时,必须在两个时钟引脚跳变之间进行,否则最终值可能有误

2.2.2. 知识点2:寄存器两个字节 = 地址 + 数据

MAX7219内部16位的寄存器,被串行输入数据后,并不是直接一一对应地并出到了DIG0 ~ 7、SEGA ~ DP这16个输出管脚上的,而是内部还有一层业务转换。

寄存器数据状态如下图:
在这里插入图片描述

  • 第1个字节的高4位用不到,所以标注了XXXX
  • 第1个字节的低4位为ADDRESS地址,作为寻址位寄存器或控制寄存器使用,按官方文档共用14种类型
  • 第2个字节的8位为DATA数据,不同的ADDRESS下的数据有不同的含义
2.2.4. 知识点3:ADDRESS地址位的使用方式

寄存器第一个字节的地址表我从手册上截图下来:
在这里插入图片描述
ADDRESS高4位用不到,所以标注成X,咱们实际使用时终归还是要传值过去的,这里我们统一高4位给0,相对于地址0我们就传0x00,后面都用该方式。

不同ADDRESS地址代表的含义和对应的DATA用法:

类型寄存器地址说明DATA用法
No-Op0x00不显示DATA=1 ??
Digit 0 ~ 70x01 ~ 0x08LED屏的位码也就是控制哪一个行要显示
例如,我们控制的是DIG 0(0x01),也就是led屏的第1行,依次类推到第8行。
DATA的8个字节就是对应控制该行下8列led的亮灭情况。
Decode Mode0x09译码模式DATA=0x00 不译码(我们连接LED点阵屏用这个)
DATA=0x01 BCD译码只取digit 0
DATA=0x0F BCD译码取digit 0到3
DATA=0xFF BCD译码取digit 0到7
(BCD码不在我们这篇里介绍了)
Intensity0x0A亮度DATA取值范围0 ~ 15,数值越大亮度越高
Scan Limit0x0B扫描限制
2.2.5. 知识点4:数据字节控制led的顺序

需要注意的是,控制顺序不是A/B/C/D/E/F/G/DP,而是DP在最高位,见下图所示。也就是说我们在控制段码时,按位串入状态值时,要按DP、A、B、C、D、E、F、G的次序依次位移进入寄存器。

在这里插入图片描述

2.2.6. 知识点5:初始化模块

因为我们不是拿这模块来玩花活儿的,目的就是点亮led矩阵,所以需要在使用模块进行图案控制前,把位码控制外的其他Address都设置好,具体的有:

  • 模块不测试LED,向模块发送:[0x0F, 0x00]
  • 需要扫描所有位码,向模块发送:[0x0B, 0x07]
  • 模块亮度,向模块发送:[0x0A, 0x07] (半亮,根据自己需要调整亮度)
  • 不译码,向模块发送:[0x09, 0x00]
  • 关断控制器处于显示状态,向模块发送:[0x0C, 0x01]

3. 接线电路图与实操

3.1. 接线方式说明

3.1.1. 芯片与点阵屏接线方式

根据上面我们分析MAX7219的驱动原理,位码连接到点阵屏的行引脚、段码连接到点阵屏的列引脚。

行码通过地址位输出了DIG 0 到7,对应接到LED点阵的行1到行8管脚即可;
段码部分,由于最高位是 SEG DP,所以我们接线顺序是 DP端接列1的管脚(⑬管脚),其次才是SEG A、B。。。

具体对应关系表:

管脚控制点阵屏对象点阵屏管脚
DIG 0行1
DIG 1行2
DIG 2行3
DIG 3行4
DIG 4行5
DIG 5行6
DIG 6行7
DIG 7行8
SEG DP列1
SEG A列2
SEG B列3
SEG C列4
SEG D列5
SEG E列6
SEG F列7
SEG G列8
3.1.2. 芯片与nodemcu开发板进行串行输入的连线
管脚nodemcu针脚GPIO
DIND7Pin(13)
CSD8Pin(15)
CLKD5Pin(14)
V+3V3-
GNDGND-
3.1.3. max7219还需连接的地方
  • 两个GND需要串起来
  • V+与ISET之间用一个10K电阻串接

3.2. 接线模拟与实物展示

3.2.1. 模拟接线图

在这里插入图片描述

3.2.2. 实物效果

在这里插入图片描述

有点乱,简直没眼看,这个接线接了半个多小时(汗!)

4. 取模方式与控制代码

4.1. 取模原理

线已经接好了,在实际编写代码之前,咱们还是要考虑清楚图案该怎样实际展示到led点阵屏上面。

由于我们把DIG0~7都对应到了点阵屏的行1-8管脚上,且行控制已经交由MAX7219来控制了,我们只需要关心在具体的某一行上对应的8个led我们要以怎样的组合来控制亮灭。一行上的8个led又通过了SEG系列的管脚进行了对应。

我们按照按照前面“知识点4”说明,最先送入的位是DP,就是控制第1列led灯珠的亮灭的。那么我们就直观的按照当前行的亮灭状态从左到右取值,左边是最高位,再按从左到右的顺序移入位状态给max7219芯片即可对应起来。比如:第4行,应该取模为0x81。

在这里插入图片描述

4.2. 实际取模

取模的软件比较多,也有专门针对8x8点阵屏的取模工具,不过我用多了PCtoLCD2002,觉得顺手就好用这个取模了。

用法不多说,配置按图标注的来即可,其实心里面想想把点阵屏刚好跟取模窗1:1对应就好。
在这里插入图片描述
手动建立一个8*8的图形区域,自己标注爱心图案,按照选项配置下来,生成的字模就得到了:
{0x00,0x66,0x99,0x81,0x42,0x24,0x18,0x00}

好了,下面就要进入编码部分实际控制一下看看效果了。

5. 实验效果

5.1. 实验代码

from machine import Pin
import time

# 准备数据引脚
pin_clk = Pin(14, Pin.OUT, value=1) #D5,时钟,上升跳变时数据位移锁存
pin_cs = Pin(15, Pin.OUT, value=1)  #D8,上升跳变时,数据全部推入锁存
pin_din = Pin(13, Pin.OUT, value=1) #D7,待移入的数据

def write_byte(data):
    "按位移入数据"
    for i in range(8):
        pin_clk.off()
        pin_din.value(1 if ((data << i) & 0x80) else 0)  # 从高位开始送数据
        pin_clk.on()

def write_data(addr, data):
    "向模块写入地址与数据"
    pin_cs.off()
    write_byte(addr)
    write_byte(data)
    time.sleep_us(5)
    pin_cs.on()

def init_max7219():
    "初始化模块"
    write_data(0x0c, 0x00)  #关断处于关闭状态 
    write_data(0x0f, 0x00)  #不测试
    write_data(0x0b, 0x07)  #扫描所有位码
    write_data(0x0a, 0x0F)  #亮度0x07,半亮
    write_data(0x09, 0x00)  #不译码
    write_data(0x0c, 0x01)  #关断处于显示状态 

# 定义数据与初始模块
time.sleep_ms(50)
col = [0x00, 0x66, 0x99, 0x81, 0x42, 0x24, 0x18, 0x00]
init_max7219()

# 写图案
for n in range(8):
    write_data(n+1, col[n])

注意,程序的最后没有写while死循环,只刷了一次各行数据进入max7219芯片。也就是没有用到前面学习595芯片时的动态扫描机制,你可以理解为动态扫描功能由max7219内部来处理,不需要我们关心。

5.2. 刷入代码效果展示

在这里插入图片描述

至此,咱们的爱心终于出来了,达到了预期的目的。

如果要展示其他图案,自行按照取模部分进行配置即可。

6. 后记

前面罗里吧嗦的介绍了一堆原理分析,写得比较随意,希望不会给大家造成越看越不明白的困境吧。

其实那个MAX7219和8x8LED点阵屏,都是我从一个封装好的成品模块中拆下来的。直接用这个模块就不用像我上面接线接到吐了。

在这里插入图片描述

MAX7219是一种集成化的串行输入/输出共阴极显示驱动器,它连接微处理器与8位数字的7段数字LED显示,也可以连接条线图显示器或者64个独立的LED。其上包括一个片上的B型BCD编码器、多路扫描回路,段字驱动器,而且还有一个8*8的静态RAM用来存储每一个数据。只有一个外部寄存器用来设置各个LED的段电流

模块参数:
1.单个模块可以驱动一个8*8共阴点阵
2.模块工作电压:5V
3.模块带输入输出接口,支持多个模块级联

接线说明:
1.模块左边为输入端口,右边为输出端口。
2.控制单个模块时,只需要将输入端口接到CPU
3.多个模块级联时,第1个模块的输入端接CPU,输出端接第2个模块的输入端,第2个模块的输出端接第3个模块的输入端,以此类推…

6.1. 接线方式

接线以我们上面接的nodemcu开发机为例:

MAX7219点阵模块引脚NodeMCU管脚
VCC3V3
GNDGND
DIND7 (Pin13)
CSD8 (Pin15)
CLKD5 (Pin14)

在这里插入图片描述

6.2. 实验效果

代码不用改,开发板直接通电看效果即可:
在这里插入图片描述

6.3. 其他

这个模块是支持用SPI进行数据传输的,其实我的代码里面的write_bytewrite_data这个机制就跟SPI是差不多的了。这些内容我们后面有机会再补充学习吧。

  • 0
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值