//linux c: 串口设置
//串口操作无非以下几个:
//1 打开                       
//2 设置串口属性
//3 read write

//struct termios能够表明一切串口属性,这里不详细说明.
//详见 【Linux公开课】串口属性设置 http://mp.weixin.qq.com/s?src=3&timestamp=1467340907&ver=1&signature=2hx5roS7br3*GBJVmZQ0Om2X3KMAONfWdT1SSPB2fMDoc68n3k6nqofouSMF3UWy8HMv58IMyIT4XiugpDSQVEPSubo8oSDt*BcWwUVgdqvSUypVfgz8arph5*9QxamrlcafmoPA9fk42FwIjITW6A==
//以及 Linux应用程序开发 http://hilinux.com/man/linuxdev/ch09.html, 这篇文章对串口结构体做了比较详细的说明

struct termios {
    tcflag_t c_iflag; /* 输入参数 */
    tcflag_t c_oflag; /* 输出参数 */
    tcflag_t c_cflag; /* 控制参数*/
    tcflag_t c_ispeed; /* 输入波特率 */
    tcflag_t c_ospeed; /* 输出波特率 */
    cc_t c_line; /* 线控制 */
    cc_t c_cc[NCCS]; /* 控制字符*/
};
                       
//xereno的串口代码是太繁乱,只做对比确认用.
//下面摘抄一段网络代码进行分析:        
//串口操作示例
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <asm/termios.h>   // 在linux x86下面用#include <termios.h>

#include "serial.h"

#define DEV_NAME  "/dev/ttyS1" //同自己的驱动写的名字
    
    int set_port_attr (int fd,int  baudrate, int  databit, const char *stopbit, char parity, int vtime,int vmin );
    static void set_baudrate (struct termios *opt, unsigned int baudrate);
    static void set_data_bit (struct termios *opt, unsigned int databit);
    static void set_stopbit (struct termios *opt, const char *stopbit);
    static void set_parity (struct termios *opt, char parity);
    
    int main (int argc, char *argv[])
    {
        int fd;
        int len, i,ret;
        char buf[] = "hello ZLG!";

fd = open(DEV_NAME, O_RDWR | O_NOCTTY); //如果是在linux x86下面做实验, 这个设备是有问题的, 可不要这一步, 用fd=0直接定位到当前的终端来进行实验.
        if(fd < 0) {
        perror(DEV_NAME);
        return -1;
        }

ret = set_port_attr (fd, B115200, 8, "1", 'N',150,255 );    /* 115200 8n1                                 */
        if(ret < 0) {
               printf("set uart arrt faile \n");
               exit(-1);
        }

len = write(fd, buf, sizeof(buf));                            /* 向串口发送字符串                            */
        if (len < 0) {
               printf("write data error \n");
               return -1;
        }
        
        len = read(fd, buf, sizeof(buf));                            /* 在串口读取字符串                            */
        if (len < 0) {
            printf("read error \n");
            return -1;
        }

printf("%s \n", buf);                                      /* 打印在串口读取的字符串       */

return(0);
    }

//自定义终端属性设置函数具体定义如下
//设置终端属性的时候注意,有的项目是通过与&,而有的项目是通过或|. 不要混淆误解.
    int  set_port_attr (int fd,int  baudrate, int  databit, const char *stopbit, char parity, int vtime,int vmin )
    {
        struct termios opt;
        tcgetattr(fd, &opt);       //获取初始设置
        
        set_baudrate(&opt, baudrate);
        set_data_bit(&opt, databit);
        set_parity(&opt, parity);
        set_stopbit(&opt, stopbit);
        
        opt.c_cflag &= ~CRTSCTS;// 不使用硬件流控制
        opt.c_cflag |= CLOCAL | CREAD; //CLOCAL--忽略 modem 控制线,本地连线, 不具数据机控制功能, CREAD--使能接收标志

/*
        IXON--启用输出的 XON/XOFF 流控制
        IXOFF--启用输入的 XON/XOFF 流控制
        IXANY--允许任何字符来重新开始输出
        IGNCR--忽略输入中的回车
        */
        opt.c_iflag &= ~(IXON | IXOFF | IXANY);
        opt.c_oflag &= ~OPOST; //启用输出处理
        /*
        ICANON--启用标准模式 (canonical mode)。允许使用特殊字符 EOF, EOL,
                EOL2, ERASE, KILL, LNEXT, REPRINT, STATUS, 和 WERASE,以及按行的缓冲。
        ECHO--回显输入字符
        ECHOE--如果同时设置了 ICANON,字符 ERASE 擦除前一个输入字符,WERASE 擦除前一个词
        ISIG--当接受到字符 INTR, QUIT, SUSP, 或 DSUSP 时,产生相应的信号
        */
        opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
        opt.c_cc[VMIN] = vmin; //设置非规范模式下的超时时长和最小字符数:
        opt.c_cc[VTIME] = vtime; //VTIME与VMIN配合使用,是指限定的传输或等待的最长时间
        
        tcflush (fd, TCIFLUSH);                    /* TCIFLUSH-- update the options and do it NOW */
        return (tcsetattr (fd, TCSANOW, &opt)); /* TCSANOW--改变立即发生 */
    }
    
    //自定义set_baudrate()函数
    //使用set_baudrate()函数设置串口输入/输出波特率为115200的代码为:set_baudrate(&opt, B115200));
    //通常来说,串口的输入和输出波特率都设置为同一个值,如果要分开设置,就要分别调用cfsetispeed , cfsetospeed
        static void set_baudrate (struct termios *opt, unsigned int baudrate)
        {
             cfsetispeed(opt, baudrate);
             cfsetospeed(opt, baudrate);
        }
        
    //自定义set_stopbit函数
    //在set_stopbit()函数中,stopbit参数可以取值为:“1”(1位停止位)、“1.5”(1.5位停止位)和“2”(2位停止位)。
        static void set_stopbit (struct termios *opt, const char *stopbit)
        {
            if (0 == strcmp (stopbit, "1")) {
                opt->c_cflag &= ~CSTOPB;                                                           /* 1位停止位t             */
            } else if (0 == strcmp (stopbit, "1.5")) {
                opt->c_cflag &= ~CSTOPB;                                                           /* 1.5位停止位            */
            }else if (0 == strcmp (stopbit, "2")) {
                opt->c_cflag |= CSTOPB;                                                            /* 2 位停止位             */
            }else {
                opt->c_cflag &= ~CSTOPB;                                                           /* 1 位停止位             */
            }
        }
    
    //set_data_bit函数
    //CSIZE--字符长度掩码。取值为 CS5, CS6, CS7, 或 CS8
        static void set_data_bit (struct termios *opt, unsigned int databit)
        {
            opt->c_cflag &= ~CSIZE;
            switch (databit) {
            case 8:
                opt->c_cflag |= CS8;
                break;
            case 7:
                opt->c_cflag |= CS7;
                break;
            case 6:
                opt->c_cflag |= CS6;
                break;
            case 5:
                opt->c_cflag |= CS5;
                break;
            default:
                opt->c_cflag |= CS8;
        break;
            }
        }
        
    //set_parity函数
    //在set_parity函数中,parity参数可以取值为:‘N’和‘n’(无奇偶校验)、‘E’和‘e’(表示偶校验)、‘O’和‘o’(表示奇校验)。
        static void set_parity (struct termios *opt, char parity)
        {
            switch (parity) {
            case 'N':                                                                                   /* 无校验          */
            case 'n':
                opt->c_cflag &= ~PARENB;
                break;
            case 'E':                                                                                   /* 偶校验          */
            case ‘e‘:
                opt->c_cflag |= PARENB;
                opt->c_cflag &= ~PARODD;
                break;
            case 'O':                                                                                   /* 奇校验           */
            case ‘o‘:
                opt->c_cflag |= PARENB;
                opt->c_cflag |= ~PARODD;
                break;
            default:                                                                                    /* 其它选择为无校验 */
                opt->c_cflag &= ~PARENB;
                break;
            }
        }

mcu svn:
https://123.57.81.221/svn/xida/trunk/mcu/stm32

