No description
  • C 91%
  • Assembly 4.8%
  • Makefile 2.2%
  • HTML 2%
Find a file
2026-06-06 18:40:36 +08:00
.claude can compile mario 2026-03-30 07:58:43 +08:00
1.程序/STM32_LED64X64_Clock_V4.0 init 2026-03-27 19:54:04 +08:00
mario can compile mario 2026-03-30 07:58:43 +08:00
CLAUDE.md init 2026-03-27 19:54:04 +08:00
note.txt merge note 2026-06-06 17:23:23 +08:00
README.org update readme 2026-06-06 18:40:36 +08:00

Mario Clock — STM32 + HUB75E 64×64 RGB LED 点阵屏

项目概述

在 64×64 RGB LED 点阵屏上播放马里奥动画,同时叠加一个 0–999 循环递增的数字计数器。动画以"来回顾盼"(正放+倒放)方式循环播放,帧切换由定时器中断触发。

项目包含两套工程:

  • Keil 工程 — 原始版本,基于 STM32 SPL(标准外设库),使用 ARMCC 编译器
  • mario 工程 — 移植版,基于 libopencm3,使用 GCC 工具链,命令行构建

硬件

MCU

项目 Keil 工程 mario 工程
芯片 STM32F103ZE (512K Flash) STM32F103C8T6 (64K Flash)
晶振 12MHz 外部 8MHz 外部
系统时钟 72MHz (PLL) 72MHz (PLL)
调试接口 SWD (PA13/PA14) SWD (PA13/PA14)
JTAG 已禁用 (释放 PB3/PB4) 已禁用 (释放 PB3/PB4)

LED 面板

  • 类型:64×64 全彩 RGB LED 点阵屏
  • 接口:=HUB75E=(2×8 排针,共 16 针)
  • 结构:上下半屏独立驱动(R1/G1/B1 驱动上半 32 行,R2/G2/B2 驱动下半 32 行)
  • 颜色深度:RGB222(每通道 2 位 = 64 色)

引脚接线 (mario 工程,标准 HUB75E 映射)

所有信号线接在 GPIOB,引脚定义见 =mario/src/led.c:6-19=:

信号 引脚 功能
R1 PB0 上半屏 红色数据
G1 PB1 上半屏 绿色数据
B1 PB2 上半屏 蓝色数据
R2 PB3 下半屏 红色数据
G2 PB4 下半屏 绿色数据
B2 PB5 下半屏 蓝色数据
A PB6 行地址 bit0
B PB7 行地址 bit1
C PB8 行地址 bit2
D PB9 行地址 bit3
E PB10 行地址 bit4
CLK PB11 移位时钟
LAT PB12 锁存脉冲
OE PB13 输出使能 (低有效)

*重要*:Keil 工程的引脚映射不同——由于作者的面板 RGB 线序错位,R1/G1/B1 在程序中被调换了顺序(PB0=G1, PB1=B1, PB3=R1)。如果你的面板颜色不对,检查 led.c 中最前面的 LED_x_OUT 宏定义。

电源

LED 面板全白时电流可达 3–5A,*不能*从 STM32 开发板的 3.3V 取电。面板需要独立的 5V 电源供电,控制器和面板 共地 即可。

调试器接线

  • 用 ST-Link / CMSIS-DAP / J-Link 等调试器
  • 接 4 根线:=3.3V=, GND, PA13(SWDIO), PA14(SWCLK)

软件工作原理

总体架构

┌──────────────────────────────────────────────┐
│ main()                                       │
│   ├─ 系统初始化 (时钟, GPIO, 定时器)           │
│   └─ while(1)                                │
│        ├─ [display_flag=1] 播放一遍动画 + 更新数字 │
│        └─ [display_flag=0] 持续刷新当前帧        │
└──────────────────────────────────────────────┘
                     ▲
                     │ display_flag
                     │ num (0-999)
┌──────────────────────────────────────────────┐
│ TIM2 中断 (每 10ms)                           │
│   ├─ 计数 100 次 ≈ 1 秒置位 display_flag      │
│   └─ num++, 模 1000                           │
└──────────────────────────────────────────────┘

动画播放流程 (main.c)

动画共有 6 帧(=gImage_Mario_1= 到 =gImage_Mario_6=),播放方式为"来回顾盼": 1→2→3→4→5→6→[更新数字]→5→4→3→2→1

每帧调用 led_display_64x64_rgb222() 重复 GIF_DELAY_TIME (10) 次,目的是让扫描循环多执行几轮以维持视觉亮度和控制帧率。

当 display_flag==0 时(没有动画需要播放),主循环持续扫描第 1 帧作为"待机画面",让 LED 保持显示而非黑屏。

TIM2 定时器 (timer.c)

TIM2 是帧更新的"心跳"。配置如下:

参数 值 说明
PSC 7200-1 预分频:72MHz ÷ 7200 = 10kHz
ARR 10000-1 自动重装载:10kHz ÷ 10000 = 1Hz
实际中断频率 每 10ms 一次 —

每次中断中,软件计数器自增。累计 100 次(≈ 1 秒)后置位 display_flag~,同时将 ~num 加 1(模 1000 循环)。主循环检测到 display_flag==1 后播放一整遍动画,然后将其清零。

注意: mario 工程的中断处理方式与 Keil 工程不同。Keil 工程在每次 10ms 中断中都置位 flag(中断频率本身是 10ms),而 mario 工程中用软件计数器 counter 累加到 100 才触发,实际帧切换间隔约 1 秒。

HUB75E 显示驱动 (led.c)

HUB75E 接口的核心是 行扫描 + /移位输出/。64×64 面板被分为上下两个 32 行,同时驱动。

数据格式

图像数据以 RGB222 格式存储,每像素用 2 字节:

  • 上半像素:第 1 字节高 4 位 = G[1:0] B[1:0],第 1 字节低 4 位 + 第 2 字节 = R[1:0]
  • 下半像素:存储在数组后半段,格式相同

每个 64×64 的帧占 8192 字节(64×64×2 = 4096 像素 × 2 字节/像素)。

一次扫描输出过程 (led_display_64x64_rgb222())

  1. 解码 (led_get_rgb222_pic):将 RGB222 格式的帧数据解成 RGB 缓冲数组 ~gImage_RGB_up/down[2048][3]~,每通道值 = 0–3(2 位)
  2. 数字叠加 (led_num_color_set):将 4 位数字对应区域的像素挖空(背景透明效果)
  3. *扫描输出*:4 级灰度 × 32 行循环:

    • 设置行地址(A/B/C/D/E 五根地址线)
    • 逐像素移位输出 64×6 个颜色位(上下半屏各 RGB 3 位),每个 CLK 脉冲输出一列
    • LAT 锁存脉冲:将移位寄存器数据锁存到输出端
    • OE 脉冲:使能输出,点亮当前行
    • line++ ,进入下一行

4 级灰度实现

灰度通过 PWM 思想 实现:外层循环 grayscale 0→3 共 4 轮。对于每个像素,只有当当前灰度级 < 像素通道值时,才将该颜色引脚置高。例如像素 R=2,则灰度级 0 和 1 时亮,2 和 3 时灭,视觉上就是 50% 占空比的红色。

系统初始化 (sysinit.c)

步骤 说明
时钟 外部 8MHz 晶振 → PLL 倍频至 72MHz
AFIO 使能复用功能时钟,释放 PB3/PB4
JTAG 禁用 JTAG,保留 SWD 调试接口
GPIO 所有 HUB75E 引脚初始化为 50MHz 推挽输出

马里奥帧数据

6 帧动画数据定义在 mario/src/font.c=,每帧 8192 字节的压缩 RGB222 数据,通过 =mario/include/font.h 以 extern 声明导出。

构建与烧录

Keil 工程

  1. 用 Keil uVision 打开 1.程序/STM32_LED64X64_Clock_V4.0/example.uvprojx
  2. 重要:在 Project Options → C/C++ → Optimization 设为 ~Level 1 (-O1)~(提升帧率)
  3. F7 编译
  4. F8 下载到芯片

mario 工程(推荐)

依赖:~arm-none-eabi-gcc~, libopencm3, make, openocd

编译:

cd mario/
make

生成文件:=mario_led.elf=, mario_led.bin, mario_led.hex

烧录(使用 OpenOCD,默认 CMSIS-DAP):

make flash

如果使用 ST-Link,修改 =mario/Makefile:14=:

OPENOCD_INTERFACE = interface/stlink.cfg

调试:

make debug-server   # 终端 1:启动 OpenOCD
make debug          # 终端 2:启动 GDB

调试串口

mario 工程有调试串口:UART1 (PA9=TX, PA10=RX) @ 115200 8N1。启动时会输出 ~=== Mario LED Matrix ===~。

常见问题

  • *颜色不对*:检查 led.c 中 R1/G1/B1 的引脚宏定义,不同面板的 RGB 线序可能错位
  • *亮度/帧率低*:确保编译优化等级为 -O1~(Keil)或 ~-Os~(GCC);减少 ~GIF_DELAY_TIME 可加快动画速度但会降低亮度
  • *花屏/抖动*:杜邦线过长会导致信号质量问题,建议打 PCB
  • *面板不亮*:检查 OE 引脚初始状态是否为 HIGH(关闭输出),以及面板独立供电是否正常