历史上的今天
今天是:2024年12月17日(星期二)
2018年12月17日 | STM32笔记:RCC结构与配置流程
2018-12-17 来源:eefocus
以前使用STM32写程序的时候,使用的都是默认时钟。因此写数码管显示、A/D测量电压的时候都没有去关心RCC时钟配置这个事情。那时候只知道在配置外设的时候使用GPIO_InitTypeDef或者ADC_InitTypeDef这些结构体对外设进行初始化,以及使用RCC_APB2PeriphClockCmd或者RCC_ADCCLKConfig函数对外设的时钟开启与配置。
这几天尝试使用STM32的USB通信写一个鼠标,发现一些例程中有关于时钟配置的代码,才注意起这个事情。为此进行了一些学习,并且记录如下的笔记。
一、RCC的结构
以下是STM32时钟系统的结构图:

从图中,我们可以看到,STM32的时钟有四个来源:外部晶振提供的高速外部时钟(HSE)、外部晶振提供的低速外部时钟(LSE)、内部RC振荡器提供的高速内部时钟(HSI)、内部RC振荡器提供的低速内部时钟(LSI)。看上去RCC的工作过程好像很复杂,其实细看并不然。
举个例子吧,Keil编写程序是默认的时钟为72Mhz,其实是这么来的:外部晶振提供的8MHz(与电路板上的晶振的相关)通过PLLXTPRE分频器后,进入PLLSRC选择开关,进而通过PLLMUL锁相环进行倍频(x9)后,为系统提供72MHz的系统时钟(SYSCLK)。之后是AHB预分频器对时钟信号进行分频,然后为低速外设提供时钟。
当然,在实际应用中,我们也可以为系统时钟作其他的设置。譬如把内部高速RC振荡器(HSI RC)二分频后,通过PLLSRC选择开关进行倍频而不使用外部晶振作为输入,HSI也可以直接通过SW选择开关来提供系统时钟。
此外,STM32还提供了一个时钟监视系统(CSS),用于监视高速外部时钟(HSE)的工作状态。倘若HSE失效,会自动切换(高速内部时钟)HSI作为系统时钟的输入。
二、RCC配置流程
1、将RCC寄存器恢复为默认值 RCC_DeInit
2、打开外部高速时钟晶振 RCC_HSEConfig
3、等待外部高速时钟晶振工作
4、设置AHB时钟 RCC_HCLKConfig
5、设置高速APB时钟 RCC_PCLK2Config
6、设置低速APB时钟 RCC_PCLK1Config
7、设置PLL锁相环 RCC_PLLConfig
8、打开PLL锁相环 RCC_PLLCmd
9、等待PLL锁相环工作 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)
10、设置系统时钟 RCC_SYSCLKConfig
11、判断PLL是否为系统时钟 while(RCC_GetSYSCLKSource()!=0x08)
12、打开要使用的外设时钟 RCC_APB2PeriphClockCmd/RCC_APB1PeriphClockCmd
以上步骤只是举个例子。根据RCC的工作过程,查阅参考手册与库函数的手使用册可以自己进行的配置。
使用代码再举一个例子吧
void RCC_Configuration(void)
{
//----------使用外部RC晶振-----------
RCC_DeInit(); //初始化为缺省值
RCC_HSEConfig(RCC_HSE_ON); //使能外部的高速时钟
while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET); //等待外部高速时钟使能就绪
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Enable Prefetch Buffer
FLASH_SetLatency(FLASH_Latency_2); //Flash 2 wait state
RCC_HCLKConfig(RCC_SYSCLK_Div1); //HCLK = SYSCLK
RCC_PCLK2Config(RCC_HCLK_Div1); //PCLK2 = HCLK
RCC_PCLK1Config(RCC_HCLK_Div2); //PCLK1 = HCLK/2
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9); //PLLCLK = 8MHZ * 9 =72MHZ
RCC_PLLCmd(ENABLE); //Enable PLLCLK
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //Wait till PLLCLK is ready
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //Select PLL as system clock
while(RCC_GetSYSCLKSource()!=0x08); //Wait till PLL is used as system clock source
//---------打开相应外设时钟--------------------
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能APB2外设的GPIOA的时钟
}
史海拾趣
|
我找到一款功能不错的PCB设计软件,叫EAGLE,是德国一家叫CadSoft的公司研发的,这个软件有四个版本,专业版,标准版,免费试用版和简化版。专业版支持255个绘图层,带有自动布线功能,而且还可以导入其他设计工具或程序的数据,生成Gerber和Excell ...… 查看全部问答> |
|
三星2416在WINCE5.0上的休眠问题,头大了。。高手进来看看。。 能够正常进入休眠模式,但是唤醒后无论有没有操作,过一小会就出现异常并死机,串口打印如下信息: 红色的是没有操作死机的打印信息: Data Abort: Thread=83f7f6d0 Proc=815fb580 \'device.exe\' AKY=00000005 PC=8039bd50(NK.EXE+0x0019bd50) ...… 查看全部问答> |
|
写了一个小的应用程序,通过修改注册表,设置成开机自动运行.(我用vs2005远程跑是没问题的) 可是,开机时会卡在log界面上.请问下高手,问题在哪里? 添加注册表如下: [HKEY_LOCAL_MACHINE\\init] \"Launch50\"=\"startup.exe\" \"Depend50\"=hex:14 ...… 查看全部问答> |
|
现在我的系统中使用的字型文件是一个名叫:mingliu.ttc的字型文件(这个是一个能支持繁体中文的字型文件)。现在我把系统的字体修改为:使用New Times Roman字型,这样就会出现一个问题,在显示中文的地方就会出现口口(框框)不能正常显示。这应该 ...… 查看全部问答> |
|
采用定时器1、3的周期中断,两个同时用,两个周期寄存器的设置是一样的,定时器1的周期中断和3的周期中断优先级一样,都是2级,怎么写中断向量表?中断优先级一样的两个中断怎么进行设置?要求1的周期中断高于3的周期中断,谢谢!… 查看全部问答> |
|
我用的是CROSS—2.95.3,编译1.1.2没问题,但编译1.1.4老是不能,出现在cc1: invalid option \'abi=apcs-gnu\'错误,把编译系统换成CROSS-3.2也还是同样的问题。今天试了下CROSS-3.3.2也还是同样的问题。 是编译系 ...… 查看全部问答> |




