初学HAL库|STM32HAL库实现OLED

目录

前言

一、为什么要移植OLED?

二、对移植过程的思考

2.1 江协代码的粗略分析

2.1.1 对第一部分的江协代码进行分析

2.1.2 对第二部分的江协代码进行分析

2.2 将江协代码与HAL的区别

三、进行移植

3.1 CubeMx配置

3.1.1 选择芯片型号

3.1.2 System Core配置

3.1.3 时钟树设置(Clock Configuration)

3.1.4 Project Manager设置

3.2 代码编写

3.2.1 将程序设置为自启动模式

3.2.2 创建自己的文件夹

3.2.3 开始移植,修改江协代码

四、移植后的效果图

总结

参考文献


前言

文章为记录个人学习HAL库的成果,使用的芯片型号为:STM32F103C8T6,使用辅助软件:CubeMx,这篇文章是对江协标准库OLED进行移植,所用到的OLED文件来源于江协。参考的视频来源于B站up主野生绿波电龙,视频的BV号为:BV1jr421L7kU

以及B站up主江协科技,视频的BV号为:BV1th411z7sn

以及B站up主成电应电科协,视频BV号为:BV1y7411m7gg

一、为什么要移植OLED?

OLED作为单片机数据显示的一个外设,我们可以把各类参数显示在OLED上面,就比如可以把

STM32F103C8T6与OpenMv通信过程的关键信息显示在OLED上,这样我们可以通过单片机接收到的数据对其进行下一步的判断、处理;也可以作为检验代码是否出错的排查工具。因此,OLED对于单片机而言,其功能十分重要。

二、对移植过程的思考

2.1 江协代码的粗略分析

打开江协的代码,我们可以发现关于OLED有三个函数,分别为:OLED.c,OLED.h,OLED_Font.h

查看江协的OLED.c的代码,我们会发现他是用软件模拟IIC通信来进行的,我们可以将要修改代码分为两个部分:

第一部分是模拟IIC中定义时钟总线和数据总线,第二部分是引脚的初始化操作。

2.1.1 对第一部分的江协代码进行分析

这是一个define的宏定义,是对GPIO口进行写入的操作。这时候我看到了“BitAction”,这是啥玩意?字面意思是bit行动?我进行了如下操作。

对“BitAction”进行选中,找到它定义的地方,可以发现它是一个结构体:

因此我们就可以知道它的作用了,它的作用是对端口进行使能或不使能。而BitAction(x)则可以通过x的取值来选择其为使能或不使能。

2.1.2 对第二部分的江协代码进行分析

第二部分倒是更方便理解,由于其是对GPIO口的初始化,我们可以在之后的CubeMx中直接对其进行配置。值得注意的是“GPIO_Speed”的部分,江协将单片机端口的速度设置成了50MHZ,对应HAL库的速度选值我们可以参考下表(来源于成电应电科协视频P43的4分15秒处)

因此在配置引脚输出速度时可以选用“MEDIUM”

2.2 江协代码与HAL库的区别

在江协代码的第一部分中,我们会发现“GPIO_WriteBit(GPIOB, GPIO_Pin_8, (BitAction)(x))”的这种格式与HAL库的格式不相符,HAL对于GPIO口写入的格式应该为“HAL_GPIO_WritePin(GPIOx,GPIO_PIN_x,GPIO_PIN_SET(或者是GPIO_PIN_RESET))”,因此我们在移植的时候首先要对其进行改写。

那么在HAL库中有没有像标准库那样“BitAction”的结构体对GPIO端口进行使能或不使能操作呢?在标准库中,我们发现“BitAction”所存放的位置是“stm32f10x_gpio.h”中。

那么在HAL库中有没有类似的文件呢?我去翻了翻HAL的gpio口的文件,发现有和“BitAction”类似功能的函数,它在HAL库中名字为“GPIO_PinState”,被存放在“stm32f1xx_hal_gpio.h”中。

因此我们在HAL库中要把“BitAction”替换为“GPIO_PinState”。

三、进行移植

3.1 CubeMx配置

3.1.1 选择芯片型号

打开CubeMx软件:

在搜索框中输入芯片型号“STM32F103C8”,并选择该型号:

3.1.2 System Core配置

点击“SYS”,将Debug选择为“Serial Wire”,其余地方保持默认设置即可,不用更改。

点击“RCC”,将“High Speed Clock(HSE)”选择为“Crystal/Ceramic Resonator”,其余地方保持默认设置即可,不用更改。

点击芯片的“PB8”引脚,选择“GPIO_Output”(PB9同理)

点击"GPIO",再点击"PB8",将“GPIO mode”设置为开漏输出模式(Output Open Drain),速度选择“Medium”,“PB9”的设置与“PB8”的设置一样,这里就不重复赘述了。

3.1.3 时钟树设置(Clock Configuration)

点击“Clock Configuration”,将框中的“8”修改为“72”,然后按下回车键

在弹出来的框中选择“OK”

3.1.4 Project Manager设置

输入项目名称“OLED”,将“EWARM”改为“MDK-ARM”

版本更改为V5

点击“Code Generator”,勾选图片第二个框中的内容(这是用于生成对应的.c和.h文件的),然后点击“GENERATE CODE”生成代码

点击“Open Project”打开keil5

3.2 代码编写

3.2.1 将程序设置为自启动模式

点击菜单栏中的“魔术棒”

点击“Debug”,然后再点击“Settings”

点击“Flash Download”,勾选选项“Reset and Run”,再点击“确定”

3.2.2 创建自己的文件夹

创建自己的文件夹可以区别于CubeMx生成代码时创建的文件夹,更为方便管理。

打开文件路径,创建一个新文件夹“MyUsed”

文件路径位置每个人不一定相同,可以根据自己的CubeMx中的这个位置来定位(这里我的文件路径的位置是在F盘,STM32文件夹下的CubeMx文件夹,CubeMx文件夹下的test文件夹,test文件夹下的OLED文件夹,请根据自己的位置来定位文件夹路径):

把江协的三个关于OLED的代码复制到“MyUsed”文件夹下

打开keil5,按照下面四步进行操作

在刚刚创建好的“MyUsed”文件夹,右击鼠标

点击“向上一级”

把文件类型改为“All files”,之后打开“MyUsed”

按住鼠标左键,将三个OLED代码全部选中后点击“Add”,添加完成后点击“Close”关闭标签页

此时三个文件就被加入到Keil5所创建的文件夹“MyUsed”中了,但它的路径还未添加,keil5无法识别,接下来是添加路径:

点击魔术棒,再点击“C/C++”,然后点击三个小点

点击文件夹图标,再点击三个小点

返回文件的上一级

点击“MyUsed”,选中后点击“选择文件夹”

点击“OK”,再点击“OK”

自此,创建自己的文件夹就完成了。

3.2.3 开始移植,修改江协代码

打开keil5左侧的“MyUsed”文件夹中的OLED.c,将头文件处“#include "stm32f10x.h"改为“#include gpio.h”;将“GPIO_WriteBit”替换为“HAL_GPIO_WritePin”;将“GPIO_Pin”改为“GPIO_PIN”;将“BitAction"替换为“GPIO_PinState”。结果如下所示:

#include "gpio.h"
#include "OLED_Font.h"

/*引脚配置*/
#define OLED_W_SCL(x)		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,(GPIO_PinState)(x))
#define OLED_W_SDA(x)		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,(GPIO_PinState)(x))

对引脚初始化函数“void OLED_I2C_Init(void)”进行修改,将标准库对引脚的初始化改为CubeMx自动生成的引脚初始化,即:

/*引脚初始化*/
void OLED_I2C_Init(void)
{
	MX_GPIO_Init();
	
	OLED_W_SCL(1);
	OLED_W_SDA(1);
}

添加OLED的头文件,打开main.c文件,在“ /* USER CODE BEGIN Includes */ ”和“ /* USER CODE END Includes */ ”之间添加头文件#include "OLED.h"

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "OLED.h"
/* USER CODE END Includes */

初始化OLED,在“ /* USER CODE BEGIN SysInit */ ”和“ /* USER CODE END SysInit */ ”之间添加“OLED_Init();”

/* Configure the system clock */
    SystemClock_Config();

/* USER CODE BEGIN SysInit */
    OLED_Init();
/* USER CODE END SysInit */

开始测试在OLED上显示数据,在“ /* USER CODE BEGIN 2 */ ”和“ /* USER CODE END 2 */ ”之间写入代码:

/* Configure the system clock */
    SystemClock_Config();

/* USER CODE BEGIN SysInit */
    OLED_Init();
/* USER CODE END SysInit */

/* Initialize all configured peripherals */
    MX_GPIO_Init();

/* USER CODE BEGIN 2 */
    OLED_ShowChar(1, 1, 'A');
    OLED_ShowString(1, 3, "HelloWorld!");
    OLED_ShowNum(2, 1, 12345, 5);
    OLED_ShowString(3, 1, "NaOH");
/* USER CODE END 2 */

至此,OLED的移植就结束了。

四、移植后的效果图


 


总结

移植完OLED后可以用于之后的串口通信部分,来检查数据的收发是否有问题,对我而言还是挺有帮助的,这也正是我移植OLED的目的之一。OLED相较于单片机就好似printf相较于C语言,如果没有printf,C语言的学习将会很困难,你无法对代码进行测试,OLED的作用就在于此。

参考文献

[1] 成电应电科协. (2020, March 24). 【STM32教程】入门教程(基于HAL库+CubeMX+MDK-ARM) [Video]. Retrieved from https://www.bilibili.com/video/BV1y7411m7gg?p=43

[2] breeze0321. (2022, April 4). STM32F103c8t6 - CubeMX 快速实现时钟配置 - 最大72M时钟的设定及实验测试. CSDN博客. <https://blog.csdn.net/weixin_43604457/article/details/123262730>

[3] 野生绿波电龙. (2024, May 19). P3.移植江协OLED显示屏【HAL库复现江协全部STM32例子合集】 [Video]. Retrieved from https://www.bilibili.com/video/BV1jr421L7kU/?spm_id_from=333.788

[4] 江协科技. (2021, July 29). STM32入门教程-2023版 细致讲解 中文字幕 [Video]. Retrieved from

https://www.bilibili.com/video/BV1th411z7sn?p=10

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值