嵌入式单片机开发 - 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();
相关推荐
-Springer-1 天前
STM32 学习 —— 个人学习笔记11-1(SPI 通信协议及 W25Q64 简介 & 软件 SPI 读写 W25Q64)
笔记·stm32·学习
LN花开富贵1 天前
【ROS】鱼香ROS2学习笔记一
linux·笔记·python·学习·嵌入式·ros·agv
yrx0203071 天前
串口空闲中断+DMA接收+环形缓冲区 && 串口DMA发送+环形缓冲区
stm32·单片机
t***5441 天前
如何在现代C++中更有效地应用这些模式
java·开发语言·c++
itman3011 天前
C语言、C++与C#深度研究:从底层到现代开发演进全解析
c语言·c++·c·内存管理·编译模型
LCG元1 天前
STM32实战:基于STM32F103的4G模块(EC20)HTTP通信
stm32·嵌入式硬件·http
爱编码的小八嘎1 天前
C语言完美演绎8-2
c语言
送外卖的CV工程师1 天前
STM32+Makefile编译+OpenOCD 烧录调试
stm32·单片机·嵌入式硬件·makefile·调试·烧录·openocd
豆包公子1 天前
程序流监控:AUTOSAR CP 功能安全在裸机 MCU 上的实现(理论篇)
运维·单片机·嵌入式硬件·安全·车载系统·autosar
Hical_W1 天前
为 C++ Web 框架设计三层 PMR 内存池:从原理到实战
c++·github