zoukankan      html  css  js  c++  java
  • linux下串口控制

    /*  本程序符合GPL条约
     *  Beneboy 2003-5-16
    */
    #include <stdio.h>              // printf
    #include <fcntl.h>              // open
    #include <string.h>             // bzero
    #include <stdlib.h>             // exit
    #include <sys/times.h>          // times
    #include <sys/types.h>          // pid_t
    #include <termios.h>  //termios, tcgetattr(), tcsetattr()
    #include <unistd.h>
    #include <sys/ioctl.h>          // ioctl
    #include "MyCom.h"


    #define TTY_DEV "/dev/ttyS" //端口路径
    //接收超时
    #define TIMEOUT_SEC(buflen,baud) (buflen*20/baud+2)
    #define TIMEOUT_USEC 0


    /*******************************************
     * 获得端口名称
    ********************************************/
    char *get_ptty(pportinfo_t pportinfo)
    {
     char *ptty;

     switch(pportinfo->tty){
      case '0':{
       ptty = TTY_DEV"0";
      }break;
      case '1':{
       ptty = TTY_DEV"1";
      }break;
      case '2':{
       ptty = TTY_DEV"2";
      }break;
     }
     return(ptty);
    }

    /*******************************************
     * 波特率转化转换函数
    ********************************************/
    int convbaud(unsigned long int baudrate)
    {
     switch(baudrate){
      case 2400:
       return B2400;
      case 4800:
       return B4800;
      case 9600:
       return B9600;
      case 19200:
       return B19200;
      case 38400:
       return B38400;
      case 57600:
       return B57600;
      case 115200:
       return B115200;
      default:
       return B9600;
     }
    }

    /*******************************************
     * Setup comm attr
     * fdcom: 串口文件描述符, pportinfo: 待设置的端口信息s
     *
    ********************************************/
    int PortSet(int fdcom, const pportinfo_t pportinfo)
    {
     struct termios termios_old, termios_new;
     int  baudrate, tmp;
     char databit, stopbit, parity, fctl;

     bzero(&termios_old, sizeof(termios_old));
     bzero(&termios_new, sizeof(termios_new));
     cfmakeraw(&termios_new);
     tcgetattr(fdcom, &termios_old);   //get the serial port attributions

     /*------------设置端口属性----------------*/

     //baudrates
     baudrate = convbaud(pportinfo -> baudrate);
     cfsetispeed(&termios_new, baudrate);  //填入串口输入端波特率
     cfsetospeed(&termios_new, baudrate);  //填入串口输出端波特率
     termios_new.c_cflag |= CLOCAL;   //控制模式, 保证程序不会成为端口的占有者
     termios_new.c_cflag |= CREAD;   //控制模式, 使能端口读取输入的数据


     // 控制模式, flow control
     fctl = pportinfo-> fctl;
     switch(fctl){
      case '0':{
       termios_new.c_cflag &= ~CRTSCTS;  //no flow control
      }break;
      case '1':{
       termios_new.c_cflag |= CRTSCTS;   //hardware flow control
      }break;
      case '2':{
       termios_new.c_iflag |= IXON | IXOFF |IXANY; //software flow control
      }break;
     }

     //控制模式, data bits
     termios_new.c_cflag &= ~CSIZE;  //控制模式, 屏蔽字符大小位
     databit = pportinfo -> databit;
     switch(databit){
      case '5':
       termios_new.c_cflag |= CS5;
      case '6':
       termios_new.c_cflag |= CS6;
      case '7':
       termios_new.c_cflag |= CS7;
      default:
       termios_new.c_cflag |= CS8;
     }

     //控制模式 parity check
     parity = pportinfo -> parity;
     switch(parity){
      case '0':{
       termios_new.c_cflag &= ~PARENB;  //no parity check
      }break;
      case '1':{
       termios_new.c_cflag |= PARENB;  //odd check
       termios_new.c_cflag &= ~PARODD;
      }break;
      case '2':{
       termios_new.c_cflag |= PARENB;  //even check
       termios_new.c_cflag |= PARODD;
      }break;
     }

     //控制模式, stop bits
     stopbit = pportinfo -> stopbit;
     if(stopbit == '2'){
      termios_new.c_cflag |= CSTOPB; //2 stop bits
     }
     else{
      termios_new.c_cflag &= ~CSTOPB; //1 stop bits
     }

     //other attributions default
     termios_new.c_oflag &= ~OPOST;   //输出模式, 原始数据输出

     termios_new.c_cc[VMIN]  = 1;   //控制字符, 所要读取字符的最小数量
     termios_new.c_cc[VTIME] = 1;   //控制字符, 读取第一个字符的等待时间,  unit: (1/10)second

     tcflush(fdcom, TCIFLUSH);   //溢出的数据可以接收,但不读
     tmp = tcsetattr(fdcom, TCSANOW, &termios_new); //设置新属性, TCSANOW: 所由改变立即生效
     tcgetattr(fdcom, &termios_old);
     return(tmp);
    }

    /*******************************************
     * Open serial port
     * tty: 端口号 ttyS0, ttyS1, ....
     * 返回值为串口文件描述符
    ********************************************/
    int PortOpen(pportinfo_t pportinfo)
    {
     int fdcom; //串口文件描述符
     char *ptty;

     ptty = get_ptty(pportinfo);
     //fdcom = open(ptty, O_RDWR | O_NOCTTY | O_NONBLOCK | O_NDELAY);
     fdcom = open(ptty, O_RDWR | O_NOCTTY | O_NONBLOCK);

     return (fdcom);
    }

    /*******************************************
     * Close serial port
    ********************************************/
    void PortClose(int fdcom)
    {
     close(fdcom);
    }

    /********************************************
     * send data
     * fdcom: 串口描述符, data: 待发送数据, datalen: 数据长度
     * 返回实际发送长度
    *********************************************/
    int PortSend(int fdcom, char *data, int datalen)
    {
     int len = 0;

     len = write(fdcom, data, datalen); //实际写入的长度
     if(len == datalen){
      return (len);
     }
     else{
      tcflush(fdcom, TCOFLUSH);
      return -1;
     }
    }

    /*******************************************
     * receive data
     * 返回实际读入的字节数
     *
    ********************************************/
    int PortRecv(int fdcom, char *data, int datalen, int baudrate)
    {
     int readlen, fs_sel;
     fd_set fs_read;
     struct timeval tv_timeout;

     FD_ZERO(&fs_read);
     FD_SET(fdcom, &fs_read);
     tv_timeout.tv_sec = TIMEOUT_SEC(datalen, baudrate);
     tv_timeout.tv_usec = TIMEOUT_USEC;

     fs_sel = select(fdcom+1, &fs_read, NULL, NULL, &tv_timeout);
     if(fs_sel){
      readlen = read(fdcom, data, datalen);
      return(readlen);
     }
     else{
      return(-1);
     }

     return (readlen);
    }

    //*************************Test*********************************
    int main(int argc, char *argv[])
    {
     int fdcom, i, SendLen, RecvLen;
     struct termios termios_cur;
     char RecvBuf[256];
            char writeBuf[256];
     portinfo_t portinfo ={
      '0',                          // print prompt after receiving
       9600,                       // baudrate: 9600
       '8',                          // databit: 8
       '0',                          // debug: off
       '0',                          // echo: off
       '2',                          // flow control: software
       '0',                          // default tty: COM1
       '0',                          // parity: none
       '1',                          // stopbit: 1
        0                           // reserved
     };

     if(argc != 2){
      printf("Usage: <type 0 -- send 1 -- receive> ");
      printf("   eg:");
      printf("        MyPort 0");
      exit(-1);
     }

     fdcom = PortOpen(&portinfo);
     if(fdcom<0){
      printf("Error: open serial port error. ");
      exit(1);
     }

     PortSet(fdcom, &portinfo);

            while(1)
     if(atoi(argv[1]) == 0)
            {
      //send data
      //for(i=0; i<1000; i++)
                    {
                            //fgets(writeBuf,256,stdin);
                            scanf("%s",writeBuf);
       SendLen = PortSend(fdcom, writeBuf, strlen(writeBuf));
       if(SendLen>0)
                            {
        //printf("send data %s", writeBuf);
       }
       else
                            {
        printf("Error: send failed. ");
       }

                            if(strncmp(writeBuf,"exit",4)==0)
                               break;
       sleep(1);
      }
      //PortClose(fdcom);
     }
     else
           {
      //for(;;)
                    {
       RecvLen = PortRecv(fdcom, RecvBuf, 256, portinfo.baudrate);
       if(RecvLen>0)
                            {
        /*for(i=0; i<RecvLen; i++)
                                    {
         printf("Receive data No %d is %x. ", i, RecvBuf[i]);
        }//*/
                                    RecvBuf[RecvLen] = '';
        printf("read data %s ",RecvBuf);

                                    if(strncmp(RecvBuf,"exit",4)==0)
                                        break;
       }
       else
                            {
        //printf("Error: receive error. ");
       }
       sleep(1);
      }
     }
            PortClose(fdcom);
     return 0;
    }

  • 相关阅读:
    null in ABAP and nullpointer in Java
    SAP ABAP SM50事务码和Hybris Commerce的线程管理器
    Hybris service layer和SAP CRM WebClient UI架构的横向比较
    SAP ABAP和Linux系统里如何检查网络传输的数据量
    SAP CRM WebClient UI和Hybris的controller是如何被调用的
    SAP CRM和Cloud for Customer订单中的业务伙伴的自动决定机制
    SAP CRM WebClient UI和Hybris CommerceUI tag的渲染逻辑
    SAP BSP和JSP页面里UI元素的ID生成逻辑
    微信jsapi支付
    微信jsapi退款操作
  • 原文地址:https://www.cnblogs.com/james1207/p/3253488.html
Copyright © 2011-2022 走看看