STM32F407系统时钟解析

发布者:MysticGlow最新更新时间:2018-10-13 来源: eefocus关键字:STM32F407  系统时钟 手机看文章 扫描二维码
随时随地手机看文章

STM32F407系统时钟解析


STM32F4时钟系统初始化是在system_stm32f4xx.c中的SystemInit()函数中完成的。对于系统时钟关键寄存器设置主要是在SystemInit函数中调用SetSysClock()函数来设置的。我们可以先看看SystemInit()函数体:

//@brief  Setup the microcontroller system

//        Initialize the Embedded Flash Interface, the PLL and update the

//        SystemFrequency variable.

//@param  None

//@retval None

void SystemInit(void)

{

  // FPU settings ------------------------------------------------------------

  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)

    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  // set CP10 and CP11 Full Access

  #endif

 

  // Reset the RCC clock configuration to the default reset state ------------

  // Set HSION bit

  RCC->CR |= (uint32_t)0x00000001;

 

  // Reset CFGR register

  RCC->CFGR = 0x00000000;

 

  // Reset HSEON, CSSON and PLLON bits

  RCC->CR &= (uint32_t)0xFEF6FFFF;

 

  // Reset PLLCFGR register

  RCC->PLLCFGR = 0x24003010;

 

  // Reset HSEBYP bit

  RCC->CR &= (uint32_t)0xFFFBFFFF;

 

  // Disable all interrupts

  RCC->CIR = 0x00000000;

 

#ifdef DATA_IN_ExtSRAM

  SystemInit_ExtMemCtl();

#endif // DATA_IN_ExtSRAM

         

  // Configure the System clock source, PLL Multiplier and Divider factors,

     AHB/APBx prescalers and Flash settings ----------------------------------

  SetSysClock();

 

  // Configure the Vector Table location add offset address ------------------

#ifdef VECT_TAB_SRAM

  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; // Vector Table Relocation in Internal SRAM

#else

  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; // Vector Table Relocation in Internal FLASH

#endif

}

  SystemInit函数开始先进行浮点运算单元设置,然后是复位PLLCFGR,CFGR寄存器,同时通过设置CR寄存器的HSI时钟使能位来打开HSI时钟。默认情况下如果CFGR寄存器复位,那么是选择HSI作为系统时钟,这点大家可以查看RCC->CFGR寄存器的位描述最低2位可以得知,当低两位配置为00的时候(复位之后),会选择HSI振荡器为系统时钟。也就是说,调用SystemInit函数之后,首先是选择HSI作为系统时钟。

在设置完相关寄存器后,接下来SystemInit函数内部会调用SetSysClock函数。这个函数比较长,我们就把函数一些关键代码行截取出来给大家讲解一下。这里我们省略一些宏定义标识符值的判断而直接把针对STM32F407比较重要的内容贴出来:

//@brief  Configures the System clock source, PLL Multiplier and Divider factors,

//        AHB/APBx prescalers and Flash settings

//@Note   This function should be called only once the RCC clock configuration  

//        is reset to the default reset state (done in SystemInit() function).   

//@param  None

//@retval None

static void SetSysClock(void)

{

//////////////////////////////////////////////////////////////////////////

//          PLL (clocked by HSE) used as System clock source            //

//////////////////////////////////////////////////////////////////////////

  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;

  

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

  {

// Select regulator voltage output Scale 1 mode, System frequency up to 168 MHz

    RCC->APB1ENR |= RCC_APB1ENR_PWREN;

    PWR->CR |= PWR_CR_VOS;

 

    // HCLK = SYSCLK / 1 

    RCC->CFGR |= RCC_CFGR_HPRE_DIV1;

      

    // PCLK2 = HCLK / 2 

    RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;

    

    // PCLK1 = HCLK / 4 

    RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;

 

    // Configure the main PLL

    RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |

                   (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);

 

    // Enable the main PLL

    RCC->CR |= RCC_CR_PLLON;

 

    // Wait till the main PLL is ready

    while((RCC->CR & RCC_CR_PLLRDY) == 0)

    {

    }

   

    // Configure Flash prefetch, Instruction cache, Data cache and wait state

    FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;

 

    // Select the main PLL as system clock source

    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));

    RCC->CFGR |= RCC_CFGR_SW_PLL;

 

    // Wait till the main PLL is used as system clock source

    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != 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

  }

}

  这段代码的大致流程是这样的:先使能外部时钟HSE,等待HSE稳定之后,配置AHB,APB1,APB2时钟相关的分频因子,也就是相关外设的时钟。等待这些都配置完成之后,打开主PLL时钟,然后设置主PLL作为系统时钟SYSCLK时钟源。如果HSE不能达到就绪状态(比如外部晶振不能稳定或者没有外部晶振),那么依然会是HSI作为系统时钟。

  在这里要特别提出来,在设置主PLL时钟的时候,会要设置一系列的分频系数和倍频系数参数。大家可以从SetSysClock函数的这行代码看出:

  RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |

          (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);

这些参数是通过宏定义标识符的值来设置的。默认的配置在System_stm32f4xx.c文件开头的地方配置。对于我们开发板,我们的设置参数值如下:

    #define PLL_M      8

    #define PLL_Q      7

    #define PLL_N      336

    #define PLL_P       2

所以我们的主PLL时钟为:

    PLL=8MHz * N/ (M*P)=8MHz* 336/(8*2) = 168MHz

在开发过程中,我们可以通过调整这些值来设置我们的系统时钟。

这里还有个特别需要注意的地方,就是我们还要同步修改stm32f4xx.h中宏定义标识符HSE_VALUE的值为我们的外部时钟:

#if !defined  (HSE_VALUE)

#define HSE_VALUE    ((uint32_t)8000000)  //Value of the External oscillator in Hz

 

