编写语言:C++
编写平台:VS
运用平台:STM32和PC
非常实用的一个解析程序,自己编写的也简单。
*.h
#define BUF_LEN 1024 //buf长度 #define CONF_BUF_LEN 128 //保存代解析数据 #define DATA_BUF_LEN 100 //保存解析数据 //此处为最大传输数据 #define CONF_BUF_BEST_LEN 4 //基本数据长度 /*/////////////////协议定义////////////////////// // 0x6B 0x66 长度 数据 校验(长度+数据的和) //最基本的数据 0x6B 0x66 0x01 0x01 0x2 用法:1.调用add();函数,在中断函数,或者线程 2.调用checke_con();函数,在主函数或者线程,中断 */ //针头 #define ZT1 0x6B #define ZT2 0x66 /////////////////////////////////////////////// class uart { public: uart(void); ~uart(void); private: unsigned char buf[BUF_LEN]; //buf队列 unsigned char conf_buf[CONF_BUF_LEN]; //代解析到的数据 unsigned int conf_buf_len; //代解析数据长度 public: unsigned char data_buf[DATA_BUF_LEN]; //解析数据:长度+数据 unsigned char data_buf_len; unsigned int buf_len; //buf长度 unsigned char *in; //队列头 unsigned char *out; //队列未 public: //添加数据到队列 void add(unsigned char temp); //出队数据到队列 unsigned char del(); //检查命令 int checke_con(); };
.cpp
#include "stdafx.h" #include "uart.h" #include "string.h" uart::uart(void) { in=buf; out=buf; buf_len=0; conf_buf_len=0; data_buf_len=0; memset(buf,0,BUF_LEN); } uart::~uart(void) { } //添加数据到队列 void uart::add(unsigned char temp) { *in++=temp; buf_len++; if(in==(buf+BUF_LEN))in=buf; //printf("buf:%s\n",buf); } //出队数据到队列 unsigned char uart::del() { unsigned char ch; if(buf_len>0) { buf_len--; ch=*out++; if(out==(buf+BUF_LEN))out=buf; return ch; } return 0; } //检查命令 int uart::checke_con() { int len=0; int data_len=0; unsigned char c=0; if(buf_len>0) { c=del(); //printf("(1):%x \n",c); conf_buf[conf_buf_len++]=c; if(conf_buf_len>DATA_BUF_LEN+CONF_BUF_BEST_LEN)conf_buf_len=0; } else return 0; if(conf_buf_len>=CONF_BUF_BEST_LEN) { int i=0; if(conf_buf[2]>DATA_BUF_LEN) //长度不大于可用长度 { for(i=0;i<conf_buf_len-1;i++) { conf_buf[i]=conf_buf[i+1]; } conf_buf_len-=1; return 0; } //while(i<conf_buf_len) //{ // printf("%x ",conf_buf[i]); // i++; //} //printf("\n"); if(conf_buf[len]!=ZT1) //判断针头 { for(i=0;i<conf_buf_len-1;i++) { conf_buf[i]=conf_buf[i+1]; } conf_buf_len-=1; return 0; } if(conf_buf[len+1]!=ZT2) //判断针头 { for(i=0;i<conf_buf_len-1;i++) { conf_buf[i]=conf_buf[i+1]; } conf_buf_len-=1; return 0; } len+=2; data_len=conf_buf[len]; //数据长度 //printf("len:%d\n",data_len); //printf("buf_len:%d\n",conf_buf_len); if((data_len+CONF_BUF_BEST_LEN)<=(conf_buf_len)) //数据包长度刚和等于数据长度加基本数据包 { int N=len; int sum=0; data_buf_len=0; while(N<=data_len+len) { data_buf[data_buf_len++]=conf_buf[N]; sum+=conf_buf[N++]; } data_buf[data_buf_len]=0; //printf("sum:%d\n",sum); if(sum==conf_buf[N]) //判断校验 { for(i=0;i<(data_len+CONF_BUF_BEST_LEN);i++) { conf_buf[i]=conf_buf[i+data_len+CONF_BUF_BEST_LEN]; } conf_buf_len-=(data_len+CONF_BUF_BEST_LEN); return 1; }else //检验失败 { for(i=0;i<conf_buf_len-1;i++) { conf_buf[i]=conf_buf[i+1]; } conf_buf_len-=1; } } } return 0; }
main.c
// 串口协议0.6.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "uart.h" #include "windows.h" #include "conio.h" uart U; //子线程函数 DWORD WINAPI ThreadFun(LPVOID pM) { int v=0; while(1) { //if(U.buf_len>0) //{ // printf("%x ",U.del()); // v++; // if(v==12)printf("\n"),v=0; //} if(U.checke_con()) { printf("解析出数据--------ok:"); for(int i=0;i<U.data_buf_len;i++) { printf("%x ",U.data_buf[i]); } printf("\n"); } Sleep(2); } } int _tmain(int argc, _TCHAR* argv[]) { char ch; int n=1; int chi=10; unsigned char str[]={0x6b,0x43,0x66,0x6B,0x66,0x03,0x02,0x1,0x21,0x27,0x12,0x66,0x32,0x12,0x6B,0x66,0x01,0x02,0x3}; unsigned char str1[]={0x6B,0x66,0x03,0x02,0x1,0x21,0x27,0x6B,0x66,0x01,0x02,0x3}; HANDLE handle = CreateThread(NULL, 0, ThreadFun, NULL, 0, NULL); while(chi--) { for(int i=0;i<12;i++) U.add(str1[i]); Sleep(100); //getch(); //printf("\n"); //printf("\nadd:%d\n",n++); } while(1); return 0; }
运行效果: