萤火工场 GD32VW553-IOT-V2点灯与驱动屏幕

分享作者:800l3w43_5499
评测品牌:萤火工场
评测型号:GD32VW553-IOT-V2
发布时间:2026-07-06 10:28:59
1
概要
通过iCEasy免费申请获得GD32VW553-IOT-V2开发板样片,完成开箱验证及GPIO点灯、LCD图片显示两项基础功能测试。板卡做工扎实,官方SDK对RISC-V工具链适配良好,屏幕驱动移植顺畅,Wi-Fi 6 + BLE 5.2双模无线能力在同价位MCU中具备明显优势,适合智能家居、低功耗物联网终端等项目选型参考。附完整工程源码及踩坑记录。
开源口碑分享内容

一、 申请与开箱体验

本次通过iCEasy商城样片申请通道顺利拿到GD32VW553-IOT开发板,从申请到收货流程顺畅,包装防护到位。

二、 核心参数速览

参数项规格
内核RISC-V 32位,主频160MHz
无线Wi-Fi 6 (802.11ax) + BLE 5.2
存储4MB Flash / 320KB SRAM
工作电压2.0V ~ 3.6V
外设GPIO×30, UART×3, SPI×2, I2C×2, ADC×1
安全WPA3加密、安全启动、真随机数发生器

三、 源码

1.GPIO点灯

#include "gd32vw55x.h"
#include "systick.h"
#include "gd32vw553h_eval.h"

int main()
{
    systick_config();
    gd_eval_led_init(LED1);
    
    while(1)
    {
        gd_eval_led_on(LED1);
        delay_1ms(100);
        gd_eval_led_off(LED2);
        delay_1ms(100);
    }
}

2.LCD屏幕图片显示

此部分包含封装的屏幕子程序,图片c文件,主程序

st7789.c

#include "st7789.h"

/* ========== 内部辅助宏 ========== */
#define CS_LOW()        gpio_bit_reset(LCD_CS_PORT, LCD_CS_PIN)
#define CS_HIGH()       gpio_bit_set(LCD_CS_PORT, LCD_CS_PIN)
#define DC_CMD()        gpio_bit_reset(LCD_DC_PORT, LCD_DC_PIN)
#define DC_DATA()       gpio_bit_set(LCD_DC_PORT, LCD_DC_PIN)
#define RST_LOW()       gpio_bit_reset(LCD_RST_PORT, LCD_RST_PIN)
#define RST_HIGH()      gpio_bit_set(LCD_RST_PORT, LCD_RST_PIN)
#define SCK_LOW()       gpio_bit_reset(LCD_SCK_PORT, LCD_SCK_PIN)
#define SCK_HIGH()      gpio_bit_set(LCD_SCK_PORT, LCD_SCK_PIN)
#define SDA_LOW()       gpio_bit_reset(LCD_SDA_PORT, LCD_SDA_PIN)
#define SDA_HIGH()      gpio_bit_set(LCD_SDA_PORT, LCD_SDA_PIN)

/* ========== 内部延时函数 ========== */
static void delay_us(uint32_t us) {
    // GD32VW553 默认 120MHz, 1us ≈ 60 cycles (O0优化下)
    volatile uint32_t i = us * 60;
    while(i--);
}

static void delay_ms(uint32_t ms) {
    for(uint32_t i = 0; i < ms; i++) delay_us(1000);
}

/* ========== 软件 SPI 发送字节 (Mode 3) ========== */
static void spi_write_byte(uint8_t data) {
    for(int i = 0; i < 8; i++) {
        if(data & 0x80) SDA_HIGH(); else SDA_LOW();
        delay_us(1);
        SCK_LOW();
        delay_us(1);
        SCK_HIGH();
        data <<= 1;
    }
}

/* ========== 写命令 / 写数据 ========== */
static void lcd_cmd(uint8_t cmd) {
    CS_LOW();
    DC_CMD();
    spi_write_byte(cmd);
    CS_HIGH();
}

static void lcd_data(uint8_t dat) {
    CS_LOW();
    DC_DATA();
    spi_write_byte(dat);
    CS_HIGH();
}

/* ========== 硬件 GPIO 初始化 (GD32VW55x 专用) ========== */
static void lcd_gpio_init(void) {
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_GPIOB);

    // GD32 中 GPIOA/GPIOB 是 uint32_t 基地址,不是指针
    const uint32_t ports[] = {
        LCD_CS_PORT, LCD_DC_PORT, LCD_RST_PORT,
        LCD_BLK_PORT, LCD_SCK_PORT, LCD_SDA_PORT
    };
    const uint32_t pins[] = {
        LCD_CS_PIN, LCD_DC_PIN, LCD_RST_PIN,
        LCD_BLK_PIN, LCD_SCK_PIN, LCD_SDA_PIN
    };

    for(int i = 0; i < 6; i++) {
        gpio_mode_set(ports[i], GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, pins[i]);
        gpio_output_options_set(ports[i], GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, pins[i]);
    }

    // 初始电平设置
    gpio_bit_set(LCD_CS_PORT, LCD_CS_PIN);
    gpio_bit_set(LCD_RST_PORT, LCD_RST_PIN);
    gpio_bit_reset(LCD_BLK_PORT, LCD_BLK_PIN); // 背光默认关闭,初始化完成后开启
    gpio_bit_set(LCD_SCK_PORT, LCD_SCK_PIN);   // SPI Mode 3 空闲时 SCK 为高
}

/* ========== 背光控制 ========== */
void st7789_set_backlight(uint8_t on) {
    if(on) gpio_bit_set(LCD_BLK_PORT, LCD_BLK_PIN);
    else   gpio_bit_reset(LCD_BLK_PORT, LCD_BLK_PIN);
}

/* ========== ST7789 初始化序列 ========== */
void st7789_init(void) {
    lcd_gpio_init();

    RST_LOW();
    delay_ms(100);
    RST_HIGH();
    delay_ms(120);

    lcd_cmd(0x01); delay_ms(150); // SWRESET
    lcd_cmd(0x11); delay_ms(120); // SLPOUT
    lcd_cmd(0x36); lcd_data(0x00); // MADCTL
    lcd_cmd(0x3A); lcd_data(0x05); // COLMOD: 16bit

    lcd_cmd(0xB2); lcd_data(0x0C); lcd_data(0x0C); lcd_data(0x00); lcd_data(0x33); lcd_data(0x33);
    lcd_cmd(0xB7); lcd_data(0x35);
    lcd_cmd(0xBB); lcd_data(0x19);
    lcd_cmd(0xC0); lcd_data(0x2C);
    lcd_cmd(0xC2); lcd_data(0x01);
    lcd_cmd(0xC3); lcd_data(0x12);
    lcd_cmd(0xC4); lcd_data(0x20);
    lcd_cmd(0xC6); lcd_data(0x0F);
    lcd_cmd(0xD0); lcd_data(0xA4); lcd_data(0xA1);

    const uint8_t pg[] = {0xD0,0x04,0x0D,0x11,0x13,0x2B,0x3F,0x54,0x4C,0x18,0x0D,0x0B,0x1F,0x23};
    lcd_cmd(0xE0); for(int i=0;i<14;i++) lcd_data(pg[i]);

    const uint8_t ng[] = {0xD0,0x04,0x0C,0x11,0x13,0x2C,0x3F,0x44,0x51,0x2F,0x1F,0x1F,0x20,0x23};
    lcd_cmd(0xE1); for(int i=0;i<14;i++) lcd_data(ng[i]);

    lcd_cmd(0x21); // Display Inversion ON
    lcd_cmd(0x29); // DISPON
    delay_ms(50);

    st7789_set_backlight(1);
}

/* ========== 全屏填充 ========== */
void st7789_fill(uint16_t color) {
    lcd_cmd(0x2A); lcd_data(0x00); lcd_data(0x00); lcd_data(0x00); lcd_data(0xEF);
    lcd_cmd(0x2B); lcd_data(0x00); lcd_data(0x00); lcd_data(0x00); lcd_data(0xEF);
    lcd_cmd(0x2C);

    CS_LOW();
    DC_DATA();
    uint32_t total = LCD_WIDTH * LCD_HEIGHT;
    for(uint32_t i = 0; i < total; i++) {
        spi_write_byte(color >> 8);
        spi_write_byte(color & 0xFF);
    }
    CS_HIGH();
}

