编写语言: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;
}
运行效果: