• linux 串口 拼帧处理


    串口每次read数据可能不是完整的数据,参照网上的代码,写了拼帧的代码#include <stdio.h>

    #include <termios.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <strings.h>
    #include <sys/time.h>
    #include <sys/types.h>
    
    
    int speed_arr[] = { B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1200, B300};
    int name_arr[] =  { 115200,  57600,  38400,  19200,  9600,  4800,  2400,  1200,  300};
    
    /**
    *@brief  Set Serial Port BitRate
    *@param  fd     Type : int The File Description of Serial Port
    *@param  speed  Type : int  Serial Speed
    *@return  void
    */
    void set_speed(int fd, int speed)
    {
        int   i;
        int   status;
        struct termios   Opt;
        tcgetattr(fd, &Opt);
        for( i=0; i < (sizeof(speed_arr) / sizeof(int)); i++ )
        {
            if (speed == name_arr[i])
            {
                tcflush(fd, TCIOFLUSH);
                cfsetispeed(&Opt, speed_arr[i]);
                cfsetospeed(&Opt, speed_arr[i]);
                status = tcsetattr(fd, TCSANOW, &Opt);
                if (status != 0)
                {
                    perror("tcsetattr fd");
                    return;
                }
                tcflush(fd,TCIOFLUSH);
            }
        }
    }
    
    /**
    *@brief   Set Serial Port Databits, Stopbits and Parity.
    *@param  fd     Type:  int The File Description of Serial Port
    *@param  databits Type:  int Databits 7 or 8
    *@param  stopbits Type:  int Stopbits 1 or 2
    *@param  parity  Type:  int  Parity Type: n,N,e,E,o,O,s,S
    */
    int set_Parity(int fd, int databits, int parity, int stopbits)
    {
        struct termios options;
        if ( tcgetattr( fd,&options)  !=  0)
        {
            perror("SetupSerial 1");
            return(-1);
        }
        options.c_cflag &= ~CSIZE;
        switch (databits)               /*Set Datebits*/
        {
        case 7:
            options.c_cflag |= CS7;
            break;
        case 8:
            options.c_cflag |= CS8;
            break;
        default:
            fprintf(stderr,"Unsupported data size
    ");
            return(-1);
        }
    
        switch (parity) /*Set Parity*/
        {
        case 'n':
        case 'N':
              options.c_cflag &= ~PARENB;   /* Clear parity enable */
              options.c_iflag &= ~INPCK;     /* Enable parity checking */
              break;
        case 'o':
        case 'O':
              options.c_cflag |= (PARODD | PARENB); /* Odd Checking*/
              options.c_iflag |= INPCK;             /* Disnable parity checking */
              break;
        case 'e':
        case 'E':
              options.c_cflag |= PARENB;     /* Enable parity */
              options.c_cflag &= ~PARODD;   /* Even Checking*/
              options.c_iflag |= INPCK;       /* Disnable parity checking */
              break;
        case 'S':
        case 's':  /*as no parity*/
              options.c_cflag &= ~PARENB;
              options.c_cflag &= ~CSTOPB;
              break;
        default:
              fprintf(stderr,"Unsupported parity
    ");
              return(-1);
        }
    
        switch (stopbits)               /*Set Stobits*/
        {
        case 1:
            options.c_cflag &= ~CSTOPB;
            break;
        case 2:
            options.c_cflag |= CSTOPB;
            break;
        default:
            fprintf(stderr,"Unsupported stop bits
    ");
            return(-1);
        }
        /* Set input parity option */
        if (parity != 'n')
          options.c_iflag |= INPCK;
    
        /*以下两句添加后发送方可以不加回车换行,但是read读取不完整*/
        options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);     /*Input*/
        options.c_oflag &= ~OPOST;  /*Output*/
    
        //屏蔽功能: NL(换行)->CR(回车)、CR->NL、忽略输入回车
        options.c_iflag &= ~(INLCR | ICRNL | IGNCR);
        options.c_oflag &= ~(ONLCR | OCRNL);
    
        tcflush(fd,TCIFLUSH);
        //未设置O_NONBLOCK或O_NDELAY
        options.c_cc[VTIME] = 150; /* Timeout in 15 seconds*/
        options.c_cc[VMIN] = 0; /* Update the options and do it NOW */
        if (tcsetattr(fd,TCSANOW,&options) != 0)
        {
          perror("SetupSerial 3");
          return(-1);
        }
        return(0);
    }
    
    
    
    void print_frame(unsigned char *buf,int size)
    {
        int i;
        for(i = 0; i < size; i++)
        {
            printf("0x%x ", buf[i]);
        }
        printf("
    ");
    }
    
    
    void getCompleteFrame(unsigned char *inBuf,int inCnt,unsigned char *outBuf,int *destCnt,int *readStatus)
    {
        int i;
        for(i = 0; i < inCnt; i++)
        {
            if(inBuf[i] == 0x01 && inBuf[i+1] == 0x03)//header
            {
                outBuf[(*destCnt)++] = inBuf[i];
                *readStatus = 1;
                continue;
            }
            if(*readStatus == 1)//body
            {
                outBuf[(*destCnt)++] = inBuf[i];
            }
            if(*destCnt == outBuf[2] && *readStatus == 1)//tail
            {
                print_frame(outBuf,*destCnt);
                *readStatus = 0;
                *destCnt = 0;
                memset(outBuf, -1, sizeof(outBuf));
               // memset(inBuf,0,sizeof(inBuf));
                continue;
            }
        }
    }
    
    
    int main(void)
    {
        unsigned char battery_msg[512];
        int fd;
        unsigned char read_buf[512] = {0};
        int nread = 0;
        fd = open("/dev/ttyS0", O_RDWR|O_NOCTTY);
        if (fd > 0)
        {
            printf("Open  Port Success!
    ");
        }
        else
        {
            printf("Can't Open port
    ");
            return(-1);
        }
    
        set_speed(fd, 115200);
        if(set_Parity(fd, 8, 'N', 1) == -1)
        {
            close(fd);
            return(-1);
        }
        int i = 0, rc = 0;
        int flag = 0;
        fd_set rset;
        struct timeval tv;
        int read_status = 0;
        int dest_cnt = 0;
    
        while (1) //循环读取数据
        {
            FD_ZERO(&rset);
            FD_SET(fd, &rset);
    
            tv.tv_sec = 5;
            tv.tv_usec = 0;
    
            rc = select(fd+1, &rset, NULL, NULL, &tv);
    
            if(rc > 0)
            {
          if(FD_ISSET(fd_485C2, &rset))
          {
    memset(read_buf,
    0, sizeof(read_buf)); usleep(100); nread = read(fd, read_buf, sizeof(read_buf)); // printf("read %d data ", nread); if(nread > 0) { getCompleteFrame(read_buf, nread, battery_msg,&dest_cnt,&read_status); }
          } } } close(fd);
    return 0; }
  • 相关阅读:
    Oracle 11g SQL Fundamentals Training Introduction02
    Chapter 05Reporting Aggregated data Using the Group Functions 01
    Chapter 01Restriicting Data Using The SQL SELECT Statemnt01
    Oracle 11g SQL Fundamentals Training Introduction01
    Chapter 04Using Conversion Functions and Conditional ExpressionsConditional Expressions
    Unix时代的开创者Ken Thompson (zz.is2120.bg57iv3)
    我心目中计算机软件科学最小必读书目 (zz.is2120)
    北京将评估分时分区单双号限行 推进错时上下班 (zz)
    佳能G系列领军相机G1X
    选购单反相机的新建议——心民谈宾得K5(转)
  • 原文地址:https://www.cnblogs.com/birdBull/p/12029933.html
Copyright © 2020-2023  润新知