#endif   // HSE_VALUE

这里默认固件库配置的是25000000,我们外部时钟为8MHz,所以我们根据我们硬件情况修改为8000000即可。

最后我们总结一下SystemInit()函数中设置的系统时钟大小:

     SYSCLK(系统时钟)             =168MHz

    AHB总线时钟(HCLK=SYSCLK)           =168MHz

    APB1总线时钟(PCLK1=SYSCLK/4)                            =42MHz

    APB2总线时钟(PCLK2=SYSCLK/2)                            =84MHz

    PLL主时钟                  =168MHz


关键字:STM32F407  系统时钟 引用地址:STM32F407系统时钟解析

上一篇:STM32F10x利用定时器测量脉冲宽度
下一篇:stm32f4 DMA任意长度buffer无停顿传输

推荐阅读最新更新时间:2024-03-16 16:16

STM32F407定时器TIM1中断
实验现象:LED灯0.5s闪烁 /**************************************************************************************** *函 数 名:bsp_Inittimer1 *函数功能:初始化定时器1 *形 参:无 *返 回 值:无 *****************************************************************************************/ void bsp_Inittimer1(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseIni
[单片机]
s3c2440系统时钟详解
一、S3C2440系统时钟体系 S3C2440的时钟控制逻辑可以外接晶振,然后通过内部电路产生时钟源;也可以直接使用内部提供的时钟源,他们通过引脚的设置来选择。时钟逻辑给整个芯片提供了3中时钟:FCLK用于CPU核、HCLK用于AHB总线上设备,比如CPU核、存储器控制器、中断控制器、LCD控制器、DMA控制器和USB主机模块等;PCLK用于用于APB总线上的设备,比如看门狗、IIS、I2C、PWM定时器、MMC接口、ADC、UART、GPIO、RTC和SPI等。 AHB(Advanced High performance Bus)系统总线总线主要用于高性能模块(如CPU、DMA和DSP等);APB(Advanced Periph
[单片机]
s3c2440<font color='red'>系统</font><font color='red'>时钟</font>详解
stm32 系统默认时钟问题
今天在看正点原子的程序时,发现程序中没有配置时钟,但是定时器竟然可以用。 刚开始以为是stm32默认时钟选择为72MHz,但是又想到系统时钟是需要代码配置的。 想到可能是在启动文件中系统调用了某些函数,查了一下,果然是这样,在startup_stm32f10x_hd.s文件中,有这么一段 ; Reset handler Reset_Handler PROC EXPORT Reset_Handler IMPORT __main IMPORT SystemInit LDR R0, =SystemInit BLX R0
[单片机]
STM32F407多通道ADC采样程序
注意STM32F407在进行AD采样时,如果引脚是浮空的,这个时候采集到的电压并不是0 1 ADC引脚的初始化 void Lsens_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); //使能GPIOF时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GP
[单片机]
<font color='red'>STM32F407</font>多通道ADC采样程序
STM32F407--GPIO的工作原理
一、参考资料 1、STM32F407ZGT6.pdf(探索者资料盘A7,硬件资料2,芯片资料) 2、STM32F4xx中文参考手册.pdf(探索者资料盘A8,STM32参考资料) 3、STM32F4开发指南-库函数版本_V1.1.pdf(探索者资料盘A) 二、GPIO口的基本结构 三、引脚的说明 注:STM32大部分引脚可以当GPIO口外,还可以复用为外设功能引脚(如串口)。 四、GPIO的工作模式 1、4种输入模式 (1)GPIO_Mode_IN_FLOATING 浮空输入 (2)GPIO_Mode_IPU 上拉输入 (3)GPIO_Mode_IPD 下拉输入 (4)GPIO_Mode_AI
[单片机]
STM32F407--GPIO的工作原理
hi3531的时钟系统
时钟管理模块对芯片时钟输入、时钟生成和控制进行统一的管理,包括: 时钟管理模块有以下两部分输入:
[单片机]
hi3531的<font color='red'>时钟</font><font color='red'>系统</font>
在Keil V5下新建STM32F407工程
1、 建立工程目录 新建一个工程目录,用来存放工程文件,源文件,头文件等,例如在桌面上新建一个名称为My_Project的目录。 2、 建立工程子目录 在步骤1建立的工程文件夹中建立子目录,用来存储工程中用到的不同文件。建立CMSIS、Library、Listing、Output、Project、User六个子目录,如下图所示。 下面来讲一下这六个子目录的作用。 CMSIS目录:用来存放和内核相关的文件 Library目录:用来存放STM32F4 标准外设固件库源码文件和对应的头文件。 Listing目录:用来存放列表文件。 Output目录:用来存放编译过程中产生的中间文件。 Projec
[单片机]
在Keil V5下新建<font color='red'>STM32F407</font>工程
STM32F407玩控制—复合模糊控制
个人觉得,控制理论可以说都是数学,并且是一种专门的数学,或者说是一种应用数学,模糊控制也不例外,它是建立在模糊集合论基础上的,模糊集合可以看成是普通集合的拓展,那什么是集合,对不起,没有定义,集合属于初始概念,是不定义的概念,对不定义概念的理解,可以借助于公理,公理可以看成是初始概念的定义,扯远了,回到集合,那怎么理解集合,集合大致可以看成是有相同属性事物的总和,什么是模糊集合,这么说吧,比如我们描述一个人,其属性可以有美丑、气质,也可以有高矮、胖瘦、年老等等,那颜值究竟有多高,那气质究竟有多好,在模糊集合中就用隶属度来表示,比如,定义一个胖子集合A,大胖子a1,属于A的隶属度为1.0,中胖子a2,属于A的隶属度为0.8,小胖子a
[单片机]
用<font color='red'>STM32F407</font>玩控制—复合模糊控制
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved