数字电路的知识告诉我们:任意复杂的电路控制系统都可以经由门电路组成的组合电路实现。STM32 内部也是由多种多样的电路模块组合在一起实现的。当一个电路越复杂,在达到正确的输出结果前,它可能因为延时会有一些短暂的中间状态,而这些中间状态有时会导致输出结果会有一个短暂的错误,这叫做电路中的“毛刺现象”,如果电路需要运行得足够快,那么这些错误状态会被其它电路作为输入采样,最终形成一系列的系统错误。为了解决这个问题,在单片机系统中,设计时以时序电路控制替代纯粹的组合电路,在每一级输出结果前对各个信号进行采样,从而使得电路中某些信号即使出现延时也可以保证各个信号的同步,可以避免电路中发生的“毛刺现象”,达到精确控制输出的效果。
由于时序电路的重要性,因此在 MCU 设计时就设计了专门用于控制时序的电路,在芯片设计中称为时钟树设计。由此设计出来的时钟,可以精确控制我们的单片机系统,一个 MCU 越复杂,时钟系统也会相应地变得复杂,如 STM32F4 的时钟系统比较复杂,不像简单的 51 单片机一个系统时钟就可以解决一切。对于 STM32F4 系列的芯片,正常工作的主频可以达到 168Mhz,但并不是所有外设都需要系统时钟这么高的频率,比如看门狗以及 RTC 只需要几十 Khz 的时钟即可。同一个电路,时钟越快功耗越大,同时抗电磁干扰能力也会越弱,所以对于较为复杂的 MCU 一般都是采取多时钟源的方法来解决这些问题。
STM32 本身非常复杂,外设非常的多,为了保持低功耗工作,STM32 的主控默认不开启这些外设功能。用户可以根据自己的需要决定 STM32 芯片要使用的功能,这个功能开关在 STM32主控中也就是各个外设的时钟。
1. CM4时钟系统
① HSE 高速外部时钟信号:HSE 是高速的外部时钟信号,可以由有源晶振或者无源晶振提供,频率从 4-26MHZ 不等。当使用有源晶振时,时钟从 OSC_IN 引脚进入,OSC_OUT 引脚悬空,当选用无源晶振时,时钟从 OSC_IN 和 OSC_OUT 进入,并且要配谐振电容。如果我们使用 HSE 或者 HSE 经过 PLL 倍频之后的时钟作为系统时钟 SYSCLK,当 HSE 故障时候,不仅 HSE 会被关闭,PLL 也会被关闭,此时高速的内部时钟时钟信号 HSI 会作为备用的系统时钟,直到 HSE恢复正常,HSI=16M。
② 锁相环 PLL:PLL 的主要作用是对时钟进行倍频,然后把时钟输出到各个功能部件。PLL 有两个,一个是主PLL(②),另外一个是专用的 PLLI2S©,他们均由 HSE 或者 HSI 提供时钟输入信号。
主 PLL 有两路的时钟输出,第一个输出时钟 PLLCLK 用于系统时钟(最高是 168M),第二个输出用于 USB OTG FS 的时钟(48M)、RNG 和 SDIO 时钟(<=48M)。专用的 PLLI2S 用于生成精确时钟,给 I2S 提供时钟。
HSE 或者 HSI 经过 PLL 时钟输入分频因子 M(2~63)分频后,成为 VCO 的时钟输入,VCO 的时钟必须在 1~2M 之间,VCO 输入时钟经过 VCO 倍频因子 N 倍频之后,成为 VCO 时钟输出,VCO 时钟必须在 192~432M 之间。VCO 输出时钟之后有三个分频因子:PLLCLK 分频因子 p,USB OTG FS/RNG/SDIO 时钟分频因子 Q,分频因子 R(F446 才有,F407 没有)。③ 系统时钟 SYSCLK:系统时钟来源可以是:HSI、PLLCLK、HSE,具体的由时钟配置寄存器 RCC_CFGR 的 SW 位配置。如果系统时钟是由 HSE 经过 PLL 倍频之后的 PLLCLK 得到,当 HSE 出现故障的时候,系统时钟会切换为 HSI=16M,直到 HSE 恢复正常为止。
④ AHB 总线时钟 HCLK:系统时钟 SYSCLK 经过 AHB 预分频器分频之后得到时钟叫 AHB 总线时钟,即 HCLK,分频因子可以是:[1,2,4,8,16,64,128,256,512],具体的由时钟配置寄存器 RCC_CFGR 的 HPRE 位设置。
⑤ APB2 总线时钟 PCLK2:APB2 总线时钟 PCLK2 由 HCLK 经过高速 APB2 预分频器得到,分频因子可以是:[1,2,4,8,16],PCLK2 属于高速的总线时钟,片上高速的外设就挂载到这条总线上,比如 USART1、SPI1 等。
⑥ APB1 总线时钟 PCLK1:APB1 总线时钟 PCLK1 由 HCLK 经过低速 APB 预分频器得到,分频因子可以是:[1,2,4,8,16],PCLK1 属于低速的总线时钟,最高为 42M,片上低速的外设就挂载到这条总线上,比如 USART2/3/4/5、SPI2/3,I2C1/2 等。
A RTC 时钟:RTCCLK 时钟源可以是 HSE 1 MHz(HSE 由一个可编程的预分频器分频)、LSE 或者 LSI 时钟。选择方式是编程 RCC 备份域控制寄存器 (RCC_BDCR) 中的 RTCSEL[1:0] 位和 RCC 时钟配置寄存器 (RCC_CFGR) 中的 RTCPRE[4:0] 位。所做的选择只能通过复位备份域的方式修改。我们通常的做法是由 LSE 给 RTC 提供时钟,大小为 32.768KHZ。LSE 由外接的晶体谐振器产生,所配的谐振电容精度要求高,不然很容易不起震。
B 独立看门狗时钟:独立看门狗时钟由内部的低速时钟 LSI 提供,大小为 32KHZ。
C I2S 时钟:I2S 时钟可由外部的时钟引脚 I2S_CKIN 输入,也可由专用的 PLLI2SCLK 提供,具体的由 RCC 时钟配置寄存器 (RCC_CFGR) 的 I2SSCR 位配置。我们在使用 I2S 外设驱动 W8978 的时候,使用的时钟是 PLLI2SCLK,这样就可以省掉一个有源晶振。
D PHY 以太网时钟:F407 要想实现以太网功能,除了有本身内置的 MAC 之外,还需要外接一个 PHY 芯片,常见的 PHY 芯片有 DP83848 和 LAN8720,其中 DP83848 支持 MII 和 RMII 接口,LAN8720 只支持 RMII 接口。使用 RMII 接口的好处是使用的 IO 减少了一半,速度还是跟 MII 接口一样。当使用 RMII 接口时,PHY 芯片只需输出一路时钟给 MCU 即可,如果是 MII 接口,PHY 芯片则需要提供两路时钟给 MCU。
E USB PHY 时钟:F407 的 USB 没有集成 PHY,要想实现 USB 高速传输的话,必须外置 USB PHY 芯片,常用的芯片是 USB3300。当外接 USB PHY 芯片时,PHY 芯片需要给 MCU 提供一个时钟。
F MCO 时钟输出:MCO 是微控制器时钟输出引脚,主要作用是可以对外提供时钟,相当于一个有源晶振。F407 中有两个 MCO,由 PA8/PC9 复用所得。MCO1 所需的时钟源通过 RCC 时钟配置寄存器 (RCC_CFGR) 中的 MCO1PRE[2:0] 和 MCO1[1:0] 位选择。MCO2 所需的时钟源通过 RCC 时钟配置寄存器 (RCC_CFGR) 中的MCO2PRE[2:0] 和 MCO2 位选择。有关 MCO 的 IO、时钟选择和输出速率的具体信息如下表所示:
2 个内部时钟源:
内部时钟源
就是芯片上电即可产生,不需要借助外部电路。
- 高速内部振荡器 HSI:由内部 RC 振荡器产生,频率为 16MHz。芯片上电时默认由内部的 HSI 时钟启动。
- 低速内部振荡器 LSI:由内部 RC 振荡器产生,频率为 32kHz,可作为独立看门狗的时钟源。
2 个外部时钟源:
外部时钟源
就是从外部通过接晶振的方式获取时钟源,故而都有精度高的优点。
- 高速外部振荡器 HSE:外接石英/陶瓷谐振器,频率为 4MHz~26MHz。本开发板使用的是 8MHz。
- 低速外部振荡器 LSE:外接 32.768kHz 石英晶体,主要作用于 RTC 的时钟源。
输入时钟源 产生部件 频率 作用时钟源 系统时钟SYSCLK(最高168MHz) 168MHz 以太网PTP时钟 系统时钟SYSCLK(最高168MHz) 1.设置AHB预分配器 168MHz 1.系统时钟 FCLK
2.AHB总线的HCLK时钟
AHB1:GPIOA-I、CRC、RCC
AHB1:Flash接口寄存器
AHB1:BKPSRAM、DMA1-2
AHB1:以太网MAC、USB OTG HS
AHB2:USB OTG FS、DCMI
AHB2:CRPY、HASH、RNG
系统时钟SYSCLK(最高168MHz) 1.设置AHB预分配器
2. 设置时钟源选择位(默认/1 或 /8)168MHz 系统定时器 SysTick 系统时钟SYSCLK(最高168MHz) 1.设置低速 APB1 预分频器(默认/4)
2.硬件自动设置倍频(默认*2)84MHz APB1:TIM2-7、TIM12-14
系统时钟SYSCLK(最高168MHz) 1.设置低速 APB1 预分频器(默认/4) 42MHz APB1:RTC、BKP寄存器、WWDG、IWDG
APB1:I2S2ext、SPI2/I2S2、SPI3/I2S3、2S3ext
APB1:USART2、USART3、UART4、UART55
APB1:I2C1、I2C2、I2C3、CAN1、CAN2
APB1:PWR、DAC、UART7、UART8
系统时钟SYSCLK(最高168MHz) 1.设置高速 APB2 预分频器(默认/2)
2.硬件自动设置倍频(默认*2)168MHz APB2:TIM1、TIM8-11
系统时钟SYSCLK(最高168MHz) 1.设置高速 APB2 预分频器(默认/2) 84MHz APB2:USART1、USART6、ADC1-3
APB2:SDIO、SPI1、SPI4、SYSCFG
APB2:EXTI、SPI5、SPI6
1.1 时钟配置(寄存器版)
1.2 时钟配置(标准库版)
extern void HSE_SetSysClock(void) { RCC_DeInit(); //RCC外设初始化成复位状态 RCC_HSEConfig(RCC_HSE_ON); //打开HSE 振荡器, 开发板 HSE = 8MHz if( RCC_WaitForHSEStartUp() == SUCCESS) // 等待HSE启动稳定 { // 调压器电压输出级别配置为1,以便在器件为最大频率工作时使性能和功耗实现平衡 RCC->APB1ENR |= RCC_APB1ENR_PWREN; PWR->CR |= PWR_CR_VOS; RCC_HCLKConfig(RCC_SYSCLK_Div1); // HCLK = SYSCLK/1,AHB=168MHz(最大) RCC_PCLK2Config(RCC_HCLK_Div2); // PCLK2 = HCLK /2,APB2=84MHz(最大84MHz) RCC_PCLK1Config(RCC_HCLK_Div4); // PCLK1 = HCLK /4,APB1=42MHz(最大42MHz) //设置PLL来源时钟,设置VCO分频因子m,设置VCO倍频因子n,设置系统时钟分频因子p,设置OTG FS,SDIO,RNG分频因子q RCC_PLLConfig(RCC_PLLSource_HSE, HSE_PLLM, HSE_PLLN, HSE_PLLP, HSE_PLLQ); RCC_PLLCmd(ENABLE); // 使能PLL, 主 PLL 开启 while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) // 等待 PLL 稳定 { } // 配置FLASH预取指,指令缓存,数据缓存和等待状态(CPU时钟周期为5个等待周期) FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_5WS; RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // 当PLL稳定之后,把PLL时钟切换为系统时钟SYSCLK while (RCC_GetSYSCLKSource() != 0x08) // 读取时钟切换状态位,确保PLLCLK被选为系统时钟 { } //启用时钟安全系统(CSSON),检测HSE失效时自动切换回HSI,防止HSE异常导致系统崩溃 RCC_ClockSecuritySystemCmd(ENABLE); } else{ // HSE启动出错处理,使用 HSI 作为时钟源设置时钟 HSI_SetSysClock(); } }
1.3 HSE故障切换和自动恢复
以下方案实现HSE故障检测、自动切换到HSI、以及定时尝试恢复的功能,适用于需要高可靠性的工业控制场景。使用时需根据实际硬件调整晶振频率和分频系数。
2. CM3时钟系统
同 CM4 类似: