串口數據解析總結


在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