RCC—使用HSE配置系統時鐘

RCC—使用HSE配置系統時鐘

芯片提供時鐘就要有時鐘樹
時鐘樹在參考手冊RCC章節開頭就有(這裏的時鐘樹看到感覺眼睛打了馬賽克,小弟截圖技術有限)
在這裏插入圖片描述

什麼是晶振?

晶振:晶體振盪器,用於各種電路中產生振盪頻率,每個單片機裏都會有晶振,給單片機提供時鐘頻率,振盪得越快,時鐘頻率就越高,單片機運行的速度就越快

解析時鐘樹的方法:(系統時鐘)

  1. 時鐘是由晶振提供的,首先要找到時鐘的入口點。圖中OSC_IN 和 OSC_OUT,這兩個是外部晶振的引腳,所以時鐘是從這裏進入的。接有源晶振時,時鐘從OSC_IN進入,OSC_OUT懸空。接無源晶振時,時鐘從OSC_IN 和 OSC_OUT一起進入
  2. 時鐘進入以後會經過PLL鎖相環,進入前會經過一個M分頻,進入PLL鎖相環之後就會進入N倍頻,輸出時經過一個P分頻,輸出的時鐘爲PLLCLK
  3. 可以選擇PLLCLK、HSE、HIS作爲系統時鐘
  4. 然後經過AHB總線的分頻因子,成爲HCLK作爲AHB總線的時鐘,或者再經過APB的分頻因子作爲APB1、APB2總線的時鐘(根據參考手冊AHB總線頻率最大爲180MHZ 、高速APB2總線頻率最大爲90MHZ 低速APB1總線頻率最大爲45MHZ)
    上述分析的是時鐘樹的系統時鐘,還有其他時鐘RTC實時時鐘、看門狗時鐘、I2S時鐘、以太網時鐘、MCO輸出時鐘,這些等需要用到的時鐘看吧

下面用固件庫編寫使用HSE配置系統時鐘函數

(HSI也是同樣的思路)

  1. 啓動HSE,在頭文件尋找HSE啓動的函數void RCC_HSEConfig(uint8_t RCC_HSE)
  2. 等待HSE穩定ErrorStatus RCC_WaitForHSEStartUp(void)
    這個函數是如何實現的:在這個函數中還調用了函數
    FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG)
    那先講解這個函數是如何實現的:這個函數的功能是檢查是否設置了指定的RCC標誌。RCC的標誌(RCC_FLAG)都會有自己的值,首先檢查參數,然後得到RCC寄存器的位號(根據RCC的標誌確定在RCC的哪個寄存器裏),最後獲得RCC寄存器的位置判斷是否設置了指定的參數,然後返回值,如果設置了返回1,否返回0
    判斷HSE是否準備好,如果是返回1,否返回0
  3. 設置HCLK、APB1、APB2預分頻因子
    void RCC_HCLKConfig(uint32_t RCC_SYSCLK)
    void RCC_PCLK1Config(uint32_t RCC_HCLK)
    void RCC_PCLK2Config(uint32_t RCC_HCLK)
  4. 設置進入PLL鎖相環的M分頻因子 PLL鎖相環的N倍頻因子 出PLL鎖相環的P分頻因子 void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ)控制系統時鐘的頻率就在於這幾個分頻因子
  5. 啓動PLL void RCC_PLLCmd(FunctionalState NewState)
    等待PLL穩定 使用了FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG)把RCC_FLAG設爲RCC_FLAG_PLLRDY,若準備好返回1
  6. 設置PLLCLK爲系統時鐘void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource)
  7. 讀取狀態位確保PLLCLK被選中爲系統時鐘
    uint8_t RCC_GetSYSCLKSource(void)//該函數功能:返回時鐘源用作系統時鐘
    若返回數值爲PLLCLK數值,則PLLCLK被選爲系統時鐘

代碼如下

函數的形參根據函數中需要傳入的數據所設定

		void HSE_SetSysclk ( uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ)
			{
			    RCC_HSEConfig(RCC_HSE_ON);
			    if(RCC_WaitForHSEStartUp()==SUCCESS)
			    {
			        RCC_HCLKConfig(RCC_SYSCLK_Div1);
			        RCC_PCLK1Config(RCC_HCLK_Div4);
			        RCC_PCLK2Config(RCC_HCLK_Div2);
			        RCC_PLLConfig(RCC_PLLSource_HSE,PLLM, PLLN, PLLP, PLLQ);
			        RCC_PLLCmd(ENABLE);
			        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);
			        
			        
			        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
			        while(RCC_GetSYSCLKSource()!=0x08);
			    }
			    else
			    {
			        while(1)
			        {
			            
			        }
			    }
			}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章