轻量级的串口控制LCD显示屏,通过串口即可交互。
A lightweight UART-controlled LCD module with interactive capabilities via serial communication.
-
支持多种图形绘制命令(点、线、矩形、圆、字符、字符串、图片)
-
具有一个大容量的缓冲区
-
支持EEPROM存储数据
-
支持蜂鸣器播放音符序列
-
6P 0.5mmFPC连接器实现供电和通信,5V供电,3.3V TTL串口控制。
serial-lcd-module/
├─hardware/ # 原理图、PCB、BOM 清单
├─resource/ # 资源文件
└─software/
├─example/ # Python 演示脚本
└─serial-lcd-module-v203g6u6/ # MCU 工程目录
使用5V供电,正常工作时电流不应超过500mA。
3.3V TTL的UART接口,波特率115200bps,8数据位,1停止位,无校验位(最常见的串口配置)。
不等长的通信帧,通信帧以\0结尾,依赖串口空闲中断实现截取通信帧,应确保帧间隔至少相差2字节数据。
通信帧无缓冲区,非即时处理,不可高速连续操作。
WCH生产的CH32V203G6U6,具有32KB的FLASH和10KB的SRAM,工作在120MHz的主频下,使用24MHz的晶振提供时钟。
中景园电子生产的0.96寸 TFT-LCD 显示屏,分辨率80x160,色彩RGB565,驱动ST7735,焊接式13Pin。可调亮度。
预留焊盘,支持3.3V供电的无源蜂鸣器,驱动电流不应超过200mA。
基于性能考虑,该模块没有完善的存储区域越界保护功能,控制时应当注意越界问题。
| 区域 | 长度 | 可操作 | 说明 |
|---|---|---|---|
| SRAM缓冲区 | 4096B | R/W | 作LCD缓冲用 |
| 蜂鸣器音符序列FIFO | 1024B | W | 作蜂鸣器播放缓冲用 |
| EEPROM | 32KB | R/W | 持久化存储数据用 |
| USART接收缓冲区 | 320B | X | 主控处理串口接收数据 |
| USART发送缓冲区 | 256B | X | 主控处理串口发送数据 |
显示屏的坐标原点(0, 0)位于屏幕左上角,一般地,绘制时的定位原点也位于绘制区域左上角。默认是行扫描模式,例如对于一个3rowx2colomn的RGB565图片:
| 0x0000 | 0x0001 | 0x0002 |
|---|---|---|
| 0x0100 | 0x0101 | 0x0102 |
写入的顺序应当是 0x0000 0001 0002 0100 0101 0102。注意0x0000对应的像素位置即绘制的坐标。
蜂鸣器支持播放F3(175Hz)到F5(698Hz)的15个音以及停顿。具体如下表:
| 自然音阶 | F3 | G3 | A3 | B3 | C4 (Do) | D4 (Re) | E4 (Mi) | F4 (Fa) | G4(Sol) | A4(La) | B4(Si) | C5 | D5 | E5 | F5 | Mute |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 编码 | 0x00 | 0x10 | 0x20 | 0x30 | 0x40 | 0x50 | 0x60 | 0x70 | 0x80 | 0x90 | 0xa0 | 0xb0 | 0xc0 | 0xd0 | 0xe0 | 0xf0 |
| 频率/Hz | 175 | 196 | 220 | 247 | 262 | 294 | 330 | 349 | 392 | 440 | 494 | 523 | 587 | 659 | 698 | 0 |
蜂鸣器播放音乐时切换音频的时间片最短支持到32Hz,即120BPM下一个64分音符的持续时间,或240BPM下一个32分音符的持续时间,支持同一音阶的时长累加。
为了确保播放时的声音连续,使用FIFO进行数据的添加与音频的输出。FIFO中数据元素长度1字节,高4位作为音阶编码,低4位表示持续时长。单个元素的构造方式如下: 音阶编码 | (持续时长单位数-1)(一单位为1/32s)
若该元素的下一元素音阶编码不变,则持续时长可累加。
例如,想播放持续5/32s的C4(Do),需要向FIFO中写入0x44;若想播放17/32s的D4(Re),需要向FIFO中写入0x5f 0x50。
所有通信帧均以\0结尾。上位机向该模块发送一帧数据时应注意不可中断,否则意外触发该模块主控的串口空闲中断导致协议解析出错。
从上位机向该串口屏模块发送的一个通信帧格式如下:
| 结构 | 命令字节 | 数据部分 | 结束符 |
|---|---|---|---|
| 长度/Byte | 1 | 0~254 | 1 |
| 备注 | 不可为0x00 | 取决于命令 | 固定为\0(0x00) |
不建议数据部分长于250字节。
若无实际返回数据需要,串口通信一帧处理完毕后将该通信帧命令字节返回;若有实际返回数据需要,根据实际需要发送数据帧;若解析失败,返回0x00。
禁止使用0x00开始的通信帧。
在显示屏的(x, y)处绘制一个色彩为color的点。
| 结构 | 命令 | x | y | color | 结束符 |
|---|---|---|---|---|---|
| 长度/Byte | 1 | 2 | 2 | 2 | 1 |
| 内容 | 0x01 | 高字节×256+低字节 | 高字节×256+低字节 | RGB565格式 | 0x00 |
例如在显示屏的(16, 32)位置画一个绿色(0x07e0)的点:
发送: 0x01 00 10 00 20 07 e0 00
返回: 0x01
在显示屏上从点(x0, y0)到(x1, y1)绘制一条颜色为color的直线。
| 结构 | 命令 | x0 | y0 | x1 | y1 | color | 结束符 |
|---|---|---|---|---|---|---|---|
| 长度/Byte | 1 | 2 | 2 | 2 | 2 | 2 | 1 |
| 内容 | 0x02 | 高字节×256+低字节 | 高字节×256+低字节 | 高字节×256+低字节 | 高字节×256+低字节 | RGB565格式 | 0x00 |
例如在显示屏上从(16, 32)到(48, 64)绘制一条绿色(0x07e0)的直线:
发送: 0x02 00 10 00 20 00 30 00 40 07 e0 00
返回: 0x02
在显示屏上绘制一个从(x0, y0)到(x1, y1)的空心矩形,颜色为color。
| 结构 | 命令 | x0 | y0 | x1 | y1 | color | 结束符 |
|---|---|---|---|---|---|---|---|
| 长度/Byte | 1 | 2 | 2 | 2 | 2 | 2 | 1 |
| 内容 | 0x03 | 高字节×256+低字节 | 高字节×256+低字节 | 高字节×256+低字节 | 高字节×256+低字节 | RGB565格式 | 0x00 |
例如在显示屏上绘制一个从(16, 32)到(48, 64)的红色(0xf800)空心矩形:
发送: 0x03 00 10 00 20 00 30 00 40 f8 00 00
返回: 0x03
在显示屏上以(x, y)为圆心,半径为r,颜色为color的空心圆。
| 结构 | 命令 | x | y | 半径 | color | 结束符 |
|---|---|---|---|---|---|---|
| 长度/Byte | 1 | 2 | 2 | 1 | 2 | 1 |
| 内容 | 0x04 | 高字节×256+低字节 | 高字节×256+低字节 | 半径(像素) | RGB565格式 | 0x00 |
例如在显示屏上以(32, 48)为圆心绘制一个半径为16的绿色(0x07e0)空心圆:
发送: 0x04 00 20 00 30 10 07 e0 00
返回: 0x04
在显示屏上填充一个从(x0, y0)到(x1, y1)的矩形区域,颜色为color。
| 结构 | 命令 | x0 | y0 | x1 | y1 | color | 结束符 |
|---|---|---|---|---|---|---|---|
| 长度/Byte | 1 | 2 | 2 | 2 | 2 | 2 | 1 |
| 内容 | 0x05 | 高字节×256+低字节 | 高字节×256+低字节 | 高字节×256+低字节 | 高字节×256+低字节 | RGB565格式 | 0x00 |
例如在显示屏上填充一个从(0, 0)到(79, 159)的蓝色(0x001f)区域:
发送: 0x05 00 00 00 00 00 4f 00 9f 00 1f 00
返回: 0x05
在显示屏的(x, y)位置显示一个字符ch,前景色为fg,背景色为bg,字体大小为font_size。
字体大小支持如下几种:
| 字体大小 | font_size值 |
|---|---|
| FONTSIZE_1206 | 12 |
| FONTSIZE_1608 | 16 |
| FONTSIZE_2412 | 24 |
| FONTSIZE_3216 | 32 |
| 结构 | 命令 | x | y | ch | fg | bg | font_size | 结束符 |
|---|---|---|---|---|---|---|---|---|
| 长度/Byte | 1 | 2 | 2 | 1 | 2 | 2 | 1 | 1 |
| 内容 | 0x06 | 高字节×256+低字节 | 高字节×256+低字节 | ASCII码 | RGB565格式 | RGB565格式 | 字体大小(如16) | 0x00 |
例如在(10, 20)位置显示字符'A',前景白色(0xffff),背景黑色(0x0000),字体大小16:
发送: 0x06 00 0a 00 14 41 ff ff 00 00 10 00
返回: 0x06
在显示屏的(x, y)位置显示一个字符串str,前景色为fg,背景色为bg,字体大小为font_size。
| 结构 | 命令 | x | y | fg | bg | font_size | str(不定长) | 结束符 |
|---|---|---|---|---|---|---|---|---|
| 长度/Byte | 1 | 2 | 2 | 2 | 2 | 1 | n | 1 |
| 内容 | 0x07 | 高字节×256+低字节 | 高字节×256+低字节 | RGB565格式 | RGB565格式 | 字体大小 | ASCII字符串 | 0x00 |
例如在(0, 0)位置显示字符串"Hi",前景白色(0xffff),背景黑色(0x0000),字体大小16:
发送: 0x07 00 00 00 00 ff ff 00 00 10 48 69 00
返回: 0x07
在显示屏的(x, y)位置显示一张宽w、高h的图片,图片数据从缓冲区的index位置开始读取。
| 结构 | 命令 | x | y | w | h | index | 结束符 |
|---|---|---|---|---|---|---|---|
| 长度/Byte | 1 | 2 | 2 | 2 | 2 | 2 | 1 |
| 内容 | 0x08 | 高字节×256+低字节 | 高字节×256+低字节 | 宽度(像素) | 高度(像素) | 缓冲区起始索引 | 0x00 |
例如在(0, 0)位置显示一张宽40、高40的图片,数据从缓冲区索引0开始:
发送: 0x08 00 00 00 00 00 28 00 28 00 00 00
返回: 0x08
调整显示屏背光亮度,percent为0~100之间的整数。
| 结构 | 命令 | percent | 结束符 |
|---|---|---|---|
| 长度/Byte | 1 | 1 | 1 |
| 内容 | 0x09 | 亮度百分比(0~100) | 0x00 |
例如将亮度调整为80%:
发送: 0x09 50 00
返回: 0x09
将数据写入SRAM缓冲区,从index位置开始写入。
| 结构 | 命令 | index | data[n] | 结束符 |
|---|---|---|---|---|
| 长度/Byte | 1 | 2 | n | 1 |
| 内容 | 0x20 | 高字节×256+低字节 | 写入数据 | 0x00 |
例如从索引0写入3字节数据0x11 0x22 0x33:
发送: 0x20 00 00 11 22 33 00
返回: 0x20
从SRAM缓冲区的index位置读取length字节数据。
| 结构 | 命令 | index | length | 结束符 |
|---|---|---|---|---|
| 长度/Byte | 1 | 2 | 1 | 1 |
| 内容 | 0x21 | 高字节×256+低字节 | 读取长度(1~255) | 0x00 |
例如从索引0读取3字节数据:
发送: 0x21 00 00 03 00
返回: 0x11 22 33 00(示例)
将数据写入EEPROM,从addr位置开始写入。
| 结构 | 命令 | addr | data[n] | 结束符 |
|---|---|---|---|---|
| 长度/Byte | 1 | 2 | n | 1 |
| 内容 | 0x22 | 高字节×256+低字节 | 写入数据 | 0x00 |
例如向地址0写入3字节数据0x11 0x22 0x33:
发送: 0x22 00 00 11 22 33 00
返回: 0x22
从EEPROM的addr位置读取length字节数据。
| 结构 | 命令 | addr | length | 结束符 |
|---|---|---|---|---|
| 长度/Byte | 1 | 2 | 1 | 1 |
| 内容 | 0x23 | 高字节×256+低字节 | 读取长度(1~255) | 0x00 |
例如从地址0读取3字节数据:
发送: 0x23 00 00 03 00
返回: 0x11 22 33 00(示例)
从EEPROM的eeprom_addr位置读取len字节数据,写入SRAM缓冲区的buf_index位置。
| 结构 | 命令 | eeprom_addr | buf_index | len | 结束符 |
|---|---|---|---|---|---|
| 长度/Byte | 1 | 2 | 2 | 1 | 1 |
| 内容 | 0x24 | 高字节×256+低字节 | 高字节×256+低字节 | 读取长度 | 0x00 |
例如从EEPROM地址0读取3字节数据写入缓冲区索引0:
发送: 0x24 00 00 00 00 03 00
返回: 0x24
读取蜂鸣器当前状态和FIFO中剩余音符数量。
| 结构 | 命令 | 结束符 |
|---|---|---|
| 长度/Byte | 1 | 1 |
| 内容 | 0x30 | 0x00 |
发送: 0x30 00
返回: 状态字节 FIFO长度高字节 FIFO长度低字节 0x00
例如蜂鸣器正在播放,FIFO中有512字节:
返回: 0x01 02 00 00
状态字节有以下几种:
| 状态 | 宏 | 值 |
|---|---|---|
| 停止播放 | BEEP_STOP | 0x00 |
| 正在播放 | BEEP_PLAY | 0x01 |
向蜂鸣器FIFO中填入音符序列,每个音符为1字节。
| 结构 | 命令 | note[n] | 结束符 |
|---|---|---|---|
| 长度/Byte | 1 | n | 1 |
| 内容 | 0x31 | 音符数据 | 0x00 |
例如填入两个音符:C4持续4单位、D4持续1单位:
发送: 0x31 43 50 00
返回: 0x31
控制蜂鸣器的播放状态。
| 结构 | 命令 | mode | 结束符 |
|---|---|---|---|
| 长度/Byte | 1 | 1 | 1 |
| 内容 | 0x32 | 0=停止,1=开始播放,2=清空FIFO | 0x00 |
例如开始播放:
发送: 0x32 01 00
返回: 0x32
执行模块复位操作,拉低LCD_RST和NRST引脚。
| 结构 | 命令 | 结束符 |
|---|---|---|
| 长度/Byte | 1 | 1 |
| 内容 | 0xff | 0x00 |
发送: 0xff 00
返回: 0xff
该返回值返回较为迅速,在发送返回值后进行持续50ms的LCD驱动复位和全片复位。
见该项目的python示例
本项目部分设计与文档结构由 Microsoft Copilot 协助完成,感谢其在协议规范与工程逻辑上的高效支持。

