天天看點

STM32_時鐘複位? 使用者選擇位元組的進一步資訊,請參考STM32F10xxx閃存程式設計手冊。時鐘樹簡圖代碼學習

STM32時鐘學習

  • 複位
    • 程式設計控制系統複位
  • ? 使用者選擇位元組的進一步資訊,請參考STM32F10xxx閃存程式設計手冊。
  • 時鐘樹簡圖
    • 實際的寄存器操作
      • (1)對RCC_CR寄存器進行設定
      • (2)時鐘配置寄存器(RCC_CFGR)
      • (3)RCC PLL configuration register (RCC_PLLCFGR)
      • (4)RCC clock interrupt register (RCC_CIR)
      • (5)RCC AHB1 peripheral reset register (RCC_AHB1RSTR)複位
      • (6)RCC AHB1 peripheral clock register (RCC_AHB1ENR)使能
      • (7)備份域控制寄存器 (RCC_BDCR)
  • 代碼學習

f(VCO clock) = f(PLL clock input) × (PLLN / PLLM)

f(PLL general clock output) = f(VCO clock) / PLLP

f(USB OTG FS, SDIO, RNG clock output) = f(VCO clock) / PLLQ

PLLN with 192 ≤ PLLN ≤ 432

PLLM with 2 ≤ PLLM ≤ 63

PLLP = 2, 4, 6, or 8

4 <= PLLQ <= 15

複位

支援三種複位形式,分别為系統複位、上電複位和備份區域複位。

電源複位:除了備份區域外的所有寄存器

系統複位:除了時鐘控制器的RCC_CSR寄存器中的複位标志位和備份區域中的寄存器以外的所有寄存器

備份區域複位:隻影響備份區域

産生電源複位的事件:

  1. 上電/掉電複位(POR/PDR複位)
  2. 從待機模式中傳回

産生備份區域複位的事件:

  1. 軟體複位,備份區域複位可由設定備份域控制寄存器 (RCC_BDCR)中的BDRST位産生。
  2. 在VDD和VBAT兩者掉電的前提下,VDD或VBAT上電将引發備份區域複位

産生一個系統複位的事件:

  1. NRST引腳上的低電平(外部複位)
  2. 視窗看門狗計數終止(WWDG複位)
  3. 獨立看門狗計數終止(IWDG複位)
  4. 軟體複位(SW複位)
  5. 低功耗管理複位

程式設計控制系統複位

我們所能控制的隻有系統複位

(1)可通過檢視RCC_CSR控制狀态寄存器中的複位狀态标志位識别複位事件來源。

(2)軟體的方式進行系統複位:通過将Cortex™-M3中斷應用和複位控制寄存器中的SYSRESETREQ位置’1’

(3)低功耗管理複位

在以下兩種情況下可産生低功耗管理複位:

在進入待機模式時産生低功耗管理複位:

通過将使用者選擇位元組中的nRST_STDBY位置’1’将使能該複位。這時,即使執行了進入待

機模式的過程,系統将被複位而不是進入待機模式。

在進入停止模式時産生低功耗管理複位:

通過将使用者選擇位元組中的nRST_STOP位置’1’将使能該複位。這時,即使執行了進入停機

模式的過程,系統将被複位而不是進入停機模式。

? 使用者選擇位元組的進一步資訊,請參考STM32F10xxx閃存程式設計手冊。

時鐘樹簡圖

STM32為了低功耗,将所有的外設時鐘都設定為disable。使用外設,需要打開對應時鐘。

看圖了解時鐘源—>系統時鐘來源—>各個外設時鐘

STM32_時鐘複位? 使用者選擇位元組的進一步資訊,請參考STM32F10xxx閃存程式設計手冊。時鐘樹簡圖代碼學習

三種不同的時鐘源可被用來驅動系統時鐘(SYSCLK): HSI振蕩器時鐘、 HSE振蕩器時鐘、 PLL時鐘(内部PLL可以用來倍頻HSI RC的輸出時鐘或HSE晶體輸出時鐘)。

這些裝置有40kHz低速内部RC、32.768kHz低速外部晶體2種二級時鐘源,當不被使用時,任一個時鐘源都可被獨立地啟動或關閉,由此優化系統功耗。

實際的寄存器操作

(1)對RCC_CR寄存器進行設定

Reset value: 0x0000 XX83 where X is undefined.

STM32_時鐘複位? 使用者選擇位元組的進一步資訊,請參考STM32F10xxx閃存程式設計手冊。時鐘樹簡圖代碼學習

STM32F207支援一種專用的PLL(PLLI2S),用于在I2S接口上生成精确的時鐘,以實作高品質的音頻性能。

(2)時鐘配置寄存器(RCC_CFGR)

Reset value: 0x0000 0000

STM32_時鐘複位? 使用者選擇位元組的進一步資訊,請參考STM32F10xxx閃存程式設計手冊。時鐘樹簡圖代碼學習

(3)RCC PLL configuration register (RCC_PLLCFGR)

Address offset: 0x04

Reset value: 0x24003010

該寄存器用于根據公式配置鎖相環時鐘輸出

(4)RCC clock interrupt register (RCC_CIR)

(5)RCC AHB1 peripheral reset register (RCC_AHB1RSTR)複位

STM32_時鐘複位? 使用者選擇位元組的進一步資訊,請參考STM32F10xxx閃存程式設計手冊。時鐘樹簡圖代碼學習

(6)RCC AHB1 peripheral clock register (RCC_AHB1ENR)使能

當外設時鐘沒有啟用時,軟體不能讀出外設寄存器的數值,傳回的數值始終是0x0。

(7)備份域控制寄存器 (RCC_BDCR)

代碼學習

沒有打開任何外設時鐘的代碼學習

或操作開,與操作關

開HSI

關HSE、CSS、PLL

關HSEBYP

開HSE

不同應用下,時鐘頻率的選擇和使用過程中出現誤差的一個校準(配置對應寄存器)

系統複位後,HSI振蕩器被選為系統時鐘。當時鐘源被直接或通過PLL間接作為系統時鐘時,它将不能被停止。隻有當目标時鐘源準備就緒了(經過啟動穩定階段的延遲或PLL穩定),從一個時鐘源到另一個時鐘源的切換才會發生。在被選擇時鐘源沒有就緒時,系統時鐘的切換不會發生。直至目标時鐘源就緒,才發生切換。在時鐘控制寄存器(RCC_CR)裡的狀态位訓示哪個時鐘已經準備好了,哪個時鐘目前被用作系統時鐘。通過設定備份域控制寄存器(RCC_BDCR)裡的RTCSEL[1:0]位,RTCCLK時鐘源可以由HSE/128、LSE或LSI時鐘提供。除非備份域複位,此選擇不能被改變。

/*********************************系統初始化*************************************/
	/*            PLL (clocked by HSE) used as System clock source                */
  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  /* 其他不變,HSION=1 */
	RCC->CR |= (uint32_t)0x00000001;
  /* Reset CFGR register */
  RCC->CFGR = 0x00000000;
  /* 其他不變,HSEON, CSSON, PLL OFF*/
  RCC->CR &= (uint32_t)0xFEF6FFFF;
  /* Reset PLLCFGR register */
  RCC->PLLCFGR = 0x24003010;
  /*  其他不變,HSEBYP off */
  RCC->CR &= (uint32_t)0xFFFBFFFF;
  /* Disable all interrupts */
  RCC->CIR = 0x00000000;
  /* 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)
  {
    /* 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_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;

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