日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

STM32的时钟系统RCC详细整理

發布時間:2025/6/15 windows 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32的时钟系统RCC详细整理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一、綜述:

1、時鐘源

?STM32?中,一共有?5?個時鐘源,分別是?HSI??HSE??LSI??LSE??PLL?

?HSI?是高速內部時鐘,?RC?振蕩器,頻率為?8MHz?

?HSE?是高速外部時鐘,可接石英?/?陶瓷諧振器,或者接外部時鐘源,頻率范圍是?4MHz – 16MHz?

?LSI?是低速內部時鐘,?RC?振蕩器,頻率為?40KHz?

?LSE?是低速外部時鐘,接頻率為?32.768KHz?的石英晶體;

?PLL?為鎖相環倍頻輸出,嚴格的來說并不算一個獨立的時鐘源,?PLL?的輸入可以接?HSI/2?、?HSE?或者?HSE/2?。PLL倍頻可選擇為?2 – 16?,但是其輸出頻率最大不得超過?72MHz?。

其中,?40kHz??LSI?供獨立看門狗?IWDG?使用,另外它還可以被選擇為實時時鐘?RTC?的時鐘源。另外,實時時鐘RTC?的時鐘源還可以選擇?LSE?,或者是?HSE??128?分頻。

STM32?中有一個全速功能的?USB?模塊,其串行接口引擎需要一個頻率為?48MHz?的時鐘源。該時鐘源只能從?PLL?端獲取,可以選擇為?1.5?分頻或者?1?分頻,也就是,當需使用到?USB?模塊時,?PLL?必須使能,并且時鐘配置為?48MHz?72MHz?。

另外?STM32?還可以選擇一個時鐘信號輸出到?MCO??(PA.8)?上,可以選擇為?PLL?輸出的?2?分頻、?HSI??HSE或者系統時鐘。

系統時鐘?SYSCLK?,它是提供?STM32?中絕大部分部件工作的時鐘源。系統時鐘可以選擇為?PLL?輸出、?HSI?、HSE?。系系統時鐘最大頻率為?72MHz?,它通過?AHB?分頻器分頻后送給各個模塊使用,?AHB?分頻器可以選擇?1?、?2?4??8?、?16?、?64?、?128??256?、?512?分頻AHB分頻器輸出的時鐘送給?5?大模塊使用:

???????送給?AHB?總線、內核、內存和?DMA?使用的?HCLK?時鐘;

???????通過?8?分頻后送給?Cortex?的系統定時器時鐘STCLK

???????直接送給?Cortex?的空閑運行時鐘?FCLK?

???????送給?APB1?分頻器。?APB1?分頻器可以選擇?1?、?2?、?4??8??16?分頻,其輸出一路供?APB1?外設使用(PCLK1?最大頻率?36MHz?),另一路送給定時器?(Timer)2??3?、?4?倍頻器使用。該倍頻器根據PCLK1的分頻值自動選擇?1?或者?2?倍頻,時鐘輸出供定時器?2??3?、?4?使用。

???????送給?APB2?分頻器。?APB2?分頻器可以選擇?1??2?、?4?、?8??16?分頻,其輸出一路供?APB2?外設使用(PCLK2?,最大頻率?72MHz?),另外一路送給定時器?(Timer)1?倍頻使用。該倍頻器根據PCLK2的分頻值自動選擇1??2?倍頻,時鐘輸出供定時器?1?使用。另外?APB2?分頻器還有一路輸出供?ADC?分頻器使用,分頻后送給?ADC?模塊使用。?ADC?分頻器可選擇為?2??4?、?6?、?8?分頻。

需要注意的是定時器的倍頻器,當?APB?的分頻為?1?時,它的倍頻值為?1?,否則它的倍頻值就為?2?

?

2、APB1APB2連接的模塊

①連接在?APB1(?低速外設?)?上的設備有:電源接口、備份接口、?CAN?、?USB??I2C1?、?I2C2??UART2?、UART3??SPI2?、窗口看門狗、?Timer2??Timer3?、?Timer4?。?注意?USB?模塊雖然需要一個單獨的?48MHz?的時鐘信號,但是它應該不是供?USB?模塊工作的時鐘,而只是提供給串行接口引擎?(SIE)?使用的時鐘。?USB?模塊的工作時鐘應該是由?APB1?提供的。

②連接在?APB2?(高速外設)上的設備有:?UART1??SPI1?、?Timer1?、?ADC1?、?ADC2??GPIOx(PA~PE)?、第二功能?IO?口。

?

二、寄存器介紹:

typedef struct

{

??__IO uint32_t CR;

??__IO uint32_t CFGR;

??__IO uint32_t CIR;

??__IO uint32_t APB2RSTR;

??__IO uint32_t APB1RSTR;

??__IO uint32_t AHBENR;

??__IO uint32_t APB2ENR;

??__IO uint32_t APB1ENR;

??__IO uint32_t BDCR;

??__IO uint32_t CSR;

#ifdef STM32F10X_CL?

??__IO uint32_t AHBRSTR;

??__IO uint32_t CFGR2;

#endif /* STM32F10X_CL */

#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)??

??uint32_t RESERVED0;

??__IO uint32_t CFGR2;

#endif /* STM32F10X_LD_VL || STM32F10X_MD_VL || STM32F10X_HD_VL */

} RCC_TypeDef;

1、時鐘控制寄存器(RCC_CR):(復位值為0x0000 xx83,內部低速時鐘使能和就緒,內部時鐘校準)

主要功能:內外部高速時鐘的使能和就緒標志(含內部高速時鐘校準調整),外部高速時鐘旁路,時鐘安全系統CSS使能,PLL使能和PLL就緒標志

