《STM32时钟配置方法详解.docx》由会员分享,可在线阅读,更多相关《STM32时钟配置方法详解.docx(9页珍藏版)》请在三一办公上搜索。
1、一、在STM32中,有五个时钟源,为HSI、HSE、1.S1.1.SE、P1.1.oHSl是高速内部时钟,RC振荡器,频率为8MHz。HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz16MHz01.Sl是低速内部时钟,RC振荡器,频率为40kHz。1.SE是低速外部时钟,接频率为32.768kHz的石英晶体。P1.1.为锁相环倍频输出,其时钟输入源可选择为HSI/2、HSE或者HSE2o倍频可选择为216倍,但是其输出频率最大不得超过72MHzo二、在STM32上如果不使用外部晶振,OSCN和OSCJDUT的接法:如果使用内部RC振荡器而不使用外部晶振,请按照下
2、面方法处理:对于100脚或144脚的产品,OSCN应接地,OSJOUT应悬空。对于少于100脚的产品,有2种接法:第1种:OSCN和OSC_OUT分别通过IOK电阻接地。此方法可提高EMC性能;第2种:分别重映射OSCN和OSQOUT至PDO和PDl,再配置PDO和PDl为推挽输出并输出此方法可以减示功耗并(相对上面)节省2个外部电阻。三、用HSE时钟,程序设置时钟参数流程:01,将RCC寄存器重新设置为默认值RCC-Delnit;02打开外部高速时钟晶振HSERCC_HSEConfig(RCC_HSE_ON);03、等待外部高速时钟晶振工作HsEStartUpStatus=RCC_WaitF
3、orHSEStartUp();04设置AHB时钟RCC_HC1.KConfig;05设置高速AHB时钟RCC.PC1.K2Config;06、设置低速速AHB时钟RCC.PC1.KlConfig;07、设置P1.1.RCC.P1.1.Config;08、打开P1.1.RCe.P1.1.Cmd(ENAB1.E);09、等待P1.1.工作While(RCC1.GetFlagStatus(RCC1.F1.AG_P1.1.RDY)二二RESET)10、设置系统时钟RCC-SYSC1.KConfig;11、判断是否P1.1.是系统时钟WhiIe(RCC1.GetSYSe1.KSOUrCe()!=0x08
4、)12、打开要使用的外设时钟RCC_APB2PeriphClockCmd()/RCC_APB1PeriphClockCmdO四、下面是STM32软件固件库的箱港中对RCC的配置函数(使用外部8MHz晶振)*FunctionName:ReC.ConfigurationDescription:RCC配宜(使用外部8MHz晶振)*Input:无*0UtPUt:无*Return:无VoidRCC-Configuration(Void)/*将外注RCC寄存器重设为缺省值*/RCC_DeInit();*设直外部高速晶振(HSE)*/RCC_HSEConfig(RCC_HSE_ON);/RCC_HSE_ON
5、HSE晶振打开(ON)/*等番HSE起振*/HSEStartUPStatUS=RCC-WaitForHSEStartUpO;if(HSEStartUpStatus=SUCCESS)SUCCESS:HSE晶振稳定且就绪/*设置AHB时钟(HC1.K)RCC_HC1.KConfig(RCC_SYSC1.K_Div1);/RCC_SYSC1.K_Div1AHB时钟=系统高钟/*设置高速AHB时钟(PC1.K2)*/RCC_PC1.K2Config(RCC_HC1.K_Div1);/RCC_HC1.K_Div1APB2时钟=HC1.K/*设置低速AHB时钟(PC1.KI)*/RCC_PC1.K1Con
6、fig(RCC_HC1.K_Div2);/RCC_HC1.K_Div2APB1时钟=HC1.K2/*设置F1.ASH存储器延时时钟周期数*/F1.ASH_Set1.atency(F1.ASH_1.atency_2);/F1.ASH_1.atency_22延时周期/*选择F1.ASH预取指缓存存模式*/F1.ASH_PrefetchBufferCmd(F1.ASH_PrefetchBuffer_Enable);/预取指缓存使能/*设置P1.1.时钟源及倍频系数*/RCC_P1.1.Config(RCC_P1.1.Source_HSE_Divl,RCC_P1.1.Mul_9);/P1.1.的输入时
7、钟=HSE时钟频率;RCe1.P1.1.MU1.9P1.1.输入时钟x9/*使能P1.1.*/RCC-P1.1.Cmd(ENAB1.E);/*检卷指定的RCC标志位(P1.1.准备好标志)设置与否*/while(RCC_GetFlagStatus(RCC_F1.AG_P1.1.RDY)=RESET)/*设置系统时钟(SYSC1.K)*/RCC_SYSC1.KConfig(RCC_SYSC1.KSource_P1.1.C1.K);/RCC_SYSC1.KSource_P1.1.C1.K选择P1.1.作为系统时钟*P1.1.返回用作系统时论的时钟源*/whUe(RCC.GetSYSC1.KSour
8、ce()!=0x08)0x08:P1.1.作为系统时钟/*使能森者失能APB2外设时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOBRCC_APB2Periph_GPI0C,ENAB1.E);/RCC_APB2Periph_GPIOAGPIOA时钟/RCC_APB2Periph_GPIOBGPIOB时钟/RCC_APB2Periph_GPI0CGPI0C时钟/RCC_APB2Periph_GPI0DGPI0D时钟五、原钟频率STM32F103内部8M的内部震荡,经过倍频后最高可以达到72M。目前Tl的M3系列
9、芯片最高频率可以达到80Mo在STM32固件库3.0中对时钟频率的选择进行了大大的简化,原先的一大堆操作都在后台进行。系统给出的函数为SystemInitOo但在调用前还需要进行一些宏定义的设置,具体的设置在system_stm32f10x.c文件中。文件开头就有一个这样的定义:/#defineSYSC1.K_FREQ_HSEHSE_Value/#defineSYSC1.K_FREQ_20MHz20000000/#defineSYSC1.K_FREQ_36MHz36000000#defineSYSC1.K_FREQ_48MHZ48000000/#defineSYSC1.K_FREQ_56MHz
10、56000000#defineSYSC1.K_FREQ_72MHz72000000ST官方推荐的乐接晶欣是8M,所以库函数的设置都是假定你的硬件已经接了8M晶振来运算的.以上东西就是默认晶振8M的时候,推荐的CPU频率选择.在这里选择了:#defineSYSC1.K_FREQ_72MHz72000000也就是103系列能跑到南最大值72M然后这个C文件继续往下看#elifdefinedSYSC1.K_FREQ_72MHzCOnStUint32SyStemFreqUenCy=SYSC1.K_FREQ_72MHz;constuint32_tSystemFrequency_SysClk=SYSC1.
11、K_FREQ_72MHz;constuint32_tSystemFrequency_AHBClk=SYSC1.K_FREQ_72MHz;constuint32_tSystemFrequency_APBlClk=(SYSC1.K_FREQ_72MHz/2);constuint32_tSystemFrequency_APB2Clk=SYSC1.K_FREQ_72MHz;这就是在电义了CPU跑72M的时候,各个系统的虚度了.他们分别是:硬件频率,系统时钟,AHB总线频率,APBl总线频率,APB2总线频率.再往下看,看到这个T:#elifdefinedSYSC1.K_FREQ_72MHzstatic
12、voidSetSysClockTo72(void);这就是定义72M的时候,设置时钟的函数.这个函数被SetSySClOCk()函数调用,而SetSySClOCko函数则是被SyStemlnit()函数调用.最后SyStemInit()函数,就是被你调用的了所以设置系统时钟的流程就是:首先用户程序调用SyStemlnit()函数,这是一个库函数,然后SyStemInit()函数里面,进行了一些寄存器必要的初始化后,就调用SetSySCIoCko函数。SetSySeIOCko函数根据那个#defineSYSC1.K_FREQ_72MHZ72000000的宏定义,知道了要调用SetSySCIoCk
13、To72()这个函数,宇是,加一堆麻烦而复杂的设置!#$%八然后,CPU跑起来了,而且速度是72M.虽然说的有点累赘,但大家只需要知道用户要设置频率,程序中就做的就两个事情:第一个:SyStem_stm32fl0x.cI#defineSYSC1.K_FREQ_72MHz72000000第二个:调用SystemInitOSTM32系统时钟详解一.什么是时钟1 .什么是时钟对单片机有什么作用时钟是由电路产生的具有周期性的脉冲信号,相当于单片机的心脏,要想使用单片机的外设必须开启相应的时钟,驱动外设的本质是操作寄存器,而寄存器是由D触发器构成,而触发器需要时钟才能改写值,所以要想操作寄存器必须开启对
14、应外设的时钟。对CPU来说假设CPU在一个时钟周期内执行一条指令(二进制代码),若时钟频率越高,而时钟等于1/f为频率的倒数,则时钟周期更短则在相同的时间CPU能够执行更多的指,CPU的运行速度更快,文章的后面会有STM32超频实验,让灯闪烁的更快。(后面会详细讲解实验原理)2 .为什么要有时钟树STM32时钟系统主要的目的就是给相对独立的外设模块提供时钟,主要也是为了降低整个芯片的功耗,所有外设时钟默认都是关闭状态(disable)当我们使用某个外设就要开启这个外设的时钟(enable),不同外设需要的时钟频率不同,没必要所有外设都用高速时钟造成浪费,而且有些外设也接受不了这么高的频率,这也
15、是为什么STM32有四个时钟源的原因,就是兼容不同速度的外设,STM32的四个时钟源分别为:HSE.1.SEHSk1.SI二 .STM32的时钟源主要有:内部时钟外部时钟锁相环倍频输出时钟2.1 详细介绍HSI(内部高速时钟)它是RC振荡器,频率可以达到8MHZ,可作为系统时钟和P1.1.锁相环的输HSE(外部高速时钟)接入晶振范围是4-16MHZ,可作为系统时钟和P1.1.锁相环的输入,还可以经过128分频之后输入给RTCo1.SI(内部低速时钟)它是RC振荡器,频率大概为40KHZ,供给独立看门狗或者RTC并且独立看门口只能依靠1.SI作为时钟源1.SE(外部低速时钟)通常外接32.768
16、MHZ晶振提供给RTCP1.1.(锁相环)用来倍频输出。因为开发板外部晶振只有8MHZ,而STM32最大工作频率是72MHZ。他可以通过HSl输入,HSE输入或两分频输入,通过P1.1.倍频(2-16),倍频之后输入给系统时钟。MCO(时钟输出管脚)通常对应STM32PA8,它可以选择一个时钟信号输出,给外部的系统提供时钟源三 .标准库的时钟配置3.15 tm32启动文件首先打开StartUp_stm32fl0XJKI.s,该文件为Stm32的启动文件,在该文件内会发现有这么一块用汇编写的代码。ReseCHandlerPROCEXPORTReset-HandlerIWEAKIMPORT_mai
17、nIMPORTSystemInit1.DRRO,=SystemInitB1.XRO1.DRRO,=_mainBXROENDP通过这段汇编代码可以看出,程序在执行main函数之前,会先执行SystemInit函数。3.25 ystemInit函数详解VoidSystemInit(Void)*ResettheRCCclockconfigurationtothedefaultresetstate(fordebugpurpose)*/*SetHSIONbit*RCC-CR=(uint32-t)OxOOOOOOO1;*ResetSW,HPRE,PPRE1,PPRE2,ADCPREandMCObits*/
18、#ifndefSTM32Fl0X_C1.RCC-CFGR&=(uint32_t)0xF8FF0000;#elseRCC-CFGR&=(Uint32)OXFOFFOO00;#endif7*STM32F10X_C1.*/*ResetHSEON,CSSONandP1.1.ONbits*/RCC-CR&=(uint32_t)OxFEF6FFFF;*ResetHSEBYPbit*/RCC-CR&=(Uint32_t)OXFFFBFFFF;*ResetP1.1.SRC,P1.1.XTPRE,P1.1.MU1.andUSBPREOTGFSPREbits*/RCC-CFGR&=(uint32_t)0xFF80
19、FFFF;#ifdefSTM32F10X_C1.*ResetP1.1.2ONandP1.1.3ONbits*RCC-CRClR=OxOOFFOOOO;*ResetCFGR2register*RCC-CFGR2=0x00000000;#elifdefined(STM32F10X_1.D_V1.)|defined(STM32F10X_MD_V1.)|(definedSTM32F10X_HD_V1.)*Disableallinterruptsandclearpendingbits*RCC-ClR=0x009F0000;*ResetCFGR2register*RCC-CFGR2=0x00000000;
20、#else/*DiSableaninterrUPtSandClearPendingbits*/RCC-CIR=0x009F0000;#endii7*STM32F10X_C1.*/#ifdefined(STM32F10X.HD)(definedSTM32F1OX_X1.)|(definedSTM32F1OX_HD_V1.)#ifdefDATAJN_ExtSRAMSystemInit_ExtMemCtl();#endii7*DATAJN_ExtSRAM*/#endif*ConfiguretheSystemclockfrequency,HC1.K,PC1.K2andPC1.KIprescalers*
21、/*ConfiguretheFlash1.atencycyclesandenableprefetchbuffer*/SetSysClock();#ifdefVECT_TAB_SRAMSCB-VTOR=SRAM_BASE|VECT_TAB_OFFSET;/*VectorTabieRelocationinInternalSRAM.*/#elseSCB-VTOR=F1.ASH_BASE|VECT_TAB_OFFSET;/*VectorTableRelocationinInternalF1.ASH.*/#endif打开内部8M时钟RCC-CR|=(uint32_t)0x00000001通过查看寄存器手
22、M可知,这段代码为打开内部8M时钟。时的控制寄存叁(RCe_CR)WitgMPfIO100OXXS3.X代义5M:七寸府收,?T,FH7ItUkHHSlON1.:也就ft置TitIR,从普HH4mn累附”的得发筌逢廿厢硬件r*03内UMH的同CIk簿b,UMHxMHItftKAHMM1.lflnAttftIVWVfl*MIaR於零.0:AseMHrHWKMiItaMHz!llfJfCf.设置时钟配置寄存器#ifndefSTM32FlOX_C1.RCC-CFGR&=(uint32_t)0xF8FF0000;#elseRCC-CFGR&=(uint32_t)0xF0FF0000;#endi“*ST
23、M32F1OX_C1.*/对应寄存器说明可看着STM32中文参考手册_V10的6.3.2时钟配置寄存器(RCC_CFGR)章节。后履代码,有兴趣可根据STM32中文参考手册_V10手册,查看代码具体作用。2.3SetSySCIoCko函数详解staticvoidSetSysClock(void)#ifdefSYSC1.K_FREQ_HSESetSysClockToHSE();#elifdefinedSYSC1.K_FREQ_24MHzSetSysClockTo24();#elifdefinedSYSC1.K_FREQ_36MHzSetSysClockTo36();#elifdefinedSYS
24、C1.K_FREQ_48MHzSetSysClockTo48();#elifdefinedSYSC1.K_FREQ_56MHzSetSysClockTo56();#elifdefinedSYSC1.K_FREQ_72MHzSetSysClockTo72();#endifsystem_stm32f10x.c文件中会根据芯片的型号定义对应的宏#ifdefined(STM32F10X_1.D_V1.)|(definedSTM32F10X_MD_V1.)|(definedSTM32F10X_HD_V1.)/*#defineSYSC1.K_FREQ_HSEHSE_VA1.UE*/#defineSYSC1
25、.K_FREQ_24MHz24000000#else/*#defineSYSC1.K_FREQ_HSEHSE_VA1.UE*/*#defineSYSC1.K_FREQ_24MHz24000000*/*#defineSYSC1.K_FREQ_36MHz36000000*/*#deflneSYSC1.K_FREQ_48MHz48000000*/*#defineSYSC1.K_FREQ_56MHz56000000*/#defineSYSC1.K_FREQ_72MHz72000000#endif3.时钟配置函数3.1 时钟初始化配置函数VoidSystemInit(Void);SYSC1.K(系统时钟
26、尸72MHZ;AHB总线时钟(HC1.K=SYSC1.K)=72MHZ;APBI总线时钟(PC1.KI=SYSC1.K/2)=36MHZ;APB2总线时钟(PC1.K1=SYSC1.K/1)=72MHZ;P1.1.主时钟=72MHZ;3.2 外设时钟使能配置函数voidRCC_AHBPeriphClockCmd(uint32_tRCC_AHBPeriph,FunctionaIStateNewState);voidRCC_APB2PeriphClockCmd(uint32_tRCC_APB2Periph,FunctionalStateNewState);voidRCC_APB1PeriPhCIO
27、CkCmd(Uint32RCC_APB1PeriphiFunctionalStateNewState);3.3 时钟源使能函数VoidRCC_HSICmd(FUnCtiOnalStateNeWState);voidRCC_1.SICmd(FunctionalStateNewState);VoidRCC_P1.1.Cmd(FUnCtiOnaIStateNeWState);VoidRCC_RTCC1.KCmd(FUnCtiOnalStateNeWState);3.4 时钟痛和倍频因子配置函数V oidRCC1.HSEConfig(Uint32RCC1.HSE);V oidRCC1.SYSC1.KC
28、onfig(Uint32RCe1.SYSC1.KSOUrce);V oidRCC1.HC1.KConfig(Uint32,ReC1.SYSC1.K);voidRCC-PC1.K1Config(Uint32RCCJ4C1.K);voidRCC_PC1.K2Config(uint32_tRCC_HC1.K);3.5 外设时钟复位函数voidRCC_APB2PeriphResetCmd(uint32_tRCC_APB2Periph,FunctionalStateNewState);voidRCC_APB1PeriphResetCmd(uint32_tRCC_APB1Periph,Functional
29、StateNewState);3.6 自定义系统时钟voidRCC_HSE_Config(u32div,u32pllm)RCC_DeInit();RCC_HSEConfig(RCC_HSE_ON);if(RCC_WaitForHSEStartUp()=SUCCESS)RCC_HC1.KConfig(RCC_SYSC1.K_Div1);RCC_PC1.K1Config(RCC_HC1.K_Div2);RCC_PC1.K2Config(RCC_HC1.K_Div1);RCC_P1.1.Config(div,pllm);RCC_P1.1.Cmd(ENAB1.E);while(RCC_GetFlagStatus(RCC_F1.AG_P1.1.RDY)=RESET)RCC_SYSC1.KConfig(RCC_SYSC1.KSource_P1.1.C1.K)While(RCC1.GetSC1.KSOUrCe()!=0x08);