linux串口编程(c)的更多相关文章

  1. storysnail的Linux串口编程笔记

    storysnail的Linux串口编程笔记 作者 He YiJun – storysnail<at>gmail.com 团队 ls 版权 转载请保留本声明! 本文档包含的原创代码根据Ge ...

  2. Linux串口编程详解(转)

    串口本身,标准和硬件 † 串口是计算机上的串行通讯的物理接口.计算机历史上,串口曾经被广泛用于连接计算机和终端设备和各种外部设备.虽然以太网接口和USB接口也是以一个串行流进行数据传送的,但是串口连接 ...

  3. linux串口编程总结

    串口本身.标准和硬件 † 串口是计算机上的串行通讯的物理接口.计算机历史上,串口以前被广泛用于连接计算机和终端设备和各种外部设备.尽管以太网接口和USB接口也是以一个串行流进行数据传送的.可是串口连接 ...

  4. linux串口编程参数配置详解(转)

    1.linux串口编程需要的头文件 #include <stdio.h>         //标准输入输出定义#include <stdlib.h>        //标准函数 ...

  5. linux串口编程参数配置详解

    1.linux串口编程需要的头文件 #include <stdio.h>         //标准输入输出定义 #include <stdlib.h>        //标准函 ...

  6. linux串口编程

    按照对linux系统的理解,串口编程的顺序无非就是open,read,write,close,而串口有波特率.数据位等重要参数需要设置,因此还应该用到设置函数,那么接下来就带着这几个问题去学习linu ...

  7. Linux串口编程进阶

    在<Linux串口编程>编程一文中介绍了串口应用中常用的基本操作,如:串口打开关闭.串口设置.数据收发等.本篇文章主要基于常规串口操作进行了扩充,主要介绍如下操作: Linux系统使用非标 ...

  8. Linux串口编程(转载)

    在嵌入式Linux中,串口是一个字设备,访问具体的串行端口的编程与读/写文件 的操作类似,只需打开相应的设备文件即可操作.串口编程特殊在于串 口通信时相关参数与属性的设置.嵌入式Linux的串口编程时 ...

  9. linux串口编程设置(转载)

    (转载)在嵌入式Linux中,串口是一个字设备,访问具体的串行端口的编程与读/写文件 的操作类似,只需打开相应的设备文件即可操作.串口编程特殊在于串 口通信时相关参数与属性的设置.嵌入式Linux的串 ...

  10. Linux 串口编程

    今天对应用层串口编程进行了验证.程序来源于以下参考链接,自己进行了一些注释和更改,记录于此. Tony Liu, 2016-6-17, Shenzhen 参考链接 https://www.ibm.co ...

随机推荐

  1. github--新手使用错误分析

    先上去github 或者任意托管的网站.注册账号,新建仓库, 在本地运行Xcode 新建工程,新建工程的时候 勾上本地 的仓库,然后 在本地的项目根目录执行下边的命令: git remote add ...

  2. one Infos

    Backend Server is still running (PID:). Please try 'euc-server stop' first. (原因很简单,进程控制脚本无restart函数功 ...

  3. 我的Hook学习笔记

    关于Hook 一.基本概念: 钩子(Hook),是Windows消息处理机制的一个平台,应用程序能够在上面设置子程以监视指定窗体的某种消息,并且所监视的窗体能够是其它进程所创建的.当消息到达后,在目标 ...

  4. Cocos2d-iPhone V3 (2) 场景转换

    Cocos2d-iPhone V3 (2) 场景转换 博客:http://blog.csdn.net/prevention 作者:大锐哥 - 1. 准备工作 创建一个场景会吧? #import &qu ...

  5. HTTP初步注解

    搜集了一下网上的资源和自己看过的一些书,小小总结了一波HTTP,现在也只是很肤浅的了解,期望以后深入理解后能写出更有营养的笔记. HTTP协议的主要特点 + 支持客户/服务器模式.+ 简单快速:客户向 ...

  6. 【转】Linq实现DataTable行列转换

    出处:http://www.cnblogs.com/li-peng/ 转换前的table: 转换后的table: 代码里有详细的说明, 还有一些参数我都截图了下面有 using System;usin ...

  7. BestCoder Round #47

    1001 Senior's Array 题目链接:1001 题意:给你一个长度为n的序列,你必须修改序列中的某个数为P,求修改后的最大连续子序列和. 思路:数据量比较小,可以直接暴力做, 枚举序列的每 ...

  8. preg_replace的用法

    <?php $str1 = "03/28/2015"; // 要替换成 2015-03-28 echo preg_replace("/([0-1][1-9])\/( ...

  9. javascript函数querySelector

    querySelector用于获得dom节点,可以接受三种类型的参数:id(#),class(.),标签.很像jquery的选择器.不过只能返回一个子孙元素,但是jquery选择器的话,可以返回一组元 ...

  10. codeforces 628F. Bear and Fair Set 网络流

    题目链接 F. Bear and Fair Set time limit per test 2 seconds memory limit per test 256 megabytes input st ...