2、時鐘配置寄存器(RCC_CFGR):(復位值為0x0000 0000

主要功能:系統時鐘源切換及狀態,AHB、APB1、APB2ADC、USB預分頻PLL輸入時鐘源選擇及HSE輸入PLL分頻選擇PLL倍頻系數MCOPA8)引腳微控制器時鐘輸出。

3、時鐘中斷寄存器?(RCC_CIR):(復位值: 0x0000 0000

主要功能:LSILSE、HISHSE、PLL就緒中斷標志HSE時鐘失效導致時鐘安全系統中斷標志,LSI、LSE、HIS、HSE、PLL就緒中斷使能,清除LSILSEHIS、HSE、PLL就緒中斷,清除時鐘安全系統中斷。

4APB2外設復位寄存器?(RCC_APB2RSTR):(復位值: 0x0000 0000

主要功能:AFIOIOPAIOPB、IOPCIOPDIOPE、IOPFIOPGADC1ADC2、TIM1、SPI1、TIM8、USART1ADC3復位。

5、APB1外設復位寄存器?(RCC_APB1RSTR)?:(復位值: 0x0000 0000

主要功能:TIM2、TIM3TIM4、TIM5、TIM6、TIM7、WWDG、SPI2、SPI3USART2、USART3USART4、USART5、I2C1I2C2、USB、CAN、BKPPWR、DAC復位。

6、AHB外設時鐘使能寄存器?(RCC_AHBENR)?:(復位值: 0x0000 0014睡眠模式時SRAM、閃存接口電路時鐘開啟)

主要功能:DMA1DMA2、SRAMFLITF、CRCFSMC、SDIO時鐘使能。

7、APB2外設時鐘使能寄存器(RCC_APB2ENR)?:(復位值: 0x0000 0000

主要功能:AFIO、IOPA、IOPB、IOPC、IOPD、IOPE、IOPFIOPGADC1、ADC2TIM1SPI1TIM8、USART1、ADC3時鐘使能。

8、APB1外設時鐘使能寄存器(RCC_APB1ENR)?:(復位值: 0x0000 0000

主要功能:TIM2、TIM3、TIM4TIM5TIM6TIM7WWDG、SPI2、SPI3USART2、USART3、USART4USART5I2C1、I2C2、USBCANBKPPWR、DAC時鐘使能。

9、備份域控制寄存器?(RCC_BDCR)?:(復位值: 0x0000 0000

主要功能:外部低速振蕩器使能和就緒標志及旁路、RTC時鐘源選擇和時鐘使能、備份域軟件復位。

10、控制/狀態寄存器?(RCC_CSR)?:(復位值: 0x0C00 0000 NRST引腳復位標志、上電/掉電復位標志)

主要功能:內部低速振蕩器就緒、清除復位標志、NRST引腳復位標志、上電/掉電復位標志、軟件復位標志、獨立看門狗復位標志、窗口看門狗復位標志、低功耗復位標志。

三、初始化設置

采用8MHz?外部HSE?時鐘,在?MDK?編譯平臺中,程序的時鐘設置參數流程如下:

?????RCC?寄存器重新設置為默認值:RCC_DeInit();

????打開外部高速時鐘晶振?HSE?????RCC_HSEConfig(RCC_HSE_ON);

????等待外部高速時鐘晶振工作:???????HSEStartUpStatus = RCC_WaitForHSEStartUp();

????設置?AHB?時鐘?(HCLK)???????????RCC_HCLKConfig(RCC_SYSCLK_Div1);

????????設置APB 2時鐘?(APB2)?????RCC_PCLK2Config(RCC_HCLK_Div1);

????????設置APB1?時鐘?(APB1)?????RCC_PCLK1Config(RCC_HCLK_Div2);

????????設置?PLL????????RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

????打開?PLL???????????????????????????????????RCC_PLLCmd(ENABLE);

????等待?PLL?工作:????while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

設置系統時鐘:????RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

判斷?PLL?是否是系統時鐘:????????while(RCC_GetSYSCLKSource() != 0x08);

1、使用庫函數進行時鐘系統初始化配置

void RCC_config()//如果外部晶振為8MPLLCLK=SYSCLK=72MHCLK=72M//P2CLK=72MP1CLK=36MADCCLK=36MUSBCLK=48MTIMCLK=72M

{

???????ErrorStatus HSEStartUpStatus;?//?定義錯誤狀態變量

???????RCC_DeInit();//RCC寄存器重新設置為默認值

???????RCC_HSEConfig(RCC_HSE_ON);?//打開外部高速時鐘晶振

???????HSEStartUpStatus = RCC_WaitForHSEStartUp();//?等待外部高速時鐘晶振工作

???????if(HSEStartUpStatus == SUCCESS)

???????{

???????RCC_HCLKConfig(RCC_SYSCLK_Div1);//設置AHB不分頻,HCLK=SYSCLK

???????RCC_PCLK2Config(RCC_HCLK_Div1);//設置APB2不分頻,P2CLK=HCLK

???????RCC_PCLK1Config(RCC_HCLK_Div2);?//設置APB1?2分頻,P1CLK=HCLK/2

???????FLASH_SetLatency(FLASH_Latency_2);//設置FLASH代碼延時

???????FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//使能預取指緩存

???????RCC_PLLConfig(RCC_PLLSource_HSE_Div1,?RCC_PLLMul_9);//設置PLL時鐘源,

//外部時鐘不分頻,為HSE9倍頻8MHz * 9 = 72MHz

???????RCC_PLLCmd(ENABLE);//使能PLL

???????while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);//等待PLL準備就緒

???????RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//設置PLL為系統時鐘源

???????while(RCC_GetSYSCLKSource() != 0x08);//判斷PLL是否是系統時鐘

???????}

????????????/*RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD, ENABLE);?//?打開?PB??PD?用于點亮?LED?*/

}

2、使用寄存器進行RCC時鐘初始化配置

void RCC_init(u8 PLL)//輸入PLL的倍頻值216倍頻

//HCLK=PLLCLK=SYSCLK=P2CLK=P1CLK*2=ADCCLK*2=TIMCLK=USBCLK*2/3

{

???????unsigned char temp=0;??

???????//RCC_DeInit();??????????????//RCC寄存器重新設置為默認值

???????RCC->CR|=0x00010000;??//外部高速時鐘使能HSEON

???????while(!(RCC->CR>>17));//等待外部時鐘就緒

???????RCC->CFGR=0X00000400; //APB1=DIV2;APB2=DIV1;AHB=DIV1;

???????PLL-=2;//抵消2個單位

???????RCC->CFGR|=PLL<<18;???//設置PLL倍頻值?2~16

???????RCC->CFGR|=1<<16;?????//PLL時鐘源選擇

???????FLASH->ACR|=0x32;?????//FLASH 2個延時周期

???????RCC->CR|=0x01000000;??//PLLON

???????while(!(RCC->CR>>25));//等待PLL鎖定

???????RCC->CFGR|=0x00000002;//PLL作為系統時鐘??????

???????while(temp!=0x02)?????//等待PLL作為系統時鐘設置成功

???????{??

??????????????temp=RCC->CFGR>>2;

??????????????temp&=0x03;

???????}???

}

四、相關庫函數解析

1、庫中所涉及到的結構體

typedef struct{uint32_t SYSCLK_Frequency; /*!< returns SYSCLK clock frequency expressed in Hz */uint32_t HCLK_Frequency; /*!< returns HCLK clock frequency expressed in Hz */uint32_t PCLK1_Frequency; /*!< returns PCLK1 clock frequency expressed in Hz */uint32_t PCLK2_Frequency; /*!< returns PCLK2 clock frequency expressed in Hz */uint32_t ADCCLK_Frequency; /*!< returns ADCCLK clock frequency expressed in Hz */}RCC_ClocksTypeDef;

2、庫函數解析

void RCC_DeInit(void);//將外設RCC寄存器設為缺省值;(除RCC_BDCRRCC_CSR

void RCC_HSEConfig(uint32_t RCC_HSE);//設置外部高速晶振(HSE);

//輸入:RCC_HSE_OFFRCC_HSE_ONRCC_HSE_Bypass(HSE旁路)

ErrorStatus RCC_WaitForHSEStartUp(void);//等待HSE起振;

//返回值:SUCCESS,HSE晶振穩定且就緒;ERRORHSE晶振未就緒

void RCC_AdjustHSICalibrationValue(uint8_t HSICalibrationValue);//調整內部高速晶振(HSI)校準值

//輸入:校準補償值(該參數取值必須在00x1F之間)

void RCC_HSICmd(FunctionalState NewState);//使能或者失能內部高速晶振(HSI

//輸入:ENABLE或者DISABLE(如果HSI被用于系統時鐘,或者FLASH編寫操作進行中,那么它不能被停振)

void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t RCC_PLLMul);//設置PLL時鐘源及倍頻系數

//輸入:RCC_PLLSource_HSI_Div2RCC_PLLSource_HSE_Div1RCC_PLLSource_HSE_Div2

//輸入:RCC_PLLMul_2RCC_PLLMul_16

void RCC_PLLCmd(FunctionalState NewState);//?使能或者失能PLL

//輸入:ENABLE或者DISABLE

#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL) || defined (STM32F10X_CL)

?void RCC_PREDIV1Config(uint32_t RCC_PREDIV1_Source, uint32_t RCC_PREDIV1_Div);//

#endif

#ifdef??STM32F10X_CL

?void RCC_PREDIV2Config(uint32_t RCC_PREDIV2_Div);//

?void RCC_PLL2Config(uint32_t RCC_PLL2Mul);//

?void RCC_PLL2Cmd(FunctionalState NewState);//

?void RCC_PLL3Config(uint32_t RCC_PLL3Mul);//

?void RCC_PLL3Cmd(FunctionalState NewState);//

#endif /* STM32F10X_CL */

void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);//設置系統時鐘(SYSCLK)

//?RCC_SYSCLKSource_HSIRCC_SYSCLKSource_HSERCC_SYSCLKSource_PLLCLK

uint8_t RCC_GetSYSCLKSource(void);//?返回用作系統時鐘的時鐘源

//返回值:0x00 HSI作為系統時鐘,0x04 HSE作為系統時鐘,0x08 PLL作為系統時鐘

void RCC_HCLKConfig(uint32_t RCC_SYSCLK);//設置AHB時鐘(HCLK

//輸入:RCC_SYSCLK_Div1RCC_SYSCLK_Div2RCC_SYSCLK_Div4RCC_SYSCLK_Div8RCC_SYSCLK_Div16

//RCC_SYSCLK_Div32RCC_SYSCLK_Div64RCC_SYSCLK_Div128RCC_SYSCLK_Div256RCC_SYSCLK_Div512

void RCC_PCLK1Config(uint32_t RCC_HCLK);//?設置低速AHB時鐘(PCLK1

//輸入:?RCC_HCLK_Div1,?RCC_HCLK_Div2,?RCC_HCLK_Div4,?RCC_HCLK_Div8,?RCC_HCLK_Div16

void RCC_PCLK2Config(uint32_t RCC_HCLK);//?設置高速AHB時鐘(PCLK2

//輸入:RCC_HCLK_Div1,?RCC_HCLK_Div2,?RCC_HCLK_Div4,?RCC_HCLK_Div8,?RCC_HCLK_Div16

void RCC_ITConfig(uint8_t RCC_IT, FunctionalState NewState);//?使能或者失能指定的RCC中斷

//輸入:RCC_IT_LSIRDY??LSI就緒中斷->ENABLE或者DISABLE

//RCC_IT_LSERDY??LSE就緒中斷,RCC_IT_HSIRDY??HSI就緒中斷

//RCC_IT_HSERDY??HSE就緒中斷,RCC_IT_PLLRDY??PLL就緒中斷

#ifndef STM32F10X_CL

?void RCC_USBCLKConfig(uint32_t RCC_USBCLKSource);//?設置USB時鐘(USBCLK

//輸入:RCC_USBCLKSource_PLLCLK_1Div5USB時鐘?= PLL時鐘除以1.5

RCC_USBCLKSource_PLLCLK_Div1USB時鐘?= PLL時鐘

#else

?void RCC_OTGFSCLKConfig(uint32_t RCC_OTGFSCLKSource);//

#endif /* STM32F10X_CL */

void RCC_ADCCLKConfig(uint32_t RCC_PCLK2);//?設置ADC時鐘(ADCCLK

//RCC_PCLK2_Div2,ADC時鐘?= PCLK / 2;RCC_PCLK2_Div4,ADC時鐘?= PCLK / 4;

//RCC_PCLK2_Div6,ADC時鐘?= PCLK / 6;RCC_PCLK2_Div8,ADC時鐘?= PCLK / 8

#ifdef STM32F10X_CL

?void RCC_I2S2CLKConfig(uint32_t RCC_I2S2CLKSource); //????????????????????????????????

?void RCC_I2S3CLKConfig(uint32_t RCC_I2S3CLKSource);//

#endif /* STM32F10X_CL */

void RCC_LSEConfig(uint8_t RCC_LSE);//?設置外部低速晶振(LSE

//輸入:RCC_LSE_OFF,LSE晶振OFF;RCC_LSE_ON,LSE晶振ON;

//RCC_LSE_Bypass,LSE晶振被外部時鐘旁路

void RCC_LSICmd(FunctionalState NewState);//?使能或者失能內部低速晶振(LSI

//輸入:ENABLE或者DISABLE???(IWDG運行的話,LSI不能被失能)

void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource);//設置RTC時鐘(RTCCLK)(RTC時鐘一經選定即不能更改,除非復位后備域)

//輸入:RCC_RTCCLKSource_LSE,選擇LSE作為RTC時鐘;RCC_RTCCLKSource_LSI,選擇LSI作為RTC時鐘;RCC_RTCCLKSource_HSE_Div128,選擇HSE時鐘頻率除以128作為RTC時鐘

void RCC_RTCCLKCmd(FunctionalState NewState);//?使能或者失能RTC時鐘

//輸入:ENABLE或者DISABLE

void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks);//?返回時鐘的頻率

//輸入:指向結構RCC_ClocksTypeDef的指針,包含了各個時鐘的頻率(單位為Hz

void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);//?使能或者失能AHB外設時鐘

