stm32串口接收完整的数据包

借鉴了文章:《stm32串口中断接收方式详细比较》

文章地址:http://blog.csdn.net/kevinhg/article/details/40186169

串口的配置这里不做说明,仅对中断中的协议解析进行描述

数据帧协议:

帧头1 帧头2 数据长度 有效数据 crc_1 crc_2
B5  5B 03 00 57 0B

帧头1+帧头2+数据长度(包含有效数据、crc_1、crc_2)+有效数据 + crc_1 + crc_2(校验为帧头到有效数据)

crc16校验未深入学习,代码也不是自己写的,我仅是拿来用,所以未给出,也可以选择其他校验方法。

crc16函数声明:uint16_t CRC16(uint8_t * buf, uint16_t Len); 返回值为uint16_t校验值

代码如下:

/****************************
函数名称: USART2_IRQHandler
功    能:串口2接收中断
参    数:无
返 回 值:无
作    者:Yao
****************************/

uint8_t Uart2_Buffer[256];        //接收缓冲区
uint8_t Uart2_Rx = 0;             //Uart2_Buffer下标
uint8_t Uart2_head1;              //帧头1
uint8_t Uart2_head2;              //帧头2
uint8_t Uart2_Len;                //数据长度(第三字节以后包含crc)
uint16_t Uart2_temp;              //CRC16()返回值
uint8_t Uart2_Sta;                //数据帧正确标志
uint8_t Uart2_tx2;                //发送计数

uint16_t CRC16(uint8_t * buf, uint16_t Len);  //crc16函数声明,定义未给出。返回uint16_t校验值

void USART2_IRQHandler()
{
  if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET)
    {
      USART_ClearITPendingBit(USART2,USART_IT_RXNE);
      Uart2_Buffer[Uart2_Rx] = USART_ReceiveData(USART2);
      Uart2_Rx++;
      Uart2_Rx &= 0xFF;
    }
  if(Uart2_Buffer[Uart2_Rx-1] == 0xB5)   //判断帧头1
    Uart2_head1 = Uart2_Rx-1;
  else if((Uart2_Rx-1 == Uart2_head1+1)&&(Uart2_Buffer[Uart2_Rx-1] == 0x5B)) //判断帧头1数据后是否为帧头2
    Uart2_head2 = Uart2_Rx-1;
  else if(Uart2_Rx-1 == Uart2_head2+1) //得到数据长度
    Uart2_Len = Uart2_Buffer [Uart2_Rx-1]; 

  else if(Uart2_Rx-1 == Uart2_head1 + Uart2_Len+2) //确保接收一帧数据
    {
      Uart2_temp = CRC16(&Uart2_Buffer[Uart2_head1],Uart2_Len+1);  //计算crc
      if(((Uart2_temp&0x00ff)==Uart2_Buffer[Uart2_head1+Uart2_Len+1])&&(((Uart2_temp>>8)&0x00ff)==Uart2_Buffer[Uart2_head1+Uart2_Len+2])) //判断crc是否正确
      {
        Uart2_Sta = 1;  //标志置1
      }
    }

  if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) == SET)
    {
      USART_ClearFlag(USART2,USART_FLAG_ORE);
      USART_ReceiveData(USART2);
    } 

  if(Uart2_Sta) //检测到标志
    {
      for(Uart2_tx2=0;Uart2_tx2 <= Uart2_Len+2;Uart2_tx2++,Uart2_head1++)
      USART2_SendByte(Uart2_Buffer[Uart2_head1]); //从缓冲区中第Uart2_head1字节开始,接收总共Uart2_Len+2个字节

      Uart2_Rx = 0; //下标清0
      Uart2_Sta = 0; //标志置0
    }
}

转载请说明出处:http://www.cnblogs.com/zhengluyao/p/8030291.html

时间: 2024-10-07 02:33:31

stm32串口接收完整的数据包的相关文章

STM32串口接收小结

