揭秘STM32单片机时钟系统:掌握配置奥秘,掌控时间节奏
发布时间: 2024-07-03 12:01:49 阅读量: 13 订阅数: 14 ![](https://csdnimg.cn/release/wenkucmsfe/public/img/col_vip.0fdee7e1.png)
![](https://csdnimg.cn/release/wenkucmsfe/public/img/col_vip.0fdee7e1.png)
![揭秘STM32单片机时钟系统:掌握配置奥秘,掌控时间节奏](https://img-blog.csdnimg.cn/direct/3cc11191bd97445182de38ca19368cf9.png)
# 1. STM32时钟系统概述**
STM32单片机时钟系统是芯片内部一个至关重要的模块,负责为整个系统提供稳定的时钟信号,确保芯片各模块的正常运行。时钟系统由多个时钟源、时钟树和时钟控制单元组成,通过配置这些组件,可以满足不同应用场景对时钟精度的要求。
本篇文章将深入剖析STM32时钟系统,从时钟源配置、时钟树配置到时钟中断和监测,全方位解析其工作原理和配置方法,帮助开发者掌握时钟系统的精髓,掌控时间节奏。
# 2. 时钟源配置
STM32单片机提供了丰富的时钟源,包括内部时钟源和外部时钟源。内部时钟源由单片机内部电路产生,而外部时钟源则需要外部器件提供。
### 2.1 内部时钟源
内部时钟源主要包括HSI、LSI和HSE。
#### 2.1.1 HSI
HSI(High-Speed Internal oscillator)是高速内部时钟,其频率通常为16MHz或8MHz。HSI是单片机内部最基本的时钟源,无需外部器件即可使用。
**代码块:**
```c
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInit(&RCC_OscInitStruct);
```
**逻辑分析:**
这段代码用于配置HSI时钟源。`RCC_OscInitTypeDef`结构体用于配置时钟源参数。`OscillatorType`字段指定时钟源类型为HSI,`HSIState`字段使能HSI时钟,`HSICalibrationValue`字段用于校准HSI时钟频率。
#### 2.1.2 LSI
LSI(Low-Speed Internal oscillator)是低速内部时钟,其频率通常为32kHz或40kHz。LSI时钟频率较低,但功耗也较低,适合于低功耗应用。
**代码块:**
```c
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
RCC_OscInitStruct.LSICalibrationValue = RCC_LSICALIBRATION_DEFAULT;
RCC_OscInit(&RCC_OscInitStruct);
```
**逻辑分析:**
这段代码用于配置LSI时钟源。`OscillatorType`字段指定时钟源类型为LSI,`LSIState`字段使能LSI时钟,`LSICalibrationValue`字段用于校准LSI时钟频率。
#### 2.1.3 HSE
HSE(High-Speed External oscillator)是高速外部时钟,其频率通常为8MHz或25MHz。HSE时钟源需要外部晶振或陶瓷谐振器提供。
**代码块:**
```c
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInit(&RCC_OscInitStruct);
```
**逻辑分析:**
这段代码用于配置HSE时钟源。`OscillatorType`字段指定时钟源类型为HSE,`HSEState`字段使能HSE时钟,`HSEPredivValue`字段用于配置HSE时钟预分频器。
### 2.2 外部时钟源
外部时钟源主要包括PLL和LSE。
#### 2.2.1 PLL
PLL(Phase-Locked Loop)是锁相环,它可以将一个时钟源的频率倍频或分频。STM32单片机提供了多个PLL,可以灵活配置。
**代码块:**
```c
RCC_PLLInitTypeDef RCC_PLLInitStruct = {0};
RCC_PLLInitStruct.PLLSource = RCC_PLLSOURCE_HSI;
RCC_PLLInitStruct.PLLM = 16;
RCC_PLLInitStruct.PLLN = 336;
RCC_PLLInitStruct.PLLP = RCC_PLLP_DIV2;
RCC_PLLInitStruct.PLLQ = RCC_PLLQ_DIV2;
RCC_PLLInitStruct.PLLR = RCC_PLLR_DIV2;
RCC_PLLInit(&RCC_PLLInitStruct);
```
**逻辑分析:**
这段代码用于配置PLL时钟源。`PLLSource`字段指定PLL输入时钟源,`PLLM`字段指定PLL输入时钟分频器,`PLLN`字段指定PLL倍频器,`PLLP`、`PLLQ`和`PLLR`字段指定PLL输出时钟分频器。
#### 2.2.2 LSE
LSE(Low-Speed External oscillator)是低速外部时钟,其频率通常为32.768kHz。LSE时钟源需要外部晶振或陶瓷谐振器提供。
**代码块:**
```c
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.LSEStartUpTime = RCC_LSE_STARTUPTIME_1S;
RCC_OscInit(&RCC_OscInitStruct);
```
**逻辑分析:**
这段代码用于配置LSE时钟源。`OscillatorType`字段指定时钟源类型为LSE,`LSEState`字段使能LSE时钟,`LSEStartUpTime`字段指定LSE时钟启动时间。
# 3. 时钟树配置**
### 3.1 时钟树结构
STM32的时钟树是一个分层结构,从时钟源开始,经过一系列的分频器和多路复用器,最终为不同的外设提供所需的时钟信号。时钟树的结构如下图所示:
```mermaid
graph LR
subgraph 时钟源
HSI --> 分频器
LSI --> 分频器
HSE --> 分频器
PLL --> 分频器
LSE --> 分频器
end
subgraph 分频器
分频器 --> 多路复用器
end
subgraph 多路复用器
多路复用器 --> 外设
end
```
### 3.2 时钟分频
时钟分频器用于降低时钟频率,以满足不同外设的时钟要求。分频器可以将输入时钟频率除以一个固定的因子,从而产生一个较低的输出时钟频率。
STM32的分频器有两种类型:
- **整系数分频器:**将输入时钟频率除以一个整数因子。
- **小数系数分频器:**将输入时钟频率除以一个分数因子。
分频器的配置通过寄存器进行,其中包含分频因子和控制位。例如,以下代码配置分频器将输入时钟频率除以 2:
```c
RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;
```
### 3.3 时钟多路复用
时钟多路复用器用于选择多个时钟源中的一个作为输出时钟。多路复用器可以配置为自动切换到备份时钟源,如果主时钟源发生故障。
STM32的多路复用器有两种类型:
- **单路复用器:**选择一个时钟源作为输出时钟。
- **多路复用器:**选择多个时钟源作为输出时钟,并根据优先级自动切换。
多路复用器的配置通过寄存器进行,其中包含时钟源选择位和控制位。例如,以下代码配置多路复用器选择 HSI 时钟源作为输出时钟:
```c
RCC->CFGR |= RCC_CFGR_SW_HSI;
```
# 4. 时钟中断和监测
### 4.1 时钟中断
STM32单片机提供时钟中断功能,当时钟系统发生故障或异常时,可以触发中断,以便及时采取措施。时钟中断的配置步骤如下:
1. **使能时钟中断**:在RCC寄存器中设置**CIRC**(Clock Interrupt Request Control)位,使能时钟中断。
2. **配置中断优先级**:在NVIC寄存器中设置**NVIC_IPR**(Interrupt Priority Register)寄存器,配置时钟中断的优先级。
3. **编写中断服务程序**:在用户程序中编写时钟中断服务程序,处理时钟中断事件。
**代码块:**
```c
// 使能时钟中断
RCC->CIRC |= RCC_CIRC_LSIRDYIE | RCC_CIRC_HSIRDYIE | RCC_CIRC_HSERDYIE | RCC_CIRC_PLLRDYIE;
// 配置时钟中断优先级
NVIC_SetPriority(RCC_IRQn, 3);
// 时钟中断服务程序
void RCC_IRQHandler(void)
{
// 处理时钟中断事件
}
```
**逻辑分析:**
* RCC->CIRC寄存器用于使能时钟中断,其中:
* RCC_CIRC_LSIRDYIE:使能LSI就绪中断
* RCC_CIRC_HSIRDYIE:使能HSI就绪中断
* RCC_CIRC_HSERDYIE:使能HSE就绪中断
* RCC_CIRC_PLLRDYIE:使能PLL就绪中断
* NVIC_SetPriority函数用于配置时钟中断的优先级,其中3表示较高的优先级。
* RCC_IRQHandler函数是时钟中断服务程序,用于处理时钟中断事件。
### 4.2 时钟监测
STM32单片机提供时钟监测功能,可以监测时钟系统的稳定性和可靠性。时钟监测的配置步骤如下:
1. **使能时钟监测**:在RCC寄存器中设置**CR**(Clock Control Register)寄存器的**CSSON**(Clock Security System Enable)位,使能时钟监测。
2. **配置监测窗口**:在RCC寄存器中设置**ICSR**(Interrupt and Status Register)寄存器的**WWDG**(Window Watchdog)位,配置时钟监测窗口。
3. **配置中断优先级**:在NVIC寄存器中设置**NVIC_IPR**寄存器,配置时钟监测中断的优先级。
4. **编写中断服务程序**:在用户程序中编写时钟监测中断服务程序,处理时钟监测中断事件。
**代码块:**
```c
// 使能时钟监测
RCC->CR |= RCC_CR_CSSON;
// 配置监测窗口
RCC->ICSR |= RCC_ICSR_WWDG_0;
// 配置时钟监测中断优先级
NVIC_SetPriority(RCC_IRQn, 3);
// 时钟监测中断服务程序
void RCC_IRQHandler(void)
{
// 处理时钟监测中断事件
}
```
**逻辑分析:**
* RCC->CR寄存器用于使能时钟监测,其中:
* RCC_CR_CSSON:使能时钟安全系统
* RCC->ICSR寄存器用于配置时钟监测窗口,其中:
* RCC_ICSR_WWDG_0:配置监测窗口为0
* NVIC_SetPriority函数用于配置时钟监测中断的优先级,其中3表示较高的优先级。
* RCC_IRQHandler函数是时钟监测中断服务程序,用于处理时钟监测中断事件。
### 4.3 时钟故障处理
当时钟系统发生故障时,STM32单片机可以采取措施进行故障处理。时钟故障处理的步骤如下:
1. **检测时钟故障**:通过时钟中断或时钟监测功能检测时钟故障。
2. **切换到备用时钟源**:如果主时钟源发生故障,可以切换到备用时钟源,以保证系统继续运行。
3. **重新配置时钟系统**:如果时钟故障可以恢复,可以重新配置时钟系统,恢复正常运行。
**代码块:**
```c
// 检测时钟故障
if (RCC->CSR & RCC_CSR_LSIRDY) {
// LSI就绪,切换到LSI时钟源
RCC->CFGR |= RCC_CFGR_SW_LSI;
} else if (RCC->CSR & RCC_CSR_HSIRDY) {
// HSI就绪,切换到HSI时钟源
RCC->CFGR |= RCC_CFGR_SW_HSI;
}
// 重新配置时钟系统
RCC->CFGR |= RCC_CFGR_PLLSRC_HSI | RCC_CFGR_PLLMUL_6;
```
**逻辑分析:**
* RCC->CSR寄存器用于检测时钟故障,其中:
* RCC_CSR_LSIRDY:LSI就绪标志
* RCC_CSR_HSIRDY:HSI就绪标志
* RCC->CFGR寄存器用于切换时钟源,其中:
* RCC_CFGR_SW_LSI:切换到LSI时钟源
* RCC_CFGR_SW_HSI:切换到HSI时钟源
* RCC->CFGR寄存器还用于重新配置时钟系统,其中:
* RCC_CFGR_PLLSRC_HSI:PLL时钟源选择HSI
* RCC_CFGR_PLLMUL_6:PLL倍频因子为6
# 5. 时钟系统应用**
STM32单片机的时钟系统不仅为系统提供了稳定的时间基准,还为各种外设和功能提供了时钟源。在实际应用中,时钟系统可以应用于以下几个方面:
**5.1 定时器配置**
定时器是STM32单片机中重要的外设,广泛用于各种时间测量和控制应用。定时器的时钟源可以由内部时钟源(如HSI、LSI)或外部时钟源(如HSE)提供。
**代码示例:**
```c
// 使用HSI时钟源配置定时器2
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // 使能定时器2时钟
TIM2->PSC = 7999; // 分频系数为8000
TIM2->ARR = 999; // 自动重装载值
TIM2->CNT = 0; // 清除计数器
TIM2->CR1 |= TIM_CR1_CEN; // 使能定时器
```
**5.2 实时时钟配置**
实时时钟(RTC)是STM32单片机中用于保持时间和日期的专用外设。RTC的时钟源通常由外部低速时钟源(如LSE)提供,以确保在断电情况下也能保持时间准确性。
**代码示例:**
```c
// 使用LSE时钟源配置RTC
RCC->BDCR |= RCC_BDCR_LSEON; // 使能LSE
while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0); // 等待LSE稳定
RCC->BDCR |= RCC_BDCR_RTCSEL_LSE; // 选择LSE作为RTC时钟源
RCC->APB1ENR |= RCC_APB1ENR_PWREN; // 使能PWR时钟
PWR->CR |= PWR_CR_DBP; // 使能备份域写入
RCC->BDCR |= RCC_BDCR_RTCEN; // 使能RTC
```
**5.3 通信外设时钟配置**
STM32单片机集成了丰富的通信外设,如UART、SPI、I2C等。这些外设的时钟源通常由内部时钟源(如HSI、PLL)或外部时钟源(如HSE)提供。
**代码示例:**
```c
// 使用PLL时钟源配置UART2
RCC->APB1ENR |= RCC_APB1ENR_USART2EN; // 使能UART2时钟
RCC->CFGR |= RCC_CFGR_PPRE1_DIV2; // APB1分频系数为2
RCC->PLLCFGR |= RCC_PLLCFGR_PLLM_DIV3; // PLL输入时钟分频系数为3
RCC->PLLCFGR |= RCC_PLLCFGR_PLLN_MUL9; // PLL倍频系数为9
RCC->PLLCFGR |= RCC_PLLCFGR_PLLSRC_HSE; // PLL输入时钟源为HSE
RCC->CR |= RCC_CR_PLLON; // 使能PLL
while ((RCC->CR & RCC_CR_PLLRDY) == 0); // 等待PLL稳定
RCC->CFGR |= RCC_CFGR_USART2SW_PLL; // 选择PLL作为UART2时钟源
```
0
0
相关推荐
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)