STMicroelectronics 系列:STM32L4 系列_(3).STM32L4系列的低功耗技术
STM32L4系列的低功耗技术
1. 低功耗概述
STM32L4系列单片机是STMicroelectronics公司推出的高性能低功耗微控制器,广泛应用于各种需要长时间运行且功耗要求严格的嵌入式系统。低功耗技术是STM32L4系列的核心优势之一,通过多种机制和优化措施,实现了在不同工作模式下的最低功耗。
2. 低功耗工作模式
STM32L4系列支持多种低功耗工作模式,包括低功耗运行模式(Low-Power Run)、低功耗睡眠模式(Low-Power Sleep)、停止模式(Stop)、待机模式(Standby)和低功耗待机模式(Low-Power Standby)。每种模式都有其独特的功耗特性和适用场景。
2.1 低功耗运行模式(Low-Power Run)
低功耗运行模式是最基本的低功耗模式,在此模式下,CPU和外设都在运行,但通过降低时钟频率和关闭不必要的外设来减少功耗。此模式适用于需要保持较高性能但同时减少功耗的场景。
代码示例:
// 降低系统时钟频率到2 MHz
void enterLowPowerRunMode(void) {
// 配置系统时钟
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
// 使能内部低速时钟(LSI)
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
// 选择LSI作为系统时钟源
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_LSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);
}
2.2 低功耗睡眠模式(Low-Power Sleep)
低功耗睡眠模式下,CPU停止运行,但外设和RAM保持供电,可以快速唤醒。此模式适用于CPU不需要运行但外设需要继续工作的场景。
代码示例:
// 进入低功耗睡眠模式
void enterLowPowerSleepMode(void) {
// 关闭所有不必要的外设
__HAL_RCC_TIM1_DISABLE();
__HAL_RCC_TIM2_DISABLE();
__HAL_RCC_TIM3_DISABLE();
// 设置睡眠模式
HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON, PWR_SLEEPENTRY_WFI);
}
2.3 停止模式(Stop)
停止模式下,CPU和外设停止运行,但RAM保持供电。此模式功耗更低,但唤醒时间较长。适用于长时间不需要处理数据的场景。
代码示例:
// 进入停止模式
void enterStopMode(void) {
// 配置RTC唤醒中断
RTC_InitTypeDef RTC_InitStructure = {0};
RTC_InitStructure.HourFormat = RTC_HOURFORMAT_24;
RTC_InitStructure.AsynchronousPrediv = 0x7F;
RTC_InitStructure.SynchronisationPrediv = 0xFF;
HAL_RTC_Init(&hrtc, &RTC_InitStructure);
// 配置RTC唤醒时间
RTC_TimeTypeDef RTC_TimeStructure;
RTC_TimeStructure.Hours = 1;
RTC_TimeStructure.Minutes = 0;
RTC_TimeStructure.Seconds = 0;
HAL_RTC_SetAlarm_IT(&hrtc, RTC_FORMAT_BIN, &RTC_TimeStructure);
// 进入停止模式
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
}
2.4 待机模式(Standby)
待机模式下,CPU、外设和RAM都停止供电,只有RTC和备份寄存器保持供电。此模式功耗最低,但唤醒时间最长。适用于长时间休眠的场景。
代码示例:
// 进入待机模式
void enterStandbyMode(void) {
// 配置RTC唤醒中断
RTC_InitTypeDef RTC_InitStructure = {0};
RTC_InitStructure.HourFormat = RTC_HOURFORMAT_24;
RTC_InitStructure.AsynchronousPrediv = 0x7F;
RTC_InitStructure.SynchronisationPrediv = 0xFF;
HAL_RTC_Init(&hrtc, &RTC_InitStructure);
// 配置RTC唤醒时间
RTC_TimeTypeDef RTC_TimeStructure;
RTC_TimeStructure.Hours = 1;
RTC_TimeStructure.Minutes = 0;
RTC_TimeStructure.Seconds = 0;
HAL_RTC_SetAlarm_IT(&hrtc, RTC_FORMAT_BIN, &RTC_TimeStructure);
// 进入待机模式
HAL_PWR_EnterSTANDBYMode();
}
2.5 低功耗待机模式(Low-Power Standby)
低功耗待机模式类似于待机模式,但可以通过更少的电源管理和更低的唤醒时间来进一步降低功耗。适用于需要极低功耗且对唤醒时间有一定要求的场景。
代码示例:
// 进入低功耗待机模式
void enterLowPowerStandbyMode(void) {
// 配置RTC唤醒中断
RTC_InitTypeDef RTC_InitStructure = {0};
RTC_InitStructure.HourFormat = RTC_HOURFORMAT_24;
RTC_InitStructure.AsynchronousPrediv = 0x7F;
RTC_InitStructure.SynchronisationPrediv = 0xFF;
HAL_RTC_Init(&hrtc, &RTC_InitStructure);
// 配置RTC唤醒时间
RTC_TimeTypeDef RTC_TimeStructure;
RTC_TimeStructure.Hours = 1;
RTC_TimeStructure.Minutes = 0;
RTC_TimeStructure.Seconds = 0;
HAL_RTC_SetAlarm_IT(&hrtc, RTC_FORMAT_BIN, &RTC_TimeStructure);
// 配置低功耗待机模式
PWR->CR3 &= ~PWR_CR3_APC; // 关闭APC(Auto Power Control)
PWR->CR1 |= PWR_CR1_LPR; // 使能低功耗模式
// 进入低功耗待机模式
HAL_PWR_EnterSTANDBYMode();
}
3. 低功耗外设配置
STM32L4系列单片机提供了多种低功耗外设,如低功耗定时器(LPTIM)、低功耗USART(LPUART)和低功耗SPI(LPSPI)。这些外设可以在低功耗模式下继续工作,从而在功耗和功能之间取得平衡。
3.1 低功耗定时器(LPTIM)
LPTIM是一种低功耗定时器,可以在停止模式下继续运行。通过配置LPTIM,可以在不同的低功耗模式下实现周期性唤醒或其他定时功能。
代码示例:
// 配置LPTIM
void configureLPTIM(void) {
LPTIM_HandleTypeDef hlptim1;
// 基本配置
hlptim1.Instance = LPTIM1;
hlptim1.Init.Prescaler = LPTIM_PRESCALER_1;
hlptim1.Init.CounterSource = LPTIM_COUNTERSOURCE_INTERNAL;
hlptim1.Init.TriggerSource = LPTIM_TRIGSOURCE_NONE;
hlptim1.Init.UpdateMode = LPTIM_UPDATE_MODE_IMMEDIATE;
hlptim1.Init.AutoReloadWriteMode = LPTIM_AUTORELOAD_WRITE_MODE_SINGLE;
hlptim1.Init.Input1Source = LPTIM_INPUT1_SRC_GPIO;
hlptim1.Init.Input2Source = LPTIM_INPUT2_SRC_GPIO;
hlptim1.Init.RepetitionCounter = 0;
HAL_LPTIM_Init(&hlptim1);
// 配置周期性中断
hlptim1.Init.Period = 1000; // 1秒周期
HAL_LPTIM_ConfigTimeOut(&hlptim1, &hlptim1.Init, LPTIM_STATE_STOP, LPTIM_STATE_START);
}
// 进入停止模式并配置LPTIM唤醒
void enterStopModeWithLPTIM(void) {
configureLPTIM();
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
}
3.2 低功耗USART(LPUART)
LPUART是一种低功耗串行通信接口,可以在停止模式下继续接收数据。通过配置LPUART,可以在低功耗模式下实现串行通信。
代码示例:
// 配置LPUART
void configureLPUART(void) {
LPUART_HandleTypeDef hlpuart1;
// 基本配置
hlpuart1.Instance = LPUART1;
hlpuart1.Init.BaudRate = 9600;
hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;
hlpuart1.Init.StopBits = UART_STOPBITS_1;
hlpuart1.Init.Parity = UART_PARITY_NONE;
hlpuart1.Init.Mode = UART_MODE_TX_RX;
hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
hlpuart1.Init.ClockPrescaler = UART_PRESCALER_1;
hlpuart1.Init.AdvancedInit.HighSpeedConfig = UART_HIGH_SPEED_DISABLE;
hlpuart1.Init.AdvancedInit.HighSpeedValue = UART_HIGH_SPEED_VALUE_0;
hlpuart1.Init.AdvancedInit.IdleStateDetect = UART_IDLE_STATE_DETECT_DISABLE;
hlpuart1.Init.AdvancedInit.RxPinActiveLevel = UART_RX_PIN_ACTIVE_LEVEL_HIGH;
hlpuart1.Init.AdvancedInit.TxPinActiveLevel = UART_TX_PIN_ACTIVE_LEVEL_HIGH;
hlpuart1.Init.AdvancedInit.AdvancedFeaturesInit = UART_ADVFEATURES_NO_INIT;
HAL_LPUART_Init(&hlpuart1);
// 配置中断
HAL_NVIC_SetPriority(LPUART1_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(LPUART1_IRQn);
}
// LPUART中断处理函数
void LPUART1_IRQHandler(void) {
HAL_LPUART_IRQHandler(&hlpuart1);
}
// LPUART接收完成回调函数
void HAL_LPUART_RxCpltCallback(LPUART_HandleTypeDef *hlpuart) {
// 处理接收到的数据
uint8_t receivedData;
HAL_LPUART_Receive(hlpuart, &receivedData, 1, HAL_MAX_DELAY);
// 执行相应的操作
}
// 进入停止模式并配置LPUART唤醒
void enterStopModeWithLPUART(void) {
configureLPUART();
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
}
3.3 低功耗SPI(LPSPI)
LPSPI是一种低功耗SPI接口,可以在停止模式下继续通信。通过配置LPSPI,可以在低功耗模式下实现SPI通信。
代码示例:
// 配置LPSPI
void configureLPSPI(void) {
LPSPI_HandleTypeDef hlpspi1;
// 基本配置
hlpspi1.Instance = LPSPI1;
hlpspi1.Init.Mode = LPSPI_MODE_MASTER;
hlpspi1.Init.BaudRatePrescaler = LPSPI_BAUDRATEPRESCALER_2;
hlpspi1.Init.DataSize = LPSPI_DATASIZE_8BIT;
hlpspi1.Init.FirstBit = LPSPI_FIRSTBIT_MSB;
hlpspi1.Init.NSS = LPSPI_NSS_SOFT;
hlpspi1.Init.TIMode = LPSPI_TIMODE_DISABLE;
hlpspi1.Init.CRCCalculation = LPSPI_CRCCALCULATION_DISABLE;
hlpspi1.Init.CRCPolynomial = 10;
hlpspi1.Init.Image = LPSPI_IMAGE_DISABLE;
hlpspi1.Init.ImageSize = LPSPI_IMAGE_SIZE_0;
hlpspi1.Init.ImagePolarity = LPSPI_IMAGE_POLARITY_HIGH;
hlpspi1.Init.ImagePrescaler = LPSPI_IMAGE_PRESCALER_1;
hlpspi1.Init.ImageMode = LPSPI_IMAGE_MODE_MASTER;
hlpspi1.Init.AdvancedInit.CRCCalculation = LPSPI_CRCCALCULATION_DISABLE;
hlpspi1.Init.AdvancedInit.CRCPolynomial = 10;
hlpspi1.Init.AdvancedInit.AdvancedFeaturesInit = LPSPI_ADVFEATURES_NO_INIT;
HAL_LPSPI_Init(&hlpspi1);
// 配置中断
HAL_NVIC_SetPriority(LPSPI1_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(LPSPI1_IRQn);
}
// LPSPI中断处理函数
void LPSPI1_IRQHandler(void) {
HAL_LPSPI_IRQHandler(&hlpspi1);
}
// LPSPI传输完成回调函数
void HAL_LPSPI_TxCpltCallback(LPSPI_HandleTypeDef *hlpspi) {
// 处理传输完成后的操作
uint8_t sendData = 0x55;
HAL_LPSPI_Transmit(hlpspi, &sendData, 1, HAL_MAX_DELAY);
}
// 进入停止模式并配置LPSPI唤醒
void enterStopModeWithLPSPI(void) {
configureLPSPI();
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
}
4. 低功耗编程技巧
在STM32L4系列单片机中,通过一些编程技巧可以进一步降低功耗。这些技巧包括优化代码执行、合理配置GPIO、使用DMA传输数据等。
4.1 优化代码执行
优化代码执行可以减少CPU的运行时间,从而降低功耗。通过使用高效的算法和减少不必要的循环,可以显著提高能效。
代码示例:
// 使用高效的算法减少CPU运行时间
void efficientAlgorithm(void) {
uint32_t sum = 0;
uint32_t data[1000] = {0}; // 假设data数组已经初始化
// 使用向量化指令加速求和
for (int i = 0; i < 1000; i += 4) {
sum += data[i] + data[i + 1] + data[i + 2] + data[i + 3];
}
// 处理求和结果
// ...
}
4.2 合理配置GPIO
合理配置GPIO可以减少不必要的电流消耗。通过设置GPIO为高阻态或输入模式,可以减少漏电流。
代码示例:
// 合理配置GPIO
void configureGPIO(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
// 使能GPIO时钟
__HAL_RCC_GPIOA_CLK_ENABLE();
// 配置PA0为输入模式
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// 配置PA1为高阻态
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
4.3 使用DMA传输数据
使用DMA(Direct Memory Access)传输数据可以减少CPU的干预,从而降低功耗。通过配置DMA,可以在CPU休眠时继续传输数据。
代码示例:
// 配置DMA传输数据
void configureDMA(void) {
DMA_HandleTypeDef hdma_spi1_tx;
// 使能DMA时钟
__HAL_RCC_DMA1_CLK_ENABLE();
// 配置DMA通道
hdma_spi1_tx.Instance = DMA1_Channel2;
hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_spi1_tx.Init.Mode = DMA_NORMAL;
hdma_spi1_tx.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_Init(&hdma_spi1_tx);
// 配置SPI使用DMA传输
__HAL_LINKDMA(&hspi1, hdmatx, hdma_spi1_tx);
}
// 使用DMA传输数据
void useDMA(void) {
uint8_t sendData[100] = {0}; // 假设数据已经初始化
HAL_SPI_Transmit_DMA(&hspi1, sendData, 100); // 使用DMA传输数据
}
5. 低功耗调试和测试
在开发低功耗应用时,调试和测试是非常重要的环节。通过使用STMicroelectronics提供的调试工具和方法,可以确保应用在低功耗模式下正常运行。
5.1 使用STM32CubeIDE调试
STM32CubeIDE提供了强大的调试功能,可以方便地测试低功耗模式下的应用。通过设置断点和监视变量,可以详细分析功耗特性。
步骤:
-
打开STM32CubeIDE,创建或打开一个STM32项目。
-
在项目中设置断点,以便在进入低功耗模式时暂停。
-
使用调试器连接目标板,开始调试。
-
监视变量和寄存器,确保低功耗模式下的配置正确。
5.2 使用功耗测量工具
使用功耗测量工具,如万用表或电流探头,可以准确测量STM32L4系列单片机在不同模式下的功耗。通过对比不同配置下的功耗,可以优化应用的能效。
步骤:
-
将STM32L4系列单片机连接到功耗测量工具。
-
编写测试代码,进入不同的低功耗模式。
-
记录每个模式下的功耗数据。
-
分析功耗数据,
作者:kkchenkx