话接上贴,上回说到使用 STM32f0的定时器定时闪烁led。这回来说说它的时钟配置。之所以这么安排,先讲定时器,是因为讲了定时器,再更改时钟配置,会比较好判断现象。 之前我们也有讲到,stm32f0这片子上电默认主频是16MHz,但由于内部bootloader帮我们配置了时钟,所以上电之后,时钟频率为48MHz,这次我们就来尝试着修改它的主频,并根据上面一讲的定时器闪烁led现象看看结果,好吧。。。 这里还要用到参考手册里面的时钟树那张图:
从图中我们可以看到外部HSE经过选择开关SW后再经过AHB预分频器为cpu、内存、DMA和AHB总线提供时钟,再经过APB预分频器为APB外设提供时钟,再次经过APB1预分频器为定时器提供时钟,这里我们要做的,就是关闭PLL,然后配置上面的各个预分频器而已,这里我们让cpu跑1MHz,让定时器驱动led还是1s闪烁一次好吧。。。
由于我们的f0工作在48MHz的状态,时钟来源为HSE-PLL,根据说明,我们如果要改变HSE的状态,这种情况下是不能直接改变的,必须首先将时钟切换到另一个时钟源,说明如下:
我们这里切换回HSI好吧,然后修改完HSE之后,再切换回来,好吧。。。 分析void SystemInit (void)这个函数,发现原厂工程师们在开启HSE+PLL并设置成系统时钟之后,上电默认的时钟源HSI并没有关闭,依然在运行,这么做有好处也有坏处,优点是当HSE或者PLL出现问题被CSS系统关闭时,可以迅速切换回HSI作为时钟源,无需等待HSI启动稳定。缺点是在有低功耗要求条件下,留着HSI是一个比较耗电的部件,如果确实有需要,就可以关掉HSI。这里对我们来说还方便了一点点,我们可以直接将时钟切换回HSI,甚至不用判断HSI稳定与否,然后对HSE进行配置,当然,为了考虑健壮性,还是判断下好吧。 在这里我还要忍不住吐槽一句f0的库真是太烂了,没办法,只能看源码找函数了。。。
打开stm32f0xx_rcc.c这个文件,我是用notepad++打开的,然后装了tagsview插件,就可以在插件中显示文件中的各种数据类型、函数等,在这里和大家推荐下。如下图:
因为使用固件库的.chm帮助文件太难找了,所以还是用源码对照着参考手册找函数吧,这样也比直接配置寄存器强多了。。。
前面说了一大堆理论,还没讲实践,下面来实战。将上节的代码拷贝重命名为CLK+ tiM+LED文件夹,然后在User目录下创建两个新文件:
在.h文件中输入:
简单得很,对吧。就这一个对外函数,因为我们用的功能还少。。。在.c文件里输入如下内容:
我挺懒的,这么容易理解的例子和函数名,我一般都是不写注释的,这里稍微和大家讲讲这几行的意思吧。4-6行是将系统时钟切换回HSI,因为我们不论是操作HSE还是PLL,当他们是系统时钟的时候,是都不能直接写的,这样很不安全。根据手册说明,我们先把系统时钟切换到HSI,然后就可以随心去虐HSE和PLL了。。。 8-9行用来关闭PLL和HSE,其中PLL关了之后就没必要再开了,之所以修改HSE之前关闭它,纯属为了安全,虽然说不关也不一定有问题,但是还是这样子安全嘛,对吧。。。 11-12两行配置了HCLK和PCLK的分频比,前面在时钟树那里讲到定时器的时钟来源是HSE-HCLK-PCLK-APB1这里面APB1我也不清楚是啥,看时钟树的框图很明显就可以理解,当PCLK预分频系数为1的时候,APB1不变,当PCLK预分频系数不为1的时候,APB1倍频之后给定时器提供时钟,我们这里由于HCLK设置成了1M,为了玩一玩APB1的倍频,我们把PCLK设置成了2分频,然后APB1会自动将频率倍成1M之后给定时器提供时钟,这里要注意,我们只是在这个例子中这么玩玩才这么设置的,如果PCLK在1M的HCLK下2分频,成了500kHz,那么很多外设,尤其是有可能需要高速跑的SPI之类的,也就只能500kHz了,这里需要注意下。。。 剩下的几行就是重新将系统时钟配置为HSE,我们这里也学习st的工程师们,没有关闭HSI,大家用低功耗的时候,可以考虑关闭它。。。
都搞定了之后,在main.c中修改成这样:
到这里,大家如果把程序下载进去之后就可以跑了,但是现象应该是5s左右闪烁一次。这是为什么呢?因为我们虽然配置了主时钟和定时器时钟,但定时器计数值和重新装载值还是上节配置的呢,看下timer6.c:
我们把这两行改成这样:
然后重新运行,就可以看到我们上节讲的1s闪烁一次现象一样了。我们运行 仿真,打开系统寄存器,找到RCC这个寄存器。如下图:
对照参考手册,很明显可以发现,PLL已经被关闭。HCLK为8分频,PCLK为HCLK的2分频。
实际上,在我们个人玩mcu的时候,如果软件架构设计的好,cpu跑在1MHz的主频下,是可以应对大部分情况的,而且还可以节省“很多”的电量,我们看一下相关资料
在运行状态下,每MHz消耗250uA的电流,如果我们跑一个1MHz和48MHz都能应对的应用,这二者之间的电流消耗分别为:250uA <--> 12mA,看到差距了吧,如果使用电池供电的场合,那种普通的纽扣电池容量为40mAH的话,后者不到四个小时就耗光了所有电能。。。
至此,更改系统时钟篇结束,下回进入我们项目的第一个应用:PWM+舵机。。。
|