嵌入式单片机开发 - HAL 库 STM32F1 外设的时钟使能(时钟使能宏、时钟禁用宏)

概述

  1. STM32 外设的时钟使能宏(ENABLE 系列)与时钟禁用宏(DISABLE系列)位于 STM32F1xx_hal_rcc.h

  2. 下面主要以 APB2 总线上的外设的时钟使能宏与时钟禁用宏为例


一、时钟使能宏

1、基本介绍
c 复制代码
#define __HAL_RCC_AFIO_CLK_ENABLE()   do { \
                                        __IO uint32_t tmpreg; \
                                        SET_BIT(RCC->APB2ENR, RCC_APB2ENR_AFIOEN);\
                                        /* Delay after an RCC peripheral clock enabling */\
                                        tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_AFIOEN);\
                                        UNUSED(tmpreg); \
                                      } while(0U)

#define __HAL_RCC_GPIOA_CLK_ENABLE()   do { \
                                        __IO uint32_t tmpreg; \
                                        SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPAEN);\
                                        /* Delay after an RCC peripheral clock enabling */\
                                        tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPAEN);\
                                        UNUSED(tmpreg); \
                                      } while(0U)

#define __HAL_RCC_GPIOB_CLK_ENABLE()   do { \
                                        __IO uint32_t tmpreg; \
                                        SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPBEN);\
                                        /* Delay after an RCC peripheral clock enabling */\
                                        tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPBEN);\
                                        UNUSED(tmpreg); \
                                      } while(0U)

#define __HAL_RCC_GPIOC_CLK_ENABLE()   do { \
                                        __IO uint32_t tmpreg; \
                                        SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPCEN);\
                                        /* Delay after an RCC peripheral clock enabling */\
                                        tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPCEN);\
                                        UNUSED(tmpreg); \
                                      } while(0U)

#define __HAL_RCC_GPIOD_CLK_ENABLE()   do { \
                                        __IO uint32_t tmpreg; \
                                        SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);\
                                        /* Delay after an RCC peripheral clock enabling */\
                                        tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);\
                                        UNUSED(tmpreg); \
                                      } while(0U)

#define __HAL_RCC_ADC1_CLK_ENABLE()   do { \
                                        __IO uint32_t tmpreg; \
                                        SET_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC1EN);\
                                        /* Delay after an RCC peripheral clock enabling */\
                                        tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_ADC1EN);\
                                        UNUSED(tmpreg); \
                                      } while(0U)

#define __HAL_RCC_TIM1_CLK_ENABLE()   do { \
                                        __IO uint32_t tmpreg; \
                                        SET_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM1EN);\
                                        /* Delay after an RCC peripheral clock enabling */\
                                        tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_TIM1EN);\
                                        UNUSED(tmpreg); \
                                      } while(0U)

#define __HAL_RCC_SPI1_CLK_ENABLE()   do { \
                                        __IO uint32_t tmpreg; \
                                        SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI1EN);\
                                        /* Delay after an RCC peripheral clock enabling */\
                                        tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SPI1EN);\
                                        UNUSED(tmpreg); \
                                      } while(0U)

#define __HAL_RCC_USART1_CLK_ENABLE()   do { \
                                        __IO uint32_t tmpreg; \
                                        SET_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN);\
                                        /* Delay after an RCC peripheral clock enabling */\
                                        tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_USART1EN);\
                                        UNUSED(tmpreg); \
                                      } while(0U)
  • 这些时钟使能宏的结构相同,只是针对不同的外设
说明
__HAL_RCC_AFIO_CLK_ENABLE() 使能 AFIO 的时钟
__HAL_RCC_GPIOA_CLK_ENABLE() 使能 GPIOA 的时钟
__HAL_RCC_GPIOB_CLK_ENABLE() 使能 GPIOB 的时钟
__HAL_RCC_GPIOC_CLK_ENABLE() 使能 GPIOC 的时钟
__HAL_RCC_GPIOD_CLK_ENABLE() 使能 GPIOD 的时钟
__HAL_RCC_ADC1_CLK_ENABLE() 使能 ADC1 的时钟
__HAL_RCC_TIM1_CLK_ENABLE() 使能 TIM1 的时钟
__HAL_RCC_SPI1_CLK_ENABLE() 使能 SPI1 的时钟
__HAL_RCC_USART1_CLK_ENABLE() 使能 USART1 的时钟
2、解读
c 复制代码
#define __HAL_RCC_AFIO_CLK_ENABLE()   do { \
                                        __IO uint32_t tmpreg; \
                                        SET_BIT(RCC->APB2ENR, RCC_APB2ENR_AFIOEN);\
                                        /* Delay after an RCC peripheral clock enabling */\
                                        tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_AFIOEN);\
                                        UNUSED(tmpreg); \
                                      } while(0U)
  • __HAL_RCC_AFIO_CLK_ENABLE() 为例
  1. 使用 do { ... } while(0) 结构,确保宏在使用时的安全性

  2. 声明一个临时变量 tmpreg

  3. SET_BIT 设置 RCC->APB2ENR 寄存器中对应的位,这里是 RCC_APB2ENR_AFIOEN

