文章目录
1. 复位
STM32F10xxx支持三种复位模式,分别是:系统复位、上电复位、备份区域复位。
1.1 系统复位
请查阅参考手册
1.2 上电复位
请查阅参考手册
1.3 备份区域复位
请查阅参考手册
2. 时钟树
2.1 HSE时钟
High Speed External Clock signal,高速的外部时钟,一般来自无源晶振(4-16MHz),通常使用8MHz,利用RCC_CR时钟控制寄存器的位16:HSEON控制。通过PLL倍频至72MHz使用。
2.2 HSI时钟
Low Speed Internal Clock signal,高速的内部时钟,内部8MHz时钟,精度较小,受温度影响较大。当HSE故障时,系统时钟会自动切换到HSI,直到HSE启动成功,利用RCC_CR时钟控制寄存器的位0:HSION控制。
2.3 锁相环时钟 PLLCLK
经过HSI/2、HSE倍频所得,利用CFGR寄存器的:PLLXTPRE、PLLMUL控制,
注意:PLL时钟源头使用HSI/2时,PLLMUL最大只能是16,这时PLLCLK最大只有64MHz,小于ST官方推荐的最大时钟72MHz。
2.4 系统时钟 SYSCLK
锁相环时钟最高为72MHz,来源有HSI、HSE、PLLCLK,通过CFGR寄存器的SW为控制。注意:通常的配置是SYSCLK=PLLCLK=72MHz。
2.5 AHB总线时钟 HCLK
Advanced High-performance Bus,来自系统时钟的分频,一般设置为HCLK=SYSCLK=72MHz。通过CFGR的HPRE控制。AHB高速总线时钟,速度最高为72MHz,为AHB总线外设提供时钟、为Cortex系统定时器提供时钟(SysTick)、为内核提供时钟(FCLK)。
2.6 APB1总线时钟 PCLK1
APB1低速总线时钟,最高36MHz,为APB1总线的外设提供时钟,2倍频之后则为APB1总线的定时器2-7提供时钟,最大为72MHz。经过HCLK分频获得,一般配置为PCLK1=HCLK/2=36MHz,通过RCC_CFGR寄存器的PPRE1位控制。
2.7 APB2总线时钟 PCLK2
APB2高速总线时钟,最高72MHz,为APB2总线的外设提供时钟,2倍频之后则为APB2总线的定时器1和8提供时钟,最大为72MHz。经过HCLK分频获得,一般配置为PCLK1=HCLK=72MHz,通过RCC_CFGR寄存器的PPRE2位控制。
2.8 RTC时钟 (实时时钟)
为芯片内部的RTC外设提供时钟,一般来自HSE_RTC(HSE分频得到)、LSE(外部32.768KHz的晶体提供)、LSI(32KHz),通过RCC备份域控制寄存器RCC_BDCR的RTCSEL位控制。
独立看门狗时钟:IWDGCLK,由LSI提供
2.9 MCO时钟输出
microcontroller clock output,微控制器时钟输出引脚,由GPIO_PA8复用所得。来自PLLCLK/2、HSE、HSI、SYSCLK,通过CFGR的MCO位控制。
2.10 时钟安全系统 (CSS)
时钟安全系统可以通过软件被激活。一旦其被激活,时钟监测器将在HSE振荡器启动延迟后被使能,并在HSE时钟关闭后关闭。如果HSE时钟发生故障, HSE振荡器被自动关闭,时钟失效事件将被送到高级定时器(TIM1和TIM8)的刹车输入端,并产生时钟安全中断CSSI,允许软件完成营救操作。此CSSI中断连接到Cortex™-M3的NMI中断(不可屏蔽中断)。
注意: 一旦CSS被激活,并且HSE时钟出现故障, CSS中断就产生,并且NMI也自动产生。 NMI将被不断执行,直到CSS中断挂起位被清除。因此,在NMI的处理程序中必须通过设置时钟中断寄存器(RCC_CIR)里的CSSC位来清除CSS中断。如果HSE振荡器被直接或间接地作为系统时钟, (间接的意思是:它被作为PLL输入时钟,并且PLL时钟被作为系统时钟),时钟故障将导致系统时钟自动切换到HSI振荡器,同时外部HSE振荡器被关闭。在时钟失效时,如果HSE振荡器时钟(被分频或未被分频)是用作系统时钟的PLL的输入时钟, PLL也将被关闭。
3. 时钟配置
参考手册
中相关寄存器进行时钟配置,
3.1 相关寄存器描述
时钟配置寄存器在STM32上的基地址为:0x40021000
3.1.1 时钟控制寄存器 (RCC_CR)
3.1.2 时钟配置寄存器(RCC_CFGR)
3.1.3 时钟中断寄存器(RCC_CIR)
3.1.4 APB2外设复位寄存器(RCC_APB2RSTR)
3.1.5 APB1外设复位寄存器(RCC_APB1RSTR)
3.1.6 AHB外设时钟使能寄存器(RCC_AHBENR)
3.1.7 APB2外设时钟使能寄存器(RCC_APB2ENR)
3.1.8 APB1外设时钟使能寄存器(RCC_APB1ENR)
3.1.9 备份域控制寄存器 (RCC_BDCR)
3.1.10 控制/状态寄存器(RCC_CSR)
3.1.11 闪存访问控制寄存器 FLASH_ACR
3.2 配置例程代码
// 固件库时钟配置例程如下
static void SetSysClockTo72(void)
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
/* Enable HSE */
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
/* Wait till HSE is ready and if Time out is reached exit */
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if ((RCC->CR & RCC_CR_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
}
if (HSEStatus == (uint32_t)0x01)
{
/* Enable Prefetch Buffer */
FLASH->ACR |= FLASH_ACR_PRFTBE;
/* Flash 2 wait state */
FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;
/* HCLK = SYSCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
/* PCLK1 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
#ifdef STM32F10X_CL
/* Configure PLLs ------------------------------------------------------*/
/* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
/* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */
RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);
/* Enable PLL2 */
RCC->CR |= RCC_CR_PLL2ON;
/* Wait till PLL2 is ready */
while((RCC->CR & RCC_CR_PLL2RDY) == 0)
{
}
/* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */
RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 |
RCC_CFGR_PLLMULL9);
#else
/* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
RCC_CFGR_PLLMULL));
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
#endif /* STM32F10X_CL */
/* Enable PLL */
RCC->CR |= RCC_CR_PLLON;
/* Wait till PLL is ready */
while((RCC->CR & RCC_CR_PLLRDY) == 0)
{
}
/* Select PLL as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
/* Wait till PLL is used as system clock source */
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
{
}
}
else
{ /* If HSE fails to start-up, the application will have wrong clock
configuration. User can add here some code to deal with this error */
}
}
__IO 表示防止编译器优化,使每次读取都去寄存器去读取。