• linux下串口编程的个人心得


    我刚刚完成了一个串口的项目,有一点收获,就说说着段时间的体会吧!

    一开始在网上找资料,最多是《Linux Serial HOWTO 中譯版》,浏览地址:http://linux.cis.nctu.edu.tw/chinese/how-to/Serial-HOWTO.html。以及众多这个版本的摘选,内容是大同小异的。

    后来发现,其实串口编程的实质就是多串口属性的设置。
    而属性也就下面这么几个:
    c_cflag Control options
    c_lflag Line options
    c_iflag Input options
    c_oflag Output options
    c_cc Control characters
    c_ispeed Input baud (new interface)
    c_ospeed Output baud (new interface)
    关键是理解有那些属性参数可以设置以及是什么意思。

    继续找资料。发现下面的经典文章,可以说基本上所有的串口编程的文章都或多或少的参考了这篇文章,《Serial Programming Guide for POSIX Operating Systems》是一定要看的,我读的是5th Edition, 3rd Revision - Updated March 11, 2003,下载地址:http://www.easysw.com/~mike/serial/index.html

    当把这篇文章看完之后,基本可以解决串口的设置问题了。不过这是一个英文的版本,本人打算在暑假里把他翻译为中文版本。

    关于具体的例子:
    http://www.comptechdoc.org/os/linux/programming/c/linux_pgcserial.html不错,很详细,不过比较复杂。
    中文的《Linux Serial HOWTO 中譯版》上面就有不少,也很值得参考。

    下面的是我的程序,一个串口读取,往mysql数据库写数据的程序:
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <termios.h>
    #include <errno.h>
    #include <ctype.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>

    #include "mysql.h"

    #define BAUDRATE B9600
    #define DEVICE "/dev/ttyS0"
    #define _POSIX_SOURCE 1
    #define FALSE 0
    #define TRUE 1

    int insertdb(int d1, int d2, int d3, int d4) {
     MYSQL connect;
     int res, no1, no2, sd1, sd2;
     char *query = "INSERT INTO mydata  ( stime, sno1, sno2, sdata1, sdata2 ) VALUES ( '%s', %d, %d, %x, %x)";
     char *sql, *st1;
     struct tm *ptr;
     time_t lt;
     
     no1 = d1;
     no2 = d2;
     sd1 = d3;
     sd2 = d4;
     lt = time(NULL);
     ptr = localtime(&lt);
     st1 = (char *)asctime(ptr);
     st1[strlen(st1) -1 ] = '/0';
     sql = (char *)malloc(255*sizeof(char));
     sprintf(sql, query, st1, no1, no2, sd1, sd2);
     
    /* debug here
     printf("%c : ", st1[strlen(st1)]);
     printf("%s : %d :",sql, strlen(st1));
     return EXIT_SUCCESS;
    */
     
     mysql_init(&connect);
     
     if(mysql_real_connect(&connect, "localhost", "root", "root", "mytest", 0, NULL, 0)) {
      printf("connect success!/n");

      res = mysql_query(&connect, sql);

      if(!res) {
       printf("insert success!/n");
      } else {
       fprintf(stderr, "insert error %d: %s/n", mysql_errno(&connect), mysql_error(&connect));
       return EXIT_FAILURE;
      }

      mysql_close(&connect);
     } else {
      fprintf(stderr, "connect fail!/n");
      return EXIT_FAILURE;
     }

     return EXIT_SUCCESS;
    }

    int main(void) {
     int fd, res_w, res_r, i, j, k;
     struct termios oldtio,newtio;
     char inbuf[255];
     char cbuf[4];
     int buf[4];

     res_w = 0;
     res_r = 0;
     
     fd = open(DEVICE, O_RDWR | O_NOCTTY ); // | O_NDELAY);
     if(fd < 0) {
      perror(DEVICE);
      exit(-1);
     }

     tcgetattr(fd, &oldtio);

    bzero(&newtio,sizeof(struct termios));

    newtio.c_cflag|= (CLOCAL | CREAD);
    newtio.c_cflag|=BAUDRATE;
    newtio.c_cflag&=~CSTOPB;
    newtio.c_cflag&=~PARENB;
    newtio.c_cflag&=~CSIZE;
    newtio.c_cflag|=CS8;
    newtio.c_cflag&=~CRTSCTS;

    newtio.c_lflag=0;

    newtio.c_oflag=0;

    newtio.c_cc[VMIN]=4;
    newtio.c_cc[VTIME]=0;

    newtio.c_iflag&=~(IXON|IXOFF|IXANY);

    cfsetispeed(&newtio, BAUDRATE);
    cfsetospeed(&newtio, BAUDRATE);

    tcsetattr(fd, TCSANOW, &newtio);

    tcflush(fd, TCIFLUSH);

             cbuf[0] = 0x00; 
    //  cbuf[1] = 0x00;

      j = 0;

    for(k = 0; k < 4; k++) {
     switch (j) {
      case 0: 
      default:
       cbuf[1] = 0x00;
       j = 2;
       break;
      case 2:
       cbuf[1] = 0x02;
       j = 0;
       break;
     }
       
     res_w = write(fd, cbuf, 2);

    /* debug here 
    printf("cbuf : %x %x /n", cbuf[0], cbuf[1]);
    printf("buf : %x : %x : %x : %x /n", inbuf[0], inbuf[1], inbuf[2], inbuf[3]);
    */
     res_r = read(fd, &inbuf, 255);
     
     if(res_r != -1) {
      for(i = 0; i < res_r; i++) {
       buf[i] = (int)inbuf[i];
       buf[i] = buf[i] & 0xff;
      // printf(" %x ", buf[i]);   
      }
      printf("/n");
      if(insertdb(buf[0], buf[1], buf[2], buf[3]))
       printf("insert into db success!");
     }
     else {
      perror("read fail");
      exit(-1);
     }// if end here
    }// for end here 

     tcsetattr(fd, TCSANOW, &oldtio);

     close(fd);
     exit(0);
    } // main end here

  • 相关阅读:
    C# 用装饰模式
    31天重构学习笔记4. 降低方法
    JData 使用教程 对输入数据进行验证(服务端验证)
    sql over的作用及用法
    31天重构学习笔记3. 提升方法
    《博客园精华集》
    const和static readonly 区别
    JData 使用教程(四) 对输入数据进行验证(客户端验证)
    用JQuery制作简单实用的下拉菜单
    图片压缩后,依然很大的解决方案
  • 原文地址:https://www.cnblogs.com/ainima/p/6331637.html
Copyright © 2020-2023  润新知