概述
STM32 外设的时钟使能宏(ENABLE 系列)与时钟禁用宏(DISABLE系列)位于
STM32F1xx_hal_rcc.h
下面主要以 APB2 总线上的外设的时钟使能宏与时钟禁用宏为例
一、时钟使能宏
1、基本介绍
#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、解读
#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()
为例
使用
do { ... } while(0)
结构,确保宏在使用时的安全性声明一个临时变量 tmpreg
SET_BIT
设置RCC->APB2ENR
寄存器中对应的位,这里是RCC_APB2ENR_AFIOEN
#define SET_BIT(REG, BIT) ((REG) |= (BIT))
READ_BIT
读取该位值到临时变量,这个操作是为了插入延迟,确保时钟稳定,即读取操作会在写入操作之后
#define READ_BIT(REG, BIT) ((REG) & (BIT))
UNUSED(tmpreg)
避免编译器警告未使用的变量
3、演示
// 使能 GPIOA 和 GPIOB 的时钟
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
二、时钟禁用宏
1、基本介绍
#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、解读
#define __HAL_RCC_AFIO_CLK_DISABLE() (RCC->APB2ENR &= ~(RCC_APB2ENR_AFIOEN))
- 以
__HAL_RCC_AFIO_CLK_DISABLE()
为例,直接使用RCC->APB2ENR
寄存器,然后使用按位与操作&=
来清除对应的位,这里是RCC_APB2ENR_AFIOEN
3、演示
// 禁用 GPIOA 和 GPIOB 的时钟
__HAL_RCC_GPIOB_CLK_DISABLE();
__HAL_RCC_GPIOE_CLK_DISABLE();