当前位置:首页 > 技术 > 正文内容

大尺寸 8x8 LED 点阵模块(MAX7219)的多种显示与动态频谱实现

访客 技术 2026年10月7日 1

8x8 LED 点阵模块是嵌入式开发中常见的显示外设。本文介绍的大尺寸(6mm 方格)点阵屏通常采用 MAX7219 驱动芯片。该芯片支持串行输入,可级联,并具备 16 级亮度控制。通过简单的 3 线接口(DIN、CS、CLK),即可实现数字、字符以及复杂图形的动态显示。

项目一:字符与中文静态轮播

本方案通过直接操作寄存器的方式,控制 MAX7219 驱动点阵屏轮流显示数字 0-9 以及中文字符"中"和"国"。我们将自定义字模数据存储在二维数组中,并通过位移操作实现串行通信。


/*
  硬件连接:
  MAX7219  ->  Arduino UNO
  VCC      ->  5V
  GND      ->  GND
  DIN      ->  D12
  CS       ->  D11
  CLK      ->  D10
*/

const int PIN_CLK = 10;
const int PIN_LOAD = 11;
const int PIN_DATA = 12;

// 定义字符字模:0-9, 中, 国
unsigned char glyph_table[12][8] = {
  {0x3C, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3C}, // 0
  {0x08, 0x18, 0x28, 0x08, 0x08, 0x08, 0x08, 0x08}, // 1
  {0x7E, 0x02, 0x02, 0x7E, 0x40, 0x40, 0x40, 0x7E}, // 2
  {0x3E, 0x02, 0x02, 0x3E, 0x02, 0x02, 0x3E, 0x00}, // 3
  {0x08, 0x18, 0x28, 0x48, 0xFE, 0x08, 0x08, 0x08}, // 4
  {0x3C, 0x20, 0x20, 0x3C, 0x04, 0x04, 0x3C, 0x00}, // 5
  {0x3C, 0x20, 0x20, 0x3C, 0x24, 0x24, 0x3C, 0x00}, // 6
  {0x3E, 0x22, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08}, // 7
  {0x00, 0x3E, 0x22, 0x22, 0x3E, 0x22, 0x22, 0x3E}, // 8
  {0x3E, 0x22, 0x22, 0x3E, 0x02, 0x02, 0x02, 0x3E}, // 9
  {0x08, 0x7F, 0x49, 0x49, 0x7F, 0x08, 0x08, 0x08}, // 中
  {0xFE, 0xFE, 0x92, 0xFE, 0x9A, 0xFE, 0x82, 0xFE}  // 国
};

void send_byte(unsigned char data) {
  for (int i = 8; i >= 1; i--) {
    digitalWrite(PIN_CLK, LOW);
    digitalWrite(PIN_DATA, (data & 0x80) ? HIGH : LOW);
    data <<= 1;
    digitalWrite(PIN_CLK, HIGH);
  }
}

void write_reg(unsigned char addr, unsigned char val) {
  digitalWrite(PIN_LOAD, LOW);
  send_byte(addr);
  send_byte(val);
  digitalWrite(PIN_LOAD, HIGH);
}

void init_screen() {
  write_reg(0x09, 0x00); // 译码模式
  write_reg(0x0a, 0x03); // 亮度设置
  write_reg(0x0b, 0x07); // 扫描界限
  write_reg(0x0c, 0x01); // 开启模式
  write_reg(0x0f, 0x00); // 测试关闭
}

void setup() {
  pinMode(PIN_LOAD, OUTPUT);
  pinMode(PIN_CLK, OUTPUT);
  pinMode(PIN_DATA, OUTPUT);
  init_screen();
}

void loop() {
  for (int char_idx = 0; char_idx < 12; char_idx++) {
    for (int col = 1; col <= 8; col++) {
      write_reg(col, glyph_table[char_idx][col - 1]);
    }
    delay(1000);
  }
}

项目二:利用 Matrix 库实现 Sprite 图形控制

使用 Matrix 库可以更方便地处理点阵显示。通过 Sprite 对象,我们可以预定义图形并直接指定坐标绘制,非常适合需要精准定位的级联显示场景。


#include <Sprite.h>
#include <Matrix.h>

// 参数:DIN, CLK, CS, 模块数量
Matrix canvas = Matrix(12, 10, 11, 3);

Sprite glyph_L = Sprite(5, 8,
    B11000,
    B11000,
    B11000,
    B11000,
    B11000,
    B11000,
    B11111,
    B11111
);

Sprite glyph_E = Sprite(5, 8,
    B11111,
    B11111,
    B11000,
    B11110,
    B11110,
    B11000,
    B11111,
    B11111
);

void setup() {
  canvas.setBrightness(2);
}

void loop() {
  canvas.clear();
  delay(500);
  
  // 在级联点阵的不同位置写入图形
  canvas.write(17, 0, glyph_L);
  delay(800);
  canvas.write(9, 0, glyph_E);
  delay(800);
  canvas.clear();
}

项目三:横向滚动文本显示

在长条形级联屏幕中,横向滚动显示是最常见的功能。通过 MaxMatrix 库,可以轻松建立字母库并实现平滑移位。


#include <MaxMatrix.h>
#include <avr/pgmspace.h>

int DATA_IN = 12;
int CS_PIN = 11;
int CLK_PIN = 10;
int MODULE_COUNT = 3;

MaxMatrix led_wall(DATA_IN, CS_PIN, CLK_PIN, MODULE_COUNT);

// 示例字母库片段(空格, !, ")
const unsigned char FONT_LIB[] PROGMEM = {
  3, 8, B00000000, B00000000, B00000000,
  1, 8, B01011111,
  3, 8, B00000011, B00000000, B00000011
};

char message[] = "ARDUINO RUN ";
byte render_buffer[10];

void scroll_text(char* text, int speed) {
  while (*text != 0) {
    char c = *text - 32;
    // 从程序存储区拷贝字模数据
    memcpy_P(render_buffer, FONT_LIB + 7 * c, 7); 
    led_wall.writeSprite(32, 0, render_buffer);
    
    for (int i = 0; i < render_buffer[0] + 1; i++) {
      delay(speed);
      led_wall.shiftLeft(false, false);
    }
    text++;
  }
}

void setup() {
  led_wall.init();
  led_wall.setIntensity(5);
}

void loop() {
  scroll_text(message, 80);
}

项目四:基于 MAX9812 的动态音乐频谱

结合声音传感器(如 MAX9812),可以将环境音量实时映射到点阵屏上,形成跳动的频率柱。本方案采用峰峰值采样法,并在显示上增加了平滑下降效果。


#include "LedControl.h"

// DIN=12, CS=11, CLK=10, 1个模块
LedControl visualizer = LedControl(12, 11, 10, 1);

const int SENSOR_PIN = A4;
const int SAMPLE_WINDOW = 50; // 50ms采样窗口
unsigned int peak_to_peak = 0;
unsigned int last_level[8] = {0};

void setup() {
  visualizer.shutdown(0, false);
  visualizer.setIntensity(0, 4);
  visualizer.clearDisplay(0);
}

void loop() {
  unsigned long start_time = millis();
  unsigned int sig_max = 0;
  unsigned int sig_min = 1024;

  while (millis() - start_time < SAMPLE_WINDOW) {
    unsigned int raw_val = analogRead(SENSOR_PIN);
    if (raw_val < 1024) {
      if (raw_val > sig_max) sig_max = raw_val;
      if (raw_val < sig_min) sig_min = raw_val;
    }
  }

  peak_to_peak = sig_max - sig_min;
  // 将 0-1023 的模拟量映射到点阵的 0-7 行
  int display_height = map(peak_to_peak, 0, 800, 0, 8);

  for (int i = 0; i < 8; i++) {
    // 简单的缓慢坠落逻辑
    if (display_height >= last_level[i]) {
      last_level[i] = display_height;
    } else if (last_level[i] > 0) {
      last_level[i]--;
    }
    
    render_column(i, last_level[i]);
  }
  delay(10);
}

void render_column(int col, int height) {
  byte row_data = 0;
  for (int i = 0; i < height; i++) {
    row_data |= (1 << i);
  }
  visualizer.setRow(0, col, row_data);
}

在实际应用中,通过级联多个 8x8 模块,可以构建更大面积的显示阵列。结合 FFT(快速傅里叶变换)算法,还可以在此硬件基础上实现更精确的分频频谱仪,展示不同频段的声音动态。

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。