Skip to content

Repository files navigation

LED Matrix Simulator

基于 C++ + SDL2 + Dear ImGui 的点阵屏模拟器,用于与单片机进行串口调试。


功能概述

  • 点阵大屏模拟:由多个小屏拼接组成大屏,支持任意行列配置
  • 多协议支持:通过抽象协议接口支持不同点阵面板协议,可在运行时切换
  • 自动串口扫描:每 2 秒扫描一次 COM 口,可配置波特率
  • 帧协议解析:解析来自单片机的刷屏指令(全屏/区域/单点/清屏/文本显示)
  • 文本渲染:迪文屏协议支持 ASCII 文本的 5×7 点阵渲染
  • 分区配置:对大屏任意像素区域配置独立滚动效果
  • 配置持久化:所有配置自动读写 cfg.ini(与可执行文件同目录)
  • 命令窗口:串口收发数据、程序运行日志实时显示,支持 HEX 手动发送

环境要求(MSYS2 + ucrt64)

# 安装依赖(MSYS2 ucrt64 终端中执行)
pacman -S mingw-w64-ucrt-x86_64-gcc \
          mingw-w64-ucrt-x86_64-cmake \
          mingw-w64-ucrt-x86_64-SDL2 \
          mingw-w64-ucrt-x86_64-ninja \
          curl

快速构建

# 在 MSYS2 ucrt64 终端中
cd /path/to/led_matrix_sim
bash build.sh debug     # Debug 构建
bash build.sh release   # Release 构建

脚本会自动:

  1. 检查依赖工具
  2. 下载 Dear ImGui 源码到 third_party/imgui/
  3. CMake 配置 + 编译
  4. 复制 SDL2.dll 到 bin/

构建产物:bin/LedMatrixSim.exe


手动构建(可选)

mkdir build && cd build
cmake .. -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Debug
# 如果找不到编译器,显式指定:
cmake .. -G "MinGW Makefiles" -DCMAKE_CXX_COMPILER="D:/msys64/mingw64/bin/g++.exe" -DCMAKE_BUILD_TYPE=Debug
cmake --build . --parallel

协议系统

模拟器采用抽象协议接口(IProtocolParser),支持多种点阵屏协议,可在 UI 中随时切换。

Simple 协议(默认)

简化的二进制帧协议,适合快速测试和通用调试。

帧格式

[0xAA] [CMD] [LEN_H] [LEN_L] [DATA...] [CHECKSUM]
  • 0xAA:帧头
  • CMD:命令字节
  • LEN_H/L:Data 段长度(大端,2 字节)
  • DATA:可变长数据
  • CHECKSUM:XOR(CMD, LEN_H, LEN_L, DATA...)

命令表

CMD 名称 数据格式 说明
0x01 FULL_FRAME 位图(总像素数/8 字节,行主序,MSB first) 全屏刷新
0x02 REGION_WRITE X_H X_L Y_H Y_L W H + 位图 局部区域写
0x03 CLEAR (无数据) 清屏
0x04 SET_PIXEL X_H X_L Y_H Y_L VAL 单像素写
0xF0 PING (无数据) 心跳,模拟器回复 PONG
0xF1 PONG (无数据) 心跳响应

单片机示例代码(C)

#include <stdint.h>
#include <string.h>

void serial_send_frame(uint8_t cmd, const uint8_t *data, uint16_t len) {
    uint8_t cs = cmd ^ (uint8_t)(len >> 8) ^ (uint8_t)(len & 0xFF);
    for (uint16_t i = 0; i < len; i++) cs ^= data[i];

    uint8_t header[4] = {0xAA, cmd, (uint8_t)(len>>8), (uint8_t)(len&0xFF)};
    HAL_UART_Transmit(&huart1, header, 4, 100);
    if (len > 0) HAL_UART_Transmit(&huart1, (uint8_t*)data, len, 500);
    HAL_UART_Transmit(&huart1, &cs, 1, 100);
}

void lcd_flush(const uint8_t *framebuf, uint16_t len) {
    serial_send_frame(0x01, framebuf, len);
}

void lcd_clear(void) {
    serial_send_frame(0x03, NULL, 0);
}

void lcd_set_pixel(uint16_t x, uint16_t y, uint8_t val) {
    uint8_t d[5] = {(uint8_t)(x>>8),(uint8_t)x,
                    (uint8_t)(y>>8),(uint8_t)y, val};
    serial_send_frame(0x04, d, 5);
}

DianZhengPing 协议(迪文屏 / 通普风格)

适用于类似 resources/lcdmatrix/DianZhengPing.c 中的点阵面板控制卡协议。

帧格式

[0xAA] [0xA5] [LEN_L] [LEN_H] [DATA...] [CRC_L] [CRC_H] [0x5A] [0x55]
  • 0xAA 0xA5:双字节帧头
  • LEN_L/H:DATA 段长度(2 字节,不含 SF 字段)
  • DATA:参见下方详细结构
  • CRC_L/H:CRC16 校验(通常为 0x00 表示关闭)
  • 0x5A 0x55:帧尾

DATA 段结构(文本显示命令 0x10 0x03)

