stm32在外部32mhz晶振下的时钟配置方法-皇冠最新app版本

×
单片机 > 单片机程序设计 > 详情

stm32在外部32mhz晶振下的时钟配置方法

发布时间:2024-07-29 发布时间:
|

1. 硬件平台


本例程使用的是 stm32f302rdt6 芯片,其时钟配置方法在其它st单片机中也类似。

2. 实验目的


使用外部 32mhz 晶振配置系统时钟为 72mhz。

3. 配置原理


根据stm32f302rd芯片的参考手册,可以查看该芯片的时钟树结构,这里我们配置系统时钟 sysclk 为72mhz,所以这里只需要修改 prediv 的分频值为4分频,其它 pll 倍频等配置和使用8mhz外部晶振时配置相同。 

这里写图片描述

4. 修改配置

(1)打开工程里的 system_stm32f30x.c 文件,找到 setsysclock() 函数,进行时钟配置修改。这里我们只需要将外部时钟四分频后得到8mhz的时钟,所示我们只需要添加 rcc->cfgr2 |= (uint32_t)rcc_cfgr2_prediv1_div4;来实现时钟的分频。

static void setsysclock(void)

{

  __io uint32_t startupcounter = 0, hsestatus = 0;


/******************************************************************************/

/*            pll (clocked by hse) used as system clock source                */

/******************************************************************************/


  /* 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 and set flash latency */

    flash->acr = flash_acr_prftbe | (uint32_t)flash_acr_latency_1;


     /* hclk = sysclk / 1 */

     rcc->cfgr |= (uint32_t)rcc_cfgr_hpre_div1;


     /* pclk2 = hclk / 1 */

     rcc->cfgr |= (uint32_t)rcc_cfgr_ppre2_div1;


     /* pclk1 = hclk / 2 */

     rcc->cfgr |= (uint32_t)rcc_cfgr_ppre1_div2;


    /* pll configuration */

    rcc->cfgr &= (uint32_t)((uint32_t)~(rcc_cfgr_pllsrc | rcc_cfgr_pllxtpre | rcc_cfgr_pllmull));

    rcc->cfgr |= (uint32_t)(rcc_cfgr_pllsrc_prediv1 | rcc_cfgr_pllxtpre_prediv1 | rcc_cfgr_pllmull9);


    /*!< prediv1 input clock divided by 4 */  

    rcc->cfgr2 |= (uint32_t)rcc_cfgr2_prediv1_div4;     // add. by zhixiaoxing


    /* 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)rcc_cfgr_sws_pll)

    {

    }

  }

  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 */

  }

}


(2)全局搜索 hse_value 空定义,在 stm32f30x.h 文件中,这里我们将外部晶振时钟修改为 32000000 hz


#if !defined  (hse_value) 

#define hse_value            ((uint32_t)32000000) /*!< value of the external oscillator in hz */

#endif /* hse_value */


5. 查看总线时钟


在对stm32时钟进行配置后,为了进一步验证配置的正确性,我们可以使用仿真来查看系统各总线的时钟频率。首先在主函数中添加如下代码:


int main(void)

{

    rcc_clockstypedef get_rcc_clock;    

    rcc_getclocksfreq(&get_rcc_clock); // 获取系统时钟配置

}

通过仿真可以查看各总线时钟的配置频率,如下图所示: 
这里写图片描述 
note:注意一定要修改宏 #define hse_value ((uint32_t)32000000) /!< value of the external oscillator in hz /的值,因为时钟使用该宏定义进行计算。

5. 慎入此坑


在时钟配置时,需要注意的一些问题: 

(1)在时钟树任何一个倍频的环节都不能超频,即使后面分频系数较大,还是会导致时钟配置失败; 

(2)在配置外部晶振四分频时,发现了一个诡异的问题,cfgr2寄存器一定要在cfgr寄存器之后,否则会导致cgfr2寄存器的值与配置的不符,至今不明其诡异之处?


/* pll configuration */

rcc->cfgr &= (uint32_t)((uint32_t)~(rcc_cfgr_pllsrc | rcc_cfgr_pllxtpre | rcc_cfgr_pllmull));

rcc->cfgr |= (uint32_t)(rcc_cfgr_pllsrc_prediv1 | rcc_cfgr_pllxtpre_prediv1 | rcc_cfgr_pllmull9);


/*!< prediv1 input clock divided by 4 */  

rcc->cfgr2 |= (uint32_t)rcc_cfgr2_prediv1_div4;     // add. by zhixiaoxing




『本文转载自网络,皇冠最新app版本的版权归原作者所有,如有侵权请联系删除』

热门文章 更多
stm32问题记录:这回keil编译器背锅
网站地图