2024-10-31 01:03 AM - last edited on 2024-10-31 01:16 AM by Andrew Neil
Can STM32L431 configure the RX of the serial port to EXTI wake-up in STOP2 mode? Why can't I wake up? And idle interrupts cannot be used either. The manual states that the EXTI and RX pins have been connected together in hardware, but the STOP2 mode cannot wake up the serial port, so it seems that its method cannot be used. Only the most primitive way of configuring RX as EXTI can be used, but it still cannot wake up
Enter STOP2,
void EnterStop2ModeRTC(void)
{
__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();//Configure RX for serial port 3 as EXTI
HAL_SuspendTick();
//HAL_DBGMCU_EnableDBGStopMode();
__HAL_RCC_PWR_CLK_ENABLE();
HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI); // Enter STOP2
}
Exit STOP2
void ExitStop2ModeRTC(void)
{
SystemClock_Config();
HAL_ResumeTick();
SCB->SCR &= ~SCB_SCR_SLEEPONEXIT_Msk;
}
Main
int main()
{
.....
.....
while (1)
{
while (getExitLPM3())
{
saveData();
lcdActionPro(); // lcd
keyActPro();
// if (uart[_COM3].active)
// {
// }
}
}
EnterStop2ModeRTC();
}
}
In the function getExitLPM3(), it is determined whether a flag is set. If it is set, it enters the while function inside
EXTI callback function:
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;
}
}
Exited STOP2 mode in the callback function of EXTI and reconfigured the serial port RX pin as the receive pin
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);
}
UART interrupt
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);
// }
}
There seems to be a logical problem in the middle, but I can't figure it out haha. The flag bit is set to true and will continue to loop in the inner while loop, unable to exit or enter STOP2. However, I don't know where to set it to false. I originally wanted to use IDLE to interrupt during idle, but after using it, I couldn't receive data. Now when not in use, the first packet of data is always incorrect. Can you help me check? Thank you all