STM32L4的串口收发
简述
基于HAL库改写的串口收发程序,基于Instance中断再双串口的情况下不能进入,改用串口中断函数,最后发现是没有在开始开串口中断,如下:
HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer1, RXBUFFERSIZE);//该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量
HAL_UART_Receive_IT(&huart2, (uint8_t *)aRxBuffer2, RXBUFFERSIZE);//该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量
但是此种情况下,智能接收定长数据,否则会出现接收不正确现象。
串口接收定长回调函数
下面是基于HAL库串口中断的 串口中断回调函数源码
.
// An highlighted block
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
while(HAL_UART_Transmit(&huart1, (uint8_t*)myBuffer, sizeof(myBuffer), 1000)!= HAL_OK);
while(HAL_UART_Transmit(&huart1, (uint8_t*)aRxBuffer1, RXBUFFERSIZE, 1000)!= HAL_OK);
while(HAL_UART_Transmit(&huart1, (uint8_t*)Enter, sizeof(Enter), 1000)!= HAL_OK);
buffer1[0] = *aRxBuffer1;
while(HAL_UART_Transmit(&huart2, (uint8_t*)myBuffer, sizeof(myBuffer), 1000)!= HAL_OK);
while(HAL_UART_Transmit(&huart2, (uint8_t*)aRxBuffer2, RXBUFFERSIZE, 1000)!= HAL_OK);
while(HAL_UART_Transmit(&huart2, (uint8_t*)Enter, sizeof(Enter), 1000)!= HAL_OK);
buffer2[0] = *aRxBuffer2;
printf("%s\r\n", buffer1);
printf("%s\r\n", buffer2);
}
串口接收不定长数据回调函数
串口接收不定长数据源码来源于网上大神,但是,此种方法虽然通用,但是由于采用延时计数器的方法来保存接收数据,这样,如果串口发送数据过快,接收数据不准确甚至后面的数据全都接收错误。
void LPUART1_IRQHandler(void)// 低功耗串口1中断服务函数
{
if(__HAL_UART_GET_FLAG(&hlpuart1, UART_FLAG_RXNE))// 如果接收到一个字节
{
Res_Buf[Res_Count++]=hlpuart1.Instance->RDR; // 把数据保存到接收数组
Res_Sign = 1; // 表示已经接收到数据
Res_Times = 0; // 延时计数器清0
}
}
程序解释
程序里面有4个全局变量,分别是:
unsigned char Res_Buf[256]; //接收数据的数组,用来接收串口数据
unsigned char Res_Count=0; //接收数据的字节计数器,表示本次一帧数据包含几个字节
unsigned char Res_Sign=0; //接收到数据标志,接收到1个字节就会置1
unsigned char Res_Times=0; // 延时计数器,用来判断有没有接收完一帧数据
在串口中断函数里面,每接收到一个字节,就会把接收到的字节保存到Res_Buf数组中,同时,字节计数器+1。然后把Res_Sign置1,表示已经接收到串口数据,但是,有没有接收完,是不一定的。在主函数当中,发现这个变量等于1了,就开始启动延时计数Res_Times,让这个变量++,只要延时到了5ms,就表示接收完一帧数据,退出do while后就可以开始处理数据了,但是,当接收到第二个字节以后,会在中断函数里面把Res_Times清0,也就是说,主函数里面的Res_Times++以后,白加了,只要有数据还没有接收完,这个Res_Times就会一直清0,如果串口接收能接收一万年也接收不完一帧数据,那一万年,Res_Times也到不了5。只有当再也没有串口数据过来了,Res_Times才会加到5,然后退出do while,表示接收完一帧数据了,可以开始处理了。
总结
如果接收定长数据的情况,可以用第一种方法,且可以适应高速传输,如果是在传输速度要求不高的情况下,可以采用第二种方法。