zoukankan      html  css  js  c++  java
  • 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; }
  • 相关阅读:
    JVM如何执行方法调用
    JVM如何实现反射
    JVM是如何处理异常的
    Java类加载
    windows-Kafka安装
    Google Eventbus简单使用
    队列c#版
    python 元类

    Spring Mvc 笔记二之异常和文件上传
  • 原文地址:https://www.cnblogs.com/birdBull/p/12029933.html
Copyright © 2011-2022 走看看