你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F030的USART唤醒STOP模式

[复制链接]
tgwfcc 提问时间:2018-6-18 15:49 /
如题,像网上说的那样,进入STOP模式下把USART的RX初始化为外部中断。
可以唤醒,唤醒后重新初始化为USART的RX,但是接收不到数据。
时钟选用内部LSI和HSI,HSI作为系统时钟。
void USART1_RX_Interrupt(void)
{
        GPIO_InitTypeDef        GPIO_InitStruct;
        NVIC_InitTypeDef         NVIC_InitStruct;
        EXTI_InitTypeDef        EXTI_InitStruct;

        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
       
        //USART1 RX=PA3
        GPIO_InitStruct.GPIO_Pin         = UART_RX_PIN;
        GPIO_InitStruct.GPIO_Mode         = GPIO_Mode_IN;
        GPIO_InitStruct.GPIO_PuPd          = GPIO_PuPd_NOPULL;
        GPIO_Init(UART_RX_PORT, &GPIO_InitStruct);
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
        /* EXTI line(PA3) mode config */
        SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, UART_RX_EXIT_PinSource);
        EXTI_InitStruct.EXTI_Line = UART_RX_EXIT_LINE;
        EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
        EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling; //上升下降沿中断
        EXTI_InitStruct.EXTI_LineCmd = ENABLE;
        EXTI_Init(&EXTI_InitStruct);

        NVIC_InitStruct.NVIC_IRQChannel                 = EXTI2_3_IRQn;
        NVIC_InitStruct.NVIC_IRQChannelPriority = 1;
        NVIC_InitStruct.NVIC_IRQChannelCmd                 = ENABLE;
        NVIC_Init(&NVIC_InitStruct);

        //USART_ITConfig(UART_USER, USART_IT_RXNE, DISABLE);
        //USART_Cmd(UART_USER, DISABLE);//失能串口1
        //RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, DISABLE);
}


void USART1_Config(void)
{
        GPIO_InitTypeDef        GPIO_InitStructure;
        USART_InitTypeDef        USART_InitStructure;
        NVIC_InitTypeDef         NVIC_InitStructure;

        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
    //RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    RCC_USARTCLKConfig(RCC_USART1CLK_HSI);

        //USART1_TX -> PA2 , USART1_RX ->PA3                              
    GPIO_InitStructure.GPIO_Pin                = UART_TX_PIN | UART_RX_PIN;                 
    GPIO_InitStructure.GPIO_Mode        = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_OType        = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd        = GPIO_PuPd_NOPULL;
        GPIO_InitStructure.GPIO_Speed        = GPIO_Speed_50MHz;
        GPIO_Init(UART_PORT, &GPIO_InitStructure);   

        GPIO_PinAFConfig(UART_PORT, UART_TX_PinSource, UART_TX_AF);
        GPIO_PinAFConfig(UART_PORT, UART_RX_PinSource, UART_RX_AF);

        /* 使能 USART1 中断 */
        NVIC_InitStructure.NVIC_IRQChannel                        = USART1_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPriority        = 1;
        NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
        NVIC_Init(&NVIC_InitStructure);

        USART_InitStructure.USART_BaudRate                                = 115200;                                //设置串口波特率
        USART_InitStructure.USART_WordLength                        = USART_WordLength_8b;        //设置数据位
        USART_InitStructure.USART_StopBits                                = USART_StopBits_1;                //设置停止位
        USART_InitStructure.USART_Parity                                = USART_Parity_No;                //设置效验位
        USART_InitStructure.USART_HardwareFlowControl        = USART_HardwareFlowControl_None;//设置流控制
        USART_InitStructure.USART_Mode                                        = USART_Mode_Rx | USART_Mode_Tx;//设置工作模式
        USART_Init(UART_USER, &USART_InitStructure); //配置入结构体
               
        USART_ITConfig(UART_USER, USART_IT_RXNE, ENABLE);
        USART_ClearITPendingBit(UART_USER, USART_IT_RXNE);
        USART_Cmd(UART_USER, ENABLE);//使能串口1
}

void EXTI2_3_IRQHandler(void)
{
        if(EXTI_GetITStatus(UART_RX_EXIT_LINE) != RESET)
        {
                EXTI_ClearITPendingBit(UART_RX_EXIT_LINE);
                EXTI_RX_INTERRUPT_DISENABLE;
                System_ExitStopMode();
                //USART1_RX_AFMode();
                USART1_Config();
               
        }
}


static void SYSCLKConfig_STOP(void)
{  
  /* After wake-up from STOP reconfigure the system clock */
  /* Enable HSI */   
  RCC->CR |= ((uint32_t)RCC_CR_HSION);

  /* Wait till HSI is ready */
  while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET)
  {}

  /* Enable Prefetch Buffer and set Flash Latency */
  FLASH->ACR = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY;

  /* HCLK = SYSCLK */
  RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;

  /* PCLK = HCLK */
  RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE_DIV1;
       
  /* Select HSI as system clock source SYSCLK = HSI = 8 MHz*/
  RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
  RCC->CFGR |= (uint32_t)RCC_CFGR_SWS_HSI;          

  /* Wait till HSI is used as system clock source */
  while (RCC_GetSYSCLKSource() != 0x00)
  {}
}


void System_ExitStopMode(void)
{
        /*Initialize the System Clock */
        SYSCLKConfig_STOP();
       
        /* Disable the RTC Alarm interrupt */
        //RTC_ITConfig(RTC_IT_ALRA, DISABLE);
    //RTC_AlarmCmd(RTC_Alarm_A, DISABLE);
}


串口中断
if((UART_USER->ISR & 0x20) != RESET) //如果寄存器中有数据
        {
                if(UART_FindHeadFlag == 1)
                {
                        smartLockRX.buf[smartLockRX.len++] = UART_USER->RDR;
                        if(smartLockRX.len >= (smartLockRX.buf[0]+1))
                        {
                                UART_FindHeadFlag = 0;
                                UART_FindCmdFlag = 1;
                                UART_WaitRecvFlag = 0;
                                UART_WaitRecvTime = 0;
                                UART1_SendByte(0x06);        //发送应答ACK响应给智能锁
                                LED_CLOSE;
                        }
                }
                else
                {
                        uart_tmp_data <<= 8;
                        uart_tmp_data |= UART_USER->RDR;
                        if(uart_tmp_data == UART_PROTOCOL_HEAD)
                        {
                                UART_FindHeadFlag = 1;
                                smartLockRX.len = 0;
                                uart_tmp_data = 0;
                                LED_OPEN;
                        }
                }
        }

串口中断中加了LED的状态指示,没有反应。
请大家帮忙看看,有做过的说说问题在哪,谢谢!
收藏 1 评论5 发布时间:2018-6-18 15:49

举报

5个回答
feixiang20 回答时间:2018-6-18 23:19:32
检查下定时器中断,是不是数据转换出了问题

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

疯de_恒 回答时间:2018-6-27 09:34:57
以前有做过类似的东西。
你在进入STOP模式把RX设置为外部中断,靠收到串口数据的下降沿唤醒系统,但是要自动串口数据的下降沿正是串口数据起始位,等你唤醒了系统再设置串口配置,后面的串口接收就不完整了。
我建议采用以下的方式之一:
1:串口通信采用发一串数据的方式,开头用n个相同的包头(比如6个,根据波特率定),后面再加实际数据以及检验。这样在收数据处理是数据可能是少了前面一点包头的,但是其他数据还有,校验也能通过的话就可以用。这个需要测试下后面的数据能不能正常接收。
2:我以前用的方式是:双方通信定义一收一答的方式,当然应答码可以有很多,比如有“收包错误,请求重发”,那在单片机被唤醒配置为串口后,可以肯定是收到了数据,但是不保证数据是否正确,那就应答一个“收包错误”,在等一会等新的串口数据过来再处理。如果超时了就继续STOP吧。如果收到了正确的数据,就回复“OK”完成一轮通信。
以上供参考,可多尝试下看看波形数据等。

评分

参与人数 1蝴蝶豆 +4 收起 理由
zero99 + 4

查看全部评分

jcx0324 回答时间:2018-6-27 10:05:46
楼上正解,应该是唤醒后再加初始化的时间导致时序没有正常接收

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

zhdzhd 回答时间:2018-6-27 18:43:02
http://bbs.21ic.com/icview-2510278-1-2.html
建议楼主参考一下上面的链接;

MCU在唤醒的过程中丢失一些数据算是正常的,如果完全接收不到数据,应该是参数设置中出现了问题,还是参照楼上的几位的方法检查一下;如果对功耗要求不高,试试sleep模式。

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

laoganzheng 回答时间:2018-8-4 14:25:14
楼主需要重新初始化一下HSI这个内部时钟
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版