如题,像网上说的那样,进入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的状态指示,没有反应。 请大家帮忙看看,有做过的说说问题在哪,谢谢! |
【STM32F0开发日志/评测/笔记】+互补PWM波的产生
STM32F030 PB14和PB15无法输出PWM求助
【STM32F030探索套件】序列之五 外部中断
【STM32F0开发日志---二】+ucosii.2.92移植在STM32F030
上传个STM32F0+5110+内部温度传感器的菜鸟实例
【STM32F030探索套件使用问题】STM32F030 SPI方式驱动ST7565LCD失败
求一份STM32F051 I2C驱动LCD 12864的例程
STM32F0 M0 向结构体赋值进入HardFault异常
STM32F0 ADC-DMA方式采集2路数据时出现问题
STM32F030C8T6,TIM16定时慢很多问题?
评分
查看全部评分
你在进入STOP模式把RX设置为外部中断,靠收到串口数据的下降沿唤醒系统,但是要自动串口数据的下降沿正是串口数据起始位,等你唤醒了系统再设置串口配置,后面的串口接收就不完整了。
我建议采用以下的方式之一:
1:串口通信采用发一串数据的方式,开头用n个相同的包头(比如6个,根据波特率定),后面再加实际数据以及检验。这样在收数据处理是数据可能是少了前面一点包头的,但是其他数据还有,校验也能通过的话就可以用。这个需要测试下后面的数据能不能正常接收。
2:我以前用的方式是:双方通信定义一收一答的方式,当然应答码可以有很多,比如有“收包错误,请求重发”,那在单片机被唤醒配置为串口后,可以肯定是收到了数据,但是不保证数据是否正确,那就应答一个“收包错误”,在等一会等新的串口数据过来再处理。如果超时了就继续STOP吧。如果收到了正确的数据,就回复“OK”完成一轮通信。
以上供参考,可多尝试下看看波形数据等。
评分
查看全部评分
评分
查看全部评分
建议楼主参考一下上面的链接;
MCU在唤醒的过程中丢失一些数据算是正常的,如果完全接收不到数据,应该是参数设置中出现了问题,还是参照楼上的几位的方法检查一下;如果对功耗要求不高,试试sleep模式。
评分
查看全部评分