锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

稳定的串口通信协议~物联网项目

时间:2022-12-22 14:00:00 5e0100200112传感器

借鉴了PPP约定的帧格式
7.当数据区出现时e需要对7进行处理e进行转义
7E—>7D 5E
数据帧的规定

开始字符 AD数据区长度 IO数据区长度 AD数据区 IO数据区 校验位
1bit 1bit 1bit 2bit 1bit 1bit整个数据的总长
7E 02 01 00 00 00 07

各个区域的含义如下:

  • 开始字符:一个字节代表数据包的开始。固定为0x7E
  • AD数据区长度:一个字节,表示有多少传感器数据,例如,一个传感器是1*2表示02因为AD数据区是有2bit
  • IO数据区长度: 一个字节是多少?IO比如,一个io就表示01,IO数据区就1bit
  • AD数据区:两个字节,一个传感器占用两个字节
  • IO数据区:1个字节,一个IO占用字节
  • 验证和:整个数据包的总长度,包括验证位置

这套数据规则有缺陷,但在当前业务中完全足够使用
在AD如果数据区长度在100左右,验证位会溢出,哈哈哈哈
请添加图片描述

串口调试助手100ms循环发送几十分钟,无异常

异常处理1:

  • 第一条数据包发送过去,在数据包中间给出一些奇怪的数据。

异常数据2:

异常数据3:

基于代码实现CC2530实现

int  uart_count = 0;                //串口计数器 char uart_data_buff[128];           //串口接收缓冲区  #define UART_DATA_HEAD 0x7E ///判断指令帧头 char    UART_DATE_ADC_SUM = 0x00;   //传感器数量 char    UART_DATE_IO_SUM =  0x00;   //执行器和数字量传感器的数量(其状态) int     uart_data_sum =     0;      //接收指令总和 ///串口发送一个字节 void uart_send_put(char byte) { 
          U0DBUF = byte;        ///将要发送的1字节数据写入U0DBUF   while(!UTX0IF);       //等待TX中断标志,即数据发送完成   UTX0IF = 0;           //清除TX中断标志,准备下次发送 } //串口发送字节数组 void usrt_send_array(char *data, int index) { 
          int i = 0;  for(i = 0;i<index;i++)
  { 
       
    uart_send_put( data[i]); 
  }
}
//串口检验函数
void uart_data_check(char *data , int index);

//这个中断函数相当于,一个个接收的函数
#pragma vector = URX0_VECTOR
__interrupt void Scan_Byte()
{ 
       
  URX0IF=0;
  uart_data_buff[uart_count] = U0DBUF; //将数据存入缓冲区
  uart_count++;
  
  while(!U0DBUF);
  
  //-----这里是count、计算指令校验和都是 从123456789开始算的,所以取最后一位的时候记得-1

  if(uart_count == 3)//接收到前三个数据位的时候就已经可以知道整条数据的长度了
  { 
       
    if(uart_data_buff[0] == UART_DATA_HEAD) //判断帧头
    { 
       
      UART_DATE_ADC_SUM = uart_data_buff[1];//对传感器数量进行赋值
      UART_DATE_IO_SUM  = uart_data_buff[2];//对io状态的数量进行赋值
      //然后这里计算整条指令的总长度
      uart_data_sum = 1 + 1 + 1 + ((int)UART_DATE_ADC_SUM) + ((int)UART_DATE_IO_SUM) + 1;
    }
  }
  //当串口计数器大于3的时候,校验错误数据 
  if(uart_count >= 3)
  { 
       

    //若数据任意一列出现了帧头,则都全部抛弃,重新拼接
    if(uart_data_buff[uart_count-1] == UART_DATA_HEAD)
    { 
       
      //7E 04 02 12 7E 04 02 12 34 25 30 11 10 0A 这是一条错误数据
      //这里存在错误数据
      //程序运行到这里的时候uart_count = 4;uart_data_buff[4]里面是7E
      //所以将计数器赋值为1,uart_data_buff[0] 赋值帧头,从1开始继续接收数据
      uart_count = 1;
      uart_data_sum = 0;
      memset(uart_data_buff, 0, sizeof(uart_data_buff));
      UART_DATE_ADC_SUM = 0x00;
      UART_DATE_IO_SUM = 0x00;
      uart_data_buff[0] = UART_DATA_HEAD;//把帧头重新赋值到0
    }
    //最后一位是整条指令的校验和,把最后一位校验位取出来和计算出来的校验和判断
    if(uart_data_buff[uart_count-1] == uart_data_sum)
    { 
       
      //接收成功
      uart_data_check(uart_data_buff,uart_count);
      uart_count = 0;
      uart_data_sum = 0;
      UART_DATE_ADC_SUM = 0x00;
      UART_DATE_IO_SUM = 0x00;
      D3 = ~D3;
    }
  }
  
}

//串口数据校验函数
void uart_data_check(char *data , int index)
{ 
       
  //index是从123456开始算的,记得-1
  //7E 04 01 12 34 25 30 11 09
  if(data[0] == UART_DATA_HEAD && ((int)data[index-1]) == index )
  { 
       
        usrt_send_array(data,index);
  }
}
锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章