news 2026/9/2 3:59:50

天空星HC32F4A0开发板驱动0.96寸IIC OLED屏(SSD1306)移植指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
天空星HC32F4A0开发板驱动0.96寸IIC OLED屏(SSD1306)移植指南

天空星HC32F4A0开发板驱动0.96寸IIC OLED屏(SSD1306)移植指南

最近在天空星HC32F4A0开发板上做个小项目,需要接个屏幕显示点信息,就选了最常用的0.96寸OLED屏。这种小屏功耗低、显示清晰,用IIC接口接线也简单,但网上的例程大多是针对STM32的,直接拿来用肯定不行。折腾了一下午,总算把驱动移植成功了,这里把完整的移植过程分享给大家,手把手教你搞定。

1. 准备工作:了解你的OLED屏

在开始移植之前,咱们先搞清楚要驱动的对象是什么。这次用的是一块0.96英寸的单色OLED显示屏,核心驱动芯片是SSD1306。

这块屏有几个关键特点:

  • 通信接口:IIC(也叫I2C),只需要两根线(SCL时钟线和SDA数据线)就能通信,非常节省IO口。
  • 供电电压:3.3V,正好和天空星开发板的IO电平匹配,可以直接连接,不需要电平转换。
  • 分辨率:128x64像素,虽然不大,但显示文字和简单图形完全够用。
  • 物理接口:4个2.54mm间距的排针,分别是VCC(电源)、GND(地)、SCL(时钟)、SDA(数据)。

注意:不同厂家生产的0.96寸OLED屏,引脚顺序可能不一样!一定要确认你手上的屏幕引脚定义。最常见的顺序是:1脚GND,2脚VCC,3脚SCL,4脚SDA。接线前最好用万用表量一下。

2. 获取原始驱动代码

移植的第一步,得有“原材料”。我用的驱动代码是从卖家提供的资料里找到的,如果你手头没有,可以按照原始文章里提到的链接去下载。

拿到资料后,你会发现里面有个【OLED】文件夹,这就是我们要移植的核心。文件夹里通常包含这几个文件:

  • oled.c- OLED屏的驱动函数实现
  • oled.h- 函数声明和宏定义
  • oledfont.h- 字库数据(ASCII字符的点阵)
  • 可能还有sys.hdelay.h等依赖文件

把这些文件先保存好,接下来我们要把它们“改造”成适合HC32F4A0的样子。

3. 创建工程并导入文件

首先,你得有一个能编译的天空星HC32F4A0基础工程。如果还没有,可以去官方或者立创开发板(LCKFB)的网站下载一个空白工程或者点灯例程,确保工程里至少有一个能用的毫秒级延时函数(比如delay_ms)。

然后,在你的工程目录下新建一个文件夹,比如叫OLED,把刚才那几个源文件(oled.coled.holedfont.h)复制进去。

接着,在你的IDE(比如Keil MDK)里,把oled.c添加到工程的源文件组,把oled.holedfont.h所在的路径添加到头文件包含路径里。这一步是告诉编译器:“我这里有新的代码要编译,头文件在这个地方找”。

4. 修改头文件依赖(解决第一个编译错误)

直接编译肯定会报错,因为原来的代码是为别的芯片写的。咱们按照报错信息,一个个来改。

第一步:替换系统头文件打开oled.h文件,找到类似#include "sys.h"的语句。在HC32的工程里,我们通常用官方的底层库头文件。把它改成:

#include "hc32_ll.h" // 替换原来的 sys.h

这个头文件包含了HC32芯片的GPIO、时钟等底层寄存器的定义。

第二步:替换延时头文件打开oled.c文件,找到#include "delay.h"。在我们的工程里,延时函数可能定义在board.hbsp_delay.h里。根据你的工程实际情况修改,比如:

#include "board.h" // 替换原来的 delay.h,假设延时函数在board.h中声明

第三步:定义数据类型原来的代码可能用了u8u16u32这样的简写来定义变量类型。我们需要在oled.h里确保这些类型有定义。通常在HC32的工程里,这些类型已经在stdint.h里定义了(uint8_tuint16_tuint32_t)。为了兼容,我们可以在oled.h文件的开头(#include语句之后)加上:

#ifndef u8 #define u8 uint8_t #endif #ifndef u16 #define u16 uint16_t #endif #ifndef u32 #define u32 uint32_t #endif

这样,如果其他地方没定义u8,我们就把它指向uint8_t,确保代码能认。

5. 硬件连接与引脚配置

这是移植最关键的一步:告诉单片机,OLED屏接在哪两个引脚上。

硬件连接:把OLED屏的4个引脚接到天空星开发板上:

  • VCC-> 开发板的3.3V引脚
  • GND-> 开发板的GND引脚
  • SCL-> 我们选择的GPIO引脚(例如PB10)
  • SDA-> 我们选择的GPIO引脚(例如PB11)

我选择了PB10和PB11,你可以根据自己板子的空闲情况选择任意两个GPIO,但最好避开已经用于特殊功能(如串口、JTAG)的引脚。

软件配置:我们需要修改代码,把引脚定义改成我们实际连接的。

  1. 找到并修改引脚定义文件。在原始驱动代码里,可能有一个lcd_init.h或者直接在oled.h里有引脚定义。我们需要修改它。
  2. 将定义修改为HC32的格式。在oled.h(或新建一个oled_conf.h)文件中,添加或修改如下代码:
//-----------------GPIO端口定义---------------- #define OLED_GPIO_PORT GPIO_PORT_B // 使用B端口 #define OLED_SCL_PIN GPIO_PIN_10 // SCL时钟线接PB10 #define OLED_SDA_PIN GPIO_PIN_11 // SDA数据线接PB11 //-----------------OLED端口操作宏定义---------------- // 这些宏定义了如何控制引脚输出高低电平 #define OLED_SCL_Clr() GPIO_ResetPins(OLED_GPIO_PORT, OLED_SCL_PIN) // SCL拉低 #define OLED_SCL_Set() GPIO_SetPins(OLED_GPIO_PORT, OLED_SCL_PIN) // SCL拉高 #define OLED_SDA_Clr() GPIO_ResetPins(OLED_GPIO_PORT, OLED_SDA_PIN) // SDA拉低 #define OLED_SDA_Set() GPIO_SetPins(OLED_GPIO_PORT, OLED_SDA_PIN) // SDA拉高

这里用到的GPIO_SetPinsGPIO_ResetPins是HC32官方驱动库提供的函数,用于设置引脚输出高或低电平。

6. 重写OLED初始化函数(核心步骤)

原来的OLED_Init()函数里包含了GPIO初始化和SSD1306芯片的初始化序列。我们需要把GPIO初始化的部分,改成HC32库函数的写法。

打开oled.c,找到void OLED_Init(void)函数,将其内容替换为如下代码:

void OLED_Init(void) { stc_gpio_init_t stcGpioInit; // 定义GPIO初始化结构体 // 解除GPIO外设的写保护,允许配置 LL_PERIPH_WE(LL_PERIPH_GPIO); // 将结构体变量初始化为默认值 (void)GPIO_StructInit(&stcGpioInit); // 配置GPIO结构体参数 stcGpioInit.u16PinState = PIN_STAT_SET; // 初始输出高电平 stcGpioInit.u16PinDir = PIN_DIR_OUT; // 设置为输出模式 stcGpioInit.u16PullUp = PIN_PU_ON; // 使能内部上拉电阻(IIC总线通常需要上拉) // 初始化SCL引脚 (PB10) (void)GPIO_Init(OLED_GPIO_PORT, OLED_SCL_PIN, &stcGpioInit); // 初始化SDA引脚 (PB11) (void)GPIO_Init(OLED_GPIO_PORT, OLED_SDA_PIN, &stcGpioInit); // 给OLED一点上电稳定时间 delay_ms(200); // 以下是SSD1306芯片的初始化命令序列,这部分是通用的,不需要修改 OLED_WR_Byte(0xAE,OLED_CMD);// 关闭显示 OLED_WR_Byte(0x00,OLED_CMD);// 设置列地址低4位 OLED_WR_Byte(0x10,OLED_CMD);// 设置列地址高4位 OLED_WR_Byte(0x40,OLED_CMD);// 设置显示起始行 OLED_WR_Byte(0x81,OLED_CMD);// 对比度设置命令 OLED_WR_Byte(0xCF,OLED_CMD);// 对比度值 (0xCF) OLED_WR_Byte(0xA1,OLED_CMD);// 段重映射设置 (0xA1正常,0xA0左右翻转) OLED_WR_Byte(0xC8,OLED_CMD);// 扫描方向设置 (0xC8正常,0xC0上下翻转) OLED_WR_Byte(0xA6,OLED_CMD);// 正常显示 (0xA6正常,0xA7反色) OLED_WR_Byte(0xA8,OLED_CMD);// 多路复用率设置命令 OLED_WR_Byte(0x3f,OLED_CMD);// 多路复用率值 (0x3F对应64行) OLED_WR_Byte(0xD3,OLED_CMD);// 显示偏移命令 OLED_WR_Byte(0x00,OLED_CMD);// 显示偏移值 (0) OLED_WR_Byte(0xd5,OLED_CMD);// 显示时钟分频/振荡频率命令 OLED_WR_Byte(0x80,OLED_CMD);// 分频比,设置时钟为100帧/秒 OLED_WR_Byte(0xD9,OLED_CMD);// 预充电周期命令 OLED_WR_Byte(0xF1,OLED_CMD);// 预充电15个时钟,放电1个时钟 OLED_WR_Byte(0xDA,OLED_CMD);// COM引脚硬件配置命令 OLED_WR_Byte(0x12,OLED_CMD);// COM引脚配置值 (0x12) OLED_WR_Byte(0xDB,OLED_CMD);// VCOMH电平命令 OLED_WR_Byte(0x40,OLED_CMD);// VCOMH电平值 (0.77*VCC) OLED_WR_Byte(0x20,OLED_CMD);// 内存地址模式设置命令 OLED_WR_Byte(0x02,OLED_CMD);// 页地址模式 (0x02) OLED_WR_Byte(0x8D,OLED_CMD);// 电荷泵设置命令 OLED_WR_Byte(0x14,OLED_CMD);// 使能电荷泵 (0x14) OLED_WR_Byte(0xA4,OLED_CMD);// 全部点亮关闭 (0xA4) OLED_WR_Byte(0xA6,OLED_CMD);// 非反色显示 (0xA6) OLED_Clear(); // 清屏 OLED_WR_Byte(0xAF,OLED_CMD); // 最后,开启显示 }

提示:初始化序列里那一长串OLED_WR_Byte命令,是SSD1306芯片手册规定的,用来设置显示参数,比如对比度、扫描方向等。这部分代码是通用的,无论用什么单片机,只要驱动SSD1306,这些命令都一样,所以千万不要修改这些十六进制数

7. 修改IIC延时函数

SSD1306的IIC通信时序对延时有一定要求。原来的驱动里有一个IIC_delay()函数,我们需要根据HC32的时钟速度来调整。

oled.c文件里找到void IIC_delay(void)函数,它里面可能调用了一个微秒延时函数。我们需要把它改成我们工程里已有的微秒延时函数。假设我们的工程里有一个delay_us()函数:

void IIC_delay(void) { delay_us(15); // 延时大约15微秒,满足IIC时序要求 }

这个延时值(15us)是一个经验值,保证了SCL时钟信号的频率在IIC协议允许的范围内(标准模式100kHz以内)。如果后续通信不稳定,可以适当调整这个值。

8. 编写主函数进行测试

所有底层修改完成后,就可以写个简单的程序来测试了。

打开你的main.c文件,在while(1)主循环之前初始化OLED,然后在循环里显示一些内容。

#include "board.h" #include "oled.h" // 包含OLED驱动头文件 int32_t main(void) { // 硬件初始化(时钟、延时等) board_init(); // 初始化OLED OLED_Init(); OLED_Clear(); // 清屏 while(1) { // 在屏幕不同位置显示不同大小的“ABC” OLED_ShowString(0, 0, (uint8_t *)"Hello HC32!", 8, 1); // 在(0,0)坐标,用8号字体显示 OLED_ShowString(0, 16, (uint8_t *)"OLED Test", 16, 1); // 在(0,16)坐标,用16号字体显示 // 刷新显示(将缓存数据写入OLED) OLED_Refresh(); // 延时一段时间 delay_ms(1000); // 可以在这里加个清屏,实现闪烁效果 // OLED_Clear(); // delay_ms(500); } }

9. 编译、下载与调试

  1. 编译:点击编译按钮,确保0错误,0警告。
  2. 连接硬件:用杜邦线将OLED屏的SCL、SDA、VCC、GND分别连接到开发板你定义的引脚和3.3V、GND。务必检查连线是否正确,电源不要接反!
  3. 下载程序:通过调试器将程序下载到天空星HC32F4A0开发板。
  4. 上电观察:给开发板上电,你应该能看到OLED屏亮起,并显示“Hello HC32!”和“OLED Test”字样。

如果屏幕不亮:

  • 检查电源和地线是否接好,用万用表量一下OLED屏的VCC和GND之间是否有3.3V电压。
  • 检查SCL和SDA线是否接对,是否接触不良。

如果屏幕亮但无显示:

  • 检查OLED_Init()函数中的GPIO初始化部分,确认引脚配置是否正确。
  • 用逻辑分析仪或示波器抓一下SCL和SDA的波形,看是否有IIC通信信号。如果没有,检查IIC_delay函数和底层OLED_SCL_Clr/SetOLED_SDA_Clr/Set宏定义是否正确操作了引脚。

按照上面这些步骤走下来,驱动移植基本就成功了。整个过程中最关键的其实就是两步:一是把GPIO的操作换成HC32的库函数方式,二是保证IIC的时序延时正确。以后要在天空星开发板上用其他IIC设备,比如温湿度传感器、陀螺仪,思路也是一样的。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/14 17:28:21

解决LG Ultrafine显示器Windows亮度调节难题:开源工具全攻略

解决LG Ultrafine显示器Windows亮度调节难题:开源工具全攻略 【免费下载链接】LG-Ultrafine-Brightness A tool to adjust brightness of LG Ultrafine 4k/5K on Windows 项目地址: https://gitcode.com/gh_mirrors/lg/LG-Ultrafine-Brightness 直面Windows系…

作者头像 李华
网站建设 2026/7/14 17:28:21

突破黑苹果配置壁垒:OpCore-Simplify实现EFI构建效率革新

突破黑苹果配置壁垒:OpCore-Simplify实现EFI构建效率革新 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 在黑苹果系统搭建领域&#xff0…

作者头像 李华
网站建设 2026/7/14 17:28:34

3个关键步骤轻松提取Chrome浏览器保存的密码

3个关键步骤轻松提取Chrome浏览器保存的密码 【免费下载链接】chromepass Get all passwords stored by Chrome on WINDOWS. 项目地址: https://gitcode.com/gh_mirrors/chr/chromepass 一、密码困境:数字时代的隐形危机 在我们的数字生活中,密码…

作者头像 李华
网站建设 2026/7/14 17:28:32

如何突破网页动画性能瓶颈?Bodymovin革新方案与实践指南

如何突破网页动画性能瓶颈?Bodymovin革新方案与实践指南 【免费下载链接】bodymovin-extension Bodymovin UI extension panel 项目地址: https://gitcode.com/gh_mirrors/bod/bodymovin-extension 在数字化体验日益重要的今天,网页动画已成为提升…

作者头像 李华
网站建设 2026/7/14 17:28:32

BepInEx插件框架实战避坑指南:从安装到优化的全面解决方案

BepInEx插件框架实战避坑指南:从安装到优化的全面解决方案 【免费下载链接】BepInEx Unity / XNA game patcher and plugin framework 项目地址: https://gitcode.com/GitHub_Trending/be/BepInEx 核心价值:为什么BepInEx是Unity模组开发的首选框…

作者头像 李华