怡春院2017,日韩av网页,717韩国三级理伦电影,欧美久草网,亚洲欧美日韩综合,一级特黄色片子

您現在的位置: 主頁 > 技術分享 > 硬件知識 > MCU & ARM

STM32時鐘初始化函數SystemInit()詳解

 
關于SystemInit()函數實現了哪些功能,下面進行介紹:使用的是3.5的庫,用的是STM32F107VC,開發環境RVMDK4.23
已經定義了STM32F10X_CL,SYSCLK_FREQ_72MHz
函數調用順序:
startup_stm32f10x_cl.s(啟動文件) → SystemInit() →  SetSysClock () → SetSysClockTo72()
初始化時鐘用到的RCC寄存器復位值:
RCC_CR = 0x0000 xx83; RCC_CFGR = 0x0000 0000;RCC_CIR = 0x0000 0000; RCC_CFGR2 = 0x0000 0000;
SystemInit()
在調用 SetSysClock()之前RCC寄存器的值如下(都是一些與運算,或運算,在此就不贅述了):
RCC->CR = 0x0000 0083;內、外部高速時鐘的選擇使能、就緒標志
RCC->CIR = 0x00FF0000; LSI、LSE、HIS、HSE、PLL就緒中斷標志
RCC->CFGR2 = 0x00000000;系統時鐘源切換及狀態
***于這些寄存器都代表著什么意思,詳見芯片資料RCC寄存器,該文重點不在此處;
SetSysClock()函數如下
static void SetSysClock(void)
{
#ifdef SYSCLK_FREQ_HSE
  SetSysClockToHSE();
#elif defined SYSCLK_FREQ_24MHz
  SetSysClockTo24();
#elif defined SYSCLK_FREQ_36MHz
  SetSysClockTo36();
#elif defined SYSCLK_FREQ_48MHz
  SetSysClockTo48();
#elif defined SYSCLK_FREQ_56MHz
  SetSysClockTo56();  
#elif defined SYSCLK_FREQ_72MHz
//我的定義的是SYSCLK_FREQ_72MHz,所以調用SetSysClockTo72()
  SetSysClockTo72();
#endif
}
SetSysClockTo72()函數如下:
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);1、使能外部晶振
  /* 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 */
    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;    
一、先設AHB APB1 AHB2分頻寄存器RCC->CFGR  
    /* HCLK = SYSCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;2、系統時鐘不分頻作為AHB頻率所以AHB等于SYSCLK頻率0xxx: system clock not divided   Bits 7:4 HPRE: AHB prescaler:Set and cleared by software to control AHB clock division factor.
      
    /* PCLK2 = HCLK/2 */
    RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;3、AHB時鐘2分頻作為高速APB2時鐘故APB2=(AHB=SYSCLK)/2
PPRE2: APB high-speed prescaler (APB2)
Set and cleared by software to control APB high-speed clock division factor.
0xx: AHB clock not divided
    
    /* PCLK1 = HCLK */
    RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;4、AHB時鐘4分頻作為低速APB1時鐘故APB1=(APB2=AHB=SYSCLK)/4,所以定時器2~7時鐘為2倍APB1,為60M--參加文章:
STM32中定時器的時鐘源
 
PPRE1: APB Low speed prescaler (APB1)
Set and cleared by software to control APB low-speed clock division factor.
100: AHB clock divided by 2
#ifdef STM32F10X_CL
二、配置PLL2時鐘頻率
    /* Configure PLLs ------------------------------------------------------*/
    /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
    /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */
    /* Configure the main PLL */
    RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |
                   (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);5、所以PLL時鐘=8M/8*240/2=120M SYSCLK=AHB=120M,PLL時鐘=8M/8*240/2=120M,APB2=60M,APB1=30M(upt項目時鐘)
RCC_PLLCFGR_PLLSRC_HSE:
Bit 22 PLLSRC: Main PLL(PLL) and audio PLL (PLLI2S) entry clock source
1: HSE oscillator clock selected as PLL and PLLI2S clock entry
 
Bits 17:16 PLLP: Main PLL (PLL) division factor for main system clock
PLL output clock frequency = VCO frequency / PLLP with PLLP = 2, 4, 6, or 8
00: PLLP = 2
f(PLL general clock output) = f(VCO clock) / PLLP,
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define PLL_M      8   
#define PLL_N      240  
#define PLL_P      2   
 
/* USB OTG FS, SDIO and RNG Clock =  PLL_VCO / PLLQ */
#define PLL_Q      5
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /* Enable the main PLL */
    RCC->CR |= RCC_CR_PLLON; 6、使能PLL時鐘
