zoukankan      html  css  js  c++  java
  • 串口数据解析总结

    在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
    ");
                    usleep(100*1000);
                    continue;
                }
                printf("nread = %d
    ",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("
    ");
    }
  • 相关阅读:
    文件输出debug
    sweetalert
    js认清this的第一步
    Creating default object from empty value in PHP?
    matplotlib画图
    python解析库
    zabbix监控ssl证书过期时间
    aws 预留实例到期监控
    aws ec2挂载 s3
    aliyun挂载oss
  • 原文地址:https://www.cnblogs.com/lvchaoshun/p/8659588.html
Copyright © 2011-2022 走看看