借鉴了PPP协议的帧格式
数据帧的规定
开始字符 | AD数据区的长度 | IO数据区的长度 | AD数据区 | IO数据区 | 校验位 |
---|
1bit | 1bit | 1bit | 2bit | 1bit | 1bit整条数据的总长 | 7E | 02 | 01 | 00 00 | 00 | 07 |
各个区域的含义如下:
- 开始字符:1个字节,代表一个数据包的开始。固定为0x7E
- AD数据区的长度:1个字节,表示有多少个传感器数据,比如,1个传感器就1*2表示02因为AD数据区是有2bit
- IO数据区的长度: 1个字节,表示有多少个IO口,比如,1个io就表示01,IO数据区就1bit
- AD数据区:2个字节,一个传感器占用两个字节
- IO数据区:1个字节,一个IO占用一个字节
- 校验和:包括校验位在内整个数据包的总长度
这套数据规则是存在缺陷,但是在目前的业务中完全足够使用 在AD数据区的长度中大于100左右,就会存在校验位溢出的情况,哈哈哈哈
串口调试助手100ms循环发送几十分钟,未出现异常
异常处理一:
- 第一条数据包发送过去,数据包中间给予一些奇怪数据。
异常数据二:
异常数据三:
代码实现,基于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;
while(!UTX0IF);
UTX0IF = 0;
}
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);
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];
uart_data_sum = 1 + 1 + 1 + ((int)UART_DATE_ADC_SUM) + ((int)UART_DATE_IO_SUM) + 1;
}
}
if(uart_count >= 3)
{
if(uart_data_buff[uart_count-1] == UART_DATA_HEAD)
{
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;
}
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)
{
if(data[0] == UART_DATA_HEAD && ((int)data[index-1]) == index )
{
usrt_send_array(data,index);
}
}
|