基于HAL库的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,表示接收完一帧数据了,可以开始处理了。

总结

如果接收定长数据的情况,可以用第一种方法,且可以适应高速传输,如果是在传输速度要求不高的情况下,可以采用第二种方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值