天空星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脚GND2脚VCC3脚SCL4脚SDA。接线前最好用万用表量一下。2. 获取原始驱动代码移植的第一步得有“原材料”。我用的驱动代码是从卖家提供的资料里找到的如果你手头没有可以按照原始文章里提到的链接去下载。拿到资料后你会发现里面有个【OLED】文件夹这就是我们要移植的核心。文件夹里通常包含这几个文件oled.c- OLED屏的驱动函数实现oled.h- 函数声明和宏定义oledfont.h- 字库数据ASCII字符的点阵可能还有sys.h、delay.h等依赖文件把这些文件先保存好接下来我们要把它们“改造”成适合HC32F4A0的样子。3. 创建工程并导入文件首先你得有一个能编译的天空星HC32F4A0基础工程。如果还没有可以去官方或者立创开发板LCKFB的网站下载一个空白工程或者点灯例程确保工程里至少有一个能用的毫秒级延时函数比如delay_ms。然后在你的工程目录下新建一个文件夹比如叫OLED把刚才那几个源文件oled.c、oled.h、oledfont.h复制进去。接着在你的IDE比如Keil MDK里把oled.c添加到工程的源文件组把oled.h和oledfont.h所在的路径添加到头文件包含路径里。这一步是告诉编译器“我这里有新的代码要编译头文件在这个地方找”。4. 修改头文件依赖解决第一个编译错误直接编译肯定会报错因为原来的代码是为别的芯片写的。咱们按照报错信息一个个来改。第一步替换系统头文件打开oled.h文件找到类似#include sys.h的语句。在HC32的工程里我们通常用官方的底层库头文件。把它改成#include hc32_ll.h // 替换原来的 sys.h这个头文件包含了HC32芯片的GPIO、时钟等底层寄存器的定义。第二步替换延时头文件打开oled.c文件找到#include delay.h。在我们的工程里延时函数可能定义在board.h或bsp_delay.h里。根据你的工程实际情况修改比如#include board.h // 替换原来的 delay.h假设延时函数在board.h中声明第三步定义数据类型原来的代码可能用了u8、u16、u32这样的简写来定义变量类型。我们需要在oled.h里确保这些类型有定义。通常在HC32的工程里这些类型已经在stdint.h里定义了uint8_t、uint16_t、uint32_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引脚例如PB10SDA- 我们选择的GPIO引脚例如PB11我选择了PB10和PB11你可以根据自己板子的空闲情况选择任意两个GPIO但最好避开已经用于特殊功能如串口、JTAG的引脚。软件配置我们需要修改代码把引脚定义改成我们实际连接的。找到并修改引脚定义文件。在原始驱动代码里可能有一个lcd_init.h或者直接在oled.h里有引脚定义。我们需要修改它。将定义修改为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_SetPins和GPIO_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. 编译、下载与调试编译点击编译按钮确保0错误0警告。连接硬件用杜邦线将OLED屏的SCL、SDA、VCC、GND分别连接到开发板你定义的引脚和3.3V、GND。务必检查连线是否正确电源不要接反下载程序通过调试器将程序下载到天空星HC32F4A0开发板。上电观察给开发板上电你应该能看到OLED屏亮起并显示“Hello HC32!”和“OLED Test”字样。如果屏幕不亮检查电源和地线是否接好用万用表量一下OLED屏的VCC和GND之间是否有3.3V电压。检查SCL和SDA线是否接对是否接触不良。如果屏幕亮但无显示检查OLED_Init()函数中的GPIO初始化部分确认引脚配置是否正确。用逻辑分析仪或示波器抓一下SCL和SDA的波形看是否有IIC通信信号。如果没有检查IIC_delay函数和底层OLED_SCL_Clr/Set、OLED_SDA_Clr/Set宏定义是否正确操作了引脚。按照上面这些步骤走下来驱动移植基本就成功了。整个过程中最关键的其实就是两步一是把GPIO的操作换成HC32的库函数方式二是保证IIC的时序延时正确。以后要在天空星开发板上用其他IIC设备比如温湿度传感器、陀螺仪思路也是一样的。

相关新闻

4步构建专业RAG评估平台:Ragas环境部署与能力拓展指南

4步构建专业RAG评估平台:Ragas环境部署与能力拓展指南

4步构建专业RAG评估平台:Ragas环境部署与能力拓展指南 【免费下载链接】ragas Evaluation framework for your Retrieval Augmented Generation (RAG) pipelines 项目地址: https://gitcode.com/gh_mirrors/ra/ragas 一、问题定位:RAG评估环境部署…

2026/7/5 12:19:03 阅读更多 →
从文件名到数据价值:解码Landsat卫星数据命名规则与处理级别