Bit 24 PLLON: Main PLL (PLL) enable
Set and cleared by software to enable PLL.
    /* 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_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_3WS;
 
    /* Select the main PLL as system clock source */
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
    RCC->CFGR |= RCC_CFGR_SW_PLL;7、將PLL作為系統時鐘
Bits 1:0 SW: System clock switch
Set and cleared by software to select the system clock source.
Set by hardware to force the HSI selection when leaving the Stop or Standby mode or in
case of failure of the HSE oscillator used directly or indirectly as the system clock.
00: HSI oscillator selected as system clock
01: HSE oscillator selected as system clock
10: PLL selected as system clock
11: not allowed
    /* Wait till the main PLL is used as system clock source */
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
    {
    }
 
 
1:AHB, APB1,APB2時鐘確定
//HCLK = SYSCLK ,從下面的分析可以得出SYSCLK是使用PLLCLK時鐘的,也就是72MHZ(***于72MHZ如何得來,請看下面分析)
   //那么就是HCLK(AHB總線時鐘)=PLLCLK = 72MHZ    
    //AHB總線時鐘等于系統時鐘SYSCLK,也就是 AHB時鐘 = HCLK = SYSCLK = 72MHZ
   /* HCLK = SYSCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
 
   //PLCK2等于HCLK一分頻, 所以PCLK2 = HCLK,HCLK = 72MHZ, 那么PLCK2(APB2總線時鐘) = 72MHZ   
   //APB2總線時鐘等于HCLK的一分頻,也就是不分頻;APB2 時鐘 = HCLK = SYSCLK = 72MHZ 
    /* PCLK2 = HCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
 
    //PCLK1 = HCLK / 2;PCLK1 等于HCLK時鐘的二分頻,那么PCLK1(APB1) = 72MHZ / 2 = 36MHZ    
    //APB1總線時鐘等于HCLK的二分頻,也就是 APB1時鐘= HCLK / 2 = 36MHZ
    /* PCLK1 = HCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
 
2:如何得出SYSCLK(系統時鐘)為72MHZ(外部晶振25MHZ)
//記得參考英文芯片資料的時鐘樹P115頁和RCC時鐘寄存器進行理解
RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);
 
RCC_CFGR2_PREDIV2_DIV5:  PREDIV2 = 5; 5分頻
          也就是PREDIV2對輸入的外部時鐘 5分頻,那么PLL2和PLL3沒有倍頻前是25 /5 = 5MHZ
RCC_CFGR2_PLL2MUL8  : PLL2MUL = 8; 8倍頻  
          8倍頻后,PLL2時鐘 = 5 * 8 = 40MHZ; 因此 PLL2CLK = 40MHZ
RCC_CFGR2_PREDIV1SRC_PLL2 : RCC_CFGR2的第16位為1, 選擇PLL2CLK 作為PREDIV1的時鐘源
RCC_CFGR2_PREDIV1_DIV5:PREDIV1 = 5;PREDIV1對輸入時鐘5分頻 PREDIV1CLK = PLL2CLK / 5 = 8MHZ
 
以上是對RCC_CFGR2進行的配置
--------------------------------------------------------------------------------------
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | 
 RCC_CFGR_PLLMULL9); 
 
RCC_CFGR_PLLXTPRE_PREDIV1 :操作的是RCC_CFGR的第17位PLLXTPRE,操作這一位和操作RCC_CFGR2寄存器的
位[3:0]中的**位是相同的效果  
RCC_CFGR_PLLSRC_PREDIV1 :選擇PREDIV1輸出作為PLL輸入時鐘;PREDIV1CLK = 8MHZ,所以輸入給PLL倍頻的
時鐘源是8MHZ
RCC_CFGR_PLLMULL9 :PLLMUL = 9;PLL倍頻系數為9,也就是對 PLLCLK = PREDIV1CLK * 8 = 72MHZ
 
以上是對RCC_CFGR進行的配置
---------------------------------------------------------------------------------------------------
 
 RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;   //選擇PLLCLK作為系統時鐘源 
 
--------------------------------------------------------------------------------------------------
***此基本配置已經完成,配置的時鐘如下所述:
SYSCLK(系統時鐘) = 72MHZ
AHB總線時鐘   = 72MHZ
APB1總線時鐘  = 36MHZ
APB2總線時鐘  = 72MHZ
PLL時鐘   = 72MHZ
PLL2時鐘  = 40MHZ

版權*轉載申明:
本站內容為本站編輯或整理,所以轉載務必通知本站并以超鏈接形式注明內容來自本站,以免帶來不必要麻煩。文章出處:http://www.360doc.com/content/17/0905/13/6973384_684731817.shtml
 

?