STM32时钟框图
STM32系统时钟RCC(基于HAL库)

STM32系统时钟RCC(基于HAL库)基础认识为什么要有时钟:时钟就是单⽚机的⼼脏,其每跳动⼀次,整个单⽚机的电路就会同步动作⼀次。
时钟的速率决定了两次动作的间隔时间。
速率越快,单⽚机在单位时间内所执⾏的动作将越多。
时钟是单⽚机运⾏的基础,时钟信号推动单⽚机内各个部分执⾏相应的指令。
时钟系统就是CPU的脉搏,决定cpu速率。
为什么这么多个时钟源:STM32系统是复杂的,⾼精度、低精度、⾼速、低速等,且可以对每个时钟源进⾏开关操作,可以把不需要使⽤的关闭掉。
这可以让单⽚机适⽤更多的环境中,把选择权利交个了开发者,开发者可以从精度、功耗、资源等多⽅⾯考虑。
STM32时钟:从时钟源的⾓度可分为:l 外部时钟(E)l 内部时钟(I)从时钟速率的⾓度分为:l ⾼速时钟(HS)l 低速时钟(LS)STM32在芯⽚复位后默认选⽤的是内部的⾼速时钟(HSI)进⾏⼯作,如果需要使⽤外部⾼速时钟(HSE)的话需要经过软件操作相关的寄存器配置。
外部时钟模式外部的⾼速和低速时钟均有这三个可选项⽬,图中是CubeMX提供的外部时钟选择:可选类型为l Disable(关闭,不使⽤外部时钟)l BYPASS Clock Source(旁路时钟源)l Crystal/Ceramic Resonator(外部晶体/陶瓷谐振器)外部晶体/陶瓷谐振器模式该模式较为常见,这可以为系统时钟提供较为精确的时钟源。
该时钟源是由外部⽆源晶体与MCU内部时钟驱动电路共同配合形成,有⼀定的启动时间,精度较⾼。
为了减少时钟输出的失真和缩短启动稳定时间,晶体/陶瓷谐振器和负载电容必须尽可能地靠近振荡器引脚。
负载电容值必须根据所选择的晶体来具体调整。
整体上讲,陶瓷晶体和⽯英晶体的主要区别就在于精度和温度稳定性上。
⽯英晶体⽐陶瓷晶体精度要⾼,温度稳定性要好。
旁路时钟源模式该模式下必须提供外部时钟。
外部时钟信号(50%占空⽐的⽅波、正弦波或三⾓波)必须连到SOC_IN引脚,此时OSC_OUT引脚对外呈⾼阻态。
STM32F4时钟树概述

STM32F4时钟树概述STM32F4 相对于 STM32F1 来说,时钟部分复杂了很多, STM32F4 的时钟配置,我们提供两个函数: Sys_Clock_Set 和Stm32_Clock_Init。
其中 Sys_Clock_Set 是核⼼的系统时钟配置函数,由 Stm32_Clock_Init 调⽤,实现对系统时钟的配置。
外部程序,⼀般调⽤ Stm32_Clock_Init函数来配置时钟。
sys⽂件夹中在 STM32F4 中,有 5 个最重要的时钟源,为 HSI、 HSE、 LSI、 LSE、 PLL。
其中 PLL 实际是分为两个时钟源,分别为主 PLL 和专⽤PLL。
从时钟频率来分可以分为⾼速时钟源和低速时钟源,在这 5 个中 HSI, HSE 以及 PLL 是⾼速时钟, LSI 和 LSE 是低速时钟。
从来源可分为外部时钟源和内部时钟源,外部时钟源就是从外部通过接晶振的⽅式获取时钟源,其中 HSE 和LSE 是外部时钟源,其他的是内部时钟源。
①、 LSI 是低速内部时钟, RC 振荡器,频率为 32kHz 左右。
供独⽴看门狗和⾃动唤醒单元使⽤。
②、 LSE 是低速外部时钟,接频率为 32.768kHz 的⽯英晶体。
这个主要是 RTC 的时钟源。
③、 HSE 是⾼速外部时钟,可接⽯英/陶瓷谐振器,或者接外部时钟源,频率范围为 4MHz~26MHz。
我们的开发板接的是 8M 的晶振。
HSE 也可以直接做为系统时钟或者 PLL 输⼊。
④、 HSI 是⾼速内部时钟, RC 振荡器,频率为 16MHz。
可以直接作为系统时钟或者⽤作 PLL输⼊。
⑤、 PLL 为锁相环倍频输出。
STM32F4 有两个 PLL:1)主 PLL(PLL)由 HSE 或者 HSI 提供时钟信号,并具有两个不同的输出时钟。
第⼀个输出 PLLP ⽤于⽣成⾼速的系统时钟(最⾼ 168MHz)第⼆个输出 PLLQ ⽤于⽣成 USB OTG FS 的时钟(48MHz),随机数发⽣器的时钟和 SDIO时钟。
stm32定时器时钟以及中间对齐模式

stm32定时器时钟以及中间对齐模式在永磁同步电机的控制中,需要对电机的三相定⼦施加⼀定的电压,才能控制电机转动。
现在⽤的较多的是SVPWM(SVPWM的具体原理会在后⾯另写⼀篇博客说明),要想产⽣SVPWM波形,需要控制的三相电压呈如下形式,即A、B、C三相的电压是中间对齐的,这就需要⽤到stm32定时器的中间对齐模式了。
1、stm32的时钟树stm32的时钟树如下图所⽰,简单介绍⼀下stm32时钟的配置过程。
以外部时钟作为时钟源为例。
HSE代表外部时钟(假设为8M)、SYSCLK为系统时钟,经过倍频器之后变成168M、SYSCLK经过AHB预分频器(假设分频系数为1)后变成HCLK时钟等于系统时钟SYSCLK,HCLK即AHB外部总线时钟,经过APB预分频器分出APB1时钟(分频系数为2,低速设备SYSCLK/4)与APB2时钟(分频系数为1,⾼速设备SYSCLK/2)HSE->SYSCLK->HCLK->APB1、APB2。
针对stm32f427的配置源码如下static void SetSysClock(void){#if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx) || defined (STM32F401xx)/******************************************************************************//* PLL (clocked by HSE) used as System clock source *//******************************************************************************/__IO uint32_t StartUpCounter = 0, HSEStatus = 0;/* 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){/* Select regulator voltage output Scale 1 mode */RCC->APB1ENR |= RCC_APB1ENR_PWREN;PWR->CR |= PWR_CR_VOS;/* HCLK = SYSCLK / 1*/RCC->CFGR |= RCC_CFGR_HPRE_DIV1;//AHB时钟#if defined (STM32F40_41xxx) || defined (STM32F427_437xx) || defined (STM32F429_439xx)/* PCLK2 = HCLK / 2*/RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;//APB2时钟/* PCLK1 = HCLK / 4*/RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;//APB1时钟#endif /* STM32F40_41xxx || STM32F427_437x || STM32F429_439xx *//* Configure the main PLL */RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);/* Enable the main PLL */RCC->CR |= RCC_CR_PLLON;/* Wait till the main PLL is ready */while((RCC->CR & RCC_CR_PLLRDY) == 0){}#if defined (STM32F427_437xx) || defined (STM32F429_439xx)/* Enable the Over-drive to extend the clock frequency to 180 Mhz */PWR->CR |= PWR_CR_ODEN;while((PWR->CSR & PWR_CSR_ODRDY) == 0){}PWR->CR |= PWR_CR_ODSWEN;while((PWR->CSR & PWR_CSR_ODSWRDY) == 0){}/* Configure Flash prefetch, Instruction cache, Data cache and wait state */FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS; #endif /* STM32F427_437x || STM32F429_439xx *//* Select the main PLL as system clock source */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |= RCC_CFGR_SW_PLL;/* Wait till the main PLL is used as system clock source */while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);{}}else{ /* If HSE fails to start-up, the application will have wrong clockconfiguration. User can add here some code to deal with this error */}}2、stm32定时器的时钟stm32定时器分为⾼级定时器(TIM1与TIM8)、通⽤定时器(TIM2-TIM5、TIM9-TIM14)、基本定时器(TIM6、TIM7)。
图文详解stm32时钟树

对于广大初次接触STM32的读者朋友(甚至是初次接触ARM器件的读者朋友)来说,在熟悉了开发环境的使用之后,往往“栽倒”在同一个问题上。
这问题有个关键字叫:时钟树。
众所周知,微控制器(处理器)的运行必须要依赖周期性的时钟脉冲来驱动——往往由一个外部晶体振荡器提供时钟输入为始,最终转换为多个外部设备的周期性运作为末,这种时钟“能量”扩散流动的路径,犹如大树的养分通过主干流向各个分支,因此常称之为“时钟树”。
在一些传统的低端8位单片机诸如51,AVR,PIC等单片机,其也具备自身的一个时钟树系统,但其中的绝大部分是不受用户控制的,亦即在单片机上电后,时钟树就固定在某种不可更改的状态(假设单片机处于正常工作的状态)。
比如51单片机使用典型的12MHz晶振作为时钟源,则外设如IO口、定时器、串口等设备的驱动时钟速率便已经是固定的,用户无法将此时钟速率更改,除非更换晶振。
而STM32微控制器的时钟树则是可配置的,其时钟输入源与最终达到外设处的时钟速率不再有固定的关系,本文将来详细解析STM32微控制器的时钟树。
图1是STM32微控制器的时钟树,表1是图中各个标号所表示的部件。
标号图1标号释义1 内部低速振荡器(LSI,40Khz)2 外部低速振荡器(LSE,32.768Khz)3 外部高速振荡器(HSE,3-25MHz)4 内部高速振荡器(HIS,8MHz)5 PLL输入选择位6 RTC时钟选择位7 PLL1分频数寄存器8 PLL1倍频寄存器9 系统时钟选择位10 USB分频寄存器11 AHB分频寄存器12 APB1分频寄存器13 AHB总线14 APB1外设总线15 APB2分频寄存器16 APB2外设总线17 ADC预分频寄存器18 ADC外设19 PLL2分频数寄存器20 PLL2倍频寄存器21 PLL时钟源选择寄存器22 独立看门狗设备23 RTC设备图1 STM32的时钟树在认识这颗时钟树之前,首先要明确“主干”和最终的“分支”。
STM32时钟详细配置

STM32时钟配置STM32时钟配置步骤// 开启HSI时钟寄存器操作1).开启高速时钟HSE // 设置时钟控制寄存器RCC_CR 位16 置1使能RCC->CR|= 0x00010000;位16 :HSEON:外部高速时钟使能当进入待机和停止模式时,该位由硬件清零,关闭4-16MHz外部振荡器。
当外部4-16MHz 振荡器被用作或被选择将要作为系统时钟时,该位不能被清零。
2).等待高速时钟就绪// 读取时钟控制寄存器RCC_CR位17为1就位while(!(RCC-> CR>>17));位17:HSERDY:外部高速时钟就绪标志由硬件置’1’来指示外部4-16MHz振荡器已经稳定。
在HSEON位清零后,该位需要6个外部4-25MHz振荡器周期清零。
3).设置APB1,APB2,AHB分频系数// 设置时钟配置寄存器RCC_CFGRRCC_CFGR=0x00000400;(AHB :位4-7, (低速)APB1 :位8-10, (高速)APB2 :位11-13)位7:4:HPRE[3:0]:AHB预分频(AHB Prescaler)0xxx:SYSCLK不分频位10:8:PPRE1[2:0]:低速APB预分频(APB1) 100:HCLK 2分频位13:11:PPRE2[2:0]:高速APB预分频(APB2) 0xx:HCLK不分频4).设置PLL倍频// 配置时钟配置寄存器RCC_CFGR 位18-21RCC_CFGR|=7<<18;位21:18:PLLMUL:PLL倍频系数0111:PLL 9倍频输出5).PLL输入时钟源选择// 配置时钟配置寄存器RCC_CFGR 位16RCC_CFGR|=1<<16;位16:PLLSRC:PLL输入时钟源(PLL entry clock source) 1:HSE时钟作为PLL输入时钟。
由软件置’1’或清’0’来选择PLL输入时钟源。
STM32F103时钟部分归纳

学习一款单片机,首先要了解的是它的时钟部分,在网上找到一些stm32F103时钟部分的资料,归纳总结一下。
时钟模块框图如下:仔细看上面这个框图,就可以对F103的时钟有一个清晰的认识了。
三种不同的时钟源可用作系统时钟(SYSCLOCK):HSI振荡器时钟(由芯片内部RC振荡器提供)HSE振荡器时钟(由芯片外部晶体振荡器提供)PLL时钟(通过倍频HIS或HSE振荡器倍频得到)另外还有两个时钟源:LSI内部40kHz低速RC振荡器时钟,用于驱动独立看门狗或选择驱动RTCLSE外部32.768kHz低速外部输入时钟,用于驱动RTC1.当HSI被用于作为PLL时钟的输入时,系统时钟能得到的最大频率是64MHz。
2.用户可通过多个预分频器分别配置AHB、高速APB(APB2)和低速APB(APB1)域的频率。
AHB和APB2域的最大频率是72MHz。
APB1域的最大允许频率是36MHz。
SDIO接口的时钟频率固定为HCLK/2。
3. RCC通过AHB时钟(HCLK)8分频后作为Cortex系统定时器(SysTick)的外部时钟。
通过对SysTick控制与状态寄存器的设置,可选择上述时钟或Cortex(HCLK)时钟作为SysTick时钟。
ADC时钟由高速APB2时钟经2、4、6或8分频后获得。
定时器时钟频率由APB1(PCLK1)时钟获得,分配由硬件按以下2种情况自动设置:a. 如果相应的APB预分频系数是1,定时器的时钟频率与所在APB总线频率一致。
b. 否则,定时器的时钟频率被设为与其相连的APB总线频率的2倍。
4. FCLK是Cortex-M3的自由运行时钟。
详情见ARM的Cortex-M3技术参考手册。
关于HSE、HIS、PLL、LSE、LSI时钟特性及校准直接参考STM32相关Datasheet。
系统时钟配置过程:配置过程主要对RCC_CR、RCC_CFGR、RCC_CIR这三个寄存器,进行读写访问,配置系统时钟完成后,进行对要使用的相应外设时钟进行使能和配置,不用的外设建议关闭相应的外设时钟(降低功耗)。
STM32通用定时器

STM32的定时器功能很强大,学习起来也很费劲儿.其实手册讲的还是挺全面的,只是无奈TIMER的功能太复杂,所以显得手册很难懂,我就是通过这样看手册:while(!SUCCESS){看手册…}才搞明白的!所以接下来我以手册的顺序为主线,增加一些自己的理解,并通过11个例程对TIMER做个剖析。
实验环境是STM103V100的实验板,MDK3.2 +Library2.东西都不怎么新,凑合用……TIMER主要是由三部分组成:1、时基单元。
2、输入捕获。
3、输出比较。
还有两种模式控制功能:从模式控制和主模式控制。
一、框图让我们看下手册,一开始是定时器的框图,这里面几乎包含了所有定时器的信息,您要是能看明白,那么接下来就不用再看别的了…为了方便的看图,我对里面出现的名词和符号做个注解:TIMx_ETR:TIMER外部触发引脚 ETR:外部触发输入ETRP:分频后的外部触发输入 ETRF:滤波后的外部触发输入ITRx:内部触发x(由另外的定时器触发)TI1F_ED:TI1的边沿检测器。
TI1FP1/2:滤波后定时器1/2的输入TRGI:触发输入 TRGO:触发输出CK_PSC:应该叫分频器时钟输入CK_CNT:定时器时钟。
(定时周期的计算就靠它)TIMx_CHx:TIMER的输入脚 TIx:应该叫做定时器输入信号xICx:输入比较x ICxPS:分频后的ICxOCx:输出捕获x OCxREF:输出参考信号关于框图还有以下几点要注意:1、影子寄存器。
有阴影的寄存器,表示在物理上这个寄存器对应2个寄存器,一个是程序员可以写入或读出的寄存器,称为preload register(预装载寄存器),另一个是程序员看不见的、但在操作中真正起作用的寄存器,称为shadow register(影子寄存器);(详细请参考版主博客/STM32/401461/message.aspx)2、输入滤波机制在ETR何TIx输入端有个输入滤波器,它的作用是以采样频率Fdts来采样N次进行滤波的。
STM32之RCC

STM32之RCCSTM32 RCC复位与时钟配置,忽略掉复位,首先学习时钟配置,复位以后用到再学习。
STM32有多个时钟源,分别是HSI:上电默认启动,因精度不高所以先不采用,以后如果需要再使用HSE:外部高速时钟,系统时钟一般采用它,经过PLL倍频作为系统时钟LSE:外部低速时钟,一般专门用于RTC,等到RTC模块时再使用LSI:内部低速时钟,精度不高,一般用于IWDGCLK时钟系统框图如下:STM32中各个模块都有自己的时钟,当使用相应的模块时首先记得把此模块时钟开启本次学习使用标准固件库3.3.0void RCC_Configuration(void){ErrorStatus HSEStartUpStatus;//SystemInit(); //完全可以使用此函数配置,但是为了学习先不用RCC_DeInit(); //复位RCC模块的寄存器,复位成缺省值RCC_HSEConfig(RCC_HSE_ON); //开启HSE时钟,用HSE的时钟作为PLL的时钟源HSEStartUpStatus = RCC_WaitForHSEStartUp(); //获取HSE启动状态if(HSEStartUpStatus == SUCCESS) //如果HSE启动成功{FLASH_PrefetchBufferCmd(ENABLE); //开启FLASH的预取功能FLASH_SetLatency(FLASH_Latency_2); //FLASH延迟2个周期RCC_HCLKConfig(RCC_SYSCLK_Div1); //配置HCLK,PCLK2,PCLK1,PLLRCC_PCLK2Config(RCC_HCLK_Div1);RCC_PCLK1Config(RCC_HCLK_Div2);RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);RCC_PLLCmd(ENABLE); //启动PLLwhile(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET){} //等待PLL启动完成RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //配置系统时钟while(RCC_GetSYSCLKSource() !=0x80){} //检查是否将HSE 9倍频后作为系统时钟 }}设置时钟流程:1.将RCC寄存器重新设置为默认值RCC_DeInit2.打开外部高速时钟晶振HSE RCC_HSEConfig(RCC_HSE_ON);3.等待外部高速时钟晶振工作 HSEStartUpStatus = RCC_WaitForHSEStartUp();4.设置AHB时钟RCC_HCLKConfig;5.设置高速APB2时钟 RCC_PCLK2Config;6.设置低速速APB1时钟 RCC_PCLK1Config7.设置PLL RCC_PLLConfig8.打开PLL RCC_PLLCmd(ENABLE);9.等待PLL工作while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)10.设置系统时钟RCC_SYSCLKConfig11.判断是否PLL是系统时钟while(RCC_GetSYSCLKSource() != 0x08)12.打开要使用的外设时钟RCC_APB2PeriphClockCmd()/RCC_APB1PeriphClockCmd()至此我们就将STM32的系统时钟配置好了,系统时钟72MHz,APH 72MHz,APB2 72MHz,APB1 32MHz,USB 48MHz其他至于ADC什么的先用不管,用到时再设置,本次只是大体先熟悉下STM32的时钟配置流程,便于以后程序的编写。