1、前言
这是在项目中无意发现的问题,其实有同样更复杂的工程可以运行,但是后来发现新建一个简单工程反而运行不了了,但是同样更复杂的工程可以运行说明本来同事原来已经不知道在哪里找到了解决问题的办法,但是后来忘记了,也找不到了,但是既然再次遇到并且解决了,所以特此记录,谨防再次遗忘。
2、问题与复现办法
随便新建个项目,时钟配置到稍微高点如40MHz,再随便配置个外设,用代码生成后无法运行,卡在
if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE4) != HAL_OK)
{
Error_Handler();
}
无法运行
3、解决的问题的过程
在使用STM32Cube.IDE这款软件时,可以在Clock Configuration中便捷的配置时钟树更改主频
时钟树默认主频为4M(针对我使用的这款芯片,不同芯片默认时钟树配置可能不同),当将其修改为大于40M的主频时,程序会跑飞,当DeBug一步一步往下跑的时候发现程序卡死在这个函数里
虽然不明其意,但是大概能够猜测是配置主内部稳压器输出电压,我们可以跳进去看看
if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE4) != HAL_OK)
{
Error_Handler();
}
其实在HAL库中对于这个函数也有了很详细的介绍
在这里为大家附赠上翻译(我是英语四级没过的渣用有道词典翻译的orz)
===============================================================================
#####电源控制功能#####
===============================================================================
[. .]
介绍控制电源的功能。
[. .]
(+) STM32U5系列器件嵌入两个稳压器:一个LDO(线性
电压调节器)和一个SMPS(降压转换器)并联
为数字外设SRAM1, SRAM2, SRAM3提供VCORE电源
SRAM4和嵌入式闪存。
(+) SMPS允许降低功耗,但有些
外围设备可能会受到SMPS产生的噪声的干扰,
要求应用程序在运行时切换到LDO
外围设备才能达到最佳性能。
(+) LDO和SMPS稳压器有两种模式:主稳压器模式
(当需要性能时使用),和低功率调节器模式。LDO
或SMPS可用于所有电压缩放范围,并在所有停止
模式。
(+)复位后,稳压器为LDO,范围为4。切换到SMPS
提供更低的消耗,特别是在高VDD电压。它是
可以从LDO切换到SMPS,或者从SMPS切换到LDO
任何范围,通过配置REGSEL位。建议进行切换
在改变电压范围之前,首先要到SMPS。
(+)当退出停止或待机模式时,稳压器与
进入低功耗模式时。电压量程为范围4。
(+)两个稳压器可以提供四种不同的电压(电压缩放)
并可在停止模式下运行。
电压缩放范围可以是以下值之一:
(++)电压输出刻度1:1V2
=比;当系统时钟频率高达160mhz时使用
(++)电压输出刻度2:1V1
=比;当系统时钟频率不超过100mhz时使用
(++)电压输出刻度3:1V0
=比;当系统时钟频率高达50mhz时使用
(++)电压输出刻度4:0V9
=比;当系统时钟频率高达24mhz时使用
@endverbatim
* @ {
* /
/ * *
* @brief配置主内部稳压器输出电压来实现
*性能和功耗之间的权衡。
* @param voltagscaling:指定稳压器输出电压刻度。
*该参数可以是以下值之一:
* @arg @ref PWR_REGULATOR_VOLTAGE_SCALE1:稳压输出刻度1。
*提供1.2 V的典型输出电压。
*当系统时钟频率高达160mhz时使用。
* @arg @ref PWR_REGULATOR_VOLTAGE_SCALE2:稳压输出刻度2。
*提供1.1 V的典型输出电压。
*当系统时钟频率高达100mhz时使用。
* @arg @ref PWR_REGULATOR_VOLTAGE_SCALE3:稳压器电压输出刻度3。
*提供1.0 V的典型输出电压。
*当系统时钟频率高达50mhz时使用。
* @arg @ref PWR_REGULATOR_VOLTAGE_SCALE4:稳压输出刻度4。
*提供0.9 V的典型输出电压。
*当系统时钟频率高达24mhz时使用。
* @注意在移动到电压缩放2之前,必须确保
*系统频率在50mhz到100mhz之间。
* @注意在移动到电压缩放3之前,必须确保
*系统频率在24mhz到50mhz之间。
* @注意在移动到电压缩放4之前,必须确保
*系统频率低于24mhz。
* @检索HAL状态。
* /
这里暂且没有发现什么问题,但是当我们将系统主频改到40时会发现,IDE自动生成的代码中的rang值变成了1但是按照库中说明应该是3
这表示我们更改主频实际上并没有成功,并且在此过程中发现了一个奇怪的问题
SystemPower_Config
这个函数竟然是空的
这是没有配置系统的电源吗?所以导致更改主频失败,这里没有书写任何代码,都是IDE自动生成的,对于新功能IDE可能会出错,但是最基本的没道理会出错,所以我想一定的缺少了某一步配置的问题,所以就在配置中寻找,终于找到了一个最可能的配置选项
大概意思是电源安全、权限的意思?尝试将其打开之后发现程序不会卡死可以顺利运行了,所以我想也许是更改主频就是需要这个权限吧,只是需要我们手动打开,但是回到代码中发现,其实
这个函数还是空的,对比已有可运行工程,发现是有内容的
在具体的对比配置后发现,原有工程是在这个地方配置低功耗开关的,所以推测 SystemPower_Config
这个函数是专门用来控制低功耗的,与一开始的猜想并无关系,并且一开始可能就是因为在寻找如何配置低功耗时,看到了别人将Privilege attributes
这个选项勾上了才将其勾上,误打误撞的没遇上这个问题,不过好在现在也算是解决了吧。
并且就另一部分rang的范围,在我们系统主频设为40M时,仍然是 PWR_REGULATOR_VOLTAGE_SCALE1
测试更改多个范围数值都只会在1、4之间改变,不会跳到2/3具体是为什么网上并没有搜到结果,如果有知道原因的欢迎交流讨论。