从文件名到数据价值:解码Landsat卫星数据命名规则与处理级别

1. 从一串神秘代码说起:为什么你需要读懂Landsat文件名? 如果你刚接触遥感,或者正在做环境、农业、生态相关的研究,大概率会从USGS EarthExplorer或者一些国内的数据平台下载Landsat数据。下载下来的文件,名字长得像一…

2026/7/5 9:08:30 阅读更多 →
实战指南:如何用Python高效调用TSP求解器Concord与LKH

实战指南:如何用Python高效调用TSP求解器Concord与LKH

1. 从零开始:为什么你需要专业的TSP求解器? 如果你正在处理物流路径规划、电路板钻孔、无人机巡检路线,或者任何需要在多个点之间找出一条最短回路的问题,那你大概率已经和“旅行商问题”(TSP)打过照面了。…

2026/7/5 22:48:48 阅读更多 →

最新新闻

STM32F429ZI与PCF8591的ADC/DAC信号转换实战

STM32F429ZI与PCF8591的ADC/DAC信号转换实战

1. PCF8591与STM32F429ZI的信号转换方案概述在嵌入式系统开发中,模拟信号与数字信号的相互转换是常见需求。PCF8591作为一款集成了ADC和DAC功能的芯片,通过I2C接口与主控芯片通信,能够实现4通道模拟输入和1通道模拟输出。而STM32F429ZI作为ST…

2026/7/6 7:31:11 阅读更多 →
STM32与EEPROM数据存储方案及优化实践

STM32与EEPROM数据存储方案及优化实践

1. 项目背景与核心需求在嵌入式系统开发中,数据持久化存储是一个基础但至关重要的功能。STM32L4A6RG作为一款低功耗微控制器,其内部Flash虽然可以用于数据存储,但存在擦写次数有限(约1万次)和操作复杂的缺点。而M24C04…

2026/7/6 7:31:11 阅读更多 →
STM32与AD74413R实现高精度同步数据采集与输出方案

STM32与AD74413R实现高精度同步数据采集与输出方案

1. 项目背景与核心需求在工业自动化、测试测量和音频处理等领域,经常需要同时实现高精度模拟信号采集(ADC)和输出(DAC)的功能。传统方案通常需要分别使用独立的ADC和DAC芯片,这不仅增加了系统复杂度&#x…

2026/7/6 7:29:11 阅读更多 →
PCF8591与PIC18LF45K42信号转换系统设计

PCF8591与PIC18LF45K42信号转换系统设计

1. 项目背景与核心器件选型在工业控制和嵌入式系统设计中,信号转换是连接模拟世界与数字系统的关键桥梁。PCF8591作为一款集成了ADC和DAC功能的混合信号转换芯片,配合PIC18LF45K42这款高性能8位MCU,能够构建出高性价比的多通道信号处理系统。…

2026/7/6 7:29:10 阅读更多 →
智能体内存架构设计与实现:从短期记忆到长期记忆的完整工程方案

智能体内存架构设计与实现:从短期记忆到长期记忆的完整工程方案

🚀 30款热门AI模型一站整合,DeepSeek/GLM/Qwen 随心用,限时 5 折。 👉 点击领海量免费额度 在构建复杂AI应用时,你是否遇到过这样的困境:智能体(Agent)在处理长对话或多步骤任务时…

2026/7/6 7:29:10 阅读更多 →
13DOF传感器与TM4C123的嵌入式定位导航系统设计

13DOF传感器与TM4C123的嵌入式定位导航系统设计

1. 项目背景与核心需求在智能硬件和机器人领域,精准的定位导航能力一直是技术突破的关键瓶颈。传统方案往往面临两个主要痛点:一是单一传感器(如GPS或IMU)在复杂环境中可靠性不足;二是低功耗微控制器难以承载多传感器数…

2026/7/6 7:27:09 阅读更多 →

日新闻

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2与MySQL单元测试兼容性:5个关键SQL语句差异与规避方案1. 单元测试中的数据库兼容性挑战在Java开发领域,单元测试是保证代码质量的重要环节。当应用涉及数据库操作时,测试环境的搭建往往成为开发者的痛点。H2数据库因其轻量级、内存模式和快…

2026/7/6 0:01:17 阅读更多 →
Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘 【免费下载链接】rbtray A fork of RBTray from http://sourceforge.net/p/rbtray/code/. 项目地址: https://gitcode.com/gh_mirrors/rb/rbtray 你是否厌倦了Windows任务栏上密密麻麻的图标&…

2026/7/6 0:01:17 阅读更多 →
Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C 运行时库一键安装终极指南:告别DLL缺失烦恼 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过这样的情况:下载了…

2026/7/6 0:05:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/6 6:52:56 阅读更多 →

月新闻