零.芯片简介
GD32VW553H_EVAL是兆易创新推出的一款GD32VW系列的评估板。开发板外观如下图所示:
GD32VW553系列双模无线MCU,支持Wi-Fi 6及Bluetooth LE 5.2无线连接,集成了高达4MB Flash及320KB SRAM,另有32KB可配置指令高速缓存(I-Cache),大幅提升了CPU处理效率。不仅具备出色的无线性能,芯片还配置了丰富的通用有线接口,包含3个U(S)ART、2个I2C、1个SPI以及1个四线制QSPI等, 以及多达29个可编程 GPIO 管脚。内置2个32位通用定时器、2个16位通用定时器、4个16位基本定时器、1个PWM高级定时器和1个12位ADC。供电电压1.8V - 3.6V,并提供了85℃ - 105℃宽温选择,以满足工控互联、照明设备以及插座面板等高温场景应用所需。
面向实时处理和高效通信需求,GD32VW553系列MCU采用了全新的开源指令集架构RISC-V处理器内核,主频可达160MHz,还配备了高级DSP硬件加速器、双精度浮点单元(FPU)以及指令扩展接口等资源,以出色的微架构设计实现了极佳的能效比,并提供了灵活的可扩展性。
一.搭建RT-Thread工程
1 环境准备
1.1 工具链
首先需要准备BSP编译所需的工具链,[工具链下载链接](https://www.gigadevice.com.cn/product/mcu/mcus-product-selector/gd32vw553hmq6),在该链接下载应用软件选项中的GD32 Embedded Builder。
工具链的相对路径如下:
> GD32EmbeddedBuilder_v1.5.2.30854\Tools\RISC-V Embedded GCC\8.2.0-2.2-20190521-0004\bin
1.2 下载工具
GD32VW553可以使用GD官方工具GD32AllInOneProgrammer下载,[GD32AllInOneProgrammer下载链接](https://www.gd32mcu.com/cn/download?kw=GD32+All-In-One+Programmer&lan=cn),编译出的固件可使用该软件下载。
1.3 RT-Thread ENV工具
RT-Thread的BSP可以使用官方env工具编译,需自行学习,[env下载链接](https://www.rt-thread.org/download.html#download-rt-thread-env-tool)。
2 固件编译
在BSP根路径下使用env工具打开BSP,示例如下:
然后执行pkgs --update命令添加当前BSP所需要的驱动库,示例如下(如果长时间未使用env,可首先
进行pkgs --upgrade更新软件包的链接索引)
(.venv) RTT@RSH-PC0001 E:\rt-thread\bsp\gd32\risc-v\gd32vw553h-eval
$ pkgs --upgrade
Error message:[Errno 2] No such file or directory: 'E:\\env-windows-v2.0.0\\env-windows\\tools\\bin\\..\\..\\tools\\scripts\\cmds\\.config'
open .config failed
[Use Github server - auto decision based on IP location]
Begin to upgrade env packages.
remote: Enumerating objects: 768, done.
remote: Counting objects: 100% (374/374), done.
remote: Compressing objects: 100% (16/16), done.
Receiving objects: 96% (738/768)
Receiving objects: 100% (768/768), 142.23 KiB | 5.69 MiB/s, done.
Resolving deltas: 100% (462/462), completed with 70 local objects.
From https://github.com/RT-Thread/packages
* branch HEAD -> FETCH_HEAD
==============================> Env packages upgrade done
(.venv) RTT@RSH-PC0001 E:\rt-thread\bsp\gd32\risc-v\gd32vw553h-eval
$ pkgs --update
接下来需要设置工具链字段,示例如下(使用时将下述路径调整为自己的工具链路径):
(.venv) RTT@RSH-PC0001 E:\rt-thread\bsp\gd32\risc-v\gd32vw553h-eval
$ set RTT_EXEC_PATH=E:\GD32\GD32VW5\GD32EmbeddedBuilder_v1.5.6_Rel\Tools\RISC-V Embedded GCC\8.2.0-2.2-20190521-0004\bin
接下来执行scons -j128命令编译工程,示例如下:
(.venv) RTT@RSH-PC0001 E:\rt-thread\bsp\gd32\risc-v\gd32vw553h-eval
$ scons -j16
成功编译会输出下述日志,并在BSP根路径生成**rtthread.bin**固件,该固件即下文需要烧录的固件。
LINK rtthread.elf
Memory region Used Size Region Size %age Used
flash: 66388 B 4 MB 1.58%
ram: 288 KB 288 KB 100.00%
riscv-none-embed-objcopy -O binary rtthread.elf rtthread.bin
riscv-none-embed-size rtthread.elf
text data bss dec hex filename
65152 1200 7612 73964 120ec rtthread.elf
scons: done building targets.
3 固件烧录
固件烧录需要使用上述的GD32AllInOneProgrammer软件,
需要注意的是使用上述软件烧录时需要将boot1置为高电平,烧录结束后重新设置为低电平,手动调整板载的boot跳线帽。
4 运行结果
烧录完毕后,使用串口连接自己的串口终端软件,即可通过串口与开发板交互,示例如下:
\ | /
- RT - Thread Operating System
/ | \ 5.2.1 build Mar 12 2026 14:51:49
2006 - 2025 Copyright by RT-Thread team
Hello GD32VW553H
msh >
msh >ps
thread pri status sp stack size max used left tick error tcb addr
-------- --- ------- ---------- ---------- ------ ---------- ------- ----------
tshell 20 running 0x000002d0 0x00001000 31% 0x00000009 OK 0x20002598
tidle0 31 ready 0x00000220 0x00000400 53% 0x00000019 OK 0x20000654
timer 4 suspend 0x00000290 0x00000400 64% 0x00000009 EINTRPT 0x20000ba8
main 10 suspend 0x00000280 0x00001000 17% 0x00000013 EINTRPT 0x200012b8
msh >
5 配置工程
需要利用 ENV 工具对BSP 进行配置,步骤如下:
1. 在 bsp 下打开 env 工具。
2. 输入`menuconfig`命令配置工程,配置好之后保存退出。
3. 输入`pkgs --update`命令更新软件包。
4. 输入`scons `命令重新编译工程。
二.编写SPI驱动代码
配置rt-thread的SPI驱动
使用文件资源管理器,进入目录rt-thread\bsp\gd32\risc-v\gd32vw553h-eval,在目录空白处点击右键选择ConEmu Here,打开rt-thread的env环境命令行。

使用pkgs —update命令下载gd32vw553的标准驱动库,在当前目录下的\packages\gd32-riscv-series-latest会下载好gd32vw553的标准驱动库文件。


输入menuconfig命令并按回车,进入配置rt-thread配置界面,通过光标控制箭头、Enter、ESC、空格等按键选择使能SPI。
Hardware Drivers Config --->
On-chip Peripheral Drivers --->
Enable SPI Bus --->
Enable SPI0 Bus

退出时按Y即可保存config
然后输入scons编译,然后使用串口下载,然后连接串口终端,输入list device查看设备列表

编写LCD驱动
下面将通过修改GD原厂DEMO例程的方式来实现点屏
新建BSP文件夹,里面新增bsp_lcd.c和bsp_lcd.h
代码如下:
#include "bsp_lcd.h"
_lcd_dev lcddev;
static struct rt_spi_device *lcd_dev;
static void Lcd_reset(void)
{
LCD_RST_CLR;
DELAY(100);
LCD_RST_SET;
DELAY(50);
}
static void Lcd_wr_reg(uint8_t reg)
{
LCD_DC_CLR;
rt_spi_send(lcd_dev, ®, 1);
LCD_DC_SET;
}
static void Lcd_wr_data(uint8_t data)
{
rt_spi_send(lcd_dev, &data, 1);
}
static void Lcd_wr_data_16bit(uint16_t data)
{
uint8_t buf[2];
buf[0] = data >> 8;
buf[1] = data & 0xff;
Lcd_wr_data(buf[0]);
Lcd_wr_data(buf[1]);
}
void Lcd_setwindows(uint16_t xStar, uint16_t yStar, uint16_t xEnd, uint16_t yEnd)
{
LCD_CS_CLR;
/* write the register address 0x2A */
Lcd_wr_reg(0x2A);
Lcd_wr_data_16bit(xStar);
Lcd_wr_data_16bit(xEnd);
/* write the register address 0x2B */
Lcd_wr_reg(0x2B);
Lcd_wr_data_16bit(yStar);
Lcd_wr_data_16bit(yEnd);
/* write the register address 0x2C */
Lcd_wr_reg(0x2C);
LCD_CS_SET;
}
void Lcd_clear(uint16_t Color)
{
unsigned int i, m;
uint8_t* buf = (uint8_t*)rt_malloc(80);
struct rt_spi_message msg;
for (i = 0; i < 40; i++)
{
buf[2 * i] = Color >> 8;
buf[2 * i + 1] = Color & 0xff;
}
Lcd_setwindows(0, 0, lcddev.width - 1, lcddev.height - 1);
LCD_DC_SET;
LCD_CS_CLR;
for (i = 0; i < lcddev.height; i++)
{
for (m = 0; m < lcddev.width;)
{
m += 40;
msg.send_buf = buf;
msg.recv_buf = RT_NULL;
msg.length = 80;
msg.cs_take = 0;
msg.cs_release = 0;
msg.next = 0;
rt_spi_transfer_message(lcd_dev, &msg);
}
}
LCD_CS_SET;
rt_free(buf);
}
void lcd_fill_array_spi(uint16_t Xstart, uint16_t Ystart, uint16_t Xend, uint16_t Yend, void *Image)
{
rt_uint32_t size = 0;
size = (Xend - Xstart + 1) * (Yend - Ystart + 1) * 2;
Lcd_setwindows(Xstart, Ystart, Xend, Yend);
LCD_DC_SET;
rt_spi_send(lcd_dev, Image, size);
}
static void Lcd_cmd_init(void)
{
LCD_CS_CLR;
Lcd_reset();
/* write the register address 0xCB */
Lcd_wr_reg(0xCB);
Lcd_wr_data(0x39);
Lcd_wr_data(0x2C);
Lcd_wr_data(0x00);
Lcd_wr_data(0x34);
Lcd_wr_data(0x02);
/* write the register address 0xCF */
Lcd_wr_reg(0xCF);
Lcd_wr_data(0x00);
Lcd_wr_data(0XC1);
Lcd_wr_data(0X30);
/* write the register address 0xE8 */
Lcd_wr_reg(0xE8);
Lcd_wr_data(0x85);
Lcd_wr_data(0x00);
Lcd_wr_data(0x78);
/* write the register address 0xEA */
Lcd_wr_reg(0xEA);
Lcd_wr_data(0x00);
Lcd_wr_data(0x00);
/* write the register address 0xED */
Lcd_wr_reg(0xED);
Lcd_wr_data(0x64);
Lcd_wr_data(0x03);
Lcd_wr_data(0X12);
Lcd_wr_data(0X81);
/* write the register address 0xF7 */
Lcd_wr_reg(0xF7);
Lcd_wr_data(0x20);
/* power control VRH[5:0] */
Lcd_wr_reg(0xC0);
Lcd_wr_data(0x23);
/* power control SAP[2:0];BT[3:0] */
Lcd_wr_reg(0xC1);
Lcd_wr_data(0x10);
/* vcm control */
Lcd_wr_reg(0xC5);
Lcd_wr_data(0x3e);
Lcd_wr_data(0x28);
/* vcm control2 */
Lcd_wr_reg(0xC7);
Lcd_wr_data(0x86);
Lcd_wr_reg(0x36);
Lcd_wr_data(0x48);
/* write the register address 0x3A */
Lcd_wr_reg(0x3A);
Lcd_wr_data(0x55);
/* write the register address 0xB1 */
Lcd_wr_reg(0xB1);
Lcd_wr_data(0x00);
Lcd_wr_data(0x18);
/* display function control */
Lcd_wr_reg(0xB6);
Lcd_wr_data(0x08);
Lcd_wr_data(0x82);
Lcd_wr_data(0x27);
/* 3gamma function disable */
Lcd_wr_reg(0xF2);
Lcd_wr_data(0x00);
/* gamma curve selected */
Lcd_wr_reg(0x26);
Lcd_wr_data(0x01);
/* set gamma */
Lcd_wr_reg(0xE0);
Lcd_wr_data(0x0F);
Lcd_wr_data(0x31);
Lcd_wr_data(0x2B);
Lcd_wr_data(0x0C);
Lcd_wr_data(0x0E);
Lcd_wr_data(0x08);
Lcd_wr_data(0x4E);
Lcd_wr_data(0xF1);
Lcd_wr_data(0x37);
Lcd_wr_data(0x07);
Lcd_wr_data(0x10);
Lcd_wr_data(0x03);
Lcd_wr_data(0x0E);
Lcd_wr_data(0x09);
Lcd_wr_data(0x00);
/* set gamma */
Lcd_wr_reg(0XE1);
Lcd_wr_data(0x00);
Lcd_wr_data(0x0E);
Lcd_wr_data(0x14);
Lcd_wr_data(0x03);
Lcd_wr_data(0x11);
Lcd_wr_data(0x07);
Lcd_wr_data(0x31);
Lcd_wr_data(0xC1);
Lcd_wr_data(0x48);
Lcd_wr_data(0x08);
Lcd_wr_data(0x0F);
Lcd_wr_data(0x0C);
Lcd_wr_data(0x31);
Lcd_wr_data(0x36);
Lcd_wr_data(0x0F);
/* exit sleep */
Lcd_wr_reg(0x11);
DELAY(120);
/* display on */
Lcd_wr_reg(0x29);
Lcd_wr_reg(0x2c);
LCD_CS_SET;
}
static void Lcd_pin_init(void)
{
rt_pin_mode(LCD_DC_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(LCD_RES_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(LCD_CS_PIN, PIN_MODE_OUTPUT);
}
static void Lcd_init(void)
{
Lcd_pin_init();
lcddev.width=LCD_WIDTH;
lcddev.height=LCD_HEIGHT;
Lcd_reset(); /* LCD Hardware Reset */
DELAY(120); /* Delay 120ms */
Lcd_cmd_init(); /* lcd init */
}
rt_err_t spi_device_attach(const char *bus_name, const char *device_name, rt_base_t cs_pin)
{
RT_ASSERT(bus_name != RT_NULL);
RT_ASSERT(device_name != RT_NULL);
rt_err_t result = RT_EOK;
struct rt_spi_device *spi_device;
/* attach the device to spi bus*/
spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
RT_ASSERT(spi_device != RT_NULL);
result = rt_spi_bus_attach_device_cspin(spi_device, device_name, bus_name, cs_pin, RT_NULL);
if (RT_EOK != result)
{
LOG_E("%s attach to %s faild, %d\n", device_name, bus_name, result);
}
else
{
LOG_I("%s attach to %s done", device_name, bus_name);
}
return result;
}
rt_err_t spi_lcd_init(uint32_t freq)
{
rt_err_t res = RT_EOK;
spi_device_attach(LCD_SPI_BUS_NAME, LCD_SPI_DEVICE_NAME, LCD_CS_PIN);
lcd_dev = (struct rt_spi_device *)rt_device_find(LCD_SPI_DEVICE_NAME);
if (lcd_dev != RT_NULL)
{
struct rt_spi_configuration spi_config;
spi_config.data_width = 8;
spi_config.max_hz = freq * 1000 * 1000;
spi_config.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB;
rt_spi_configure(lcd_dev, &spi_config);
}
else
{
res = -RT_ERROR;
}
Lcd_init();
Lcd_clear(WHITE);
return res;
}
三.编写屏幕测试代码
引脚连接
| 模块 | 屏幕 |
|---|---|
| VCC | VCC |
| GND | GND |
| PA12 | CS |
| PB12 | RST |
| PA9 | MOSI |
| PA11 | CLK |
| PA15 | BLK |
| PB13 | DC |
在main.c中添加测试代码,如下:
static uint16_t color_array[] =
{
WHITE, BLACK, BLUE, BRED,
GRED, GBLUE, RED, YELLOW
};
static int lcd_spi_test(void)
{
uint8_t index = 0;
for (index = 0; index < sizeof(color_array) / sizeof(color_array[0]); index++)
{
Lcd_clear(color_array[index]);
LOG_I("lcd clear color: %#x", color_array[index]);
DELAY(200);
}
return RT_EOK;
}
MSH_CMD_EXPORT(lcd_spi_test, lcd will fill color => you need init lcd first);然后使用scons命令编译、下载,打开串口终端,输入Tab键并按回车查看支持的命令列表,已经出现lcd的测试命令。

这样就可以执行刷屏测试!

开源社区 

