打印
[STM32L0]

STM32L0进入STOP模式后串口中断方式唤醒

[复制链接]
1482|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
两只袜子|  楼主 | 2023-6-16 15:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

实现方法:

1、定时休眠唤醒code

  • HAL_Delay(2000);//进行采样的时间

  • HAL_RTCEx_DeactivateWakeUpTimer(&RTCHandle);

  • HAL_RTCEx_SetWakeUpTimer_IT(&RTCHandle, 2, RTC_WAKEUPCLOCK_RTCCLK_DIV16);

  • HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);//调用库函数进入STOP模式

  • SystemClockConfig_STOP();//停机模式后唤醒,恢复时钟源

  • count1++;

  • while(count1==1)//循环的次数

  • {

  • Rx_Init();

  • count1=0;

  • flag3=0;

  • __HAL_RTC_ALARM_DISABLE_IT(&RTCHandle, RTC_IT_ALRA);

  • __HAL_RTC_ALARM_CLEAR_FLAG(&RTCHandle, RTC_IT_ALRA);

  • HAL_TIM_Base_Stop(&TimHandle);   //定时器停止

  • HAL_RTCEx_DeactivateWakeUpTimer(&RTCHandle);

  • HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);//调用库函数进入STOP模式

  • }

  • 计算方法:例如休眠4s

  • /*  RTC Wakeup Interrupt Generation:

  • Wakeup Time Base = (RTC_WAKEUPCLOCK_RTCCLK_DIV /(LSE or LSI))

  • Wakeup Time = Wakeup Time Base * WakeUpCounter

  • = (RTC_WAKEUPCLOCK_RTCCLK_DIV /(LSE or LSI)) * WakeUpCounter

  • ==> WakeUpCounter = Wakeup Time / Wakeup Time BaseTo configure the wake up timer to 4s the WakeUpCounter is set to 0x1FFF:

  • RTC_WAKEUPCLOCK_RTCCLK_DIV = RTCCLK_Div16 = 16

  • Wakeup Time Base = 16 /(~39.000KHz) = ~0,410 ms

  • Wakeup Time = ~4s = 0,410ms  * WakeUpCounter

  • ==> WakeUpCounter = ~4s/0,410ms = 9750 = 0x2616 */

  • HAL_RTCEx_SetWakeUpTimer_IT(&RTCHandle, 0x2616, RTC_WAKEUPCLOCK_RTCCLK_DIV16);




局限性:用内部时钟LSI,大小固定导致Wakeup Time Base 被限制。 Wakeup Time(最大)=0.41ms*65535(0xffff)=26.869s,可能达不到休眠时间要求。

另一种方法:改HAL_RTCEx_SetWakeUpTimer_IT(&RTCHandle, 2, RTC_WAKEUPCLOCK_CK_SPRE_16BITS);

这里RTC_WAKEUPCLOCK_CK_SPRE_16BITS是设置CR寄存器中的低三位,唤醒时钟选择,这里选择1hz,2表示工作2S后进入唤醒中断,这个数随便改,改成多少就是休眠多少时间。


使用特权

评论回复
沙发
两只袜子|  楼主 | 2023-6-16 15:12 | 只看该作者
2、串口中断唤醒

唤醒机制:在MCU进入STOP状态后,不能直接通过UART等外设唤醒,在MCU进入STOP前将RX脚设为EXTI模式,并使能对应的中断。唤醒后重新初始化串口、配置时钟。

void Rx_Init()

{

GPIO_InitTypeDef GPIO_InitStruct;

__HAL_RCC_GPIOA_CLK_ENABLE();

  // 配置UART1的Rx引脚为EXIT模式

  GPIO_InitStruct.Pin = USARTx_RX_PIN;

  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; // 特别注意这里要使用中断模式

  GPIO_InitStruct.Pull = GPIO_PULLUP;

  HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);

  HAL_NVIC_SetPriority(EXTI4_15_IRQn, 2, 0);

  HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);

}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

{

if(GPIO_Pin==USARTx_RX_PIN)

{

//  HAL_NVIC_EnableIRQ(SysTick_IRQn);

SystemClockConfig_STOP();//停机模式后唤醒,恢复时钟源

HAL_Init();

SystemClock_Config();

SystemPower_Config();

HAL_SPI_DeInit(&hspi1);

HAL_GPIO_DeInit(GPIOA,GPIO_PIN_10);//串口重新初始化时HAL_UART_Init()函数会判断if(huart->State == HAL_UART_STATE_RESET),此时才会执行HAL_UART_MspInit(huart),配置串口IO口,这句话必须有!

__HAL_RCC_GPIOA_CLK_ENABLE();

__HAL_RCC_GPIOA_CLK_ENABLE();

__HAL_RCC_GPIOB_CLK_ENABLE();

SPI_GPIO_Init();

UartHandle.Instance        = USARTx;

UartHandle.Init.BaudRate   = uart_baud;

UartHandle.Init.WordLength = UART_WORDLENGTH_8B;

UartHandle.Init.StopBits   = UART_STOPBITS_1;

UartHandle.Init.Parity     = UART_PARITY_NONE;

UartHandle.Init.HwFlowCtl  = UART_HWCONTROL_NONE;

UartHandle.Init.Mode       = UART_MODE_TX_RX;

GPIO_InitTypeDef  GPIO_InitStruct;

/*##-1- Enable peripherals and GPIO Clocks #################################*/

/* Enable GPIO TX/RX clock */

USARTx_TX_GPIO_CLK_ENABLE();

USARTx_RX_GPIO_CLK_ENABLE();

/* Enable USART2 clock */

USARTx_CLK_ENABLE();

/*##-2- Configure peripheral GPIO ##########################################*/

/* UART TX GPIO pin configuration  */

GPIO_InitStruct.Pin       = USARTx_TX_PIN;

GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;

GPIO_InitStruct.Pull      = GPIO_NOPULL;

GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_HIGH  ;

GPIO_InitStruct.Alternate = USARTx_TX_AF;

HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);

/* UART RX GPIO pin configuration  */

GPIO_InitStruct.Pin = USARTx_RX_PIN;

GPIO_InitStruct.Alternate = USARTx_RX_AF;

HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct);

HAL_NVIC_DisableIRQ(EXTI4_15_IRQn);

__HAL_GPIO_EXTI_CLEAR_IT(USARTx_RX_PIN);

HAL_NVIC_SetPriority(USARTx_IRQn, 4, 0);

HAL_NVIC_EnableIRQ(USARTx_IRQn);

}

}

使用特权

评论回复
板凳
Undshing| | 2023-6-16 23:01 | 只看该作者
stop只能用外部中断或者RTC唤醒

使用特权

评论回复
地板
AloneKaven| | 2023-6-17 23:02 | 只看该作者
不能直接通过UART等外设唤醒

使用特权

评论回复
5
Jacquetry| | 2023-6-18 22:43 | 只看该作者
AloneKaven 发表于 2023-6-17 23:02
不能直接通过UART等外设唤醒

所以才要将RX脚设为EXTI模式

使用特权

评论回复
6
out-man| | 2023-10-31 10:09 | 只看该作者
这个怎么处理串口接收数据的问题,因为收到的串口数据会丢失前几个,怎么处理的?

使用特权

评论回复
7
AloneKaven| | 2023-10-31 22:48 | 只看该作者
没法这样唤醒吧

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2034

主题

7335

帖子

10

粉丝