zoukankan      html  css  js  c++  java
  • Linux串口编程


    参考网上各种资料啊!

    1.串口简介

    1.1基础知识

    电脑与单片机串口通信是一种异步串行通信方式,将传输数据的每个字符一位接一位地传送。数据的各不同位可以分时使用同一传输通道,因此串行I/O可以减少信号连线,最少用一对线即可进行。
    串口时序图
    开始前,线路处于空闲状态,送出连续“1”。传送开始时首先发一个“0”作为起始位,然后出现在通信线上的是字符的二进制编码数据。每个字符的数据位长可以约定为5 位、6 位、7 位或8 位,一般采用ASCII 编码。后面是奇偶校验位,根据约定,用奇偶校验位将所传字符中为“1”的位数凑成奇数个或偶数个也可以约定不要奇偶校验,这样就取消奇偶校验位。最后是表示停止位的“1”信号,这个停止位可以约定持续1 位、1.5 位或2 位的时间宽度。至此一个字符传送完毕,线路又进入空闲,持续为“1”(高电平)。

    1.2引脚定义

    参考:

    http://book.51cto.com/art/201308/408900.htm

    2.串口操作

    UART的操作主要包括以下几个部分:

    • 数据发送;
    • 数据接收;
    • 产生中断;
    • 产生波特率;
    • Loopback模式;
    • 红外模式;
    • 自动流控模式。

    串口参数的配置主要包括:波特率、数据位、停止位、流控协议。

    串口操作需要的头文件:

    #include <stdio.h> ``标准输入输出定义*/ 
    #include <stdlib.h> /*标准函数库定义*/ 
    #include <unistd.h> /*Unix 标准函数定义*/ 
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h> /*文件控制定义*/
    #include <termios.h> /*PPSIX 终端控制定义*/
    #include <errno.h> /*错误号定义*/ 
    

    2.1打开串口

    在 Linux 下串口文件是位于/dev下的。

    • 串口0为:/dev/ttyS0
    • 串口1为:/dev/ttyS1
    • 串口2为:/dev/ttyS2

    打开串口是通过使用标准的文件打开函数操作:

    int fd; 
    /*以读写方式打开串口*/ 
    fd = open( "/dev/ttyS0", O_RDWR); 
    if (-1 == fd){
     /* 不能打开串口一*/ 
    perror(" 提示错误!");
     } 
    

    2.2设置串口

    2.2.1重要成员

    串口的设置主要通过设置struct termios 结构体的各成员值,来设置波特率,效验位和停止位等。在设置波特率时需在数字前加上‘B’,如B9600。B19200。使用其需通过“与”“或”操作方式。

    struct termio
    { 
    	unsigned short c_iflag; /* 输入模式标志 */
    	unsigned short c_oflag;/* 输出模式标志 */
    	unsigned short c_cflag;/* 控制模式标志*/
    	unsigned short c_lflag; /* local mode flags */
    	unsigned char c_line;/* line discipline */
    	unsigned char c_cc[NCC]; /* control characters */
    };
    

    其中,c_cflag成员

    输入模式c_iflag成员

    2.2.2重要控制函数

    Tcgetattr   取属性(termios结构)
    Tcsetattr   设置属性(termios结构)
    cfgetispeed 得到输入速度
    Cfgetospeed 得到输出速度
    Cfsetispeed 设置输入速度
    Cfsetospeed 设置输出速度
    Tcdrain     等待所有输出都被传输
    tcflow      挂起传输或接收
    tcflush     刷清未决输入和/或输出 
    Tcsendbreak 送BREAK字符
    tcgetpgrp   得到前台进程组ID
    tcsetpgrp   设置前台进程组ID
    

    3.设置串口的流程

    • 保存原先串口配置使用tcgetattr(fd,&oldtio)函数

        struct termios newtio,oldtio; 
        tcgetattr( fd,&oldtio );
      
    • 激活选项有CLOCAL和CREAD,用于本地连接和接收使能。

        newtio.c_cflag | = CLOCAL | CREAD; 
      
    • 设置波特率,使用函数cfsetispeed、 cfsetospeed

        cfsetispeed(&newtio, B115200);
        cfsetospeed(&newtio, B115200);
      
    • 设置数据位,需使用掩码设置。

        newtio.c_cflag &= ~CSIZE;
        newtio.c_cflag |= CS8; 
      
    • 设置奇偶校验位,使用c_cflag和c_iflag。

      设置奇校验:

      newtio.c_cflag |= PARENB;
      newtio.c_cflag |= PARODD;
      newtio.c_iflag |= (INPCK | ISTRIP);

      设置偶校验:

      newtio.c_iflag |= (INPCK | ISTRIP);
      newtio.c_cflag |= PARENB;
      newtio.c_cflag &= ~PARODD;

    • 设置停止位,通过激活c_cflag中的CSTOPB实现。若停 止位为1,则清除CSTOPB,若停止位为2,则激活CSTOPB。

        newtio.c_cflag &= ~CSTOPB;
      
    • 设置最少字符和等待时间,对于接收字符和等待时间 没有特别要求时,可设为0。

        newtio.c_cc[VTIME] = 0; 
        newtio.c_cc[VMIN] = 0;
      
    • 处理要写入的引用对象
      tcflush函数刷清(抛弃)输入缓存(终端驱动程序已接 收到,但用户程序尚未读)或输出缓存(用户程序已经写,但尚未发送)。

        int tcflush(int filedes, int queue)
        queue数应当是下列三个常数之一: 
        TCIFLUSH 刷清输入队列。
        TCOFLUSH 刷清输出队列。
        TCIOFLUSH 刷清输入、输出队列。
      
    • 激活配置。在完成配置后,需激活配置使其生效。使用tsettattr()函数。

    tsettattr()函数原型:

    int tcgetattr(int filedes, struct termios *termptr);
    int tcsetattr(int filedes, int opt, const struct termios * termptr); 
    tcsetattr的参数opt使我们可以指定在什么时候新的终端属性才起作用。opt可以指定为下列常数中的一个:
    TCSANOW 更改立即发生。
    TCSADRAIN 发送了所有输出后更改才发生。若更改输出参数则应使用此选择项。
    TCSAFLUSH 发送了所有输出后更改才发生。更进一步,在更改发生时未读的所有输入数据都被删除(刷清) 
    使用如:tcsetattr(fd,TCSANOW,&newtio)
    

    4.代码范例

    4.1初始化串口

    void init_tty(int fd) 
    {
    	 struct termios newtio;
    	 struct termios oldtio; 
    	 bzero(&newtio,sizeof(struct termios));
    	 tcgetattr(fd,&oldtio);
    	 newtio.c_cflag |= CLOCAL | CREAD;
    	 cfsetispeed(&newtio,B115200);    //设置输入速度 
    	 cfsetospeed(&newtio,B115200);    //设置输出速度 
    	 //设置数据位为8位
    	 newtio.c_cflag &= ~CSIZE;       //对应比特位清零 
    	 newtio.c_cflag |= CS8;          //对应比特位置位
    	 //设置无校验 
    	 newtio.c_cflag &= ~PARENB; 
    	 newtio.c_iflag &= ~INPCK;
    	 //设置1位停止位 
    	 newtio.c_cflag &= ~CSTOPB; 
    	 //设置最少字符与时间 
    	 newtio.c_cc[VTIME] = 0; 
    	 newtio.c_cc[VMIN] = 0; 
    	 //刷清串口缓存 
    	 tcflush(fd,TCIOFLUSH); 
    	 //设置新的属性到串口文件 
    	 tcsetattr(fd,TCSANOW,&newtio);
     }
    

    注意:
    如果不是开发终端之类的,只是串口传输数据,而不 需要串口来处理,那么使用原始模式(Raw Mode)方式 来通讯,设置方式如下:

    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/
    options.c_oflag &= ~OPOST; /*Output*/
    

    4.2读写串口

    读写串口时,把把串口当作文件进行读写。

    //写
    char buffer[1024];
    int Length;
    int nByte;
    nByte = write(fd, buffer ,Length) 
    //读
    char buff[1024];
    int Len;
    int readByte = read(fd,buff,Len);
    

    4.3关闭串口

    close(fd);
    

    4.4例程

    #define FALSE -1 
    #define TRUE 0
    int OpenDev(char *Dev)
    {
    	int fd = open( Dev, O_RDWR ); //| O_NOCTTY | O_NDELAY if (-1 == fd) {
    	perror("Can't Open Serial Port"); 
    	return -1;
    	} else 
    	return fd;
    }
    
    int main(int argc, char **argv){
    	int fd; int nread; char buff[512];
    	char *dev = "/dev/ttyS1"; //串口1 
    	fd = OpenDev(dev);
    	init_tty(fd);
    	//循环读取数据
    	while (1) {
    	while((nread = read(fd, buff, 512))>0){ 
    			printf("
    Len %d
    ",nread); buff[nread+1]= '';
    			printf( "
    %s", buff);
    		}
    	}
    //close(fd);
    }
    

    参考资料:

    http://www.cnblogs.com/chengmin/p/3818133.html
    http://blog.csdn.net/zhoutaopower/article/details/35785023
    http://blog.csdn.net/zhoutaopower/article/details/42400965
    http://blog.csdn.net/hwmt2012/article/details/17148331


  • 相关阅读:
    What is "Type" in managed heap?
    SQL Server 2005:一个使用新创建的User的问题和解决方法
    如何证明Application Domain的隔离性
    我的WCF之旅(10):如何在WCF进行Exception Handling
    SQLXML初体验:用XML代替TSQL来操作数据库
    我的WCF之旅(3):在WCF中实现双工通信
    我的WCF之旅(4):WCF中的序列化[下篇]
    再说String
    谈谈基于Kerberos的Windows Network Authentication[上篇]
    我所理解的Remoting(1):Marshaling & Activation[上篇]
  • 原文地址:https://www.cnblogs.com/boyiliushui/p/6675825.html
Copyright © 2011-2022 走看看