linux串口编程(c)

//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>

#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);
        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;
            }
        }

时间: 2024-10-18 07:02:31

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

linux串口编程参数配置详解

1.linux串口编程需要的头文件 #include <stdio.h>         //标准输入输出定义 #include <stdlib.h>        //标准函数库定义 #include <unistd.h>       //Unix标准函数定义 #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>          //文件控制定义 #incl

基于树莓派的Linux串口编程_实现自发自收

串口是计算机上一种非常通用设备通信的协议,常用PC机上包含的是RS232规格的串口,具有连接线少,通讯简单,得到广泛的使用. Linux对所有设备的访问是通过设备文件来进行的,串口也是这样,为了访问串口,只需打开其设备文件即可操作串口设备.在linux系统下面,每一个串口设备都有设备文件与其关联,设备文件位于系统的/dev目录下面.如linux下的/ttyS0,/ttyS1分别表示的是串口1和串口2. 树莓派UART端口的位置:见下图的GPIO14(TXD).GPIO 15(RXD) 本文是基于

Linux串口编程详解

串口本身,标准和硬件 ? 串口是计算机上的串行通讯的物理接口.计算机历史上,串口曾经被广泛用于连接计算机和终端设备和各种外部设备.虽然以太网接口和USB接口也是以一个串行流进行数据传送的,但是串口连接通常特指那些与RS-232标准兼容的硬件或者调制解调器的接口.虽然现在在很多个人计算机上,原来用以连接外部设备的串口已经广泛的被USB和Firewire替代:而原来用以连接网络的串口则被以太网替代,还有用以连接终端的串口设备则已经被MDA或者VGA取而代之.但是,一方面因为串口本身造价便宜技术成熟,

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

1.linux串口编程需要的头文件 #include <stdio.h>         //标准输入输出定义#include <stdlib.h>        //标准函数库定义#include <unistd.h>       //Unix标准函数定义#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>          //文件控制定义#include &l

storysnail的Linux串口编程笔记

storysnail的Linux串口编程笔记 作者 He YiJun – storysnail<at>gmail.com 团队 ls 版权 转载请保留本声明! 本文档包含的原创代码根据General Public License,v3 发布 GPLv3 许可证的副本可以在这里获得:http://www.gnu.org/licenses/gpl.html 本文档根据GNU Free Documentation License 1.3发布 GFDL1.3许可证的副本可以在这里获得:http://w

linux串口编程总结

串口本身,标准和硬件 ? 串口是计算机上的串行通讯的物理接口.计算机历史上,串口曾经被广泛用于连接计算机和终端设备和各种外部设备.虽然以太网接口和USB接口也是以一个串行流进行数据传送的,但是串口连接通常特指那些与RS-232标准兼容的硬件或者调制解调器的接口.虽然现在在很多个人计算机上,原来用以连接外部设备的串口已经广泛的被USB和Firewire替代:而原来用以连接网络的串口则被以太网替代,还有用以连接终端的串口设备则已经被MDA或者VGA取而代之.但是,一方面因为串口本身造价便宜技术成熟,

linux串口编程 select

1.串口的阻塞和非阻塞 阻塞的定义: 对于read,block指当串口输入缓冲区没有数据的时候,read函数将会阻塞在这里,一直到串口输入缓冲区中有数据可读取,read读到了需要的字节数之后,返回值为读到的字节数,然后整个程序才继续运行下去:(收) 对于write,block指当串口输出缓冲区满,或剩下的空间小于将要写入的字节数,则write将阻塞,一直到串口输出缓冲区中剩下的空间大于等于将要写入的字节数,执行写入操作,返回写入的字节数,然后整个程序才继续运行下去.(发) 非阻塞的定义: 对于r

嵌入式linux串口编程(二)

/*com_writer.c*/#include "uart_api.h" int main(void){ int fd; char buff[BUFFER_SIZE]; if((fd=open_port(HOST_COM_PORT))<0)  /*打开串口*/ {  perror("open serial error");  return 1; } if(set_com_config(fd,115200,8,'N',1)<0) /*配置串口*/ {  

linux 串口编程记录(一)串口参数设置

    一些常用串口属性的设置方法. 设置流控制 termios_new.c_cflag &= ~CRTSCTS; //不使用流控制 termios_new.c_cflag |= CRTSCTS; //使用硬件流控制 termios_new.c_iflag |= IXON|IXOFF|IXANY; //使用软件流控制 屏蔽字符大小位 termios_new.c_cflag &= ~CSIZE; 设置数据位大小 termios_new.c_cflag |= CS8; //使用8位数据位 te