大家都知道在使用單片機時,時鐘速度決定于外部晶振或內部RC振蕩電路的頻率,是不可以改變的。而ARM的出現打破了這一傳統的法則,可以通過軟件隨意改變時鐘速度。這一出現讓我們的設計更加靈活,但是也給我們的設計增加了復雜性。為了讓用戶能夠更簡單的使用這一功能,STM32的庫函數已經為我們設計的更加簡單方便。
在比較靠前的版本中,我們需要向下面那樣設置時鐘:
ErrorStatus HSEStartUpStatus;
void RCC_Configuration(void)
{
RCC_DeInit(); // RCC system reset(for debug purpose)
RCC_HSEConfig(RCC_HSE_ON); // Enable HSE
HSEStartUpStatus = RCC_WaitForHSEStartUp(); // Wait till HSE is ready
if (HSEStartUpStatus == SUCCESS) // 當HSE準備完畢切振蕩穩定后
{
RCC_HCLKConfig(RCC_SYSCLK_Div1); // HCLK = SYSCLK
RCC_PCLK2Config(RCC_HCLK_Div1); // PCLK2 = HCLK
RCC_PCLK1Config(RCC_HCLK_Div2); // PCLK1 = HCLK/2
FLASH_SetLatency(FLASH_Latency_2); // Flash 2 wait state
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); // Enable Prefetch Buffer
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); // PLLCLK = 8MHz * 9 = 72 MHz
RCC_PLLCmd(ENABLE); // Enable PLL
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
{
; // Wait till PLL is ready
}
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // Select PLL as system clock source
while (RCC_GetSYSCLKSource() != 0x08) // Wait till PLL is used as system clock source
{
;
}
}
}
隨之函數庫的不斷升級,到3.0以上時,我們就不用再這樣編寫時鐘設置了,我們只要做如下兩部即可:
第一個: system_stm32f10x.c 中 #define SYSCLK_FREQ_72MHz 72000000
第二個:調用SystemInit()
說明:在stm32固件庫3.0中對時鐘頻率的選擇進行了大大的簡化,原先的一大堆操作都在后臺進行。系統給出的函數為SystemInit()。但在調用前還需要進行一些宏定義的設置,具體的設置在system_stm32f10x.c文件中。
文件開頭就有一個這樣的定義:
#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
#define SYSCLK_FREQ_24MHz 24000000
#else
#define SYSCLK_FREQ_72MHz 72000000
#endif
ST 官方推薦的外接晶振是 8M,所以庫函數的設置都是假定你的硬件已經接了 8M 晶振來運算的.以上東西就是默認晶振 8M 的時候,推薦的 CPU 頻率選擇.這里選擇了使MCU工作在最大工作頻率72M,也就是PLL進行八倍倍頻。這樣就確定了系統的工作頻率。這個就是SYSCLCK。
#define SYSCLK_FREQ_72MHz 72000000
也就是103系列能跑到的最大值72M
然后這個 C文件繼續往下看
#elif defined SYSCLK_FREQ_72MHz
const uint32_t SystemFrequency = SYSCLK_FREQ_72MHz;
const uint32_t SystemFrequency_SysClk = SYSCLK_FREQ_72MHz;
const uint32_t SystemFrequency_AHBClk = SYSCLK_FREQ_72MHz;
const uint32_t SystemFrequency_APB1Clk = (SYSCLK_FREQ_72MHz/2);
const uint32_t SystemFrequency_APB2Clk = SYSCLK_FREQ_72MHz;
這就是在定義了CPU跑72M的時候,各個系統的速度了.他們分別是:硬件頻率,系統時鐘,AHB總線頻率,APB1總線頻率,APB2總線頻率.
這段代碼是在網上找的,非常坑爹,一直在system_stm32f10x.c文件中找不到。所以盡信書則不如無書。
再往下看,看到這個了:
#elif defined SYSCLK_FREQ_72MHz
static void SetSysClockTo72(void);
下面是?SetSysClockTo72(void)函數中的一部分:
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
對?這段代碼進行解析:
具體的寄存器含義可以參看stm32f10x數據手冊的第63頁。下面只做簡要說明。
RCC_CFRG為?時鐘配置寄存器。
HPRE為AHB預分頻,確定AHB的時鐘;
PPRE1為?APB1的預分頻,確定低速APB的時鐘;
PPRE2為APB2的預分頻,確定高速APB的時鐘;?
這里還需要明白一些時鐘之間的關系:
AHB (HCLK) 時鐘 = SYSCLK =72M;
APB2(PCLK2)時鐘 = AHB時鐘 =72M;
APB1(PCLK1)時鐘 = AHB 1/2時鐘 =36M;
?
這就是定義 72M 的時候,設置時鐘的函數.這個函數被 SetSysClock ()函數調用,而SetSysClock ()函數則是被 SystemInit()函數調用.最后 SystemInit()函數,就是被你調用的了。
所以設置系統時鐘的流程就是:
首先用戶程序調用 SystemInit()函數,這是一個庫函數,
然后 SystemInit()函數里面,進行了一些寄存器必要的初始化后,就調用 SetSysClock()函數. SetSysClock()函數根據那個#define SYSCLK_FREQ_72MHz 72000000 的宏定義,知道了要調用SetSysClockTo72()這個函數,
版權*轉載申明:
本站內容為本站編輯或整理,所以轉載務必通知本站并以超鏈接形式注明內容來自本站,以免帶來不必要麻煩。引文出處:http://www.360doc.com/content/17/0905/13/6973384_684740421.shtml