如题,像网上说的那样,进入STOP模式下把USART的RX初始化为外部中断。
可以唤醒,唤醒后重新初始化为USART的RX,但是接收不到数据。
时钟选用内部LSI和HSI,HSI作为系统时钟。
void USART1_RX_Interrupt(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
EX
ti_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_P
RFTBE | 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 Al
ARM 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的状态指示,没有反应。
请大家帮忙看看,有做过的说说问题在哪,谢谢!
你在进入STOP模式把RX设置为外部中断,靠收到串口数据的下降沿唤醒系统,但是要自动串口数据的下降沿正是串口数据起始位,等你唤醒了系统再设置串口配置,后面的串口接收就不完整了。
我建议采用以下的方式之一:
1:串口通信采用发一串数据的方式,开头用n个相同的包头(比如6个,根据波特率定),后面再加实际数据以及检验。这样在收数据处理是数据可能是少了前面一点包头的,但是其他数据还有,校验也能通过的话就可以用。这个需要测试下后面的数据能不能正常接收。
2:我以前用的方式是:双方通信定义一收一答的方式,当然应答码可以有很多,比如有“收包错误,请求重发”,那在单片机被唤醒配置为串口后,可以肯定是收到了数据,但是不保证数据是否正确,那就应答一个“收包错误”,在等一会等新的串口数据过来再处理。如果超时了就继续STOP吧。如果收到了正确的数据,就回复“OK”完成一轮通信。
以上供参考,可多尝试下看看波形数据等。
一周热门 更多>