ST意法半导体
直播中

神之小风

13年用户 956经验值
私信 关注
[问答]

STM32L431在STOP2模式下能否将串口的RX配置成EXTI唤醒呢?

STM32L431在STOP2模式下能否将串口的RX配置成EXti唤醒呢?为什么我的唤醒不了呢?并且空闲中断也不能用,手册中说在硬件上已经将EXTI与RX引脚连到一块了,但是呢STOP2模式不能将串口唤醒,所以它的那种方式好像不能使用,只能用最原始的将RX配置成EXTI的方式了,但是也还是唤醒不了
进入STOP2模式,
void EnterStop2ModeRTC(void) // 自定义的Enter函数{  __HAL_RCC_PWR_CLK_ENABLE();  __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);  __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&hrtc, RTC_FLAG_WUTF);  __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG();  __HAL_RTC_TIMESTAMP_CLEAR_FLAG(&hrtc, RTC_FLAG_TSF);  __HAL_RTC_TAMPER_TIMESTAMP_EXTI_CLEAR_FLAG();  while (__HAL_UART_GET_FLAG(&huart3, USART_ISR_BUSY) == SET)    ;  while (__HAL_UART_GET_FLAG(&huart3, USART_ISR_REACK) == RESET)    ;  setUca3RxToExti();//配置串口3的RX为EXTI  HAL_SuspendTick();  //HAL_DBGMCU_EnableDBGStopMode();  __HAL_RCC_PWR_CLK_ENABLE();  HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI); // 进入STOP2模式}退出STOP2
void ExitStop2ModeRTC(void){  SystemClock_Config();   HAL_ResumeTick();  SCB->SCR &= ~SCB_SCR_SLEEPONEXIT_Msk;}主函数
while (1)  {    while (getExitLPM3())    {      saveData();      lcdActionPro(); // lcd进程      keyActPro();      // if (uart[_COM3].active)      // {      // }      }    }    EnterStop2ModeRTC();  }在函数getExitLPM3()中,判断了一个标志位是否被置位,如果置位了就进入里面的while
EXTI回调函数:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){  if ((GPIO_Pin == GPIO_PIN_5))  {    ExitStop2ModeRTC();    HAL_NVIC_DisableIRQ(EXTI9_5_IRQn);    setUca3RxToRx();    // uart[_COM3].active = true;  }}在EXTI的回调函数中退出了STOP2模式并重新将串口RX引脚配置为接收引脚
void setUca3RxToExti(void){  GPIO_InitTypeDef GPIO_InitStruct;  GPIO_InitStruct.Pin = GPIO_PIN_5;  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;  GPIO_InitStruct.Pull = GPIO_NOPULL;  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);  HAL_NVIC_SetPriority(EXTI9_5_IRQn, 0, 0);  HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);  uart[_COM3].active = false;}void setUca3RxToRx(void){  GPIO_InitTypeDef GPIO_InitStruct;  GPIO_InitStruct.Pin = GPIO_PIN_5;  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;  GPIO_InitStruct.Pull = GPIO_NOPULL;  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;  GPIO_InitStruct.Alternate = GPIO_AF7_USART3;  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);  // // HAL_NVIC_SetPriority(USART3_IRQn, 0, 0);  // // HAL_NVIC_EnableIRQ(USART3_IRQn);  __HAL_UART_ENABLE_IT(&huart3, UART_IT_RXNE);  // __HAL_UART_ENABLE_IT(&huart3, UART_IT_RXNE | UART_IT_IDLE);}串口中断
void USER_USART3_IRQHandler(void){  uint8_t data = 0;  if (__HAL_UART_GET_FLAG(&huart3, UART_FLAG_RXNE) != RESET)  {    data = (uint8_t)huart3.Instance->RDR;    wrEleQueue(&uart[_COM3].Rx, data);    // uart[_COM3].active = true;    // bleAppConfig.rxAct = 1;    // bleAppConfig.tmrResp = bleAppConfig.tmrRxHold = HAL_LPTIM_ReadCounter(&hlptim1);    // __HAL_UART_CLEAR_FLAG(&huart3, UART_FLAG_RXNE);  }  // if (__HAL_UART_GET_FLAG(&huart3, UART_FLAG_IDLE))  // {  //   // uart[_COM3].flag = 1;  //   uart[_COM3].active = false;  //   __HAL_UART_CLEAR_IDLEFLAG(&huart3);  // }}中间好像逻辑有点问题,但是我想不明白了哈哈,就是那个标志位被置位true后就会一直在内层的while中循环,出不来了,就进不去STOP2了,但是不知道在哪将它给置为false,本来想使用IDLE空闲中断的,但是空闲中断使用后收不到数据,现在不使用的时候第一包数据永远都是错误的,有没有大佬能帮忙看一下,谢谢大家

回帖(3)

康根

2025-3-12 16:09:23
可以肯定的是,外部中断是可以唤醒 STOP 模式的, 所以先调试芯片正常进入STOP 模式,然后设置外部中断唤醒。


另外手册上介绍的是LPUART 才有唤醒 STOP 模式的功能, 且需要波特率最大为9600.

如果波特率太快,即使中断唤醒,从唤醒到开始工作需要一定时间,所以一定会丢掉开始的数据的。
举报

杨思

2025-3-12 16:09:30
其实,STM32L4系列里的LPUART就具有唤醒STOP2 模式下MCU的能力。


从你代码来看,使用的是UART3,你似乎想问是否可以利用UART RX脚的EXTI来唤醒MCU.


即使是UART的RX脚,也可以配置其EXTI中断能力,并可以通过该中断唤醒STOP2模式下的MCU.


假设你使用STM32cubeMx进行UART配置,创建工程后自己手动再增加基于UART RX脚的EXTI配置,


不要修改该脚的复用配置功能。


假设你使用UART3的RX脚是PC5,我们可以临时选择其它编号为5个GPIO,比方PD5,启用该脚的EXTI并
使能NVIC端的中断响应。


创建工程后,只需在 MX_GPIO_Init()函数里将PD5的 EXTI配置改为PC5的配置即可,其它不用修改。


这样就可以测试了,比起对着手册修改EXTI控制寄存器方便多了。我这样测试屡试不爽。


先一步步来,先将不影响UART功能前提下,将RX脚的EXTI功能弄出来,再来验证唤醒的事情。
举报

杨福林

2025-3-12 17:48:49

在STM32L431微控制器中,STOP2模式是一种低功耗模式,它会关闭大部分外设和时钟以节省功耗。在这种模式下,只有特定的外设和功能可以继续工作,并且只有特定的唤醒源可以唤醒微控制器。


串口RX配置为EXTI唤醒的问题




  1. 串口RX与EXTI的连接



    • 在STM32L431中,串口的RX引脚可以被配置为EXTI(外部中断)源。这意味着当RX引脚上出现信号变化时,可以触发EXTI中断。

    • 手册中提到,硬件上已经将EXTI与RX引脚连接在一起,这意味着从硬件角度来看,这种配置是可行的。




  2. STOP2模式下的唤醒源



    • 在STOP2模式下,只有特定的唤醒源可以唤醒微控制器。这些唤醒源包括RTC、LPTIM、EXTI等。

    • 串口RX引脚配置为EXTI唤醒源在理论上是可行的,但需要确保在STOP2模式下,EXTI功能仍然可用。




  3. 为什么唤醒不了



    • EXTI配置问题:确保EXTI已经正确配置,并且RX引脚已经正确映射到EXTI线上。

    • 唤醒源配置问题:在进入STOP2模式之前,确保已经正确配置了唤醒源,并且EXTI中断已经启用。

    • 时钟配置问题:在STOP2模式下,某些时钟可能会被关闭。确保在唤醒后,时钟能够正确恢复。

    • 中断优先级问题:确保EXTI中断的优先级足够高,能够及时唤醒微控制器。




空闲中断的问题



  • 在STOP2模式下,串口的外设时钟可能会被关闭,导致空闲中断无法正常工作。因此,在STOP2模式下,空闲中断可能无法使用。


代码示例


以下是一个简单的代码示例,展示如何配置EXTI为串口RX引脚唤醒源:


void EnterStop2ModeRTC(void)
{
    // 使能PWR时钟
    __HAL_RCC_PWR_CLK_ENABLE();

    // 清除唤醒标志
    __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);

    // 配置RX引脚为EXTI源
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = GPIO_PIN_10; // 假设RX引脚是GPIO_PIN_10
    GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; // 上升沿触发
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 假设RX引脚在GPIOA

    // 配置EXTI中断
    HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);

    // 进入STOP2模式
    HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
}

void EXTI15_10_IRQHandler(void)
{
    // 处理EXTI中断
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10);

    // 唤醒后恢复时钟配置
    SystemClock_Config();
}

总结



  • 在STM32L431的STOP2模式下,串口RX引脚可以配置为EXTI唤醒源,但需要确保EXTI和唤醒源的正确配置。

  • 空闲中断在STOP2模式下可能无法使用,因为串口的外设时钟可能被关闭。

  • 如果仍然无法唤醒,建议检查EXTI配置、唤醒源配置、时钟配置以及中断优先级等问题。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分