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

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

查看全部评分

す疯Ⅱ恒す 回答时间: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-174422 回答时间: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管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版