news 2026/11/4 2:31:04

stm32u5a5HAL库study-点个灯吧 顺便阅读一些函数

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
stm32u5a5HAL库study-点个灯吧 顺便阅读一些函数

ok,我们今天先通过STM32U5A5这块开发板点个灯,并通过按键去控制led的亮灭。首先,我们先看一下这块开发板的原理图。
绿色led

红色与蓝色led

按键button
ok,我们现在打开cubemx去进行一下GPIO的配置

我们将各个GPIO口添加上Labels,

STM32U5A5 开发板 LED 与用户按键引脚配置表

外设器件编号GPIO 引脚GPIO 模式有效电平User Label
绿色 LEDLD1PC7(默认)GPIO_Output高电平点亮LED_GREEN
蓝色 LEDLD2PB7GPIO_Output高电平点亮LED_BLUE
红色 LEDLD3PG2GPIO_Output高电平点亮LED_RED
用户按键B1PC13(默认)GPIO_Input高电平表示按下KEY1

小灯亮起

假如我们现在要点亮红色小灯

while(1){HAL_GPIO_WritePin(LED_RED_GPIO_Port,LED_RED_Pin,GPIO_PIN_SET);}

关于HAL_GPIO_WritePin这个函数,是HAL库提供的GPIO电平控制函数,具体请参考我上一篇博客,这里简单带过,从寄存器层面理解,这句话就是向GPIOG端口的BSRR第2位写入1,使PG2 输出高电平。
如图。小灯亮起

接下来,我们让红色 LED 以 500 ms 为间隔,交替执行点亮和熄灭操作。

