前言
最近有客户反映 STM32F103 进入 STOP 模式后无法通过串口唤醒。
一 问题分析
唤醒机制:在 MCU 进入 STOP 状态后,不能直接通过 UART 等中断外设唤醒,只能通过 EXTI 外部中断方式唤醒。但是我们可以在 MCU 进入 STOP 前将 RX 脚设为 EXTI 模式,并使能对应的中断来实现。相关代码在 STM3210B-EVAL 上测试可以实现该功能。
二 相关测试代码
- int main(void)
- {
- #ifdef DEBUG
- debug();
- #endif
- // System Init...
- System_Init();
- PWR_DeInit();
- UART_Init();
- // Global Variables Init...
- Global_Variables_Init(); // + by dsg for global variables init...
- while(1)
- {
- /* Request to enter STOP mode with regulator in low power mode*/
- PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
- }
- }
- void EXTIX_Init(void)
- {
- EXTI_InitTypeDef EXTI_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
- GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource11);
- EXTI_InitStructure.EXTI_Line=EXTI_Line11; //GPIOA.3 UART2_RX
- EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
- EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
- EXTI_InitStructure.EXTI_LineCmd = ENABLE;
- EXTI_Init(&EXTI_InitStructure);
- NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQChannel;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- }
- /*******************************************************************************
- * Function Name : EXTI15_10_IRQHandler
- * Description : This function handles External lines 15 to 10 interrupt request.
- * Input : None
- * Output : None
- * Return : None
- *******************************************************************************/
- void EXTI15_10_IRQHandler(void)
- {
- EXTI_ClearITPendingBit(EXTI_Line11);
- NVIC_GenerateSystemReset();
- }
- void PWR_EnterSTOPMode(u32 PWR_Regulator, u8 PWR_STOPEntry)
- {
- // Change the UART RX PIN to external interrupt mode
- EXTIX_Init();
- GPIO_ResetBits(GPIOC, GPIO_Pin_6);
- GPIO_ResetBits(GPIOC, GPIO_Pin_7);
- GPIO_ResetBits(GPIOC, GPIO_Pin_8);
- u32 tmpreg = 0;
- /* Check the parameters */
- assert_param(IS_PWR_REGULATOR(PWR_Regulator));
- assert_param(IS_PWR_STOP_ENTRY(PWR_STOPEntry));
- /* Select the regulator state in STOP mode ---------------------------------*/
- tmpreg = PWR->CR;
- /* Clear PDDS and LPDS bits */
- tmpreg &= CR_DS_Mask;
- /* Set LPDS bit according to PWR_Regulator value */
- tmpreg |= PWR_Regulator;
- /* Store the new value */
- PWR->CR = tmpreg;
- /* Set SLEEPDEEP bit of Cortex System Control Register */
- *(vu32 *) SCB_SysCtrl |= SysCtrl_SLEEPDEEP_Set;
- /* Select STOP mode entry --------------------------------------------------*/
- if(PWR_STOPEntry == PWR_STOPEntry_WFI)
- {
- /* Request Wait For Interrupt */
- __WFI();
- }
- else
- {
- /* Request Wait For Event */
- __WFE();
- }
- }
- void UART_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- USART_InitTypeDef USART_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
- /* Enable USART3 clock */
- RCC_APB1PeriphClockCmd( RCC_APB1Periph_USART3, ENABLE);
- // GPIO Settings for USART3
- // PB10: TXD_ROOM
- GPIO_StructInit(&GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- // PB11: RXD_ROOM
- GPIO_StructInit(&GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- /* USARTx configuration ------------------------------------------------------*/
- /* USARTx configured as follow:
- - BaudRate = 600 baud
- - Word Length = 8 Bits
- - Two Stop Bit
- - Even parity
- - Hardware flow control disabled (RTS and CTS signals)
- - Receive and transmit enabled
- */
- USART_DeInit(USART3);
- USART_InitStructure.USART_BaudRate =9600;
- USART_InitStructure.USART_WordLength = USART_WordLength_9b;
- USART_InitStructure.USART_StopBits = USART_StopBits_2;
- USART_InitStructure.USART_Parity = USART_Parity_Even;
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- USART_Init(USART3, &USART_InitStructure);
- UartRxON();
- // In initial state, waiting for indoor data...
- USART_ITConfig(USART3, USART_IT_TXE, DISABLE);
- USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
- UART_State=UART_RX; //0; // 0: received state 1: transmit state
- /* Enable the USART3 Interrupt */
- NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQChannel;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- /* Enable USART3 */
- USART_Cmd(USART3, ENABLE);
- }
复制代码
|