有人使用STM32G0芯片并用到低功耗STOP模式,期望使用低功耗外设LPUART进行唤醒。他发现STM32G0的Cube库里似乎没有相关例程,这里就简单演示下实现过程,以供参考。
我们从STM32G0参考手册不难得知,LPUART不但可以基于系统时钟工作,还可以单独基于HSE或LSE工作。下面演示令LSE作为LPUART的驱动时钟,并将其收发事件的中断作为STOP模式的唤醒源。

我们使用STM32CubeMx进行初始化配置。下面是系统的时钟树,其中LSE 32768为LPUART提供时钟,让其可以工作于STOP低功耗模式。

下面是LPUART的基本配置,波特率为9700,使能LPUART通信中断。

下面是演示代码中用到的一些参数和变量定义的截图。

下面是主要的功能参考代码。基本流程是,先在运行状态下输出working提示,然后进入STOP模式,等待LPUART的输入,这里借助串口助手完成。唤醒后将刚才收到的字符回显于串口终端,然后再通过LPUART输出working提示。。。。。。就这样循环往复。关于代码中的LPUART接收,这里使用8字符定长接收,当然也可以使用不定长接收,这时的API库函数我们可以使用 HAL_UARTEx_ReceiveToIdle_IT()。
#include "stdio.h"#include "string.h"
#define TIMEOUT (0x999)
uint8_t StringWK1[]="\r\n>>>>>>>>>>Working>>>>>>>>>>>>>>>\r\n";uint8_t StringWK2[]=">>>>>>>>>>Working>>>>>>>>>>>>>>>\r\n\r\n";
uint8_t StringWK3[]="\r\n\r\nxxxxxxx___Wake Up___xxxxxxxxxx\r\n";uint8_t StringWK4[]="xxxxxxx___Wake Up___xxxxxxxxxx\r\n\r\n";
uint8_t EchoString[40];
uint8_t IndicatingStop[]="...EnterStop Mode...\r\n\r\n";uint8_t WaitingLpuart[]="...Waiting for LPUART RX...\r\n\r\n";
uint8_t RXBuffer[]="12345678\r\n";
int main(void){
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */ SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */ MX_GPIO_Init(); MX_LPUART1_UART_Init();/* USER CODE BEGIN 2 *///LL_RCC_HSI_EnableInStopMode();/* USER CODE END 2 */
/* Infinite loop *//* USER CODE BEGIN WHILE */while (1) {/* USER CODE END WHILE *//* USER CODE BEGIN 3 */ HAL_Delay(300);
HAL_UART_Transmit(&hlpuart1, (uint8_t *)StringWK1, sizeof(StringWK1), TIMEOUT);//working提示 HAL_UART_Transmit(&hlpuart1, (uint8_t *)StringWK2, sizeof(StringWK2), TIMEOUT);//working提示
HAL_Delay(300); HAL_UART_Transmit(&hlpuart1, (uint8_t *)IndicatingStop, sizeof(IndicatingStop), TIMEOUT);//进入STIOP的提示
HAL_UART_Transmit(&hlpuart1, (uint8_t *)WaitingLpuart, sizeof(WaitingLpuart), TIMEOUT);//等待LPuarat Rx的提示
SysTick->CTRL &=(~SysTick_CTRL_TICKINT_Msk);//暂停SYSTICK中断,以免影响STOP的进入 SysTick->CTRL &=(~SysTick_CTRL_ENABLE_Msk);//暂停SYSTICK计数,以免影响STOP的进入
__HAL_RCC_PWR_CLK_ENABLE();
HAL_UART_Receive_IT(&hlpuart1, RXBuffer, 8); //做输入字符的准备,目的是为了唤醒 HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);//进入STOP模式;
//等待来自串口助手的字符输入,同时唤醒CPU。
SysTick->CTRL |=(SysTick_CTRL_TICKINT_Msk); //唤醒后恢复SYSTICK中断的使能 SysTick->CTRL |=(SysTick_CTRL_ENABLE_Msk); //唤醒后恢复SYSTICK计数的使能
HAL_Delay(10); //wakekup后稍作延时
SystemClock_Config(); //唤醒后重新配置时钟,继续工作
HAL_UART_Transmit(&hlpuart1, (uint8_t *)StringWK3, sizeof(StringWK3), TIMEOUT);//wakeup提示 HAL_UART_Transmit(&hlpuart1, (uint8_t *)StringWK4, sizeof(StringWK4), TIMEOUT);//wakeup提示
sprintf(EchoString,"The Wakeup String is: %s\r\n",RXBuffer);
HAL_UART_Transmit(&hlpuart1, (uint8_t *)EchoString, sizeof(EchoString), TIMEOUT);//将用于唤醒的接收数据回显于串口助手 }
/* USER CODE END 3 */}
/*LPUART INTERRUPT ROUTINE AND RELATED CALLBACK FUNCTION*/void USART3_4_LPUART1_IRQHandler(void){ /* USER CODE BEGIN USART3_4_LPUART1_IRQn 0 */ /* USER CODE END USART3_4_LPUART1_IRQn 0 */ HAL_UART_IRQHandler(&hlpuart1); /* USER CODE BEGIN USART3_4_LPUART1_IRQn 1 */ /* USER CODE END USART3_4_LPUART1_IRQn 1 */}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){ //RXed_Flag =0xff; //刚好收到8个字符了}
下面是演示结果截图:


OK,关于STM32G0 LPUART唤醒STOP 模式的应用演示就介绍到这里,供有需要的人参考。下次再聊。