一、在STM32中,有五个时钟源,为HSI、HSE、LSI、LSE、PLL。
①HSI是高速内部时钟,RC振荡器,频率为8MHz。
②HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz。
③LSI是低速内部时钟,RC振荡器,频率为40kHz。
④LSE是低速外部时钟,接频率为32.768kHz的石英晶体。
⑤PLL为锁相环倍频输出,其时钟输入源可选择为HSI/2、HSE或者HSE/2。倍频可选择为2~16倍,但是其输出频率最大不得超过72MHz。
二、STM32
1systclk .系统时钟
2 置AHB时钟: HCLK 运用对象 DMA1 DMA2 SRAM CRC FLITF
3 低速AHB时钟:PCLK1 ------APB1时钟 运用对象 CAN1 TIM2 TIM3 TIM4 TIM5 WWDG USART2等等
4 高速AHB时钟:PCLK2 ------APB2时钟 运用对象 GPIOA GPIOB GPIOC GPIOD
三、在STM32上如果不使用外部晶振,OSC_IN和OSC_OUT的接法:如果使用内部RC振荡器而不使用外部晶振,请按照下面方法处理:
①对于100脚或144脚的产品,OSC_IN应接地,OSC_OUT应悬空。
②对于少于100脚的产品,有2种接法:第1种:OSC_IN和OSC_OUT分别通过10K电阻接地。此方法可提高EMC性能;第2种:分别重映射OSC_IN和OSC_OUT至PD0和PD1,再配置PD0和PD1为推挽输出并输出'0'。此方法可以减小功耗并(相对上面)节省2个外部电阻
四、配置历程说明 ( 默认使用8M 外部晶振 , 倍频到72M )
注意 本设置只是挑选 库函数的 主要关键点进行详细说明,详细情况ST库函数
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);//打开 外部时钟 HSE
/* Wait till HSE is ready and if Time out is reached exit */
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_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;
……
/* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |
RCC_CFGR_PLLMULL));
/*RCC_CFGR_PLLSRC :RCC_CFGR_PLLSRC_HSI_Div2 =0 选择 内部时钟作HSI 为PLL 的时钟源
RCC_CFGR_PLLSRC_HSE =1 选择 外部时钟作HSE 为PLL 的时钟源
RCC_CFGR_PLLXTPRE:RCC_CFGR_PLLXTPRE_HSE=0; : HSE 做为PLL 的时钟源
RCC_CFGR_PLLXTPRE_HSE_Div2=1 : HSE/2 做为PLL 的时钟源
RCC_CFGR_PLLMULL :倍频系数
*/
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
/* 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;
}
五、针对外部晶振HSE 不是8M 的情况下,例如16M 倍频到72 M 需要注意一下两点:
1、首先看以下代码的含义:
/* #define SYSCLK_FREQ_HSE HSE_Value */ //定义系统时钟的频率,因为串口波特率,CAN 总线波特率 和定时器定时时间 等多个外设 的详
//细参数 ,还要通过 SYSCLK_FREQ_HSE 这个参数去计算
/* #define SYSCLK_FREQ_24MHz 24000000 */
/* #define SYSCLK_FREQ_36MHz 36000000 */
/* #define SYSCLK_FREQ_48MHz 48000000 */
/* #define SYSCLK_FREQ_56MHz 56000000 */
/* #define SYSCLK_FREQ_72MHz 72000000 */
所以 在配置的时候,要注意,不能单纯地 defined SYSCLK_FREQ_36MHz 就可以了
2.真正地配置方法是 :
(1)在 stm32f10x.h 里面选择系统时钟频率 是1/72M的
#define SYSCLK_FREQ_72MHz 72000000
(2) 然后在 static void SetSysClockTo72(void) 函数里面
将 RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);
改成:RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLXTPRE_HSE_Div2 | RCC_CFGR_PLLMULL9);
(3)一定要找到 (在stm32f10x.h里面) HSE_Value 将其改为外部晶振的16M
#if !defined HSE_Value
#ifdef STM32F10X_CL
#define HSE_Value ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
#else
#define HSE_Value ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
#endif /* STM32F10X_CL */
#endif /* HSE_Value */
#define HSE_Value ((uint32_t)16000000) /*!< Value of the External oscillator in Hz */