本帖最后由 xuwei 于 2015-6-23 14:30 編輯
RCC的函數庫介紹 本文檔主要是方便查閱使用 于天津第四項目部整理。 先瞅瞅他的宏結構體定義: typedef struct { vu32 CR; 時鐘控制寄存器 vu32 CFGR; 時鐘配置寄存器 vu32 CIR; 時鐘中斷寄存器 vu32 APB2RSTR; APB2 外設復位寄存器 vu32 APB1RSTR; APB1 外設復位寄存器 vu32 AHBENR; AHB外設時鐘使能寄存器 vu32 APB2ENR; APB2 外設時鐘使能寄存器 vu32 APB1ENR; APB1 外設時鐘使能寄存器 vu32 BDCR; 備份域控制寄存器 vu32 CSR; 控制/狀態寄存器 } RCC_TypeDef; 這里用宏typedf定義了一個名為RCC_typeDf的結構體,不過并不是RCC_typeDf變量,而是用來定義結構變量的,因為前面有個宏我是這樣看的。 再看他的地址配置: #define PERIPH_BASE ((u32)0x40000000) #define APB1PERIPH_BASE PERIPH_BASE #define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) #define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) #define RCC_BASE (AHBPERIPH_BASE + 0x1000) //下面的三個都是ST公司為了方便寫的,其實我只關心這一句啥意思呢?簡單的加法所以結論是RCC_BASE=0x4002 1000這就是我要的結果,把它設為首地址看下面 #ifndef DEBUG ... #ifdef _RCC #define RCC ((RCC_TypeDef *) RCC_BASE) //咋樣這一句費了我好大的勁, 這個= RCC_TypeDef *RCC,//定義一個結構指針 RCC= RCC_BASE=0x4002 1000//結構指針附地址 一個指針而已,這樣表示RCC指向了RCC_typeDf宏結構的首地址就指向RCC_BASE=0x4002 1000就可以用RCC->CR/RCC->CFGR之類的結構指針哩,這樣做的好處是直觀而且指針高效。 #endif /*_RCC */ ... #else /* DEBUG */ //不用理他我又沒DEBUG ... #ifdef _RCC EXT RCC_TypeDef *RCC; #endif /*_RCC */ ... #endif
RCC庫函數 這個庫要根據實際的情況使用,他是使用者不用直接操作底層的RCC寄存器而能完成操作,都是封裝好的函數直接用方便。 RCC_DeInit 將外設RCC寄存器重設為缺省值 RCC_HSEConfig 設置外部高速晶振(HSE) RCC_WaitForHSEStartUp 等待HSE起振 RCC_AdjustHSICalibrationValue 調整內部高速晶振(HSI)校準值 RCC_HSICmd 使能或者失能內部高速晶振(HSI) RCC_PLLConfig 設置PLL時鐘源及倍頻系數 RCC_PLLCmd 使能或者失能PLL RCC_SYSCLKConfig 設置系統時鐘(SYSCLK) RCC_GetSYSCLKSource 返回用作系統時鐘的時鐘源 RCC_HCLKConfig 設置AHB時鐘(HCLK) RCC_PCLK1Config 設置低速AHB時鐘(PCLK1) RCC_PCLK2Config 設置高速AHB時鐘(PCLK2) RCC_ITConfig 使能或者失能指定的RCC中斷 RCC_USBCLKConfig 設置USB時鐘(USBCLK) RCC_ADCCLKConfig 設置ADC時鐘(ADCCLK) RCC_LSEConfig 設置外部低速晶振(LSE) RCC_LSICmd 使能或者失能內部低速晶振(LSI) RCC_RTCCLKConfig 設置RTC時鐘(RTCCLK) RCC_RTCCLKCmd 使能或者失能RTC時鐘 RCC_GetClocksFreq 返回不同片上時鐘的頻率 RCC_AHBPeriphClockCmd 使能或者失能AHB外設時鐘 RCC_APB2PeriphClockCmd 使能或者失能APB2外設時鐘 RCC_APB1PeriphClockCmd 使能或者失能APB1外設時鐘 RCC_APB2PeriphResetCmd 強制或者釋放高速APB(APB2)外設復位 RCC_APB1PeriphResetCmd 強制或者釋放低速APB(APB1)外設復位 RCC_BackupResetCmd 強制或者釋放后備域復位 RCC_ClockSecuritySystemCmd 使能或者失能時鐘安全系統 RCC_MCOConfig 選擇在MCO管腳上輸出的時鐘源 RCC_GetFlagStatus 檢查指定的RCC標志位設置與否 RCC_ClearFlag 清除RCC的復位標志位 RCC_GetITStatus 檢查指定的RCC中斷發生與否 RCC_ClearITPendingBit 清除RCC的中斷待處理位 RCC庫函數介紹 1.RCC_DeInit();將外設RCC寄存器重設為缺省值 2. RCC_HSEConfig(RCC_HSE_ON); 設置外部高速晶振(HSE) RCC_HSE_OFF HSE晶振OFF RCC_HSE_ON HSE晶振ON RCC_HSE_Bypass HSE晶振被外部時鐘旁路
3. ErrorStatus HSEStartUpStatus; //定義枚舉類型變量HSEStartUpStatus /* Enable HSE */ RCC_HSEConfig(RCC_HSE_ON);//開啟外部晶振 /* Wait till HSE is ready and if Time out is reached exit */ HSEStartUpStatus = RCC_WaitForHSEStartUp();//等待晶振狀態并返回給HSEStartUpStatus if(HSEStartUpStatus == SUCCESS) //如果啟振那么執行下面的代碼來設置PLL和系統時鐘,還有那些分頻器 { /* Add here PLL ans system clock config */ } else //出錯咋辦?自己看著辦 { /* Add here some code to deal with this error */ } 4. RCC_AdjustHSICalibrationValue(0x1F); 調整內部高速晶振(HSI)校準值 5.RCC_HSICmd(ENABLE); 使能或者失能內部高速晶振(HSI)ENABLE或者DISABLE表示使能或禁能 6. RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); 設置PLL時鐘源及倍頻系數 RCC_PLLSource_HSE_Div1 PLL的輸入時鐘 = HSE時鐘頻率 RCC_PLLMul_9 PLL輸入時鐘 x 9 警告:警告:必須正確設置軟件,使PLL輸出時鐘頻率不超過72 MHz就是HSE=8MHZ,鎖相環必須是RCC_PLLMul_9;這樣才能使最大時鐘為72Mhz 7. RCC_PLLCmd(ENABLE); 使能或者失能PLL ENABLE或者DISABLE表示使能或禁能 8. RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); 設置系統時鐘(SYSCLK) RCC_SYSCLKSource_PLLCLK選擇PLL作為系統時鐘 9. if(RCC_GetSYSCLKSource() != 0x04) 返回用作系統時鐘的時鐘源 { } else { } 用作系統時鐘的時鐘源: 0x00:HSI作為系統時鐘 0x04:HSE作為系統時鐘 0x08:PLL作為系統時鐘 10. RCC_HCLKConfig(RCC_SYSCLK_Div1); 設置AHB時鐘(HCLK) RCC_SYSCLK_Div1 AHB時鐘 = 系統時鐘 11. RCC_PCLK1Config(RCC_HCLK_Div2); 設置低速AHB時鐘(PCLK1) RCC_HCLK_Div2APB1時鐘 = HCLK / 2 警告:他不得超過36MHZ,這里SYSCLK=72MHZ,2分頻=36MHZ正好
12. RCC_PCLK2Config(RCC_HCLK_Div1); 設置高速AHB時鐘(PCLK2) RCC_HCLK_Div1APB2時鐘 = HCLK 13. RCC_ITConfig(RCC_IT_PLLRDY, ENABLE); 使能或者失能指定的RCC中斷 RCC_IT_PLLRDY PLL就緒中斷:ENABLE或者DISABLE表示使能或禁能 14. RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5); 設置USB時鐘(USBCLK) RCC_USBCLKSource_PLLCLK_1Div5USB時鐘 = PLL時鐘除以1.5 警告:如果SYSCLK=72MHZ那么USB正好=48MHZ,USB一定要用的時候設為48MHZ 15. RCC_ADCCLKConfig(RCC_PCLK2_Div2); 設置ADC時鐘(ADCCLK) RCC_PCLK2_Div2ADC時鐘 = PCLK / 2如果PCLK=72MHZ,那么ADC的時鐘頻率就是36MHZ 16. RCC_LSEConfig(RCC_LSE_ON); 設置外部低速晶振(LSE) RCC_LSE_ON LSE晶振ON 17. RCC_LSICmd(ENABLE); 使能或者失能內部低速晶振(LSI) ENABLE或者DISABLE 18. RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); 設置RTC時鐘(RTCCLK) RCC_RTCCLKSource_LSE選擇LSE作為RTC時鐘 19. RCC_RTCCLKCmd(ENABLE); 使能或者失能RTC時鐘 ENABLE或者DISABLE 20.函數原型:void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks); RCC_ClocksTypeDef* RCC_Clocks是定義了一個指向RCC_ClocksTypeDef的結構體指針 typedef struct { u32 SYSCLK_Frequency; 該成員返回SYSCLK的頻率,單位 Hz u32 HCLK_Frequency; 該成員返回HCLK的頻率,單位 Hz u32 PCLK1_Frequency; 該成員返回PCLK1的頻率,單位 Hz u32 PCLK2_Frequency; 該成員返回PCLK2的頻率,單位 Hz u32 ADCCLK_Frequency; 該成員返回ADCCLK的頻率,單位 Hz }RCC_ClocksTypeDef;//宏結構說明 RCC_ClocksTypeDef RCC_Clocks; RCC_GetClocksFreq(&RCC_Clocks); 返回不同片上時鐘的頻率 這個函數可以分解為: RCC_ClocksTypeDef RCC_Clocks;//定義一個結構變量RCC_Clock RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks =&RCC_Clocks);很明顯把RCC_Clocks的地址取出給了指針 其實這里可以這樣寫: RCC_ClocksTypeDef RCC_Clocks; /定義一個結構變量RCC_Clocks RCC_GetClocksFreq(&RCC_Clocks);運行這個讀時鐘程序 變量=RCC_Clocks-> SYSCLK_Frequency;//這才是返回的SYSCLK頻率;這個變量可以用來顯示或者干其他的 有點繞:注意區別:RCC_ClocksTypeDef* RCC_Clocks和RCC_ClocksTypeDef RCC_Clocks;者分別表示一個指針和一個變量千萬不要搞混了但是指針高效 21. RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA,ENABLE); 使能或者失能AHB外設時鐘 RCC_AHBPeriph_DMA DMA時鐘ENABLE或者DISABLE 22. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_SPI1, ENABLE); 使能或者失能APB2外設時鐘 RCC_APB2Periph_GPIOA GPIOA時鐘RCC_APB2Periph_GPIOB GPIOB時鐘RCC_APB2Periph_SPI1 SPI1時鐘 ENABLE或者DISABLE 值得注意的是:這些時鐘設置好了后就可以用相應的外設了,否則白搭,時鐘沒開啟額 23. RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP | RCC_APB1Periph_PWR, ENABLE); 使能或者失能APB1外設時鐘,這里不多說了,同上 24. RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE); 強制或者釋放高速APB(APB2)外設復位 25. RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE); 強制或者釋放低速APB(APB1)外設復位 26.RCC_BackupResetCmd(ENABLE); 強制或者釋放后備域復位 27. RCC_ClockSecuritySystemCmd(ENABLE); 使能或者失能時鐘安全系統 28. RCC_MCOConfig(RCC_MCO_PLLCLK_Div2); 選擇在MCO管腳上輸出的時鐘源 RCC_MCO_PLLCLK_Div2選中PLL時鐘除以2 主意:這是向外輸出時鐘,他的端口是MCO 29. FlagStatus Status; Status = RCC_GetFlagStatus(RCC_FLAG_PLLRDY); 檢查指定的RCC標志位設置與否 if(Status == RESET) { ... } else RCC_FLAG_PLLRDY PLL就緒 這函數是典型的自定義不多說 30. RCC_ClearFlag();清除RCC的復位標志位 31. ITStatus Status; Status = RCC_GetITStatus(RCC_IT_PLLRDY); 檢查指定的RCC中斷發生與否 if(Status == RESET) { ... } else { ... } RCC_IT_PLLRDY PLL就緒中斷 32. RCC_ClearITPendingBit(RCC_IT_PLLRDY); 清除RCC的中斷待處理位 RCC_IT_PLLRDY PLL就緒中斷
|