本帖最后由 ahuaahua 于 2018-3-1 18:38 编辑
有幸在年初的答题中,获得Nucleo STM32L4R5ZI板一块。正所谓吃别人的嘴软,免费拿人家的……必须要发个评测弘扬一下ST大法好~~~但是板子寄到手时已接近春节,年后回来放浪至今才有时间拿出来玩,不知道还能不能参加评测奖励?
L4 Plus主打图形、低功耗,以及高主频、大Flash、和帅气的Ram,还有加密等等一系列特性(具体见手册),由于时间关系,本次先对最重要的低功耗特性进行验证。
1、原理验证 根据Nucleo 144的原理图,MCU主要由两个地方提供电源:VDD和VDD_MCU。其中,VDD提供给IO、模拟、USB等部分。VDD_MCU则提供给VBAT,并通过SB167选择提供给模拟部分。详见下图: 1.1 VDD来源: 经过JP6选择电源后,由U6降压为3.3V,经VDD提供给MCU。VDD前的JP5(IDD),即为板子提供的电流测试点。详见下图: 1.2 VDD_MCU来源: 由下图可知,VDD_MCU由VDD产生,产生的方式根据Nucleo板子是否带有SMPS功能(就是外部的开关电源)决定。本次到手的板子,是不带这个功能的,保持原样即可。如果有同学收到带“-P”版本的板子,需要注意这个问题,必要时修改对应的连接。
1.3 由以上原理分析可知: 只要在JP5跳线帽上测试电流,就可以大概知道MCU的功耗情况。为什么要说大概?因为还有一个器件也使用VDD_MCU,它就是U14: 追求极致的同学们可以详细查SN74LVC2T45的资料,在此我就不累赘了。
2 测试方法
2.1 必须再歌颂一次ST大法好 在STM32CubeL4库里,已经有对应的低功耗Example例程,直接编译下载到板子上即可测试。 在用户的目录下,STM32Cube\Repository\STM32Cube_FW_L4_V1.11.0\Projects\NUCLEO-L4R5ZI\Examples\PWR\PWR_ModesSelection里,可以找到一个关于这个工程的readme.txt的文件: - - PWR/PWR_ModesSelection/Inc/stm32l4xx_conf.h HAL Configuration file
- - PWR/PWR_ModesSelection/Inc/stm32l4xx_it.h Header for stm32l4xx_it.c
- - PWR/PWR_ModesSelection/Inc/main.h Header file for main.c
- - PWR/PWR_ModesSelection/Src/system_stm32l4xx.c STM32L4xx system clock configuration file
- - PWR/PWR_ModesSelection/Src/stm32l4xx_it.c Interrupt handlers
- - PWR/PWR_ModesSelection/Src/main.c Main program
- - PWR/PWR_ModesSelection/Src/lprun_test.c Low Power RUN mode test
- - PWR/PWR_ModesSelection/Src/lpsleep_test.c Low Power SLEEP mode test
- - PWR/PWR_ModesSelection/Src/run_range1_test.c RUN mode in range 1 test
- - PWR/PWR_ModesSelection/Src/run_range2_test.c RUN mode in range 2 test
- - PWR/PWR_ModesSelection/Src/shutdown_test.c SHUTDOWN mode test
- - PWR/PWR_ModesSelection/Src/sleep_range1_test.c SLEEP mode in range 1 test
- - PWR/PWR_ModesSelection/Src/sleep_range2_test.c SLEEP mode in range 2 test
- - PWR/PWR_ModesSelection/Src/standby_rtc_sram2_test.c STANDBY mode with RTC and SRAM2 preserved test
- - PWR/PWR_ModesSelection/Src/standby_rtc_test.c STANDBY mode with RTC test
- - PWR/PWR_ModesSelection/Src/standby_test.c STANDBY mode test
- - PWR/PWR_ModesSelection/Src/stop1_mroff_rtc_test.c STOP1 mode with RTC but Regulator OFF test
- - PWR/PWR_ModesSelection/Src/stop1_mroff_test.c STOP1 mode with Regulator OFF test
- - PWR/PWR_ModesSelection/Src/stop2_rtc_test.c STOP2 mode with RTC test
- - PWR/PWR_ModesSelection/Src/stop2_test.c STOP2 mode test
复制代码
2.2 简单抽其中几个,看看这些模式究竟做了什么: - void test_lprun_2mhz(void)
- {
- printf("\n\r Executing test (LPRUN 2MHz - with FLASH ART ON) \n\r");
- printf(" Please measure current then use Reset button to select another test \n\r");
- /* Set all GPIO in analog state to reduce power consumption */
- GPIO_AnalogState_Config();
-
- /* Set the System clock to 2 MHz (MSI) */
- SystemClock_2MHz();
-
- /* Suspend Tick increment to prevent wakeup by Systick interrupt. */
- /* Otherwise the Systick interrupt will wake up the device within 1ms */
- /* (HAL time base). */
- HAL_SuspendTick();
- #ifdef USE_STM32L4XX_NUCLEO
- /* Disable USART2 clock */
- __HAL_RCC_USART2_CLK_DISABLE();
- #elif USE_STM32L4XX_NUCLEO_144
- /* Disable LPUART1 clock */
- __HAL_RCC_LPUART1_CLK_DISABLE();
- #endif
-
- /* Enable Power Clock */
- __HAL_RCC_PWR_CLK_ENABLE();
-
- /* Enter LP RUN mode */
- HAL_PWREx_EnableLowPowerRunMode();
-
- /* Disable Power Clock */
- __HAL_RCC_PWR_CLK_DISABLE();
-
- while1Aligned64();
-
- }
复制代码很简单的几步: 1、把IO口都设为模拟; 2、更改时钟; 3、停掉Systick和串口; 4、打开电源时钟; 5、使能一下LP RUN; 6、关闭电源时钟; 7、死循环。
- void test_run_range1_80mhz(void)
- {
- printf("\n\r Executing test (RUN Range 1, 80MHz - with FLASH ART ON) \n\r");
- printf(" Please measure current then use Reset button to select another test \n\r");
- /* Set all GPIO in analog state to reduce power consumption */
- GPIO_AnalogState_Config();
-
- #ifdef USE_STM32L4XX_NUCLEO
- /* Disable USART2 clock */
- __HAL_RCC_USART2_CLK_DISABLE();
- #elif USE_STM32L4XX_NUCLEO_144
- /* Disable LPUART1 clock */
- __HAL_RCC_LPUART1_CLK_DISABLE();
- #endif
-
- /* Set System clock to 80 MHz (MSI) */
- SystemClock_80MHz();
-
- /* Suspend Tick increment to prevent wakeup by Systick interrupt. */
- /* Otherwise the Systick interrupt will wake up the device within 1ms */
- /* (HAL time base). */
- HAL_SuspendTick();
-
- while1Aligned64();
-
- }
复制代码更为简单的几步: 1、把IO口都设为模拟; 2、关掉串口; 3、更改时钟; 4、停掉Systick; 5、死循环。
- void test_stop2(void)
- {
- printf("\n\r Executing test (STOP2) \n\r");
- printf(" Please measure current then use Reset button to select another test \n\r");
- /* Set all GPIO in analog state to reduce power consumption */
- GPIO_AnalogState_Config();
-
- /* Enable Power Clock */
- __HAL_RCC_PWR_CLK_ENABLE();
-
- /* Enter STOP 2 mode */
- HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
-
- }
复制代码还可以更简单的几步: 1、把IO口都设为模拟; 2、关掉电源时钟; 3,发一个WFI指令。
2.4 这里需要补充啰嗦几句: 2.4.1、把IO设为模拟,这只是在测试中,排除外部干扰,使测试数据“单纯”一些的使用方法。实际产品一般不会这么用,因为这样会降低产品的抗干扰能力,比如EMI。 2.4.2、这里的测试,都没有使用外部HSE时钟,全部使用MSI(RC振荡产生)。在实际产品中,不使用外部晶振的情况比较少,而外部晶振所需要的电流,对测试的影响还是较大的。 2.4.3、由于Nucleo板的设置,VBAT是直连VDD_MCU和VDD的,所以测试并不能完全反映MCU在VDD断开,且VBAT在电池供电下的情况。
3、测试 既然方法都知道了,撸起袖子动手干吧。由于财力有限(求土豪赞助,求高大上的老板收留),拿出手的只有一个比对过、精度相对较好的4位半万用表,结果如下: No. | | | 0 | | | 1 | | | 2 | | | 3 | | | 4 | | | 5 | | | 6 | | | 7 | | | 8 | | | 9 | LPRUN 2MHz - with FLASH ART ON | | 10 | SLEEP Range 2, 24MHz - with FLASH ART ON | | 11 | SLEEP Range 1, 80MHz - with FLASH ART ON | | 12 | RUN Range 2, 24MHz - with FLASH ART ON | | 13 | RUN Range 1, 80MHz - with FLASH ART ON | |
3.1测试结果的看法: 3.1.1、在STANDBY状态中,反正都停下来了,能不用SRAM就别用,功耗增加近1倍,尽量用备份域保存数据。 3.1.2、STOP1和STOP2的功耗区别是明显的。 3.1.3、如果要RUN,且没什么性能要求,LP RUN是很好的选择。但是要注意外设的处理。 3.1.4、仪表所限,电流较低的几个测试已接近仪表的极限和误差,仅作参考。
3.2 题不是白答的,板子不是白拿的,测试不是白做的。 清楚记得,L4R5是可以跑120MHz的,这个测试只是跑到了80MHz(也就是前任L4的速度,不知是故意为之,还是忘了修改),还没显示出这个测试中MCU,最高主频的状态。
重要的事情要说第三遍了:ST大法真的好!修改时钟这种事,小手一抖,简单得不得了!
3.2.1打开最新的CubeMX,选择NucleoL4R5ZI板子,Do NOT初始化默认外设设置(因为会打开很多功能),直接进去,看时钟配置: 3.2.2选择时钟源为MSI,PLLCLK,在HCLK输入120,然后就自动算出PLLM1的N为60,R为2。然后生成代码。
3.2.3 为了偷懒,直接修改测试13。对比一下生成的代码以及测试13的代码:
CubeMX生成的代码: - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
- RCC_OscInitStruct.MSIState = RCC_MSI_ON;
- RCC_OscInitStruct.MSICalibrationValue = 0;
- RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
- RCC_OscInitStruct.PLL.PLLN = 60;
- RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
复制代码
测试13的代码: - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
- RCC_OscInitStruct.MSIState = RCC_MSI_ON;
- RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
- RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT; //这个宏的值是0
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
- RCC_OscInitStruct.PLL.PLLM = 1;
- RCC_OscInitStruct.PLL.PLLN = 40;
- RCC_OscInitStruct.PLL.PLLR = 2;
复制代码
由此可见,直接把测试13的RCC_OscInitStruct.PLL.PLLN,改成60即可。
修改代码后,再跑一次测试,结果是:
No. | | | 14 | RUN Range 1, 120MHz - with FLASH ART ON | |
好了,测试到此就结束了。 按照测试的结果计算,3.3V的电源下,MCU在全速的时候功率约为55mW,还是相当不错滴。
最后,尽管是ST大法好,还是要吐槽一下:CubeMX的功率估算,L4R5的数据还没更新(只能到80MHz)。作为当前主推的产品,请注意细节~
感谢观看,请丢给我小红花。
|