一、资料下载
萤火工场 GD32VW553-IOT 开发板 的详细资料以及环境配置方面可以看这位大佬的,这里就不多讲了。
萤火工场 GD32VW553-IOT 开发板使用指南-CSDN博客
这次使用的是 萤火工场 GD32VW553-IOT-V2开发板,以及中景园0.96寸OLED显示屏
资料下载链接:
https://pan.baidu.com/s/1U9r32qeS2jOANB0SNwtwnw
资料提取码:8888
二、规格参数
工作电压:3.3V
工作电流:15MA
模块尺寸:27.3 x 27.8 MM
像素大小:128(H) x 64(V)RGB
驱动芯片:SSD1306
通信协议:SPI
管脚数量:7 Pin(2.54mm间距排针)
以上信息见厂家资料文件
三、移植过程
我们的目标是将例程移植至开发板上。按照以下步骤,即可完成移植。
将源码导入工程;
根据编译报错处进行粗改;
修改引脚配置;
修改时序配置;
移植验证。
1、查看资料
打开厂家资料例程(例程下载见百度网盘链接下载)。具体路径见例程路径
例程路径
2、移植至工程
将厂家资料路径下的【OLED】文件夹,复制到自己创建的工程中。
复制示意图
我们打开工程(如果没有显示相关的文件夹,请右键点击Refresh)
添加头文件到工程中:
右键项目
3、引脚选择
该屏幕需要设置7个接口,具体接口说明见 各引脚说明。
模块为SPI通信协议的从机,D0为SPI信号线(SCK),D1为SPI输出线(MOSI),CS为SPI片选线(NSS)。
4、硬件SPI移植
屏幕 开发板
GND GND
VCC 3V3
SCL PA11
SDA PA9
RES PA7
DC PA6
CS PA5
修改头文件配置:
将所有的 #include "sys.h" 改为 #include "systick.h"
在 .h 文件中添加下面的定义:
#ifndef u8
#define u8 uint8_t
#endif
#ifndef u16
#define u16 uint16_t
#endif
#ifndef u32
#define u32 uint32_t
#endif
AI写代码
选择好引脚后,进入工程开始编写屏幕引脚初始化代码。
将 oled.c 源代码中的 void OLED_Init(void) 修改为如下代码。
//OLED的初始化
void OLED_Init(void)
{
//使能时钟
OLED_RCU_ENABLE();
//引脚复用
gpio_af_set(OLED_SCL_PORT, OLED_SCL_AF, OLED_SCL_PIN);
gpio_af_set(OLED_SDA_PORT, OLED_SDA_AF, OLED_SDA_PIN);
//引脚模式
gpio_mode_set(OLED_SCL_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, OLED_SCL_PIN);
gpio_mode_set(OLED_SDA_PORT, GPIO_MODE_AF, GPIO_PUPD_NONE, OLED_SDA_PIN);
gpio_mode_set(OLED_RES_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, OLED_RES_PIN);
gpio_mode_set(OLED_DC_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, OLED_DC_PIN);
gpio_mode_set(OLED_CS_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, OLED_CS_PIN);
//输出模式
gpio_output_options_set(OLED_SCL_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, OLED_SCL_PIN);
gpio_output_options_set(OLED_SDA_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, OLED_SDA_PIN);
gpio_output_options_set(OLED_RES_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, OLED_RES_PIN);
gpio_output_options_set(OLED_DC_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, OLED_DC_PIN);
gpio_output_options_set(OLED_CS_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_MAX, OLED_CS_PIN);
OLED_CS_Set(); //片选高
OLED_DC_Set(); //数据/命令高
//SPI参数定义结构体
spi_parameter_struct spi_init_struct;
/* 配置 SPI 参数 */
spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX; // 传输模式全双工
spi_init_struct.device_mode = SPI_MASTER; // 配置为主机
spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT; // 8位数据
spi_init_struct.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
spi_init_struct.nss = SPI_NSS_SOFT; // 软件cs
spi_init_struct.prescale = SPI_PSC_32;//32分频
spi_init_struct.endian = SPI_ENDIAN_MSB;//高位在前
//将参数填入SPI
spi_init(&spi_init_struct);
/* 使能 SPI */
spi_enable();
OLED_RES_Clr();
delay_ms(200);
OLED_RES_Set();
OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panel
OLED_WR_Byte(0x00,OLED_CMD);//---set low column address
OLED_WR_Byte(0x10,OLED_CMD);//---set high column address
OLED_WR_Byte(0x40,OLED_CMD);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control register
OLED_WR_Byte(0xCF,OLED_CMD);// Set SEG Output Current Brightness
OLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
OLED_WR_Byte(0xA6,OLED_CMD);//--set normal display
OLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 duty
OLED_WR_Byte(0xD3,OLED_CMD);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
OLED_WR_Byte(0x00,OLED_CMD);//-not offset
OLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
OLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
OLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge period
OLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
OLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configuration
OLED_WR_Byte(0x12,OLED_CMD);
OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomh
OLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect Level
OLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
OLED_WR_Byte(0x02,OLED_CMD);//
OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
OLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disable
OLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7)
OLED_Clear();
OLED_WR_Byte(0xAF,OLED_CMD);
}
AI写代码
打开 oled.c 文件,修改 OLED_WR_Byte函数 为下面的代码:
void OLED_WR_Byte(u8 dat,u8 cmd)
{
uint8_t recv_data = 0;
if(cmd)
OLED_DC_Set();
else
OLED_DC_Clr();
OLED_CS_Clr();
//等待发送缓冲区为空
while(RESET == spi_flag_get(SPI_FLAG_TBE) );
//通过SPI发送一个字节数据
spi_data_transmit(dat);
//等待接收缓冲区不空标志
while(RESET == spi_flag_get(SPI_FLAG_RBNE) );
recv_data = spi_data_receive();
OLED_CS_Set();
OLED_DC_Set();
}
AI写代码
将oled.h中的 OLED端口定义 宏,修改为下方代码框中的代码。
#ifndef delay_ms
#define delay_ms(x) delay_1ms(x)
#endif
#ifndef delay_us
#define delay_us(x) delay_1us(x)
#endif
//-----------------OLED端口定义----------------
#define OLED_RCU_ENABLE() rcu_periph_clock_enable(RCU_GPIOA); \
rcu_periph_clock_enable(RCU_GPIOB); \
rcu_periph_clock_enable(RCU_SPI);
#define OLED_SCL_PORT GPIOA
#define OLED_SCL_PIN GPIO_PIN_11
#define OLED_SCL_AF GPIO_AF_0
#define OLED_SDA_PORT GPIOA
#define OLED_SDA_PIN GPIO_PIN_9
#define OLED_SDA_AF GPIO_AF_0
#define OLED_RES_PORT GPIOA
#define OLED_RES_PIN GPIO_PIN_7
#define OLED_DC_PORT GPIOA
#define OLED_DC_PIN GPIO_PIN_6
#define OLED_CS_PORT GPIO
#define OLED_CS_PIN GPIO_PIN_5
#define OLED_RES_Clr() gpio_bit_write(OLED_RES_PORT, OLED_RES_PIN, 0)//RES
#define OLED_RES_Set() gpio_bit_write(OLED_RES_PORT, OLED_RES_PIN, 1)
#define OLED_DC_Clr() gpio_bit_write(OLED_DC_PORT, OLED_DC_PIN, 0)//DC
#define OLED_DC_Set() gpio_bit_write(OLED_DC_PORT, OLED_DC_PIN, 1)
#define OLED_CS_Clr() gpio_bit_write(OLED_CS_PORT, OLED_CS_PIN, 0)//CS
#define OLED_CS_Set() gpio_bit_write(OLED_CS_PORT, OLED_CS_PIN, 1)
AI写代码
到这里就移植完成了,可移步到第五节进行移植验证。
四、关键代码
oled.holed.c
#ifndef __OLED_H
#define __OLED_H
#include "gd32vw55x.h"
#include "systick.h"
#ifndef delay_ms
#define delay_ms(x) delay_1ms(x)
#endif
#ifndef delay_us
#define delay_us(x) delay_1us(x)
#endif
#ifndef u8
#define u8 uint8_t
#endif
#ifndef u16
#define u16 uint16_t
#endif
#ifndef u32
#define u32 uint32_t
#endif
//-----------------OLED端口定义----------------
#define OLED_RCU_ENABLE() rcu_periph_clock_enable(RCU_GPIOA); \
rcu_periph_clock_enable(RCU_GPIOB); \
rcu_periph_clock_enable(RCU_SPI);
#define OLED_SCL_PORT GPIOA
#define OLED_SCL_PIN GPIO_PIN_11
#define OLED_SCL_AF GPIO_AF_0
#define OLED_SDA_PORT GPIOA
#define OLED_SDA_PIN GPIO_PIN_9
#define OLED_SDA_AF GPIO_AF_0
#define OLED_RES_PORT GPIOA
#define OLED_RES_PIN GPIO_PIN_7
#define OLED_DC_PORT GPIOA
#define OLED_DC_PIN GPIO_PIN_6
#define OLED_CS_PORT GPIOB
#define OLED_CS_PIN GPIO_PIN_11
#define OLED_RES_Clr() gpio_bit_write(OLED_RES_PORT, OLED_RES_PIN, 0)//RES
#define OLED_RES_Set() gpio_bit_write(OLED_RES_PORT, OLED_RES_PIN, 1)
#define OLED_DC_Clr() gpio_bit_write(OLED_DC_PORT, OLED_DC_PIN, 0)//DC
#define OLED_DC_Set() gpio_bit_write(OLED_DC_PORT, OLED_DC_PIN, 1)
#define OLED_CS_Clr() gpio_bit_write(OLED_CS_PORT, OLED_CS_PIN, 0)//CS
#define OLED_CS_Set() gpio_bit_write(OLED_CS_PORT, OLED_CS_PIN, 1)
#define OLED_CMD 0 //写命令
#define OLED_DATA 1 //写数据
void OLED_ClearPoint(u8 x,u8 y);
void OLED_ColorTurn(u8 i);
void OLED_DisplayTurn(u8 i);
void OLED_WR_Byte(u8 dat,u8 mode);
void OLED_DisPlay_On(void);
void OLED_DisPlay_Off(void);
void OLED_Refresh(void);
void OLED_Clear(void);
void OLED_DrawPoint(u8 x,u8 y,u8 t);
void OLED_DrawLine(u8 x1,u8 y1,u8 x2,u8 y2,u8 mode);
void OLED_DrawCircle(u8 x,u8 y,u8 r);
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size1,u8 mode);
void OLED_ShowChar6x8(u8 x,u8 y,u8 chr,u8 mode);
void OLED_ShowString(u8 x,u8 y,u8 *chr,u8 size1,u8 mode);
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size1,u8 mode);
void OLED_ShowChinese(u8 x,u8 y,u8 num,u8 size1,u8 mode);
void OLED_ScrollDisplay(u8 num,u8 space,u8 mode);
void OLED_ShowPicture(u8 x,u8 y,u8 sizex,u8 sizey,u8 BMP[],u8 mode);
void OLED_Init(void);
#endif
AI写代码
五、移植验证
在 src\main.c 中如下:
#include "gd32vw55x.h"
#include "systick.h"
#include <stdio.h>
#include "main.h"
#include "gd32vw553h_eval.h"
#include "oled.h"
#include "bmp.h"
/*!
\brief toggle the led every 500ms
\param[in] none
\param[out] none
\retval none
*/
void led_spark(void)
{
static __IO uint32_t timingdelaylocal = 0U;
if(timingdelaylocal) {
if(timingdelaylocal < 500U) {
gd_eval_led_on(LED1);
} else {
gd_eval_led_off(LED1);
}
timingdelaylocal--;
} else {
timingdelaylocal = 1000U;
}
}
/*!
\brief main function
\param[in] none
\param[out] none
\retval none
*/
int main(void)
{
#ifdef __FIRMWARE_VERSION_DEFINE
uint32_t fw_ver = 0;
#endif /* __FIRMWARE_VERSION_DEFINE */
/* configure systick */
systick_config();
eclic_priority_group_set(ECLIC_PRIGROUP_LEVEL3_PRIO1);
/* initilize the LEDs, USART and key */
gd_eval_led_init(LED1);
gd_eval_com_init(EVAL_COM0);
gd_eval_key_init(KEY_TAMPER_WAKEUP, KEY_MODE_GPIO);
#ifdef __FIRMWARE_VERSION_DEFINE
fw_ver = gd32vw55x_firmware_version_get();
/* print firmware version */
printf("\r\nGD32VW55X series firmware version: V%d.%d.%d", (uint8_t)(fw_ver >> 24), (uint8_t)(fw_ver >> 16), (uint8_t)(fw_ver >> 8));
#endif /* __FIRMWARE_VERSION_DEFINE */
/* print out the clock frequency of system, AHB, APB1 and APB2 */
printf("\r\nCK_SYS is %d\r\n", rcu_clock_freq_get(CK_SYS));
printf("\r\nCK_AHB is %d\r\n", rcu_clock_freq_get(CK_AHB));
printf("\r\nCK_APB1 is %d\r\n", rcu_clock_freq_get(CK_APB1));
printf("\r\nCK_APB2 is %d\r\n", rcu_clock_freq_get(CK_APB2));
uint8_t t=' ';
OLED_Init();
OLED_ColorTurn(0);//0正常显示,1 反色显示
OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
while(1)
{
OLED_ShowPicture(0,0,128,64,BMP1,1);
OLED_Refresh();
delay_1ms(500);
OLED_Clear();
OLED_ShowChinese(0,0,0,16,1);//中
OLED_ShowChinese(18,0,1,16,1);//景
OLED_ShowChinese(36,0,2,16,1);//园
OLED_ShowChinese(54,0,3,16,1);//电
OLED_ShowChinese(72,0,4,16,1);//子
OLED_ShowChinese(90,0,5,16,1);//技
OLED_ShowChinese(108,0,6,16,1);//术
OLED_ShowString(8,16,"ZHONGJINGYUAN",16,1);
OLED_ShowString(20,32,"2014/05/01",16,1);
OLED_ShowString(0,48,"ASCII:",16,1);
OLED_ShowString(63,48,"CODE:",16,1);
OLED_ShowChar(48,48,t,16,1);//显示ASCII字符
t++;
if(t>'~')t=' ';
OLED_ShowNum(103,48,t,3,16,1);
OLED_Refresh();
delay_1ms(500);
OLED_Clear();
OLED_ShowChinese(0,0,0,16,1); //16*16 中
OLED_ShowChinese(16,0,0,24,1); //24*24 中
OLED_ShowChinese(24,20,0,32,1);//32*32 中
OLED_ShowChinese(64,0,0,64,1); //64*64 中
OLED_Refresh();
delay_1ms(500);
OLED_Clear();
OLED_ShowString(0,0,"ABC",8,1);//6*8 “ABC”
OLED_ShowString(0,8,"ABC",12,1);//6*12 “ABC”
OLED_ShowString(0,20,"ABC",16,1);//8*16 “ABC”
OLED_ShowString(0,36,"ABC",24,1);//12*24 “ABC”
OLED_Refresh();
delay_1ms(500);
OLED_ScrollDisplay(11,4,1);
}
}
AI写代码
然后编译,调试烧录。

开源社区
