概述
在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==0n");
usleep(100*1000);
continue;
}
printf("nread = %dn",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");
}
最后
以上就是怡然花瓣为你收集整理的解析串口-接收完整数据帧的全部内容,希望文章能够帮你解决解析串口-接收完整数据帧所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复