c#串口完全接收程序
待读:
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) { int n = serialPort1.BytesToRead;//先记录下来,避免某种原因,人为的原因,操作几次之间时间长,缓存不一致 RX_CNT += n;//增加接收计数 int _frame_num = 0; // 接收帧 在frame数组里的索引(接收到的数据的类型) int _frame_len = 0; // 帧长度 if (n > 20000) return;//接收到的数据过长,可能出错 serialPort1.Read(data_buf, data_num, n);//读取缓冲数据,从data_buf(缓存区)的第data_num(未读的)处开始读入,与之前未处理数据连接在一起 data_num += n; int I = 0;//每次处理接收的时候,I从0开始。 while (I < data_num - 10)//遍历接收数据 ,//data_num 上次未处理数据长度。 { if (data_buf[I] == 0xaa && data_buf[I + 1] == 0xaa)//帧头 { _frame_len = data_buf[I + 2];//帧长度() 0A _frame_num = data_buf[I + 3]; // 接收帧 在frame数组里的索引(功能) 01 if ((data_num - I - 5) >= _frame_len) // 数据接收完毕 09 { byte sum = 0;//校验和 for (int j = I; j <= I + 3 + _frame_len; j++)//计算sum sum += data_buf[j];//和 if (sum == data_buf[I + 4 + _frame_len])//sum校验通过, { int j; switch (_frame_num)//接收帧 在frame数组里的索引(接收到的数据的类型) { case 1://STATUS j = I + 4; S_acc_x = (float)((Int16)(data_buf[j] << 8 | data_buf[j + 1])) / 100;//字节处理 S_acc_y = (float)((Int16)(data_buf[j + 2] << 8 | data_buf[j + 3])) / 100;//2字节 //D_ang_yaw = (float)((Int16)(data_buf[j + 4] << 8 | data_buf[j + 5])) / 100;// S_acc_1 = (Int16)(data_buf[j + 6] << 8 | data_buf[j + 7]);//2字节 S_acc_5 = (Int32)(data_buf[j + 8] << 24 | data_buf[j + 9] << 16 | data_buf[j + 10] << 8 | data_buf[j + 11]);//4字节 break; default: break; } I = I + 5 + _frame_len; // I指向下一帧数据 } else//sum校验未通过 { I++; } } else//HEAD FUN LEN符合要求,但是数据未接收完毕 { for (int j = I; j <= data_num - 1; j++) { data_buf[j - I] = data_buf[j]; } data_num = data_num - I; return; } } else//HEAD FUN LEN 不符合要求 { I++; } } if (I < data_num) // 剩几字节没有处理完,,,处理一个字节,I 就增加1。 data_num 未处理的长度 { for (int j = I; j <= data_num - 1; j++) { data_buf[j - I] = data_buf[j];//将没有处理完的数据放到 数组的最前面。 } data_num = data_num - I; } }
发现自己的不足,善于利用找到的方法去扬长避短。行动起来。