MAX7219 示例(8位段驱动器)

发布: (2026年1月1日 GMT+8 04:35)
6 分钟阅读
原文: Dev.to

Source: Dev.to

(请提供您希望翻译的完整文本内容,我将按照要求保留源链接并将文本翻译为简体中文。)

硬件

我使用的开发板配备了一个 8 位 7 段显示器和一个 MAX7219 驱动芯片。

MAX7219 8‑digit 7‑segment

引脚分配

引脚功能
GND电源地
VCC电源(5 V)
DIN串行数据输入
CLK串行时钟
LOAD / CS锁存(芯片选择)

虽然这些引脚看起来像 SPI 接口,但 MAX7219 实际上只使用一种简单的 16 位串行协议(MAX7221 是兼容 SPI 的变体)。

串行数据格式

每个事务由 16 位 组成:

  • 上位 8 位 – 寄存器地址
  • 下位 8 位 – 该寄存器的数据

数据手册显示位是 先发送最高位 (MSB)(功能图错误地提到了先发送最低位 (LSB))。

Serial Data Format

寄存器地址映射

地址 (hex)寄存器名称描述
0x01‑0x08Digit 0‑7每位数字的段数据
0x09Decode Mode为每位数字启用/禁用 BCD 解码
0x0AIntensity亮度 (0x0 … 0xF)
0x0BScan‑Limit显示的数字位数 (0‑7)
0x0CShutdown正常运行 (0x01) / 关机 (0x00)
0x0FDisplay Test强制所有段在最大亮度下点亮

Register Address Map

  • 显示测试 寄存器会在最大亮度下点亮每位数字的所有段。
  • 关机 寄存器使用 0x01 以启用正常运行(名称有点令人困惑)。

寄存器:Scan‑Limit

Scan‑Limit 寄存器选择有多少位数是激活的:

  • 0x00 – 仅显示第 0 位(复位后默认)
  • 0x07 – 显示全部八位

如果你想 完全没有输出,可以:

  • 将设备置于 Shutdown(关机)模式 (0x0C 0x00),或
  • No‑Decode 模式下将第一位设为 0x00(无段显示),或在 BCD 模式下设为 0x0F

Register: Digit

每个数字寄存器包含 8 位,用于控制各个段(或在启用解码时表示 BCD 值)。

1. No‑Decode(原始段)模式

位对应的段 A‑G 和小数点 DP

D7DP
D6A
D5B
D4C
D3D
D2E
D1F
D0G

示例 – 要显示数字 1,应写入 0x30D5=1, D4=1,即点亮段 BC)。

No Decode Mode

2. BCD(解码)模式

Decode Mode 寄存器中的相应位被设置时,驱动器会将低四位(0x00x9)解释为十进制数字,并自动点亮相应的段。

特殊 BCD 码(0xA0xF):

字符
0xA破折号 (-)
0xBE
0xCH
0xDL
0xEP
0xF空白(所有段关闭)— 与 No‑Decode 模式下的 0x00 效果相同

你甚至可以通过发送序列 0x040C 0x030B 0x020D 0x010E 来拼出 “HELP”(第 3 位 → H,第 2 位 → E,第 1 位 → L,第 0 位 → P)。

寄存器:解码模式

Decode Mode 寄存器是一个 掩码;每个位用于为相应的数字启用 BCD 解码:

数字
D0数字 0
D1数字 1
D7数字 7
  • 0x00 – 所有数字均不进行解码(原始段模式)。
  • 0x01 – 仅为数字 0 启用 BCD 解码。
  • 0x03 – 为数字 0 和 1 启用 BCD 解码,依此类推。

加载数据(串行写入)

数据在 CLK上升沿 采样。驱动器对 DIN 进行采样并将该位移入内部的 16‑位移位寄存器(先传输最高位)。

发送单个位(Arduino‑风格伪代码)

digitalWrite(PIN_CLK, LOW);          // prepare for rising edge
if (cmd & 0x8000) {                  // MSB of the 16‑bit word?
    digitalWrite(PIN_DIN, HIGH);
} else {
    digitalWrite(PIN_DIN, LOW);
}
digitalWrite(PIN_CLK, HIGH);         // latch the bit

发送完整的 16‑位命令

// Example: enable Display‑Test (register 0x0F, data 0x01)
uint16_t cmd = 0x0F01;               // high byte = address, low byte = data

for (int i = 0; i (reg)

注意: 如果需要更高的性能,可以将其转换为宏。

构建命令

命令非常容易构建。例如,要向 digit 0 发送数字 6(使用 BCD):

// 0x1 is the register for digit 0
uint16_t cmd = buildCmd(0x1, 6);
// send the command to the module
sendCmd(cmd);

如果使用 BCD:

// 0x1 is the register for digit 0
// 6 uses segments A, C, D, E, F, G → 0b0101 1111 = 0x5F
uint16_t cmd = buildCmd(0x1, 0x5F);
sendCmd(cmd);

示例

下面的示例使用测试模式,然后重置大多数寄存器。仅重置模块已经足够,但在配置之前重置所有寄存器可以让你拥有一个干净的起点。

// Enable all 8 digits
cmdSetScanLimit(7);

// Set lowest intensity
cmdSetIntensity(0);

// Use BCD decoding for all digits
cmdSetDecodeMode(0xFF);

// Blank all segments
for (uint8_t i = 0; i < 8; i++) {
    uint16_t cmd = buildCmd(REGISTER_DIGIT0 + i, 0xF);
    sendCmd(cmd);
}

// Show all possible BCD values, finishing with a blank
for (uint8_t i = 0; i < 8; i++) {
    for (uint8_t j = 0; j < 16; j++) {
        uint16_t cmd = buildCmd(REGISTER_DIGIT0 + i, j);
        sendCmd(cmd);
        delay(200);
    }
}

示例仓库

https://github.com/danguer/arduino-examples/tree/main/max7219

Source: https://www.analog.com/media/en/technical-documentation/data-sheets/max7219-max7221.pdf

数据手册

https://www.analog.com/media/en/technical-documentation/data-sheets/max7219-max7221.pdf

Back to Blog

相关文章

阅读更多 »

RGB LED 支线任务 💡

markdown !Jennifer Davishttps://media2.dev.to/dynamic/image/width=50,height=50,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%...

Mendex:我为何构建

介绍 大家好。今天我想分享一下我是谁、我在构建什么以及为什么。 早期职业生涯与倦怠 我在 17 年前开始我的 developer 生涯……