玩STM32的时间也比较久了,最早的一直玩的是STD标准库的103系列,但是ST公司也是“与时俱进”,舍弃了当年的标准库,转而推广HAL库,反正无论怎么样把,对于STM32的使用也仅仅停留在使用阶段,底层涉入不神,我一直觉得真正的大牛们,都是趴在最底层不愿意起来的那一群,唉……底层难啊。近来由于课设要求,重新捡起来F407的板子,继续ST进阶之路。长时间不玩,对于STM32陌生了好多,这次玩板子,看的更深了点,花了一下午,终于解决了一个问题:关于板子上电以后系统时钟频率的设置问题。  

  以前最先用103的STD库做开发,后来搞过一段时间寄存器开发,一直都认为STM32的主流时钟频率比如72M,168M等是在启动文件里,main()函数之前SystemInit函数中设置,后来才发现目前的代码都没有对他进行设置。本人喜好寄存器版的简单粗暴,不需要添加过多的文件,直接建个工程,弄个main函数就开始跑程序了,那么问题就来了,这时候的系统时钟频率到底是多少呢,SystemInit没有对他设置,那么到底是在哪里设置了他呢,不然程序怎么能跑起来?带着这些问题,搞了一下午,也算是了解了!

  OK,。下面,以我自己的STM32F407的板子为例进行测试说明,HSE晶振为8M,HSI为16M

  下面是:启动文件里面的原版代码,粘来是方便大家看下,查找源码可以发现,SystemInit的代码的第一行是开启HSI时钟源,其他的基本都是复位操作,还有一些内存SRAM的设置。我们建立工程之后,直接在main中写代码,程序是可以运行的,那么这时候我的407板子的时钟是多少M呢?

 //启动代码中的函数
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP

  我分了几个部分对这个进行测试,

  一、确保程序可以运行,

 int main(void)
{
u32 fre1; fre1 = ;
}

  建立完工程,编译无错误之后,写入上面的代码,编译通过后,load到板子里,然后开启debug,调试,通过watch窗口,查看到fre1变量的值会变成2,如下图,说明程序可以运行,fre2,fre3是测试程序时添加的变量,这里不用在意。

  二、OK,测试程序可以跑,那么接下来开始思考,这时系统的主频是多少,我采用了,HAL库提供的一个函数HAL_RCC_GetSysClockFreq(),通过它可以得到系统主频的值。代码也是非常简单,

 int main(void)
{
u32 fre1;
fre1 = ;
fre1 = HAL_RCC_GetSysClockFreq();
}

  将上面的程序load到板子后,继续开启debug模式,查看系统主频,结果如下,可以看到fre1最后的值是0x00F42400,通过计算器换算之后发现该值其实是16M,那也就是说此时的系统时钟频率是16M,这就让我比较奇怪了,怎么会是16M!

  为了查看为什么此时系统时钟的值是16M,我查看了以下此时RCC中关于时钟配置的寄存器的值,如下图

  

  先来说CFGR寄存器,因为要查看的是系统时钟,那么就要搞清楚目前系统时钟的来源是谁,看最低两位的SW1和SW0,手册上是这样描述的!

由上图可以看到,该两位都是0,根据手册,此时的系统时钟来源是HSI,就没有HSE和PLL啥事,查阅407板载资料,HSI的时钟源是16MHZ,至此我明白了,原来此时的系统时钟,是由系统时钟HSI时钟源提供的,那么到底是不是呢,为了验证我的想法,我继续查看了CR寄存器,此时,他的值如下,可以看到此时HSION是被置位的,也就是此时开启了,HSI的时钟,那应该就没啥错了!

  不过还有一个疑问,就是到底是谁开启了HSI时钟呢,又是在哪段代码里开启了呢,这可以说是一个不算问题的问题,但是笔者还真的试图去源码当中找过,也真的是太不认真了,后来才发现这个CR寄存器的复位值,就直接将HSION位置1了。这句是直接从手册中截图来的,也就是每一次的复位,系统硬件都会把HSION位置1,表明此时开启了HSI时钟源!

  而且刚刚还忽略了一个严重的问题,在SystemInit()函数中,第一条代码,就是开启HSI时钟,我尝试将该行代码注释掉,发现并没有任何影响,看来确实是由硬件置位的。看到这里,问题基本被解决了一大半,此时系统的主时钟基本是有寄存器初始复位值所决定,原来搞了这么久都竟然没发现这个问题,唉,实在是太不应该,如果有像笔者一样的菜鸟的话,也在此给各位提个醒。

  三、问题基本被搞清楚了,那么我就想,既然现在是HSI时钟源,那么晚我想将系统时钟变为其他的频率,可以吗?答案是当然,我没有直接去设置168M,而是用了简单的三行代码,将时钟源选择改为了HSE,大家看过时钟树图的都应该清楚,系统时钟的来源可以是HSE,也可以是PLL,而如果要设为高速时钟的话,肯定就需要PLL,不过我的目的仅仅是测试下修改时钟,因此也就不那么麻烦了,我添加了几行代码,如下:

 int main(void)
{
u32 fre1;
fre1 = ;
fre1 = HAL_RCC_GetSysClockFreq(); /*选择时钟源为HSE*/
RCC->CR |= 0X1<<;      //开启HSE时钟
while((RCC->CR & 0X1<<16) == 1);  //等待HSERDY就绪 RCC->CFGR |= 0X1;      //时钟源选择为HSE fre1 = HAL_RCC_GetSysClockFreq();

  根据以上的代码,大家应该能猜到fre1的值的变化情况把 ,第一次为2,第二次是16M,那么第三次…………,没错就应该是8M了,结果如下:0x007a1200,经过换算,没错确实是8M,一切成功。

  四、设置时钟主频为168M

  玩过407的人应该都知道,407推荐主频为168M比较好,那么我们就在这里设置下他的系统主频,168M是一个高速时钟,那么我的时钟源肯定要不能直接使用HSE了,而应该使用PLL(其实PLL的源是HSE),而系统主频的源是PLL,这三者之间的关系大家要搞清楚。在这里我们先不做大的改动,直接将PLL时钟源开启,然后将系统时钟的源选择为PLL,测试一下时钟频率是多少,代码如下:

 int main(void)
{
u32 fre1 = ; /*选择PLL的时钟源是HSE*/
RCC->PLLCFGR |= 0X1<<; //必需在开启PLL和HSE之前设置 /*开启HSE*/
RCC->CR |= 0X1<<;
while((RCC->CR & 0X1<<) == ); /*开启PLL*/
RCC->CR |= 0X1<<;
while((RCC->CR & 0X1<<) == );//等待PLLRDY准备就绪 /*选择PLL为系统的时钟源*/
RCC->CFGR |= 0X2; FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS; //设置FALSH预取等待时间 fre1 = HAL_RCC_GetSysClockFreq();
}

  使用PLL的源得到的系统时钟经过测试为48M,结果如下图:

  

  明明没有设置过RCC_PLLCFGR的值,但是竟然还是得到了48M的时钟,原因是什么呢,跟前面一样,同样这里RCC_PLLCFGR的寄存器有个RESET值,有心的朋友可以对照着手册查看一下,该寄存器的RESET值最终能够得到pll_m = 16,pll_p = 2,pll_n = 192,计算之后同样能够的得到这个48M的时钟频率,那么如果你想要设置主频时钟为168M,那么在笔者的代码基础上修改一下PLL_CFGR寄存器的值,应该就可以解决所有的问题了,着重提醒一下,当你的时钟设置为168M后,必须要设置FLASH预取等待时间,否则会有问题!

  由于主要目的是为了测试,因此代码着实有点粗鄙不堪。不够严谨,还望各位能够见谅,这里也只是希望能够给各位分享一下,上电之后系统主频的变化。从最底层的角度来帮助分析,这样才更加清楚明了,当你底层都会了,那么无论再来什么的库都不是问题。相反,你只是停留在库的层面,这个库你会了,下次换个库,你又得花时间整!

  个人观点,不喜勿喷,希望能给予大家帮助。

关于STM32F407启动后的系统时钟频率问题的更多相关文章

  1. 关于mysql8启动后又停止(windows10系统),忘记密码以及密码过期等坑解决办法总结!

    一 我遇到的问题 1 mysql连接不了,mysql服务启动后又马上关闭 2 忘记密码或者重装服务后提示安装的随机密码过期 一个一个来,先看第一个: 1 出现这个情况很大原因是mysql安装目录有多余 ...

  2. 简单的股票信息查询系统 1 程序启动后,给用户提供查询接口,允许用户重复查股票行情信息(用到循环) 2 允许用户通过模糊查询股票名,比如输入“啤酒”, 就把所有股票名称中包含“啤酒”的信息打印出来 3 允许按股票价格、涨跌幅、换手率这几列来筛选信息, 比如输入“价格>50”则把价格大于50的股票都打印,输入“市盈率<50“,则把市盈率小于50的股票都打印,不用判断等于。

    '''需求:1 程序启动后,给用户提供查询接口,允许用户重复查股票行情信息(用到循环)2 允许用户通过模糊查询股票名,比如输入“啤酒”, 就把所有股票名称中包含“啤酒”的信息打印出来3 允许按股票价格 ...

  3. MySQL 安装和启动服务,“本地计算机 上的 MySQL 服务启动后停止。某些服务在未由其他服务或程序使用时将自动停止。”

    MySQL 安装和启动服务,以及遇到的问题 MySQL版本: mysql-5.7.13-winx64.zip (免安装,解压放到程序文件夹即可,比如 C:\Program Files\mysql-5. ...

  4. Hbase HRegionServer启动后自动关闭

    突然发现HBASE无法使用了. 然后看到在分布式的情况下,节点上的HRegionServer启动后自动关闭. 同步时间就能解决这个问题. 网上同步时间 1.  安装ntpdate工具 sudo apt ...

  5. linux启动后自动登录并运行自定义图形界面程序

    在<Ubuntu CTRL+ALT+F1~F6 进入命令模式后不支持中文显示的解决办法>一文中提到linux启动在以后运行一个独占显示器的图形程序的两种办法. 1.不启动xserver,使 ...

  6. 绿色版Tomcat 启动 + 停止 + 随系统自动启动 - - 博客频道 - CSDN.NET

    body { font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI ...

  7. 通过 U 盘启动重装 macOS 系统

    重装系统是工作和生活中经常需要做的事情,作为一名开发人员,学会该技能你才是一名合格的程序猿!以后再也不会遇到"程旭元你会装系统吗?"的尴尬了!本文主要介绍怎样通过U盘启动重新安装 ...

  8. 让windows 2003启动后直接进入桌面

    windows 2003启动后进入桌面需要解决的几个问题 1.如何去除掉 ctrl+alt+del的提示界面 2.如何设置自动登录的用户名密码 3.在异常启动时会出现关闭事件跟踪程序 也会导致不能直接 ...

  9. Android Bug分析系列:第三方平台安装app启动后,home键回到桌面后点击app启动时会再次启动入口类bug的原因剖析

    前言 前些天,测试MM发现了一个比较奇怪的bug. 具体表现是: 1.将app包通过电脑QQ传送到手机QQ上面,点击安装,安装后选择打开app (此间的应用逻辑应该是要触发 [闪屏页Activity] ...

随机推荐

  1. AllowsTransparency和WebBrowser兼容性问题解决方案

    AllowsTransparency和System.Windows.Controls.WebBrowser兼容性问题,能看这篇文章,所以原因也不用多说:最根本的就是因为MS对win32底层的WebBr ...

  2. jhipster初接触

    在Windows7部署之前把几个依赖下了 jdk:1.80 Maven :3.3.9 git:2.14.1 npm:唯一要注意的就是配置一个阿里的镜像,不然慢的你崩溃 Yeoman: npm inst ...

  3. 问题:C#属性;结果:c# 属性

    c# 属性 属性:get { //读属性代码 } set { //写属性代码 } public class Person{private string name;public string Name{ ...

  4. C++ 学习之---C++基础理论知识(也适合面试回顾)

    C++ 语言编写的基础练习 具体案例放在github中 github地址:https://github.com/Master-fd/C-Base 1. 操作符重载 2. 构造与析构 3. 函数模板 4 ...

  5. IE6中浮动双边距bug

    想要创建出漂亮的网页设计, 除了要认真学习每一个html和CSS代码之外,不可能不去了解一下臭名昭著的IE6和更早的那些IE浏览器的坏脾气,因为你本来写出的规规矩矩的代码, 漂亮的设计就此就要完成了, ...

  6. R: 绘图 pie & hist

    问题: 绘制 pie .hist 图 解决方案: 饼图函数 pie( ) pie(x, labels = names(x), edges = 200, radius = 0.8, clockwise ...

  7. 利用HTML5 与CSS3 做的放大镜

    利用HTML5 与CSS3 做的放大镜 html结构 <div class="wrap"> <div class="move"> < ...

  8. Linux之tcpdump使用详解

    1.1  三种关键字 关于类型的关键字 第一种是关于类型的关键字,主要包括host,net,port, 例如 host 210.27.48.2,指明 210.27.48.2是一台主机,net 202. ...

  9. Excel课程学习

    1.Excel软件简介 1.1历史上的其他数据处理软件与Microsoft Excel 1977年,苹果公司开发了一款数据处理软件,当时这款软件卖的非常好,用软件的尾巴摇动硬件的狗,当时有人因为这款软 ...

  10. 图(最短路径算法————迪杰斯特拉算法和弗洛伊德算法).RP

    文转:http://blog.csdn.net/zxq2574043697/article/details/9451887 一: 最短路径算法 1. 迪杰斯特拉算法 2. 弗洛伊德算法 二: 1. 迪 ...