//輸入:RCC_AHBPeriph_DMADMA時鐘->ENABLE或者DISABLE

//RCC_AHBPeriph_SRAMSRAM時鐘;RCC_AHBPeriph_FLITFFLITF時鐘

//RCC_AHBPeriph_DMA1DMA1時鐘;RCC_AHBPeriph_DMA2DMA2時鐘

//RCC_AHBPeriph_CRCCRC時鐘;RCC_AHBPeriph_FSMCFSMC時鐘

//RCC_AHBPeriph_SDIOSDIO時鐘

void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);//?使能或者失能APB2外設時鐘

//輸入:RCC_APB2Periph_AFIO,功能復用IO時鐘->ENABLE或者DISABLE

//RCC_APB2Periph_GPIOAGPIOA時鐘;RCC_APB2Periph_GPIOB,GPIOB時鐘;

//RCC_APB2Periph_GPIOC,GPIOC時鐘;RCC_APB2Periph_GPIOD,GPIOD時鐘;

//RCC_APB2Periph_GPIOE,GPIOE時鐘;RCC_APB2Periph_ADC1,ADC1時鐘;

//RCC_APB2Periph_ADC2,ADC2時鐘;RCC_APB2Periph_TIM1,TIM1時鐘;

//RCC_APB2Periph_SPI1,SPI1時鐘;RCC_APB2Periph_USART1,USART1時鐘;

//RCC_APB2Periph_ALL,全部APB2外設時鐘

void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);//?使能或者失能APB1外設時鐘

//輸入:RCC_APB1Periph_TIM2TIM2時鐘->ENABLE或者DISABLE;

//RCC_APB1Periph_TIM3,TIM3時鐘;RCC_APB1Periph_TIM4,TIM4時鐘

//RCC_APB1Periph_WWDG,WWDG時鐘;RCC_APB1Periph_SPI2,SPI2時鐘

//RCC_APB1Periph_USART2,USART2時鐘;RCC_APB1Periph_USART3,USART3時鐘

//RCC_APB1Periph_I2C1,I2C1時鐘;RCC_APB1Periph_I2C2,I2C2時鐘

//RCC_APB1Periph_USB,USB時鐘;RCC_APB1Periph_CAN,CAN時鐘

//RCC_APB1Periph_BKP,BKP時鐘;RCC_APB1Periph_PWR,PWR時鐘

//RCC_APB1Periph_ALL,全部APB1外設時鐘

#ifdef STM32F10X_CL

void RCC_AHBPeriphResetCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);//

#endif /* STM32F10X_CL */

void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);//?強制或者釋放高速APBAPB2)外設復位

//輸入:同void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);函數的值

void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);//?強制或者釋放低速APBAPB1)外設復位

//輸入:同void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);函數的值

//例:/* Enter the SPI1 peripheral to reset */

//RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, ENABLE);

/* Exit the SPI1 peripheral from reset */

//RCC_APB2PeriphResetCmd(RCC_APB2Periph_SPI1, DISABLE);

void RCC_BackupResetCmd(FunctionalState NewState);//?強制或者釋放后備域復位

void RCC_ClockSecuritySystemCmd(FunctionalState NewState);//使能或者失能時鐘安全系統

//輸入:ENABLE或者DISABLE

void RCC_MCOConfig(uint8_t RCC_MCO);//?選擇在MCO管腳上輸出的時鐘源

//輸入:RCC_MCO_NoClock?無時鐘被選中 ;RCC_MCO_SYSCLK?選中系統時鐘;

//RCC_MCO_HSI?選中HSI?RCC_MCO_HSE?選中HSE?

//RCC_MCO_PLLCLK_Div2?選中PLL時鐘除以2

//警告:當選中系統時鐘作為MCO管腳的輸出時,注意它的時鐘頻率不超過50MHz(最大I/O速率)。

FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG);//?檢查指定的RCC標志位設置與否

//輸入:待檢查的RCC標志位


//RCC_FLAG_HSIRDY?HSI晶振就緒RCC_FLAG_HSERDY?HSE晶振就緒;

//RCC_FLAG_PLLRDY?PLL就緒RCC_FLAG_LSERDY?LSI晶振就緒;

//RCC_FLAG_LSIRDY?LSE晶振就緒RCC_FLAG_PINRST?管腳復位 ;

//RCC_FLAG_PORRST?POR/PDR復位RCC_FLAG_SFTRST?軟件復位 ;

//RCC_FLAG_IWDGRST?IWDG復位RCC_FLAG_WWDGRST?WWDG復位;

//RCC_FLAG_LPWRRST?低功耗復位

//返回值:RCC_FLAG的新狀態(SET或者RESET

//例:/* Test if the PLL clock is ready or not */

//FlagStatus Status;

//Status = RCC_GetFlagStatus(RCC_FLAG_PLLRDY);

//if(Status == RESET)

//{

//...

//}

//else

void RCC_ClearFlag(void);//?清除RCC的復位標志位

//(可以清除的復位標志位有:RCC_FLAG_PINRST, RCC_FLAG_PORRST, //RCC_FLAG_SFTRST, RCC_FLAG_IWDGRST, RCC_FLAG_WWDGRST, RCC_FLAG_LPWRRST)

ITStatus RCC_GetITStatus(uint8_t RCC_IT);//?檢查指定的RCC中斷發生與否

//輸入:RCC_IT_LSIRDYLSI晶振就緒中斷;RCC_IT_LSERDYLSE晶振就緒中斷

//RCC_IT_HSIRDYHSI晶振就緒中斷;RCC_IT_HSERDYHSE晶振就緒中斷

//RCC_IT_PLLRDYPLL就緒中斷;RCC_IT_CSS,時鐘安全系統中斷

//返回值:RCC_IT的新狀態

//例:

/* Test if the PLL Ready interrupt has occurred or not */

//ITStatus Status;

//Status = RCC_GetITStatus(RCC_IT_PLLRDY);

//if(Status == RESET)

//{

//...

//}

//else

//{

//...

//}

void RCC_ClearITPendingBit(uint8_t RCC_IT);//?清除RCC的中斷待處理位

//RCC_IT_LSIRDY,LSI晶振就緒中斷;RCC_IT_LSERDY,LSE晶振就緒中斷

//RCC_IT_HSIRDY,HSI晶振就緒中斷;RCC_IT_HSERDY,HSE晶振就緒中斷

//RCC_IT_PLLRDY,PLL就緒中斷;RCC_IT_CSS,時鐘安全系統中斷

五、實例詳解

#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)//如果定義了這些系統時鐘將設為24M,如果沒有定義則為72M
/* #define SYSCLK_FREQ_HSE??? HSE_VALUE */
?#define SYSCLK_FREQ_24MHz? 24000000
#else
/* #define SYSCLK_FREQ_HSE??? HSE_VALUE */
/* #define SYSCLK_FREQ_24MHz? 24000000 */?
/* #define SYSCLK_FREQ_36MHz? 36000000 */
/* #define SYSCLK_FREQ_48MHz? 48000000 */
/* #define SYSCLK_FREQ_56MHz? 56000000 */
#define SYSCLK_FREQ_72MHz? 72000000????? //
系統時鐘默認值的定義?,如果沒有定義外部高速時鐘則用內部高速時鐘,為8000000

/*只需修改以上幾句就可以自動設置使用外部倍頻作為系統時鐘,如果以上宏都未定義則在下邊把內部高速時鐘作為系統時鐘*/
#endif

/*!< Uncomment the following line if you need to use external SRAM mounted
???? on STM3210E-EVAL board (STM32 High density and XL-density devices) or on?
???? STM32100E-EVAL board (STM32 High-density value line devices) as data memory */?
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)//
內外部SRAM選擇
/* #define DATA_IN_ExtSRAM */
#endif

/*!< Uncomment the following line if you need to relocate your vector Table in
???? Internal SRAM. */?
/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET? 0x0 /*!< Vector Table base offset field. //
向量表的基址偏移量
????????????????????????????????? This value must be a multiple of 0x100. */


/*******************************************************************************
*? Clock Definitions;
以下為把系統時鐘的定義值傳給系統內核時鐘變量,如果沒有定義外部高速時鐘則用內部高速時鐘,為8M
*******************************************************************************/
#ifdef SYSCLK_FREQ_HSE
? uint32_t SystemCoreClock???????? = SYSCLK_FREQ_HSE;??????? /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_24MHz
? uint32_t SystemCoreClock???????? = SYSCLK_FREQ_24MHz;??????? /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_36MHz
? uint32_t SystemCoreClock???????? = SYSCLK_FREQ_36MHz;??????? /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_48MHz
? uint32_t SystemCoreClock???????? = SYSCLK_FREQ_48MHz;??????? /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_56MHz
? uint32_t SystemCoreClock???????? = SYSCLK_FREQ_56MHz;??????? /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_72MHz
? uint32_t SystemCoreClock???????? = SYSCLK_FREQ_72MHz;??????? /*!< System Clock Frequency (Core Clock) */
#else?/*!< HSI Selected as System Clock source */
? uint32_t SystemCoreClock???????? = HSI_VALUE;??????? /*!< System Clock Frequency (Core Clock)?
如果沒有定義外部高速時鐘則用內部高速時鐘,為8000000*/
#endif

__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};//AHB配方表
/**
? * @}
? */

/** @addtogroup STM32F10x_System_Private_FunctionPrototypes
? * @{
? */
/*********************************************************************************
???????????????
以下為函數聲明
*********************************************************************************/
static void SetSysClock(void); //
設置系統時鐘的函數聲明
//
以下為根據不同的系統時鐘的定義來聲明用到的相應的函數,為后面的函數調用做好準備
#ifdef SYSCLK_FREQ_HSE
? static void SetSysClockToHSE(void);
#elif defined SYSCLK_FREQ_24MHz
? static void SetSysClockTo24(void);
#elif defined SYSCLK_FREQ_36MHz
? static void SetSysClockTo36(void);
#elif defined SYSCLK_FREQ_48MHz
? static void SetSysClockTo48(void);
#elif defined SYSCLK_FREQ_56MHz
? static void SetSysClockTo56(void);??
#elif defined SYSCLK_FREQ_72MHz
? static void SetSysClockTo72(void);
#endif

#ifdef DATA_IN_ExtSRAM //外部SRAM選擇后的初始化函數聲明
? static void SystemInit_ExtMemCtl(void);?
#endif /* DATA_IN_ExtSRAM */

/**
? * @}
? */

/** @addtogroup STM32F10x_System_Private_Functions
? * @{
? */

/**
? * @brief? Setup the microcontroller system
? *???????? Initialize the Embedded Flash Interface, the PLL and update the?
? *???????? SystemCoreClock variable.
? * @note?? This function should be used only after reset.
? * @param? None
? * @retval None
? */
void SystemInit (void)//
系統初始化函數,設置系統的時鐘及時鐘中斷(在startup_stm32f10x_md.s中調用)(復位RCC時鐘配置為默認狀態,直到設置時鐘函數)
{
? /* Reset the RCC clock configuration to the default reset state(for debug purpose) */
? /* Set HSION bit */
? RCC->CR |= (uint32_t)0x00000001; //
內部高速時鐘使能,內部8MHz時鐘開啟

? /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#ifndef STM32F10X_CL
? RCC->CFGR &= (uint32_t)0xF8FF0000;//MCO
微控制器沒有時鐘輸出(對外部引腳),ADC預分頻PCLK2 2分頻后作為ADC時鐘,APB預分頻HCLK不分頻,AHB預分頻SYSCLK不分頻,HSI作為系統時鐘
??????????????????????????????????? //HSI
作為系統時鐘輸出(已輸出),SYSCLK=PCLK=PCLK1=PCLK2=8MADCCLK=1/2(PCLK2)=4M
#else
? RCC->CFGR &= (uint32_t)0xF0FF0000;//
同上;RCC->CFGR27位為保留位始終為0?HSI作為系統時鐘輸出(未輸出原因為未編譯)
#endif /* STM32F10X_CL */???
??
? /* Reset HSEON, CSSON and PLLON bits */
? RCC->CR &= (uint32_t)0xFEF6FFFF;//
時鐘監測器關閉,HSE振蕩器關閉

? /* Reset HSEBYP bit */
? RCC->CR &= (uint32_t)0xFFFBFFFF;//
外部4-25MHz振蕩器沒有旁路

? /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
? RCC->CFGR &= (uint32_t)0xFF80FFFF; //PLL
時鐘1.5倍分頻作為USB時鐘,PLL 2倍頻輸出,HSE不分頻,HSI時鐘2分頻后作為PLL輸入時鐘
???????????????????????????????????? //PLLCLK=HSICLK=8M
(還未輸出),HSECLK=HSEOSC,USBCLK=PLLCLK/1.5?,除PLL外其他分頻系數都為0
#ifdef STM32F10X_CL
? /* Reset PLL2ON and PLL3ON bits */
? RCC->CR &= (uint32_t)0xEBFFFFFF;//CR
中的2628位置0

? /* Disable all interrupts and clear pending bits? */
? RCC->CIR = 0x00FF0000;//
清除中斷標志,關閉一些中斷

? /* Reset CFGR2 register */
? RCC->CFGR2 = 0x00000000; //
沒有此寄存器
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
? /* Disable all interrupts and clear pending bits? */
? RCC->CIR = 0x009F0000;//
清除中斷標志,關閉一些中斷

? /* Reset CFGR2 register */
? RCC->CFGR2 = 0x00000000; //
沒有此寄存器?????
#else
? /* Disable all interrupts and clear pending bits? */
? RCC->CIR = 0x009F0000; //
清除中斷標志,關閉一些中斷
#endif /* STM32F10X_CL */
????
#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
? #ifdef DATA_IN_ExtSRAM
??? SystemInit_ExtMemCtl();//
如果宏定義了外部SRAM則對其初始化控制
? #endif /* DATA_IN_ExtSRAM */
#endif

? /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
? /* Configure the Flash Latency cycles and enable prefetch buffer */
? SetSysClock();//
設置系統時鐘

#ifdef VECT_TAB_SRAM
? SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM.?
向量表放在內部SRAM*/
#else
? SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH.?
向量表放在內部flash*/
#endif?
}

/**
? * @brief? Update SystemCoreClock according to Clock Register Values
? * @note?? None
? * @param? None
? * @retval None
? */
void SystemCoreClockUpdate (void)
{
? uint32_t tmp = 0, pllmull = 0, pllsource = 0;

#ifdef? STM32F10X_CL
? uint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0;
#endif /* STM32F10X_CL */

#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
? uint32_t prediv1factor = 0;
#endif /* STM32F10X_LD_VL or STM32F10X_MD_VL or STM32F10X_HD_VL */
????
? /* Get SYSCLK source -------------------------------------------------------*/
? tmp = RCC->CFGR & RCC_CFGR_SWS;
??
? switch (tmp)
? {
??? case 0x00:? /* HSI used as system clock */
????? SystemCoreClock = HSI_VALUE;
????? break;
??? case 0x04:? /* HSE used as system clock */
????? SystemCoreClock = HSE_VALUE;
????? break;
??? case 0x08:? /* PLL used as system clock */

????? /* Get PLL clock source and multiplication factor ----------------------*/
????? pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
????? pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
??????
#ifndef STM32F10X_CL??????
????? pllmull = ( pllmull >> 18) + 2;
??????
????? if (pllsource == 0x00)
????? {
??????? /* HSI oscillator clock divided by 2 selected as PLL clock entry */
??????? SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
????? }
????? else
????? {
?#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
?????? prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;
?????? /* HSE oscillator clock selected as PREDIV1 clock entry */
?????? SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;?
?#else
??????? /* HSE selected as PLL clock entry */
??????? if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET)
??????? {/* HSE oscillator clock divided by 2 */
????????? SystemCoreClock = (HSE_VALUE >> 1) * pllmull;
??????? }
??????? else
??????? {
????????? SystemCoreClock = HSE_VALUE * pllmull;
??????? }
?#endif
????? }
#else
????? pllmull = pllmull >> 18;
??????
????? if (pllmull != 0x0D)
????? {
???????? pllmull += 2;
????? }
????? else
????? { /* PLL multiplication factor = PLL input clock * 6.5 */
??????? pllmull = 13 / 2;?
????? }
????????????
????? if (pllsource == 0x00)
????? {
??????? /* HSI oscillator clock divided by 2 selected as PLL clock entry */
??????? SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
????? }
????? else
????? {/* PREDIV1 selected as PLL clock entry */
????????
??????? /* Get PREDIV1 clock source and division factor */
??????? prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC;
??????? prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;
????????
??????? if (prediv1source == 0)
??????? {?
????????? /* HSE oscillator clock selected as PREDIV1 clock entry */
????????? SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;??????????
??????? }
??????? else
??????? {/* PLL2 clock selected as PREDIV1 clock entry */
??????????
????????? /* Get PREDIV2 division factor and PLL2 multiplication factor */
????????? prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4) + 1;
????????? pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8 ) + 2;?
????????? SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;?????????????????????????
??????? }
????? }
#endif /* STM32F10X_CL */?
????? break;

??? default:
????? SystemCoreClock = HSI_VALUE;
????? break;
? }
??
? /* Compute HCLK clock frequency ----------------*/
? /* Get HCLK prescaler */
? tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
? /* HCLK clock frequency */
? SystemCoreClock >>= tmp;??
}

/**
? * @brief? Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers.
? * @param? None
? * @retval None
? */
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
? SetSysClockTo72();?
#endif
?
?/* If none of the define above is enabled, the HSI is used as System clock
??? source (default after reset) */?
}

/**
? * @brief? Setup the external memory controller. Called in startup_stm32f10x.s?
? *????????? before jump to __main
? * @param? None
? * @retval None
? */?
#ifdef DATA_IN_ExtSRAM
/**
? * @brief? Setup the external memory controller.?
? *???????? Called in startup_stm32f10x_xx.s/.c before jump to main.
? * ?????? This function configures the external SRAM mounted on STM3210E-EVAL
? *???????? board (STM32 High density devices). This SRAM will be used as program
? *???????? data memory (including heap and stack).
? * @param? None
? * @retval None
? */?
void SystemInit_ExtMemCtl(void)?
{
/*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is?
? required, then adjust the Register Addresses */

? /* Enable FSMC clock */
? RCC->AHBENR = 0x00000114;
??
? /* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */??
? RCC->APB2ENR = 0x000001E0;
??
/* ---------------? SRAM Data lines, NOE and NWE configuration ---------------*/
/*----------------? SRAM Address lines configuration -------------------------*/
/*----------------? NOE and NWE configuration --------------------------------*/??
/*----------------? NE3 configuration ----------------------------------------*/
/*----------------? NBL0, NBL1 configuration ---------------------------------*/
??
? GPIOD->CRL = 0x44BB44BB;??
? GPIOD->CRH = 0xBBBBBBBB;

? GPIOE->CRL = 0xB44444BB;??
? GPIOE->CRH = 0xBBBBBBBB;

? GPIOF->CRL = 0x44BBBBBB;??
? GPIOF->CRH = 0xBBBB4444;

? GPIOG->CRL = 0x44BBBBBB;??
? GPIOG->CRH = 0x44444B44;
???
/*----------------? FSMC Configuration ---------------------------------------*/??
/*----------------? Enable FSMC Bank1_SRAM Bank ------------------------------*/
??
? FSMC_Bank1->BTCR[4] = 0x00001011;
? FSMC_Bank1->BTCR[5] = 0x00000200;
}
#endif /* DATA_IN_ExtSRAM */

#ifdef SYSCLK_FREQ_HSE
/**
? * @brief? Selects HSE as System clock source and configure HCLK, PCLK2
? *????????? and PCLK1 prescalers.
? * @note?? This function should be used only after reset.
? * @param? None
? * @retval None
? */
static void SetSysClockToHSE(void)
{
? __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
??
? /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/????
? /* 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)
? {

#if !defined STM32F10X_LD_VL && !defined STM32F10X_MD_VL && !defined STM32F10X_HD_VL
??? /* Enable Prefetch Buffer */
??? FLASH->ACR |= FLASH_ACR_PRFTBE;

??? /* Flash 0 wait state */
??? FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);

#ifndef STM32F10X_CL
??? FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0;
#else
??? if (HSE_VALUE <= 24000000)
?{
????? FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_0;
?}
?else
?{
????? FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_1;
?}
#endif /* STM32F10X_CL */
#endif
?
??? /* HCLK = SYSCLK */
??? RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
??????
??? /* PCLK2 = HCLK */
??? RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
????
??? /* PCLK1 = HCLK */
??? RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV1;
????
??? /* Select HSE as system clock source */
??? RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
??? RCC->CFGR |= (uint32_t)RCC_CFGR_SW_HSE;???

??? /* Wait till HSE is used as system clock source */
??? while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x04)
??? {
??? }
? }
? 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 */
? }??
}
#elif defined SYSCLK_FREQ_24MHz

static void SetSysClockTo72(void)//系統時鐘設置為72MSYSCLK=72MHCLK=72MPCLK1=36M(最高36M),PCLK2=72MADCCLK=36M,
{
? __IO uint32_t StartUpCounter = 0, HSEStatus = 0;//
啟動計數,HSE狀態
??
? /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/????
? /* Enable HSE */????
? RCC->CR |= ((uint32_t)RCC_CR_HSEON);//HSE
使能
?
? /* Wait till HSE is ready and if Time out is reached exit */
? do //
循環,直到HSE使能成功或者超時
? {
??? 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;//HSE
使能成功
? }
? else
? {
??? HSEStatus = (uint32_t)0x00;//HSE
使能不成功
? }?

? if (HSEStatus == (uint32_t)0x01)//HSE使能成功
? {
??? /* Enable Prefetch Buffer */
??? FLASH->ACR |= FLASH_ACR_PRFTBE;//flash
緩存使能

??? /* Flash 2 wait state */
??? FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);//
??? FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;//???

?
??? /* HCLK = SYSCLK */
??? RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;//RCC_CFGR_HPRE_DIV1=0
CFGR中的值不變
??????
??? /* PCLK2 = HCLK */
??? RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;//RCC_CFGR_PPRE2_DIV1=0
CFGR中的值不變
????
??? /* PCLK1 = HCLK/2 */
??? RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;//
低速APB預分頻把HCLK 2分頻,APB1CLK=HCLK/2

#ifdef STM32F10X_CL
??? /* Configure PLLs ------------------------------------------------------*/
??? /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
??? /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */
????????
??? RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
????????????????????????????? RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
??? RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
???????????????????????????? RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);
??
??? /* Enable PLL2 */
??? RCC->CR |= RCC_CR_PLL2ON;
??? /* Wait till PLL2 is ready */
??? while((RCC->CR & RCC_CR_PLL2RDY) == 0)
??? {
??? }
????
???
??? /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */?
??? RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
??? RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 |?
??????????????????????????? RCC_CFGR_PLLMULL9);?
#else????
??? /*? PLL configuration: PLLCLK = HSE * 9 = 72 MHz */
??? RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |? //PLL
輸入時鐘源HSI時鐘2分頻后作為PLL輸入時鐘,HSE分頻器作為PLL輸入HSE不分頻?
??????????????????????????????????????? RCC_CFGR_PLLMULL));?//PLL
倍頻系數PLL 2倍頻輸出(為了清零其他位)
??? RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9);//PLL
輸入時鐘源HSE時鐘作為PLL輸入時鐘,PLL倍頻系數PLL 9倍頻輸出?
#endif /* STM32F10X_CL */

??? /* Enable PLL */
??? RCC->CR |= RCC_CR_PLLON; //PLL
使能

??? /* Wait till PLL is ready */
??? while((RCC->CR & RCC_CR_PLLRDY) == 0)//
等待PLL使能成功
??? {
??? }
????
??? /* Select PLL as system clock source */
??? RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));//HSI
作為系統時鐘(為了清零其他位)
??? RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; //PLL
輸出作為系統時鐘??

??? /* Wait till PLL is used as system clock source */
??? while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)//
等待直到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 */
? }
}
#endif

總結

以上是生活随笔為你收集整理的STM32的时钟系统RCC详细整理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。