本文介绍了 LPBAM 功能、何时以及如何使用它,并提供了代码示例。
内容↑[隐藏]
LPBAM代表低功耗背景自主模式。它是 STM32U5 产品系列中提供的一种操作模式,允许外围设备在停止 2 模式下独立于器件电源模式运行和自主运行,而无需运行任何软件。
LPBAM 子系统可以通过 DMA 链表传输链接不同的操作。
DMA 操作可能与以下方面相关:
使用LPBAM子系统机制有两个主要优点:
总线时钟和内核时钟仅在需要时分发。
大部分产品部件都可以关闭。
模拟外设或振荡器仅在必要时才上电。
外设配置由 DMA 而不是 CPU 完成。
数据传输由 DMA 而不是 CPU 完成。
STM32U5分为两个域:CPU 域 (CD) 和 SmartRun 域 (SRD)
SRD 架构依赖于 DMA,允许在低功耗模式下自主运行,直至停止 2。 该架构还具有一个 32 位 AHB 总线矩阵,可互连:
信息 |
SRAM4 是唯一可由 LPDMA1 访问的 SRAM。 |
有 2 种类型的外围设备:
LPBAM是一种操作模式,允许外设独立于电源模式自主运行,无需运行任何软件。
LPBAM 在 Stop 2 模式下受支持。
因此,自主外设可以请求其时钟(内核或总线时钟),然后可以在停止模式下保持功能,默认情况下禁用时钟以减少功耗(LSE 和 LSI 低功耗低速振荡器除外)。
下表列出了支持 LPBAM 的所有外设。
低功耗模式 | 第 2 站 |
自主外设 | ADC4、ADF1、DAC1、LPDMA1、LPTIM1、LPTIM3、LPUART1、I2C3、SPI3 |
无源外设 | LPTIM4、LPGPIO、VREFBUF、COMP 和 OPAMP、RTC/TAMP |
信息 |
请参阅 AN5652[1]了解有关支持 LPBAM 的外围设备的更多信息。 |
要按照此示例进行操作,您需要一个 NUCLEO-U575 板。
在开始动手操作之前,请确保您已安装以下软件:
此示例的目的是在低功耗域中驱动 GPIO 引脚 (PA1),该引脚由具有两个不同频率的低功耗定时器 LPTIM 触发,该链表由 DMA 控制。
此示例的目的是演示如何:
要使用 STM32CubeMX 工具创建 LPBAM 应用程序,您需要:
信息 |
检查 AN5816[2]和这个视频[3]因为它逐步解释了如何在 STM32CubeMX 中配置 LPBAM 应用程序。 |
然后通过按下“否”按钮选择“启动没有外设初始化的项目”。为了避免生成无用的项目代码,稍后会初始化所需的外设。
要在停用 TrustZone® 时构建 LPBAM 应用程序,请执行以下操作:
STM32CubeMX工具入口点始终是标准视图。建议打开项目管理器并保存主项目。 对于此应用程序:
此时,项目已配置完毕,IOC 文件将保存在所选路径下。 为了提高系统性能,建议在单向配置中启用 ICACHE 外设。 为此,请单击“系统核心”菜单,然后单击“ICACHE”外围设备,并将“模式”更改为“1 路(直接映射缓存)”。
在此应用中,我们使用 LED(PC7 为 LED 蓝色,PG2 为 LED 红色,PB7 为 LED 绿色)来观察项目运行时状态,并使用用户按钮引脚 (PC13) 作为带有外部中断的输入。
选择 Systick 作为时基
要达到最高性能,请在“时钟配置”中,将系统时钟配置为最高值。 PLL 1 配置如下:
此时,主项目系统已配置完成。在下一步中,我们将构建“LPGPIO driving”应用程序。 点击“LPBAM场景和配置”面板
单击“ 添加应用程序”选项以添加 LPBAM 应用程序 添加 LPBAM 应用程序
时,STM32CubeMX 工具会显示 LBPAM 视图。至于标准视图,它包含“LPBAM场景和配置”,“引脚排列和配置”和“时钟配置”面板。
信息 |
项目中选择的命名应在代码生成的 API 和变量中重用。这确保了STM32CubeMX LPBAM工具视图和LPBAM生成的应用程序代码之间的一致性。 |
警告 |
建议仔细选择应用程序命名,以获得清晰易读的生成代码。 |
为此,请执行以下操作:
在引脚排列和配置中,在系统内核RCC下,启用低速时钟LSE。
要达到硬件目标的最低功耗,您需要通过 PWR 外围设备关闭所有未使用的资源。 为此,请执行以下操作:
现在在引脚排列和配置中配置LPBAM外设:
下一步是配置 DMA 通道,以确保传输 LPTIM 信号以触发 LPGPIO。
在 LPBAM 模式下,DMA 通道必须配置为链表模式。
当 DMA 传输在无限循环中完成时,DMA 通道执行模式应配置为循环模式:
接下来,转到“NVIC 设置”并启用“LPDMA1 SmartRun Channel 0 global interrupt”。
所有 LPBAM 外设(LPGPIO、LPDMA1、LPTIM)现在都已配置完毕,可用于场景队列构建。
信息 |
请注意,之所以选择 LPDMA,是因为它在 Stop2 模式下仍能正常工作。 |
要修改 Period and Repetition 计数器的值,如下图所示,请单击此图标
并选择 No check。
在“用户常量”面板中,单击“添加”并创建三个“常量”:
信息 |
检查 AN5816[2]了解如何计算用户常量 |
此时,LPTIM只需要LPTIM时钟配置,就可以生成PWM信号。
在时钟配置中,选择 LSE 作为 LPTIM1 时钟源:
STEP1:第一个节点的 LPTIM1 配置顺序如下:
1. 转到 LPTIM1 并单击“开始”前面的“ ”。
2. 将函数名称更改为“Start_1”。
3. 将启动模式更改为“连续模式”。
5. 在“触发器配置”下,将“函数执行是”保留为“不受触发器限制”。
STEP2:为第二个节点配置LPTIM1配置序列,如下所示: 1. 进入LPTIM1,
点击PWM前面的“ ”。
2. 将函数名称更改为“PWM_1”。
3. 启用周期更新状态并插入 3270 作为周期值。
4. 启用脉冲更新状态并插入 1630 作为脉冲值。
5. 在“触发器配置”下,将“函数执行是”保留为“不受触发器限制”。
STEP3:我们配置由前一个LPTIM信号触发的LPGPIO,周期为100毫秒,我们创建两个节点;一个用于设置,另一个用于重置。
1. 转到LPGPIO1,然后单击“Write Pin”前面的“ ”。
2. 将函数名称更改为“Write_Pin_1”。
3. 选择 PA1 作为引脚名称。
4. 选择 Set as the pin State(设置为引脚状态)。
5. 在“触发配置”下,将“功能执行是”从“不受触发器调节”更改为“在硬件信号的上升沿触发”。
6. 将“触发硬件信号是”从“EXTI line 0”更改为“LPTIM CH1”。
第 4 步:对于第二个节点,仅执行以下更改:
1. 将函数名称更改为“Write_Pin_2”。
2. 选择 Reset (重置) 作为引脚状态。
3. 将函数执行更改为“在硬件信号的下降沿触发”。
4. 将“触发硬件信号是”从“EXTI line 0”更改为“LPTIM CH1”。
现在,我们将 LPTIM1 配置为 50 毫秒周期来触发 LPGPIO,我们选择将 LPTIM 配置为 2 个不同的频率以显示队列的独立性。
为此,请重复步骤 2、3 和 4,并仅更改步骤 2 中的周期和脉冲值,如下所示:
现在,单击队列“GPIOstate”并选中循环模式,因此将队列置于一段时间 (1) 循环中,然后将箭头拖动到 LPTIM1: PWM_1 节点。
按照这些步骤,您的队列应如下所示:
信息 |
检查UM1718[4]用于队列和节点管理。 |
警告 |
遵守函数执行顺序:配置队列参数必须先函数,先执行。 |
此时,“LPGPIO 驱动器”应用程序内置于 STM32CubeMX LPBAM 工具中。 然后建议通过“检查LPBAM设计”按钮检查LPBAM设计。STM32CubeMX工具在后台检查所构建应用程序的一致性。它会返回 LPBAM 日志中检测到的问题。
注意:以下警告不会影响代码的生成!
现在,所有 LPBAM 应用程序依赖项都已配置。
2.4代码配置↑主应用程序和 LPBAM 应用程序已准备就绪,可以生成。
对于 LPBAM 应用程序,生成的文件是:
• lpbam_lpgpio_drive.h
• lpbam_lpgpio_drive_config.c • lpbam_lpgpio_drive_build.c • lpbam_lpgpio_drive_config.c
它们包含主应用程序正确管理任何 LPBAM 应用程序所需的所有 API。
转到 main.h 文件,在“USER CODE BEGIN INCLUDES”用户部分添加 «#include < stdint.h>»。 并在 USER CODE BEGIN ET 中添加:
/* USER CODE BEGIN Includes */
#include <stdint.h>
/* USER CODE END Includes */
/* USER CODE BEGIN ET */
typedef enum
{
PB_NOT_PRESSED = 0,
PB_PRESSED = 1,
} PB_State_t;
/* USER CODE END ET */
在 main.c 文件中,在 “USER CODE BEGIN INCLUDES” 用户部分添加 «#include “lpbam_lpgpio_drive.h”»。
/* USER CODE BEGIN Includes */
#include "lpbam_lpgpio_drive.h"
/* USER CODE END Includes */
在主 () API 的核心中,我们使用的 LED 必须在“USER CODE BEGIN PD”用户部分中初始化。
* USER CODE BEGIN PD */
#define LED_GREEN ((uint32_t) (0X0U))
#define LED_BLUE ((uint32_t) (0X1U))
#define LED_RED ((uint32_t) (0X2U))
#define ERROR_NONE ((int32_t) (0x0))
/* USER CODE END PD */
将按钮声明添加到 main.c 中的 “USER CODE BEGIN PV” 用户部分。
* USER CODE BEGIN PV */
/* Push Button State */
__IO uint32_t PushButtonState = PB_NOT_PRESSED;
/* USER CODE END PV */
现在,在 main.c 中名为“USER CODE BEGIN PFP”的用户部分下添加函数声明。
/* USER CODE BEGIN PFP */
static void Enter_Stop2_Mode(void);
static int32_t LED_On(uint32_t Led);
static int32_t LED_Off(uint32_t Led);
/* USER CODE END PFP */
为了达到最低功耗,LPBAM方案中未使用的所有引脚都配置为模拟模式,包括调试引脚。初始化 LED 和按钮后,您需要调用 LPBAM 生成的 API 来初始化、构建、链接和启动 “USER CODE BEGIN 2” 用户部分中的 LPBAM 应用程序。
警告 |
必须遵循以下调用顺序才能运行任何 LPBAM 应用程序。 |
/* LPBAM_LPGPIO_drive application init */
MX_LPGPIO_drive_Init();
/* LPBAM_LPGPIO_drive application TrigGPIO init */
MX_LPGPIO_drive_TrigGPIO_Init();
/* LPBAM_LPGPIO_drive application TrigGPIO build */
MX_LPGPIO_drive_TrigGPIO_Build();
/* LPBAM_LPGPIO_drive application TrigGPIO link */
MX_LPGPIO_drive_TrigGPIO_Link(&handle_LPDMA1_Channel0);
/* LPBAM_LPGPIO_drive application TrigGPIOstart */
MX_LPGPIO_drive_TrigGPIO_Start(&handle_LPDMA1_Channel0);
此时,LPBAM应用程序正在运行。必须进入 Stop2 模式:
/* Enter Stop2 mode */
Enter_Stop2_Mode ();
用户按钮引脚 (PC13) 配置为具有外部中断 (EXTI_Line13) 下降沿的输入。按下时,系统将从 Stop2 模式唤醒。
电路板 LED 用于监控传输状态:
/* Reset push button state */
PushButtonState = PB_NOT_PRESSED;
/* Turn LED_BLUE on */
LED_On(LED_BLUE);
/* Wait for the next push button press to stop the LPBAM LPGPIO_drive application TrigGPIO scenario */
while (PushButtonState == PB_NOT_PRESSED);
/* Turn LED_BLUE off */
LED_Off(LED_BLUE);
对于此应用程序,您还需要在“USER CODE BEGIN 2”用户部分调用以下 API。这将停止、取消链接并取消初始化 LPBAM 应用程序,并且绿色 LED 亮起。
/*LPBAM_LPGPIO_drive application TrigGPIO scenario stop */
MX_LPGPIO_drive_TrigGPIO_Stop(&handle_LPDMA1_Channel0);
/* LPBAM_LPGPIO_driveapplication TrigGPIO scenario unlink */
MX_LPGPIO_drive_TrigGPIO_UnLink(&handle_LPDMA1_Channel0);
/* LPBAM_LPGPIO_drive application TrigGPIO scenario de-init */
MX_LPGPIO_drive_TrigGPIO_DeInit();
LED_On(LED_GREEN);
任何其他服务都可以在 main.c 文件的用户代码下添加。 对于此应用程序,需要一个应用程序 API,该 API:
这些功能被添加到“USER CODE BEGIN 4”用户部分。
/* USER CODE BEGIN 4 */
static void Enter_Stop2_Mode(void)
{
/* Enter the system to STOP2 mode */
__HAL_RCC_PWR_CLK_ENABLE ();
HAL_PWREx_EnterSTOP2Mode (PWR_STOPENTRY_WFI);
/* Check that the system was resumed from stop 2 */
if (__HAL_PWR_GET_FLAG (PWR_FLAG_STOPF) == 0U)
{
Error_Handler();
}
/* Clear stop flag */
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_STOPF);
/* Check that the stop flag is cleared */
if (__HAL_PWR_GET_FLAG(PWR_FLAG_STOPF) != 0U)
{
Error_Handler();
}
}
现在,添加 GPIO_EXTI Callback 函数以及 LED_On 和 LED_Off 函数。
void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(GPIO_Pin);
PushButtonState = PB_PRESSED;
}
static int32_t LED_On(uint32_t led)
{
int32_t ret = ERROR_NONE;
if(LED_GREEN == led)
{
HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_SET);
}
else if (LED_BLUE == led)
{
HAL_GPIO_WritePin(LED_BLUE_GPIO_Port, LED_BLUE_Pin, GPIO_PIN_SET);
}
else if (LED_RED == led)
{
HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_SET);
}
else
{
// Do nothing
}
return ret;
}
static int32_t LED_Off(uint32_t led)
{
int32_t ret = ERROR_NONE;
if(LED_GREEN == led)
{
HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_RESET);
}
else if (LED_BLUE == led)
{
HAL_GPIO_WritePin(LED_BLUE_GPIO_Port, LED_BLUE_Pin, GPIO_PIN_RESET);
}
else if (LED_RED == led)
{
HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, GPIO_PIN_RESET);
}
else
{
// Do nothing
}
return ret;
}
/* USER CODE END 4 */
警告 |
对于此应用,使用的DMA通道只能访问同一电源域中的SRAM4。因此,将 RAM 的起始地址更改为可由 DMA 通道访问 |
为此,在STM32CubeIDE的Project Explorer>Debug中,转到STM32U575ZITXQ_FLASH.ld并配置RAM ORIGIN = 0x28000000和LENGTH = 16 KB
2.4.1编译和烧录↑根据应用程序阶段,可以启用或禁用调试配置。
为此,请执行以下操作:
1. 单击“调试配置”图标
2. 点击STM32 C/C 应用程序
3. 点击“新启动配置图标”
4. 在低功耗模式下启用调试
下载代码后,LPBAM 场景以无限循环重复。
使用逻辑分析仪,我们可视化了LPTIM和LPGPIO信号。
如上图所示,LPGPIO0_PA1在 50 和 100 ms 周期的LPTIM_PC1信号之后设置或复位。
2.5功耗测量↑为了测量应用的功耗,STM32 Power Shield应用用于为Nucleo板供电。 为此,您可以使用 X-NUCLEO-LPM01A[5]用于功耗测量的扩展板及其用户手册[6]
信息 |
关于使用LPBAM的功耗,请检查AN5845[7]了解更多详情。 |
Power Shield 是一种即插即用的解决方案,旨在简化功耗测量。
在stop2模式下使用带有STM32U575 Nucleo板的电源扩展板,我们测量了4.06μA,与数据表一致[8].
这种情况适用于与外部组件(如MEM传感器)连接时,例如通过I2C或SPI连接。LPBAM和LPDMA可用于将数据从外设传输到存储器中,MCU内核仅在传输完成时唤醒:完成时唤醒。
有关 SPI 或 I2C 传输的示例,请按照以下路径查看 STM32U5 Cube 固件中的示例:
1) STM32Cube\Repository\STM32Cube_FW_U5\Projects\NUCLEO-U575ZI-Q\Applications\LPBAM\LPBAM_I2C_TransmitReceive
2) STM32Cube\Repository\STM32Cube_FW_U5\Projects\NUCLEO-U575ZI-Q\Applications\LPBAM\LPBAM_SPI_TransmitReceive
我们还可以使用周期性定时器触发ADC,并在设备其余部分处于休眠状态时将数据存储在内存中。
For examples of ADC or DAC, check the example in the STM32U5 Cube Firmware following this path:
STM32Cube\Repository\STM32Cube_FW_U5\Projects\NUCLEO-U575ZI-Q\Applications\LPBAM\LPBAM_ADC_TempSense
STM32Cube\Repository\STM32Cube_FW_U5\Projects\NUCLEO-U575ZI-Q\Applications\LPBAM\LPBAM_DAC_OPAMP_SigAmpli
Information |
Check AN5816 [2] for the STM32CubeMX LPBAM TempSense application description and building. |
The LPTIM can be used for timing and output generation while the STM32 device is in low-power mode. it provides the basic functions of the STM32 general-purpose timers with the advantage of very low-power consumption. Additionally, when configured in Asynchronous counting mode, the LPTIM keeps running even when no internal clock source is active.
有关 LPTIM PWM 配比更改的示例,请按照以下路径检查 STM32U5 Cube 固件中的示例:
STM32Cube\Repository\STM32Cube_FW_U5\Projects\NUCLEO-U575ZI-Q\Applications\LPBAM\LPBAM_LPTIM_PWMGen
信息 |
检查 AN4865[9]适用于STM32 MCU和MPU上的低功耗定时器(LPTIM)应用用例。 |
更复杂的应用可以使用多个DMA通道或来自同一通道上不同外设的链式操作来构建,如AN5834中的情况[10]描述了 STM32U5 Nucleo 板中包含的 LC 传感器计量功能 NUCLEO-U575ZI-Q[11].
6参考资料↑Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved