STM32 UART串口数据接收策略

STM32 UART串口数据接收策略

串口是常见的数据通讯接口,需要在不同的应用场景下选择特定的数据接收模式,才能可靠的接收和处理数据。这里介绍常用简化串口即只有TX/RX连接的串口通讯接收策略。
在这里插入图片描述

接收传感器数据,选帧方式

典型的应用为传感器按照发送周期,不断的发送串口数据给STM32接收端,由于前后帧数据一般变化小,选择部分帧数据处理即可。这种场景就要用到串口的DMA接收方式,设定特定长度的DMA接收并启动,在接收完成后由DMA完成中断触发,进行数据处理,并重新启动DMA接收。

STM32的UART串口DMA配置为:
在这里插入图片描述

使能中断:
在这里插入图片描述

如下的帧定义为
FH1 FH2 D7 D6 D5 D4 D3 D2 D1 D0 CRC8
也就是由2个帧头字节,8个数据字节,1个校验字节组成,一帧长度为L=11个字节。

那么DMA接收启动要设置的长度为2L-1, 即21个字节,如

HAL_UART_Receive_DMA(&huart1, uart1_rx_buff, 21);

这样,当DMA接收到21个字节后触发接收完成中断,可以在接收完成中断响应函数里( void HAL_UART_RxCpltCallback(UART_HandleTypeDef huart) )将数据进行转存并设置标识,在主程序循环里识别到有有效数据收到,那么在转存的数据里,有且只有一帧有效数据,可以采用字节滑动法对帧头进行识别,再把后面对应一帧的数据取出来,用校验字节校验,如果校验正确,则进行后续处理。处理完再启动DMA接收。

如果传感器发过来的帧是变长度帧,则以最长的帧作为参考,设置DMA接收长度2L-1, 这样,在接收到的一次DMA完整数据里,可能有几个有效帧,变长度帧会有帧类型识别字节,根据识别字节进行相应处理即可。

接收单帧数据,没有其它逻辑占用MCU时序

典型的应用为主从控制系统,从机保持等待状态,等到主机发送串口指令过来后,才执行操作并做相应的结果返回。在等待主机发送串口信息时,没有其它的运行过程会影响到串口数据的接收。因此,可以先设置中断方式接收一个帧头字节,然后再在主程序里通过轮询进行后续字节的接收,接收时采用接收超时模式完整接收,因此只要把接收的buffer设置到足够包含任何单帧数据长度即可。主程序重新打开接收中断,并在下次接收到串口数据前处理完当前事务。

具体的方式介绍见:《STM32 HAL 串口收发例程(中断配合轮询)》

接收单帧数据,有其它逻辑占用MCU时序

典型的应用为主机系统,一边在执行各种功能代码,同时要接收串口数据,这样就不能采用上述的方式,因为接收到帧头数据后,在主程序里无法保证马上进入轮询接收串口数据,因此要采用如下的方式。

  1. 主程序while循环之前启动串口通过中断或DMA方式(DMA接收完成中断),接收一个帧头数据,这个帧头数据具有指示后面数据的字节长度意义;
  2. 在接收完成中断处理函数中,识别当前状态为未接收态,通过接收到帧头后设置状态标识FLAG1, 并判断后面要接收的数据长度,重新使能中断或DMA方式(DMA接收完成中断);
  3. 在接收完成中断处理函数中,别当前状态为Flag1状态,设置状态标识FLAG2
  4. 在主程序中,识别到串口Flag1状态,延时特定时间(基于一帧数据接收延时最大值),然后判断串口状态是否为FLAG2,如果,则进行数据校验和处理,然后重新打开接收一个帧头数据的串口中断或DMA方式(DMA接收完成中断);
  5. 在主程序中,识别到串口Flag1状态,延时特定时间(基于一帧数据接收延时最大值),然后判断串口状态是否为FLAG2,如果不是,则认为串口接收异常,则对串口接口进行复位,并重新打开接收一个帧头数据的串口中断或DMA方式(DMA接收完成中断);

如采用中断方式打开串口接收一个帧头数据:

HAL_UART_Receive_IT(&huart1, uart1_rxd, 1);

则串口接收完成中断响应函数为:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
   if(huart==&huart1)
   {

      if(uart1_status==0)
      {
    	  switch(uart1_rxd[0])
    	  {
    	  case 0x55:
    		  uart1_status = 0x01;
    		  HAL_UART_Receive_IT(&huart1, uart1_rxd+1, 2);
    		  break;

    	  case 0xAA:
    		  uart1_status = 0x02;
    		  HAL_UART_Receive_IT(&huart1, uart1_rxd+1, 4);
    		  break;

    	  default:
    		  HAL_UART_Receive_IT(&huart1, uart1_rxd, 1);
    	  }

      }
      else if(uart1_status==0x01)
      {
    	  uart1_status = 0xF1;

      }
      else if(uart1_status==0x02)
      {
    	  uart1_status = 0xF2;
      }
      else ;

   }
}

上述代码,在接收到帧头0x55时,设置状态标识为0x01, 然后再使能接收2个字节串口数据,当接收到后,再设置状态标识为0xF1; 在接收到帧头0xAA时,设置状态标识为0x02, 然后再使能接收4个字节串口数据,当接收到后,再设置状态标识为0xF2;

主程序while循环里的代码:

	  if(uart1_status == 0x01)
	  {
		  PY_Delay_us_t(1000000); //To guarantee frame receiving completion
		  if(uart1_status != 0xF1)  //Frame receiving abnormal
		  {
			  HAL_UART_MspInit(&huart1);
			  MX_USART1_UART_Init(); //Re-initialize uart
			  uart1_status = 0;
			  HAL_UART_Receive_IT(&huart1, uart1_rxd, 1); //Restart frame head receiving
		  }
          else //Frame receiving normal
          {
             //Do data verification and processing
          }

	  }

	  if(uart1_status == 0x02)
	  {
		  PY_Delay_us_t(1000000); //To guarantee frame receiving completion
		  if(uart1_status != 0xF2) //Frame receiving abnormal
		  {
			  HAL_UART_MspInit(&huart1);
			  MX_USART1_UART_Init();  //Re-initialize uart
			  uart1_status = 0;
			  HAL_UART_Receive_IT(&huart1, uart1_rxd, 1);  //Restart frame head receiving
		  }
          else //Frame receiving normal
          {
             //Do data verification and processing
          }

	  }

上述代码,可以保证在某次串口数据传输异常时,不会导致后续串口数据的接收继续失败。

GPIO模拟UART串口设计

GPIO模拟串口的实现可以参考:
《STM32 GPIO模拟UART串口:最简延时方式》
《STM32 GPIO模拟UART串口:外部时钟及TIM方式》

USB转TTL串口工具

STM32实现USB转TTL串口工具时,需要通过中断,DMA和缓存方式的配合,实现有效的接收和转发时序。具体介绍见:《STM32实现USB转TTL串口工具》

在不同的场景采用不同的策略,可以实现串口帧数据的有效接收和处理。

UART-CAN融合式高速串口

借用CAN总线物理层收发芯片实现高速UART串口的设计方式:《STM32实现UART-CAN融合式高速串口》

–End–

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PegasusYu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值