stm32串口的收发似乎不太一样,发只要你把数据送出去就行了,电脑会自动读取(电脑不知道你啥时候发,总不能一直等你的数据吧),而你的stm32要接受一个数据呢?一直在USART_ReceiveData吗?(当时这个问题也困扰了我,直到接触了ESP8266才用到接收)
后面我发现有个很好的东西,串口IDLE中断,能自动响应你从电脑(别的串口)接收到的不定长数据。而不是一直干等着。
先简单说说原理吧,大概是,你的stm32接收数据时,并不会马上把数据马上处理掉,而是写到你定义的缓冲区里,然后你串口线上一个BYTE长度的时间如果没接收到数据,就会产生了IDLE中断(只会产生一次,别担心一直会卡在里面,除非等下次再接收时)
代码
代码很简单,不多说,附上
static void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
}
//在初始化串口的前提下,调用此函数初始化空闲接收中断
void Uart_Idle_Receive_Config(void)
{
NVIC_Configuration();
USART_ITConfig(DEBUG_USART,USART_IT_RXNE,ENABLE);
USART_ITConfig(DEBUG_USART,USART_IT_IDLE,ENABLE);
}
中断服务函数如下
#ifdef USE_IDLE_RECEIVE //使用串口空闲中断,开启中断服务
static u16 uart_rec_count = 0;
uint8_t UART_RECEIVE_BUF[100];
void USART1_IRQHandler(void)
{
u16 times;
if(USART_GetITStatus(DEBUG_USART,USART_IT_RXNE) != RESET)
{
UART_RECEIVE_BUF[uart_rec_count] = USART_ReceiveData(DEBUG_USART);
uart_rec_count++;
//USART_ClearITPendingBit(DEBUG_USART,USART_IT_RXNE);//千万别加
}
if(USART_GetITStatus(DEBUG_USART,USART_IT_IDLE) != RESET)
{
UART_RECEIVE_BUF[uart_rec_count] = USART_ReceiveData(DEBUG_USART);//这里要读一下才能清空标志位,不然会卡在中断里
/*此处加入对接收缓冲区的操作*/
/***************************/
uart_rec_count = 0;
//USART_ClearITPendingBit(DEBUG_USART,USART_IT_IDLE);//千万别加
}
}
#endif
加个预编译头,避免你不用的时候,写了个中断服务函数程序卡在这里,要用就define一下就好了
注意:千万别软件清除中断标志位,不然会一直进IDLE中断,不信自己试试。
就是USART_ClearITPendingBit(),不然程序卡死在中断里了。你读出来,人家硬件会自动清除.
完