中景园0.96寸SPI单色屏

分享作者:wx17604144081181
评测品牌:萤火工场
评测型号:GD32VW553-IOT-V2
发布时间:2025-11-04 11:16:49
1
概要
GD32VW553-IOT-V2开发板资料下载和中景园0.96寸SPI单色屏移植步骤代码
开源口碑分享内容

一、资料下载

萤火工场 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写代码


然后编译,调试烧录。

全部评论
暂无评论
0/144