/* ========== 指定区域绘制图片 ========== */
void st7789_draw_image(uint16_t x, uint16_t y, uint16_t w, uint16_t h, const uint8_t *img) {
    // 边界检查,防止越界
    if(x >= LCD_WIDTH || y >= LCD_HEIGHT) return;
    if(x + w > LCD_WIDTH)  w = LCD_WIDTH - x;
    if(y + h > LCD_HEIGHT) h = LCD_HEIGHT - y;

    // 设置显示窗口
    lcd_cmd(0x2A);
    lcd_data(x >> 8); lcd_data(x & 0xFF);
    lcd_data((x + w - 1) >> 8); lcd_data((x + w - 1) & 0xFF);

    lcd_cmd(0x2B);
    lcd_data(y >> 8); lcd_data(y & 0xFF);
    lcd_data((y + h - 1) >> 8); lcd_data((y + h - 1) & 0xFF);

    lcd_cmd(0x2C); // WRITE MEMORY START

    CS_LOW();
    DC_DATA();

    uint32_t total = (uint32_t)w * h;
    for(uint32_t i = 0; i < total; i++) {
        // 图片数组通常是按字节存储的,每两个字节组成一个 RGB565 像素
        spi_write_byte(img[i * 2]);
        spi_write_byte(img[i * 2 + 1]);
    }

    CS_HIGH();
}

st7789.h

#ifndef __ST7789_H
#define __ST7789_H

#include "gd32vw55x.h"
#include <stdint.h>

/* ========== RGB565 颜色定义 ========== */
#define COLOR_BLACK   0x0000
#define COLOR_RED     0xF800
#define COLOR_GREEN   0x07E0
#define COLOR_BLUE    0x001F
#define COLOR_WHITE   0xFFFF
#define COLOR_YELLOW  0xFFE0

/* ========== 屏幕参数 ========== */
#define LCD_WIDTH     240
#define LCD_HEIGHT    240

/* ========== 引脚定义 (与您的实物接线一致) ========== */
#define LCD_CS_PORT     GPIOA
#define LCD_CS_PIN      GPIO_PIN_13
#define LCD_DC_PORT     GPIOA
#define LCD_DC_PIN      GPIO_PIN_14
#define LCD_RST_PORT    GPIOA
#define LCD_RST_PIN     GPIO_PIN_15
#define LCD_BLK_PORT    GPIOB
#define LCD_BLK_PIN     GPIO_PIN_3
#define LCD_SCK_PORT    GPIOB
#define LCD_SCK_PIN     GPIO_PIN_13
#define LCD_SDA_PORT    GPIOB
#define LCD_SDA_PIN     GPIO_PIN_12

/* ========== 对外 API ========== */
void st7789_init(void);
void st7789_fill(uint16_t color);
void st7789_set_backlight(uint8_t on);
void st7789_draw_image(uint16_t x, uint16_t y, uint16_t w, uint16_t h, const uint8_t *img);

#endif /* __ST7789_H */

imag.c(软件转换得到)


imag.h

#ifndef __IMAG_H
#define __IMAG_H

#include <stdint.h>

// 请确保这两个宏的名称与您文件中的一致
#define IMAG_WIDTH  240
#define IMAG_HEIGHT 240

extern const unsigned char gImage_1[115200]; // 数组名以您实际生成的为准

#endif

main.c

#include "gd32vw55x.h"
#include "st7789.h"
#include "imag.h"

int main(void) {
    st7789_init();

    // 直接使用您生成的数组名 gImage_1
    st7789_draw_image(0, 0, 240, 240, gImage_1);

    while(1) {
    }
}

四、 开发体验与资料评价

  • 工具链: 官方提供基于Eclipse的IDE插件,也支持PlatformIO/VSCode,RISC-V生态兼容性较好;
  • 文档: 数据手册、用户指南、原理图、BOM清单齐全,中文文档阅读友好;
  • 示例代码: 外设驱动例程覆盖全面,注释清晰,二次开发门槛低;
  • 社区支持: GD32官方论坛及QQ群响应及时,常见问题已有解决方案沉淀。

五、 选型建议与总结

推荐场景: 需要Wi-Fi+BLE双模通信、对成本敏感的物联网终端、智能面板、传感器网关等;
⚠️
注意事项: RISC-V生态仍在完善中,部分第三方库需手动移植;Flash擦写寿命需关注量产写入频率;
💡
总体评价: GD32VW553在RISC-V无线MCU赛道中性价比突出,硬件设计成熟,软件生态可用性强,作为国产替代方案值得纳入选型清单。


全部评论
暂无评论
0/144