目录
1. 概述
为了降低功耗,需要在运行过程中,降低STM32H7的系统时钟。之前没有用到过,降主频对外设会不会有什么影响,甚至导致死机等异常?问了问,都觉得直接降就可以了,没有问题的。
在STMF103测试了下,将72M降为16M,这里简单记录过程。基础工程STM32CubeMX使用之串口通信。
2. 直接修改外部时钟
2.1 生成时钟函数
通过修改STM32CubeMX配置分频系数,得到72M和16M的时钟初始化函数:
2.1.1 设置系统时钟为16M:
生成code,得到SystemClock_Config(),将函数名称修改为SystemClock_Config_16M()。
2.1.2 配置时钟72M:
生成code,得到SystemClock_Config()。
2.2 测试降频
在main函数中增加测试代码:
结果发现只打印出第一句:
仿真查看,是设置16M时,HAL库返回失败:
3. 借助内部时钟
想到STM32在进入主函数,调用SystemClock_Config()之前是如何运行的呢?是内部时钟。那么就尝试下先将72M切换为内部时钟,再切换回16M外部时钟。
3.1 生成时钟函数
STM32CubeMX配置为使用内部时钟:
生成code,得到SystemClock_Config(),将函数名称修改为SystemClock_Config_HSI()。
3.2 测试降频
修改测试程序:
查看测试结果:
4. 直接降频失败原因
已经实现了降频,再来看下为什么直接改外部时钟会失败。仿真查看,最后返回错误是因为寄存器倍频值与传入不符:
分析HAL_RCC_OscConfig函数:
前半部分是设置时钟源,后半部分是设置锁相环PLL。直接由72M切换为16M,则判断PLL是系统时钟,且已经ON的状态,进入最下面的else分支。这时读取寄存器内的倍频值(72M),发现与传入的倍频值(16M)不相等,则返回HAL_ERROR。
从这里看出,如果再次配置72M,是可以配置成功的。测试了下也确实如此,可以重复配置系统时钟为72M,而不是最开始认为的不能再次设置。
为什么函数逻辑是这样的呢?查找了下HAL_RCC_OscConfig函数,结果找到一个链接,也是通过内部时钟来实现:STM32实战项目:HAL_RCC_OscConfig中程序卡死问题解决办法。
根据链接方式,查找了下《STM32F10xxx参考手册中文版》,也找到了这个说明:
还是基础不太好吧。先上手用,用起来又没有回过头系统学习。
另外,调整主频后,需要重新初始化外设。测试比较简单,实际应用可能还需要先关闭外设,否则切换过程中有通信需求,是否会有影响?