串口数据解析总结


在linux下编写串口通讯程序,采用select监听串口的可读事件,一旦可读,调用read。但是我们会发现,read一次得到的数据通常不是完整的一个数据帧。

比如完整数据帧为

这里写图片描述

但是实际上需要read多次才能完全读到。

程序实际运行情况:

两次读完:

这里写图片描述

四次读完:

这里写图片描述

为了解决不能接收完整数据帧的问题,借鉴了网友的例子,并进行了一些改动:

现在的效果:

这里写图片描述

下面是程序代码:

#include "smartlight.h" int portfd = -1; void print_frame(const char *desc,uint8_t *buf,int size); void getCompleteFrame(uint8_t *inBuf,int inCnt,uint8_t *outBuf,int *destCnt,int *readStatus); void *monitor_serial_readable(void *arg); int main(int argc,char *argv[]) { int nret; pthread_t wtid; /* open serial port */ portfd = open_port(); /* set serial port */ set_opt(portfd,57600); nret = pthread_create(&wtid,NULL,monitor_serial_readable,NULL); if(nret != 0) { DEBUG_ERR(create thread failed); exit(-1); } nret = pthread_join(wtid,NULL); if(nret != 0) { DEBUG_ERR(join thread failed); exit(-1); } close(portfd); return 0; } void getCompleteFrame(uint8_t *inBuf,int inCnt,uint8_t *outBuf,int *destCnt,int *readStatus) { int i; for(i=0; i<inCnt; i++) { if(inBuf[i] == 0x11 && inBuf[i+2] == 0x00 && inBuf[i+3] == 0x00)//header { outBuf[(*destCnt)++] = inBuf[i]; *readStatus = 1; //print_frame("header",dest,dest_cnt); continue; } if(*readStatus == 1)//body { outBuf[(*destCnt)++] = inBuf[i]; //print_frame("body",dest,dest_cnt); } if(*destCnt == outBuf[1])//tail { print_frame("tail",outBuf,*destCnt); *readStatus = 0; *destCnt = 0; memset(outBuf,-1,sizeof(outBuf)); memset(inBuf,0,sizeof(inBuf)); continue; } } } void *monitor_serial_readable(void *arg) { int rc,i,nread=0; fd_set rset; struct timeval tv; uint8_t buf[1024] = {0}; uint8_t dest[1024]={0}; int read_status = 0; int dest_cnt = 0; while(1) { FD_ZERO(&rset); FD_SET(portfd,&rset); tv.tv_sec = 5; tv.tv_usec = 0; rc = select(portfd+1,&rset,NULL,NULL,&tv); if(rc == -1) { DEBUG_ERR(select error in thread); continue; } if(rc == 0) { DEBUG_INFO(select timeout in thread); continue; } else { nread = read(portfd,buf,sizeof(buf)); if(nread == -1) { perror("read"); usleep(100*1000); continue; } if(nread == 0) { printf("nread==0\n"); usleep(100*1000); continue; } printf("nread = %d\n",nread); getCompleteFrame(buf,nread,dest,&dest_cnt,&read_status); } }//END_while } void print_frame(const char *desc,uint8_t *buf,int size) { int i; printf(RED"[%s] [LEN=%d]"COLOR_END,desc,size); for(i=0; i<size; i++) { printf(BLUE"[%.2x]"COLOR_END,buf[i]); } printf("\n"); }


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM