STM32F207是如何将25M晶振时钟转换为120M系统主频时钟的?

01
时钟系统介绍
▲时钟系统专业名词缩写
时钟系统关键组成部分
01
内部高速时钟(hsi)
hsi时钟信号可以通过内部16mhz的rc振荡器产生,可以直接用于系统时钟或者用于pll输入。
hsi的rc振荡器的优势是: 在最小成本(没有外部器件)情况下提供一个时钟源。它的启动速度要比hse晶体振荡器更快,但是即使校准频率后,它的精度仍然小于外部晶体振荡器或陶瓷谐振器。
02
外部高速时钟(hse)
外部高速时钟信息(hse)可以通过两个时钟源产生:
① 外部晶体/陶瓷谐振器
② 外部用户时钟
▲两种时钟源接入示意图
03
主锁相环时钟(pll)
stm32f2xx具有两个pll
① 主要的pll通过hse或hsi提供时钟,并且有两个输出时钟;
② 专用的pll(plli2s)被用于产生一个精确的时钟去实现高质量音频效果在i2s接口;
hse/m*n/p得到pll时钟
关于pll锁相环说明
从1处输入,3处输出是1的n倍。
3处除以n又作为输入,当1和2的频率一样,就锁定了。(之所以图上是xn,因为从2看向3的)
04
低速外部时钟(lse)
lse是一个32.768khz低速外部晶振或陶瓷谐振器。
它的优点:提供低速但是高精度时钟给rtc外设,为时钟/日历或其他时间应用。
05
低速内部时钟(lsi)
lsi rc作为一个低速时钟源,它可以运行在停止和待机模式中给独立看门狗(iwdg)和自动唤醒(awu)。它的时钟频率在32mhz左右。
02
代码分析时钟初始化代码在system_stm32f2xx.c文件中,大部分时候我们不需要修改时钟代码的,各个总线的频率我们可以在文件头看到。
============================================================================= *============================================================================= * supported stm32f2xx device revision | rev b and y *----------------------------------------------------------------------------- * system clock source | pll (hse) *----------------------------------------------------------------------------- * sysclk(hz) | 120000000 *----------------------------------------------------------------------------- * hclk(hz) | 120000000 *----------------------------------------------------------------------------- * ahb prescaler | 1 *----------------------------------------------------------------------------- * apb1 prescaler | 4 *----------------------------------------------------------------------------- * apb2 prescaler | 2 *----------------------------------------------------------------------------- * hse frequency(hz) | 25000000 *----------------------------------------------------------------------------- * pll_m | 25 *----------------------------------------------------------------------------- * pll_n | 240 *----------------------------------------------------------------------------- * pll_p | 2 *----------------------------------------------------------------------------- * pll_q | 5 *----------------------------------------------------------------------------- * plli2s_n | na *----------------------------------------------------------------------------- * plli2s_r | na *----------------------------------------------------------------------------- * i2s input clock | na *----------------------------------------------------------------------------- * vdd(v) | 3.3 *----------------------------------------------------------------------------- * flash latency(ws) | 3 *----------------------------------------------------------------------------- * prefetch buffer | on *----------------------------------------------------------------------------- * instruction cache | on *----------------------------------------------------------------------------- * data cache | on *----------------------------------------------------------------------------- * require 48mhz for usb otg fs, | enabled * sdio and rng clock | *----------------------------------------------------------------------------- *============================================================================= ******************************************************************************在文件开始定义的有系统时钟频率的全局变量systemcoreclock,其他地方需要时钟频率,可以直接使用该变量。
uint32_t systemcoreclock = 120000000;时钟配置从systeminit函数执行,调用systeminit的在汇编文件中startup_stm32f2xx.s(keil编译环境)。
import __main ldr r0, =systeminit blx r0 ldr r0, =__main bx r0 endp在这里说明一下文档版本的问题:
▲ stm32f20x_user_manual的v7版和v8版对比图
上述两图的区别是系统最大时钟从120mhz变成了168mhz,我的理解是同样是stm32f20x,st由于技术进步或其他,使得新版stm32f207芯片超频支持168mhz。
下面我们主要分析systemcoreclock的120m时钟怎么从一个外部25mhz的hse得到的。
我们要从25mhz的外部时钟得到120m的系统时钟,需要上图中标注的重要4点:
1、使能hse
2、选择hse作为主pll的输入时钟
3、主pll倍频后得到120mhz时钟
4、系统时钟选择主pll时钟输出作为系统时钟
我们找到对应的代码
1、使能hse
/* enable hse */ rcc- >cr |= ((uint32_t)rcc_cr_hseon);在rcc_cr寄存器(rccclock control register rcc时钟控制器)中,有打开hse的控制位
2、选择hse作为主pll的输入时钟
/* configure the main pll */rcc- >pllcfgr = pll_m | (pll_n < > 1) -1) < < 16) | (rcc_pllcfgr_pllsrc_hse) | (pll_q < pllcfgr = pll_m | (pll_n < > 1) -1) < < 16) | (rcc_pllcfgr_pllsrc_hse) | (pll_q < cfgr &= (uint32_t)((uint32_t)~(rcc_cfgr_sw));rcc- >cfgr |= rcc_cfgr_sw_pl对于主pll的配置寄存器,在rcc_pllcfgr寄存器中有说明
整理后得知f(out)=f(in)* n / m / p
/* pll_vco = (hse_value or hsi_value / pll_m) * pll_n */#define pll_m 25#define pll_n 240/* sysclk = pll_vco / pll_p */#define pll_p 2这样就获得了120m时钟
注意:
pll_m大于等于2且小于等于63
pll_n大于等于64且小于等于432
pll_p只能是2、4、6、或8
但2对应0,4对应1,6对应2,8对应3。
st并没有使用if或case语句判断,因为对应的数据除以2减去1就是寄存器这两位的值,所以可以按照下面这样写,这种写法值得我们学习。
(((pll_p > > 1) -1) < cfgr |= rcc_cfgr_hpre_div1;/* pclk2 = hclk / 2*/rcc- >cfgr |= rcc_cfgr_ppre2_div2;/* pclk1 = hclk / 4*/rcc- >cfgr |= rcc_cfgr_ppre1_div4;** 备 注 **
** 时钟中断**
可以配置外部晶振出错时的中断,还有rcc中断,因此我们可以在外部时钟出问题时,切换为内部时钟,不至于整个系统挂掉。具体见st给的官方代码。
无源晶振不起振
没有程序,无源晶振是不起振的,需要配置rcc时钟控制寄存器的hseon位打开或关闭hse振荡器。
关于apb和pclk
f207是时钟图没有显示pclk1和pclk2,应该就是apb1和apb2
应该指的是一个pclk应该是peripheralclock的简称,看f105手册

汽车产业互联网的下一步是产业整合提升效率的阶段
3D全息投影沙盘有什么特点
功率器件上市公司中报披露,高增长,发力新能源
为双输出电源添加看门狗
华为麒麟芯片回归,魅族用实际行动欢迎Mate回归
STM32F207是如何将25M晶振时钟转换为120M系统主频时钟的?
边缘计算产业联盟会员名单
广东首创LED照明标准光组件 抢占国际先机
接地电阻测试仪的主要用途
行扫描电路的“安全检修”
蒸汽发生器与传统锅炉有哪些不同
网络摄像机的警报输入/输出
电话机器人到底强在哪里,它有哪些优势
诺坎普体育场场内覆盖升级到5G
机器人可以通过操作人员的脑电波,思维命令执行任务
基于μCOS-II的USB主机系统设计
爱立信率先完成IMT-2020(5G)系列测试
车载逆变器对电瓶有害吗
TCL科技在智能终端产业布局上完成了一次重要的战略延伸
苹果调整产品线:最畅销iPhone 6停产 已出货2.5亿台