介绍
本文以 STM32 标准库编写的 OLED 菜单模块为例,介绍如何将其移植至 HAL 库,并完成 CLion 开发环境的工程搭建、编译、下载与调试配置。
本次移植旨在将原有标准库工程转换为基于HAL库的工程架构,以便后续集成串口、ADC、DMA、SPI、I²C 等外设。借助CubeMX自动生成初始化代码,可减少底层配置工作,使开发重点更多地放在应用逻辑的实现上。
江协科技OLED模块(标准库)的移植
1.4个文件的实现均改为HAL库实现,这里列举几项:
void OLED_W_SCL(uint8_t BitValue) { /*根据BitValue的值,将SCL置高电平或者低电平*/ //GPIO_WriteBit(GPIOB, GPIO_Pin_8, (BitAction)BitValue); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, BitValue); /*如果单片机速度过快,可在此添加适量延时,以避免超出I2C通信的最大速度*/ //... } /** * 函 数:OLED写SDA高低电平 * 参 数:要写入SDA的电平值,范围:0/1 * 返 回 值:无 * 说 明:当上层函数需要写SDA时,此函数会被调用 * 用户需要根据参数传入的值,将SDA置为高电平或者低电平 * 当参数传入0时,置SDA为低电平,当参数传入1时,置SDA为高电平 */ void OLED_W_SDA(uint8_t BitValue) { /*根据BitValue的值,将SDA置高电平或者低电平*/ //GPIO_WriteBit(GPIOB, GPIO_Pin_9, (BitAction)BitValue); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9, BitValue); /*如果单片机速度过快,可在此添加适量延时,以避免超出I2C通信的最大速度*/ //... }2.创建目录HardWare/OLED,将实现后的代码复制到该目录下:
3.这里要注意将新加入的目录、c/h文件加入到CMakeList中(关键一步):
让编译器找到.h文件:加入新建的目录
# Add include paths target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE # Add user defined include paths HardWare/OLED )让编译器编译.c文件:这一步一般自动完成
# Create an executable object type add_executable(${CMAKE_PROJECT_NAME} HardWare/OLED/OLED.c HardWare/OLED/OLED.h HardWare/OLED/OLED_Data.c HardWare/OLED/OLED_Data.h)4.配置OPENOCD路径,编译烧录执行测试(main中)。
/* USER CODE BEGIN WHILE */ OLED_Printf(0,0,OLED_8X16,"this is a test"); OLED_Update(); while (1)执行成功,如图。
同时,Cube MX中的配置如图:
本文提供了移植后的OLED模块(HAL版本)作为配套资源,不包含菜单功能。读者可直接下载,并作为基于HAL库开发OLED驱动的模板使用。
OLED的移植(参考OLED模块)
创建文件Key.h,Key.c并改为替换标准库函数为HAL库函数,举个例子:
#define KEY_UP GPIO_PIN_11 #define KEY_DOWN GPIO_PIN_1 #define KEY_ENTER GPIO_PIN_6 #define KEY_BACK GPIO_PIN_4void Key_Init() { /* 开启 GPIO 时钟 */ __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); /* GPIO 初始化结构体 */ GPIO_InitTypeDef GPIO_InitStruct = {0}; /* 配置 PB1、PB11 */ GPIO_InitStruct.Pin = GPIO_PIN_1 | GPIO_PIN_11; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* 配置 PA4、PA6 */ GPIO_InitStruct.Pin = GPIO_PIN_4 | GPIO_PIN_6; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); }创建目录System,创建Menus文件,这两个文件可以直接复制过去,不涉及标准库函数。
最后编写main.c文件,将定义的宏和全局变量等复制到对应位置:
/* USER CODE BEGIN PV */ static State state1 = menu_main;//初始状态为一级菜单 /* USER CODE END PV */编译执行,成功。
Cube MX中的配置如图,这里PB6和PB7不通过Output输出高低电平,GND和VCC直接连接面包板:
资源绑定为OLED基本模块,菜单模块就不提供了。如果有不同见解可以在评论区讨论!
引用声明
本文中 OLED 驱动模块的原始代码参考并引用自江协科技 STM32 教程中的 OLED 驱动程序,其原作者版权归江协科技及原作者所有。
本文仅以学习、研究和技术交流为目的,对原有驱动进行了HAL 库移植、代码适配、接口调整及工程结构优化。涉及 HAL 接口替换、CubeMX 工程适配、CLion/CMake 配置及相关说明均为本人整理与实践所得。
若本文涉及的原始代码内容与原作者版权存在冲突,请联系本人,我将第一时间进行修改或删除。
本文重点介绍的是STM32 标准库 OLED 驱动迁移至 HAL 库的思路与实现过程,并非原创 OLED 驱动教程。如需学习 OLED 驱动原理及原始实现,建议阅读江协科技的相关课程或资料。