c 复制代码
#define SET_BIT(REG, BIT)     ((REG) |= (BIT))
  1. READ_BIT 读取该位值到临时变量,这个操作是为了插入延迟,确保时钟稳定,即读取操作会在写入操作之后
c 复制代码
#define READ_BIT(REG, BIT)    ((REG) & (BIT))
  1. UNUSED(tmpreg) 避免编译器警告未使用的变量
3、演示
c 复制代码
// 使能 GPIOA 和 GPIOB 的时钟
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();

二、时钟禁用宏

1、基本介绍
c 复制代码
#define __HAL_RCC_AFIO_CLK_DISABLE()      (RCC->APB2ENR &= ~(RCC_APB2ENR_AFIOEN))
#define __HAL_RCC_GPIOA_CLK_DISABLE()     (RCC->APB2ENR &= ~(RCC_APB2ENR_IOPAEN))
#define __HAL_RCC_GPIOB_CLK_DISABLE()     (RCC->APB2ENR &= ~(RCC_APB2ENR_IOPBEN))
#define __HAL_RCC_GPIOC_CLK_DISABLE()     (RCC->APB2ENR &= ~(RCC_APB2ENR_IOPCEN))
#define __HAL_RCC_GPIOD_CLK_DISABLE()     (RCC->APB2ENR &= ~(RCC_APB2ENR_IOPDEN))
#define __HAL_RCC_ADC1_CLK_DISABLE()      (RCC->APB2ENR &= ~(RCC_APB2ENR_ADC1EN))

#define __HAL_RCC_TIM1_CLK_DISABLE()      (RCC->APB2ENR &= ~(RCC_APB2ENR_TIM1EN))
#define __HAL_RCC_SPI1_CLK_DISABLE()      (RCC->APB2ENR &= ~(RCC_APB2ENR_SPI1EN))
#define __HAL_RCC_USART1_CLK_DISABLE()    (RCC->APB2ENR &= ~(RCC_APB2ENR_USART1EN))
  • 这些时钟禁用宏的结构相同,只是针对不同的外设
说明
__HAL_RCC_AFIO_CLK_DISABLE() 禁用 AFIO 的时钟
__HAL_RCC_GPIOA_CLK_DISABLE() 禁用 GPIOA 的时钟
__HAL_RCC_GPIOB_CLK_DISABLE() 禁用 GPIOB 的时钟
__HAL_RCC_GPIOC_CLK_DISABLE() 禁用 GPIOC 的时钟
__HAL_RCC_GPIOD_CLK_DISABLE() 禁用 GPIOD 的时钟
__HAL_RCC_ADC1_CLK_DISABLE() 禁用 ADC1 的时钟
__HAL_RCC_TIM1_CLK_DISABLE() 禁用 TIM1 的时钟
__HAL_RCC_SPI1_CLK_DISABLE() 禁用 SPI1 的时钟
__HAL_RCC_USART1_CLK_DISABLE() 禁用 USART1 的时钟
2、解读
c 复制代码
#define __HAL_RCC_AFIO_CLK_DISABLE()      (RCC->APB2ENR &= ~(RCC_APB2ENR_AFIOEN))
  • __HAL_RCC_AFIO_CLK_DISABLE() 为例,直接使用 RCC->APB2ENR 寄存器,然后使用按位与操作 &= 来清除对应的位,这里是 RCC_APB2ENR_AFIOEN
3、演示
c 复制代码
// 禁用 GPIOA 和 GPIOB 的时钟
__HAL_RCC_GPIOB_CLK_DISABLE();
__HAL_RCC_GPIOE_CLK_DISABLE();
相关推荐
aramae2 小时前
模拟实现strcmp()(C语言)
c语言·开发语言·后端
AOI小白新手上路3 小时前
韦东山 01_ARM架构与编程_2-1_处理器的区分MCU_MPU_AP_内容总结
嵌入式硬件
ysu_03143 小时前
TinyML 模型部署:从 Edge Impulse 到 STM32F103
驱动开发·stm32·嵌入式硬件·mcu·硬件架构·硬件工程·dsp开发
汉克老师5 小时前
GESP2026年9月认证C++六级( 第三部分编程题(1、数组划分))精讲
c++·gesp·小学生·学c++编程
千里码aicood6 小时前
基于PLC与机器视觉的智能分拣控制系统设计
c++·自动化·plc
zjxtxdy6 小时前
SPI通信协议
笔记·单片机
漂流瓶jz6 小时前
UVA-1442 洞穴 题解答案代码 算法竞赛入门经典第二版
c++·算法·题解·aoapc·算法竞赛入门经典·uva
朽棘不雕6 小时前
进一步了解模板
c++
金士顿7 小时前
ASP.NET Core Native AOT 到底是什么?从 C#、IL、JIT 一直讲到 Linux ARM64 ELF
嵌入式·asp.net core
恒锐丰科技林技术员9 小时前
EG1196S:高压宽输入降压 DC‑DC 芯片,电动车工业电源的优选方案
经验分享·嵌入式硬件·硬件工程