你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32库开发实战指南F103 -- 3、RCC-使用HSE/HSI配置时钟

[复制链接]
TLLED 发布时间:2018-12-8 14:43
本帖最后由 TLLED 于 2018-12-8 14:42 编辑

    通过第16章节 -- RCC-使用HSE/HSI配置时钟  的学习来重新认识系统总线和外设时钟的配置。

    一、手册中有关时钟配置的内容


    1.1、系统时钟框图:
         里面显示出STM32芯片所有时钟和有关配置的寄存器位              1.png

   
    二、系统启动有关时钟配置代码


    2.1、系统启动分析
        上篇介绍启动代码分析,会执行Reset Handler服务处理程序。
         100.png
         里面有执行SystemInit系统初始化程序
        
101.png
         102.png
         103.png
       里面调用SetSysClock函数设置系统时钟
       104.png       
       SetSysClock函数配置为72MHz后调用SetSysClockTo72函数
       105.png
       106.png
       107.png

       108.png
        上面是系统上电启动中,系统初始化和系统时钟配置过程,已经把总线时钟配置为72MHz。

   
    三、时钟配置实例


    3.1、配置HSE时钟  
        了解系统时钟配置流程后,来实践使用时钟配置。
        在系统时钟框图中,HSE时钟配置
         109.png
    >选择外部时钟OSC32_IN和OSC32_OUT两个引脚上接的8MHz无源晶振
    >通过PLLXTPRE来选择HSE时钟不分频还是2分频。
    >通过PLLSRC来选择内部时钟HSI和外部时钟HSE时钟选择。
    >通过PLLMUL来选择倍频设置,如系统总线72MHz,晶振频率8M*倍频9=72MHz

    >通过SW来选择时钟源HSI,PLLCLK和HSE时钟源。


    3.2、程序源码
         3.2.1、HSE时钟初始化
         PLL时钟倍频到72MHz
   
  1. static void HSE_SetSysClock(void)
  2. {
  3.   __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  4.   
  5.   RCC_DeInit();                                                                                        //RCC恢复默认状态  
  6.         RCC_HSEConfig(RCC_HSE_ON);                                //打开HSE时钟
  7.        
  8.         HSEStatus=RCC_WaitForHSEStartUp();   //等待HSE时钟稳定

  9.   if (HSEStatus == SUCCESS)
  10.   {
  11.     /* Enable Prefetch Buffer */
  12.                 FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);            //使能FLASH预存取缓冲区
  13.                 FLASH_SetLatency(FLASH_Latency_2);                                                                                               

  14.                 RCC_HCLKConfig(RCC_SYSCLK_Div1);                                                                                                        //AHB - HCLK=SYSCLK
  15.                 RCC_PCLK1Config(RCC_HCLK_Div2);                                                                                                                //APB1 -- PCLK1=HCLK/2
  16.                 RCC_PCLK2Config(RCC_HCLK_Div1);                                                                                                                //APB2 -- PCLK2=HCLK

  17.                 RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);                        //PLL倍频
  18.                 RCC_PLLCmd(ENABLE);                                                                                                                                                                //使能PLL
  19.                        
  20.                 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)                                        //等待PLL稳定
  21.                 {
  22.                 }
  23.                 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);                                                                //PLL稳定后,时钟切换到SYSCLK
  24.                
  25.                
  26.                 while(RCC_GetSYSCLKSource()!=0x08)                                                                                                //读取时钟切换状态位,确保PLLCLK被选为系统时钟
  27.                 {
  28.                 }
  29.   }
  30.   else
  31.   {
  32.   }
  33. }
复制代码
       3.2.2、MCO引脚初始化
  1. //MCO引脚配置
  2. void MCO_GPIO_Config(void)
  3. {
  4.         GPIO_InitTypeDef  GPIO_InitStructure;
  5.        
  6.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);                 //使能PA端口时钟
  7.        
  8.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;                                                                
  9.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                         
  10.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                                 //IO口速度为50MHz
  11.         GPIO_Init(GPIOA, &GPIO_InitStructure);                                                                
  12. }
复制代码
       3.2.3、LED引脚初始化

  1. void LED_GPIO_Config(void)
  2. {
  3.         GPIO_InitTypeDef  GPIO_InitStructure;
  4.        
  5.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);                 //使能PA端口时钟
  6.        
  7.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                                                                
  8.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                         
  9.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                                 //IO口速度为50MHz
  10.         GPIO_Init(GPIOB, &GPIO_InitStructure);       
  11. }
复制代码
       3.2.4、主程序
  1. int main(void)
  2. {
  3.         uint32_t i;
  4.         HSE_SetSysClock();
  5.         MCO_GPIO_Config();
  6.         RCC_MCOConfig(RCC_MCO_SYSCLK);       
  7.         LED_GPIO_Config();       
  8.   while (1)
  9.   {
  10.                
  11.                 for(i=0;i<0xffff;i++);
  12.                 GPIO_SetBits(GPIOB,  GPIO_Pin_9);
  13.                 for(i=0;i<0xffff;i++);
  14.                 GPIO_ResetBits(GPIOB, GPIO_Pin_9);
  15.   }
  16. }
复制代码

    四、程序执行结果


    4.1、PLL时钟设置为72MHz,倍频系数设置为9
        RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);                        //PLL倍频
        4.1.1、MCO输出时钟频率72M
        
F0002TEK.png
        4.1.2、LED引脚输出

         F0003TEK.png

   
4.2、PLL时钟设置为56MHz,倍频系数设置为7        RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_7);                        //PLL倍频
        4.2.1、MCO输出时钟频率56M
         F0005TEK.png
        4.2.2、LED引脚输出
        
F0004TEK.png
        LED输出宽度比72M时钟时,宽度变宽
    4.3、PLL时钟设置为88MHz,倍频系数设置为11        RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_11);                        //PLL倍频
        4.3.1、MCO输出时钟频率88M
         F0006TEK.png
        4.3.2、LED引脚输出
        
F0007TEK.png
        LED输出宽度比72M时钟时,宽度变窄


    五、结论



         使用外部时钟时,通过改变PLL的倍频系统可以改变SYSCLK时钟频率,来降频或超频工作。HSI配置和HSE差不多,就不在列出。








评分

参与人数 1 ST金币 +20 收起 理由
STMCU + 20

查看全部评分

收藏 评论4 发布时间:2018-12-8 14:43

举报

4个回答
STMCU-管管 回答时间:2018-12-10 10:15:27
支持
hhhhhhhaa 回答时间:2020-4-29 15:05:17
您的配置里有这样一句
RCC->CFGR &= (uint32_t)((uint32_t) ~(RCC_CFGR_PLLSRC |RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
这句话是把第16-21位清零
hhhhhhhaa 回答时间:2020-4-29 15:06:54
PLLSRC:PLL输入时钟源 (PLL entry clock source)  位16
由软件置’1’或清’0’来选择PLL输入时钟源。只能在关闭PLL时才能写入此位。
0:HSI振荡器时钟经2分频后作为PLL输入时钟
1:HSE时钟作为PLL输入时钟。
以上是手册里说的
hhhhhhhaa 回答时间:2020-4-29 15:16:47
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE| RCC_CFGR_PLLMULL9);
这句话是不是把相应的位置1 这样就能配置了

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版