偏移 字段 大小 说明
0 DES 2 目标地址 (0xFF 0xFF = 广播)
2 SRC 2 源地址
4 TID 2 通信标识 (0xB0 0xA1)
6 CMD 2 命令 (0x10 0x03 = 文本显示)
8 WID 2 条目类型 (2 = 文本)
10 REV 2 条目标识
12 STYLE 4 条目格式
16 INVERT 1 反转标志 (0x40=反转)
17 FONT_ID 1 字号 ID
18 FORMAT 2 文本显示格式
20 ENTRY 2 入场效果
22 SPENTRY 2 入场速度
24 DUENTRY 2 停留时间
26 HIGHLIGHT 2 高亮效果
28 SPHL 2 高亮速度
30 DUHL 2 高亮停留
32 EXIT 2 退出效果
34 SPEXIT 2 退出速度
36 TIMES 2 重复次数 (0xFFFF = 无限循环)
38 DISP_LEN 2 显示文本长度
40 TEXT 可变 文本数据 (通常为 GBK 编码)

目前模拟器支持 ASCII 文本的 5×7 点阵渲染。GBK 中文暂直接记录到日志。


配置文件(cfg.ini)

程序启动时自动读取可执行文件同目录的 cfg.ini,所有 UI 修改在退出时自动保存。

[display]
panel_width = 32        ; 单个小屏宽度(像素)
panel_height = 16       ; 单个小屏高度(像素)
panels_cols = 4         ; 小屏列数
panels_rows = 2         ; 小屏行数
pixel_size = 8          ; 每个像素点渲染尺寸(屏幕像素)
pixel_gap = 1           ; 像素间距
pixel_on_r = 255        ; 亮色 RGBA
pixel_on_g = 180
pixel_on_b = 0
pixel_on_a = 255

[protocol]
name = Simple           ; Simple | DianZhengPing

[serial]
port = COM3             ; 串口(留空则不自动连接)
baud_rate = 115200

[window]
win_width = 1280
win_height = 800

[regions]
count = 1
region_0 = 0,0,64,8,1,50   ; x,y,w,h,scroll_mode,speed_ms
; scroll_mode: 0=停止 1=左滚 2=右滚 3=上滚 4=下滚

工程结构

led_matrix_sim/
├── CMakeLists.txt
├── build.sh                    # 一键构建脚本
├── cfg.ini.template            # 默认配置模板
├── include/
│   ├── AppContext.h            # 全局数据上下文
│   ├── ConfigManager.h         # INI 读写
│   ├── IProtocolParser.h       # 协议抽象接口
│   ├── ProtocolParser.h        # Simple 协议解析器
│   ├── DianZhengPingParser.h   # 迪文屏协议解析器
│   ├── SerialManager.h         # 串口扫描/收发
│   ├── MatrixDisplay.h         # 点阵渲染引擎
│   ├── Region.h                # 分区滚动
│   ├── LogConsole.h            # 日志缓冲
│   └── UIManager.h             # ImGui UI
├── src/
│   ├── main.cpp
│   ├── AppContext.cpp
│   ├── ConfigManager.cpp
│   ├── SerialManager.cpp
│   ├── IProtocolParser.cpp     # 接口基类实现
│   ├── ProtocolParser.cpp      # Simple 协议
│   ├── DianZhengPingParser.cpp # 迪文屏协议 + 内嵌 5×7 字体
│   ├── MatrixDisplay.cpp
│   ├── Region.cpp
│   ├── LogConsole.cpp
│   └── UIManager.cpp
├── resources/
│   └── lcdmatrix/              # 单片机端参考代码
│       ├── DianZhengPing.c
│       └── DianZhengPing.h
├── third_party/
│   └── imgui/                  # Dear ImGui(构建时自动下载)
└── bin/                        # 编译输出
    ├── LedMatrixSim.exe
    ├── SDL2.dll
    └── cfg.ini

扩展协议

添加新协议

  1. 继承 IProtocolParser(参见 include/IProtocolParser.h
  2. 实现 feed(), name() 及可选的 build_test_frame()
  3. src/main.cppcreate_parser() 中添加分支
  4. src/UIManager.cpp 的协议下拉列表中添加名称
  5. 将新文件加入 CMakeLists.txt

协议接口

class IProtocolParser {
public:
    virtual void feed(const uint8_t* data, size_t len) = 0;  // 喂入原始字节
    virtual const char* name() const = 0;                     // 协议名称
    virtual std::vector<uint8_t> build_ack();                  // 应答帧(可选)
    virtual std::vector<uint8_t> build_test_frame(int id);    // 测试帧(可选)
protected:
    AppContext* ctx_;    // 通过它访问 framebuffer / console / serial
};

AppContext::framebuffer 是唯一共享的像素缓冲区(uint8_t 数组,0=灭,1=亮),行主序,左上角为原点。


常见问题

Q: 找不到 SDL2

pacman -S mingw-w64-ucrt-x86_64-SDL2

Q: 串口无法打开,提示 Access Denied
检查是否有其他程序(串口调试助手)占用该端口。

Q: 运行时提示 SDL2.dll 找不到
/ucrt64/bin/SDL2.dll 复制到 bin/ 目录。

Q: 如何切换协议
在程序运行后,在 "Serial Port" 面板的 "Protocol" 下拉框中选择即可实时切换。

Q: DianZhengPing 协议为什么中文没有渲染
当前内嵌字体仅覆盖 ASCII(0x20–0x7F),GBK 中文会被记录到日志但不在屏上显示。后续版本可接入 SDL2_ttf 实现全字符渲染。

About

一个串口点阵模拟器

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages