本帖最后由 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就绪中断
|