STM32串口接收数据 稍微理一下思路,一个数据从电脑发送到STM32,然后在从STM32返回到电脑显示出来. 如上图所示,发送(1所示的路线)前,STM32的淳口需要初始化的设置.包括:波特率,字长,硬件流,停止位,奇偶校验位,模式(接收,发送,接收和发送),串口的基地址(Instance).在初始化串口的函数里面,需要调用到HAL_UART_MspInit(),这是一个虚函数(_weak),HAL_UART_MspInit()会调用到HAL_GPIO_Init(),把IO口进行配置.(模式,

vc mscom控件串口接收不到数据问题

读对边距的时候,刚开始有数,后来不行了,重新拔插后可以了. 在接收到数据的程序中,oncomm()函数 中,加入了 串口打开.关闭图标的程序.使得串口接收大数据,执行这部分程序的时候,串口数据卡死了. 删掉串口打开.关闭图标的程序后,数据接收正常.

STM32cube 串口接收任意长度数据

void USART3_IRQHandler(void) { /* USER CODE BEGIN USART3_IRQn 0 */ uint32_t tmp_flag =0; uint32_t temp; tmp_flag = __HAL_UART_GET_FLAG(&huart3,UART_FLAG_IDLE); if((tmp_flag != RESET)) { __HAL_UART_CLEAR_FEFLAG(&huart3); temp = huart3.Instance->

51单片机串口接收和发送数据

第一种方法:在中断中处理 typedef unsigned char UINT8; volatile UINT8 u8Uart_Data; void InitialUART0_Timer1() { SCON = 0x50; //2015-05-04 TMOD = 0x20; TH1 = 0XFD; // 9600BPS 2015-05-04 wangrong TL1 = 0XFD; TR1 = 1; // start timer0 ES = 1; // Enable serial interru

【转载】串口中怎样接收一个完整数据包的解析

这里以串口作为传输媒介,介绍下怎样来发送接收一个完整的数据包.过程涉及到封包与解包.设计一个良好的包传输机制很有利于数据传输的稳定性以及正确性.串口只是一种传输媒介,这种包机制同时也可以用于SPI,I2C的总线下的数据传输.在单片机通信系统(多机通信以及PC与单片机通信)中,是很常见的问题. 一.根据帧头帧尾或者帧长检测一个数据帧 1.帧头+数据+校验+帧尾 这是一个典型的方案,但是对帧头与帧尾在设计的时候都要注意,也就是说帧头.帧尾不能在所传输的数据域中出现,一旦出现可能就被误判.如果用中断来

数据包的接收过程

网络栈的层次结构: 我们就从最底层开始追溯一个数据包的传递流程. 1.网络接口层 * 硬件监听物理介质,进行数据的接收,当接收的数据填满了缓冲区,硬件就会产生中断,中断产生后,系统会转向中断服务子程序. * 在中断服务子程序中,数据会从硬件的缓冲区复制到内核的空间缓冲区,并包装成一个数据结构(sk_buff),然后调用对驱动层的接口函数netif_rx()将数据包发送给链路层.该函数的实现在net/inet/dev.c中,(在整个网络栈实现中dev.c文件的作用重大,它衔接了其下的驱动层和其上的

010 使用netmap函数接管网卡,接收数据包,回应ARP请求

一.本文目的: 上一节中,我们已经在CentOS 6.7 上安装好了netmap,也能接收和发送包了,这节我们来调用netmap中的API,接管网卡,对网卡上收到的数据包做分析,并回应ARP请求. 二.netmap API简要介绍: 1.netmap API 主要包含在两个头文件中:netmap.h和netmap_user.h.在netmap/sys/net/目录下,其中netmap_user.h调用netmap.h. 2.netmap API一共七八个函数调用:nm_open()生成文件描述符

winPcap_5_打开适配器并捕获数据包

知道如何获取适配器的信息了,那我们就开始一项更具意义的工作,打开适配器并捕获数据包.编写一个程序,将每一个通过适配器的数据包打印出来. 打开设备的函数是 pcap_open(). (Open a generic source in order to capture / send (WinPcap only) traffic.) pcap_t* pcap_open ( const char * source, int snaplen, int flags, int read_timeout, st

Winpcap笔记3之打开适配器并捕获数据包

上一讲中知道了如何获取适配的信息,这一将我们讲写一个程序蒋每一个通过适配器的数据包打印出来. 打开设备的函数是pcap_open().函数原型是 pcap_t* pcap_open(const char* source,int snaplen,int flags,int read_timeout,struct pcap_rmtauth *auth,char * errbuf):' pcap_rmatauth { int type. char *username;;//Zero-terminate