stm32f103晶振调试总结

最近也是无意间拿到一块焊错了25M晶振的stm32f103晶振的板子来调试。在此总结一下,stm32f103和stm32f103修改外部晶振的学习过程。

cl:互联型产品,stm32f105/107系列

xl:超高密度产品,stm32f101/103系列

从代码看起来,在stm32f10x.h中,

#if !defined  HSE_VALUE
 #ifdef STM32F10X_CL           //STM32F105/107互联性
  #define HSE_VALUE    ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
 #else                         //其他的,stm32f103也包括其中
  #define HSE_VALUE    ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
 #endif /* STM32F10X_CL */
#endif /* HSE_VALUE */

由于板子焊接的是25M晶振,所以将 #define HSE_VALUE    ((uint32_t)8000000)  改为 #define HSE_VALUE    ((uint32_t)25000000)。

打开system_stm32f10x.c文件,

#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
/* #define SYSCLK_FREQ_HSE    HSE_VALUE */
 #define SYSCLK_FREQ_24MHz  24000000
#else
/* #define SYSCLK_FREQ_HSE    HSE_VALUE */
/* #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
#endif

默认为72Mhz,不用修改。

再找到倍频函数    static void SetSysClockTo72(void)中。

#ifdef STM32F10X_CL            //stm32f105或者stm32f107互联性的倍频函数设置
    /* 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                        //stm32f103的倍频函数设置   
    /*  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 */

在stm32f103的倍频函数设置和stm32f105的倍频函数设置这里对比,才发现!!!stm32f103这里的倍频函数中里面没有分频的设置。也就是25M的外部晶振倍频个3,是75M。是最接近72M的了,所以决定先测试一下,看看是否行得通。

之后调试了串口打印和滴答时钟。在串口打印效果来看,是可以使用的。

但是在滴答时钟定时了100ms,调试现象发现是滴答时钟实际变成了900多ms。所以,滴答时钟测试结果反映出了问题。

在查询了资料后发现,stm32f103默认的外部晶振范围是4~16M。由于25M的外部晶振,超出了。滴答时钟当外部晶振出问题时,不能使用会转换为HSI(内部高速晶振8M)。原因就出在了这里。

再返回来看一下滴答时钟的配置函数就可以发现原因。

void SysTick_Init(void)
{
    //这里的SystemCoreClock 是定义的72M
	if (SysTick_Config(SystemCoreClock / 100000))	
	{ 
		/* Capture error */ 
		while (1);
	}
    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_MSK;
}

SysTick_Config(SystemCoreClock / 100000)函数,其中也就是将SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; 计数了100000次。那滴答的时间就应该是{(SystemCoreClock / 100000)*(1 / f)}。滴答时钟本来是使用外部晶振作用的,经过倍频之后应该是72M,正确的定时时间应该是{72M / 100000*(1 / 72M)} =1 / 100000s。但是现在外部晶振异常,转换成使用了HSI(8M)。那实际上是{(72M / 100000)*(1 / 8M) } = 9 / 100000s。

现在就清楚了,滴答实际的定时时间是设置的9倍,所以就出现了调试中滴答定时100ms,却在900多ms才触发的现象。

猜你喜欢

转载自blog.csdn.net/Strange_Gu/article/details/86541127