while(1){// 点亮红色 LEDHAL_GPIO_WritePin(LED_RED_GPIO_Port,LED_RED_Pin,GPIO_PIN_SET);HAL_Delay(500);// 熄灭红色 LEDHAL_GPIO_WritePin(LED_RED_GPIO_Port,LED_RED_Pin,GPIO_PIN_RESET);HAL_Delay(500);}

HAL_Delay(500):延时 500 ms,即 0.5 s。(关于这个函数我们不细讲,后续我专门写一篇博客去讲这些常见的函数)
另外,还有一种实现方式

while(1){HAL_GPIO_TogglePin(LED_RED_GPIO_Port,LED_RED_Pin);HAL_Delay(500);}

HAL_GPIO_TogglePin函数

HAL_GPIO_TogglePin这个函数,我们展开看一下

voidHAL_GPIO_TogglePin(GPIO_TypeDef*GPIOx,uint16_tGPIO_Pin){uint32_todr;/* Check the parameters */assert_param(IS_GPIO_PIN(GPIO_Pin));/* get current Output Data Register value */odr=GPIOx->ODR;/* Set selected pins that were at low level, and reset ones that were high */GPIOx->BSRR=((odr&GPIO_Pin)<<GPIO_NUMBER)|(~odr&GPIO_Pin);}

ODR寄存器

ODR是什么?Output Data Register,输出数据寄存器,作用是用来保存一个GPIO端口各个引脚输出逻辑状态的寄存器。
对于 STM32U5A5,ODR 虽然是一个 32 位寄存器,但只有低 16 位(Bit 0~15)用于 GPIO 输出控制,高 16 位(Bit 16~31)是保留位(Reserved)。

位范围功能说明
Bit 0~15输出数据位分别对应 GPIOx 的 0~15 号引脚
Bit 16~31保留位不用于 GPIO 输出控制

保留位不是额外的 16 个 GPIO 引脚,也不能拿来控制其他 GPIO。编写寄存器代码时应遵循参考手册对保留位的规定。
为什么 ODR 要设计成 32 位?
因为 STM32 是 32 位微控制器,其外设寄存器通常采用 32 位访问形式。

位范围ODRBSRR
Bit 0~15保存 GPIO 输出状态写 1,设置对应引脚为高电平
Bit 16~31保留位写 1,复位对应引脚为低电平

HAL_GPIO_TogglePin`函数实现

首先,定义一个uint32_t类型的局部变量odr,用于保存 GPIO 输出数据寄存器(ODR)的当前值,以便进行后续的位运算。

uint32_todr;odr=GPIOx->ODR;

其中,GPIOx是指向 GPIO 外设寄存器结构体的指针,GPIOx->ODR表示该 GPIO 端口的输出数据寄存器(Output Data Register)。

因此,odr = GPIOx->ODR;的作用就是读取当前 GPIO 端口 ODR 寄存器的数值,并将其保存到局部变量odr中。

接下来,我们的目标是实现指定 GPIO 引脚的输出电平翻转,即原来为高电平(1)的引脚变为低电平(0),原来为低电平(0)的引脚变为高电平(1)。我们的思路就是,我们保存这个GPIO端口输出逻辑的状态,将这个状态取反给BSRR寄存器进行改写。

由于 BSRR 寄存器的低 16 位用于置位,高 16 位用于复位,因此不能直接将 ODR 的数值取反后写入 BSRR。

我们需要根据odr保存的输出状态,通过按位与、按位取反、左移和按位或运算,生成对应的 BSRR 控制数据。By the way,BSRR寄存器的结构(写0的位置不产生对应操作),[31:16]是复位区域,写1->输出0。[15:0]是置位区域,写1->输出1。

eg,我们的代码是控制的是PG2这个引脚,想让 PG2 输出高电平,就向 BSRR 的Bit[2] 写入 1,想让 PG2 输出低电平,就向 BSRR 的Bit [18] 写入 1。

假设PG2最初是处于高电平状态,那我的GPIOG的ODR寄存器保存着整个GPIOG端口的输出状态,ODR[2]=1;那我想让它状态翻转,直接取反赋值给BSRR不就好了吗?但是一个ODR寄存器里面保存着所有GPIOG区域内的端口的状态,直接取反,肯定会影响其他端口的状态,so,我们按位与,把想要的PIN脚状态取出,再左移16位,赋值给BSRR,即可将其状态反转。

这里有一个小插曲,当BSRR寄存器的某位处于置位状态时,由于BSRR的硬件规则,此时的ODR寄存器对应的位置会被清0,BSRR[18] 写 1 → 清除 ODR[2] → PG2 输出低电平。

那如果PG2最初是低电平状态,我的GPIOG的ODR寄存器ODR[2]=0,我想要的结果是什么?是ODR[2]=0 ->ODR[2]=1,通过按位取反和按位与生成 BSRR 的置位命令,即可将其状态反转。

GPIOx->BSRR=((odr&GPIO_Pin)<<16)|(~odr&GPIO_Pin);

最终,通过向 BSRR 写入计算结果,实现指定 GPIO 引脚输出电平的翻转。

在这里思考的有些多了,每次总是忍不住往底层走,照这样学多久才能到头啊。。

HAL_GPIO_ReadPin

我们现在让按键去控制小灯的亮灭情况

while(1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */if(HAL_GPIO_ReadPin(KEY1_GPIO_Port,KEY1_Pin)==GPIO_PIN_SET){HAL_GPIO_WritePin(LED_GREEN_GPIO_Port,LED_GREEN_Pin,GPIO_PIN_SET);}else{HAL_GPIO_WritePin(LED_GREEN_GPIO_Port,LED_GREEN_Pin,GPIO_PIN_RESET);}}

HAL_GPIO_ReadPin我盲猜啊,就是去读IDR(Input Data Register输入数据寄存器)寄存器的值,判断一下我需要的引脚的状态

我们根据底层逻辑去客观验证一下我的猜想

GPIO_PinStateHAL_GPIO_ReadPin(constGPIO_TypeDef*GPIOx,uint16_tGPIO_Pin){GPIO_PinState bitstatus;/* Check the parameters */assert_param(IS_GPIO_PIN(GPIO_Pin));if((GPIOx->IDR&GPIO_Pin)!=0U){bitstatus=GPIO_PIN_SET;}else{bitstatus=GPIO_PIN_RESET;}returnbitstatus;}

代码逻辑很简单,和我想得一模一样,if我们的IDR寄存器对应的我们需要的PIN位的那一位,是不是说的有点绕,PG2(仅展示后八位)为00000100,和IDR[2]按位与一下,就可以得到PG2的状态。

顺便插一嘴,const GPIO_TypeDef *GPIOx,这里为什么要用const,现在看的是读取引脚的函数。它只需要查看电平,所以用const表达“只读”的意思,对应地:

  • HAL_GPIO_ReadPin():读电平,参数带const。
  • HAL_GPIO_WritePin():需要写寄存器,参数不带这个const。


我们按着按键,绿灯亮起。

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

HDPE户外家具挤塑微发泡板材螺钉握持性能不足的技术归因分析

在HDPE户外家具工业化生产场景中&#xff0c;存在一种隐蔽性强、危害程度高的典型失效模式&#xff1a;板材下线时的常规力学性能指标均符合规范要求&#xff0c;但在成品装配、长距离物流运输、终端用户拆装服役过程中&#xff0c;自攻螺钉旋入后易发生滑牙、拔出及连接界面松…

作者头像 李华
网站建设 2026/11/4 2:30:16

文旅与演艺用车:景区接驳、散场疏散与酒店穿梭

文旅与演艺用车&#xff1a;景区接驳、散场疏散与酒店穿梭 晚上十点&#xff0c;主舞台灯光灭掉&#xff0c;两万人同时往出口走。停车场在八百米外&#xff0c;接驳车停在三个点位&#xff0c;每个点位要区分去广州的、去佛山的、去地铁站的。 接下来两小时&#xff0c;是这类…

作者头像 李华
网站建设 2026/11/4 2:28:40

国产嵌入式仿真软件怎么选?测试监控设计与ICD编辑功能要点

国产嵌入式仿真软件怎么选&#xff1f;测试监控设计与ICD编辑功能要点 在国防军工与高端装备研发领域&#xff0c;嵌入式系统的复杂度持续提升&#xff0c;测试监控设计与ICD编辑能力已成为评估嵌入式仿真软件工程化成熟度的关键指标。当团队需要在国产化环境下构建完整的半实物…

作者头像 李华
网站建设 2026/11/4 2:27:02

WebStorm Windows 版安装配置与实战效能评测

WebStorm Windows 版安装配置与实战效能评测 版本基准&#xff1a;WebStorm 2026.2 / Windows 10 & 11 评测立场&#xff1a;独立、可复现、数据驱动。不回避短板&#xff0c;不夸大优势。面向正在决策“是否值得为 WebStorm 付出学习成本和资源开销”的开发者。摘要 WebSt…

作者头像 李华