STM32通过串口进入和唤醒停止模式

介绍STM32的四种工作模式,重点讲解通过串口唤醒停止模式的方法。包括配置串口接收端为外部中断、进入停止模式及唤醒后的系统复位。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        STM32 具有运行、睡眠、停止和待机四种工作模式。上电复位后 STM32 处于运行状态,当内核不需要继续运行,就可以选择进入后面的三种低功耗模式降低功耗,这三种模式中,电源消耗不同、唤醒时间不同、唤醒源不同,我们可以根据不同的应用需求,选择最佳的低功耗模式。

睡眠模式:CM3 内核停止,外设仍然运行,此功耗是最高的。

停止模式:所有时钟都停止,此功耗较低,典型大概在20uA左右 。

待机模式:1.8V 内核电源关闭,此功耗最低,典型大概在2uA左右。

在实际的开发运用时,我们常用的低功耗模式是停止模式,唤醒方式是任一外部中断。本文主要讲的是通过串口唤醒和进入停止模式,要实现通过串口唤醒停止模式,就需要用到外部中断。把串口Rx引脚设置成外部中断,上升沿触发,这样在串口收到数据时就会触发外部中断,从而唤醒停止模式。相关代码如下

首先是配置串口接收端为外部中断:

/*************************************************
Function:       void EXIT_UART_Init(void)
Description:    外部中断初始化
Calls:          
Called By:     	
Input:          无
Output:         无
Return:         
Others:
*************************************************/
void EXIT_UART_Init(void)
{
	LL_EXTI_InitTypeDef EXTI_InitStruct = {0};
	
	/* GPIO Portd Clock Enable */
	LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
	
	/**/
  LL_EXTI_SetEXTISource(LL_EXTI_CONFIG_PORTA, LL_EXTI_CONFIG_LINE3);
	
	 /**/
  EXTI_InitStruct.Line_0_31 = LL_EXTI_LINE_3;
  EXTI_InitStruct.LineCommand = ENABLE;
  EXTI_InitStruct.Mode = LL_EXTI_MODE_IT;
  EXTI_InitStruct.Trigger = LL_EXTI_TRIGGER_RISING;
  LL_EXTI_Init(&EXTI_InitStruct);
	
	/**/
  LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_3, LL_GPIO_PULL_DOWN);
	
	/**/
  LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_3, LL_GPIO_MODE_INPUT);
	
	/* EXTI interrupt init*/
  NVIC_SetPriority(EXTI2_3_IRQn, 1);
  NVIC_EnableIRQ(EXTI2_3_IRQn);
}

然后使能相关时钟,进入停止模式。

/*************************************************
Function:       void enter_stop_mode(void)
Description:    进入停止模式
Calls:          
Called By:     	
Input:          无
Output:         无
Return:         
Others:
*************************************************/
void enter_stop_mode(void)
{
	EXIT_UART_Init();							//配置串口引脚为外部中断
	
	__HAL_RCC_PWR_CLK_ENABLE();		//使能 PER 时钟
	
	HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);		//进入 stop 模式
}

在低功耗模式唤醒之后,默认使用的系统时钟是HSI,所以就需要重新配置系统时钟。为了方便这里直接使用了复位系统的操作,如果在实际的项目中需要保持外部的IO口状态不变,就不能使用系统复位命令,需要重新配置系统时钟和其他外设时钟。

/*
************************************************************
*	函数名称:	void exit_stop_mode(void)
*
*	函数功能:	系统复位
*
*	入口参数:	无
*
*	返回参数:	无
*
*	说明:
************************************************************
*/
void exit_stop_mode(void)
{
	__set_FAULTMASK(1);	 //关闭所有中断
	NVIC_SystemReset();
}

STM32G070系列微控制器支持通过串口唤醒停止模式(Stop Mode),这对于低功耗应用非常重要。以下是实现这一功能的步骤注意事项: ### 实现步骤 1. **配置串口(UART/USART)**: - 初始化串口,设置波特率、数据位、停止校验位等参数。 - 使能接收中断空闲线中断。 2. **配置GPIO**: - 配置串口使用的GPIO引脚为复用功能。 - 配置唤醒引脚的中断触发方式(如上升沿或下降沿触发)。 3. **配置电源管理**: - 设置系统进入停止模式。 - 使能唤醒源,确保串口中断可以作为唤醒源。 4. **编写中断服务程序(ISR)**: - 在串口接收中断或空闲线中断中,清除中断标志位。 - 在中断服务程序中,唤醒系统。 5. **进入停止模式**: - 调用进入停止模式的函数(如`HAL_PWR_EnterSTOPMode`)。 - 系统进入低功耗模式,等待串口事件唤醒。 ### 示例代码 ```c #include "stm32g0xx_hal.h" UART_HandleTypeDef huart1; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART1_UART_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART1_UART_Init(); while (1) { // 清除相关标志位 __HAL_UART_CLEAR_FLAG(&huart1, UART_CLEAR_IDLEF); // 进入停止模式 HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); // 系统被唤醒后,重新配置系统时钟 SystemClock_Config(); // 处理接收到的数据 if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE)) { uint8_t data; HAL_UART_Receive(&huart1, &data, 1, 100); // 处理接收到的数据 } } } static void MX_USART1_UART_Init(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 9600; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_RX | UART_MODE_TX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; HAL_UART_Init(&huart1); // 使能接收中断空闲线中断 __HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE | UART_IT_IDLE); } static void MX_GPIO_Init(void) { // 初始化GPIO __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = GPIO_AF1_USART1; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } void SystemClock_Config(void) { // 系统时钟配置代码 } ``` ### 注意事项 1. **中断优先级**:确保串口中断优先级设置正确,避免与其他中断冲突。 2. **功耗管理**:在进入停止模式前,确保所有外设进入低功耗状态。 3. **唤醒时间**:系统唤醒后,需要重新配置系统时钟其他外设。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值