找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7636|回复: 1
收起左侧

STM32 ARM_RCC库函数简表与RCC启动代码

[复制链接]
ID:82781 发表于 2015-6-23 14:29 | 显示全部楼层 |阅读模式
本帖最后由 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
{
}
用作系统时钟的时钟源:
0x00HSI作为系统时钟
0x04HSE作为系统时钟
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); 强制或者释放高速APBAPB2)外设复位
25. RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE); 强制或者释放低速APBAPB1)外设复位
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就绪中断





回复

使用道具 举报

ID:82781 发表于 2015-6-23 14:30 | 显示全部楼层
STM32RCC启动代码
“基于MDK的调试器调试代码跟踪”
上电进入启动代码加载系统初始化程序设置系统时钟函数
1.复位所有的RCC寄存器,
RCC_CR=0X83;
RCC_CFGR=0;
RCC_CIR=0;
RCC_APB2RSTR=0;
RCC_APB1RSTR=0
RCC_AHBENR=0X14;
RCC_APB2ENR=0;
RCC_APB1ENR=0;
RCC_BDCR=0;
RCC_CSR=0X0C000000;
单步运行(只列出改变的寄存器)
2.RCC_CR=0X00030083;表示开启HSE外部振荡器
3.RCC_CFGR=0X001D0400;//外部引脚MCO无频率输出、usb分频1.5、9倍频PLL、HSE不分频输入PLL,HSE做为输入PLL时钟、PLL作为系统时钟
上面这个是寄存器的翻译我的解释是:外部时钟进入PLL锁相环进行9倍频后作为SYSCLK即系统时钟他不得超过72MHZ,我的是外部8MHZ晶振,算下来是系统时钟为72MHZ,另外还有一路经过USB1.5分频器就是48MHZ,作为USB的时钟,有了系统时钟其他的就小菜菜了、还设置了AHB的分频器为1,APB2分频为1,APB1的分频器设置为2,就是APB2的外设工作在72MHZ下,APB1则工作在36MHZ下,但是不要忘了一点还有使能端的,在RCC里是设置不了的,要到外设对应的寄存器中,如:GPIO,你要用的时候要开启GPIO的时钟通道奥!
4.RCC_CR=0X01030083;//开启PLL
5.RCC_CR=0X03030083//锁定PLL
完了
总结:这个顺序一定不能打乱,最后才能开启PLL和锁定,否则PLL写不了这样就设置好了RCC了,详见源代码和手册说名。


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表