Linux下C语言串口应用编程

在编写Linux串口的C程序之前,需要包含以下头文件:

#include <termios.h>

Linux系统中,一切皆文件,所以串口设备也是一类文件,学习过Linux驱动程序的学员都知道,Linux有三类设备:字符设备,块设备,网络设备。那么串口设备属于字符设备。所以串口设备的命名一般为/dev/ttySn(n = 012......),如果该串口为USB转串口,可能名称为/dev/ttyUSBn(n = 012......),不同的平台下串口的名称是不同的,且串口的名称也是可以更改的。如何更改?在板卡对应的Linux驱动中更改。

Linux下操作串口,那么也就是跟操作一个文件一样,既然是文件,也就可以使用标准的文件操作API来操作。

1、打开串口


2、关闭串口


fd为文件描述符。

如果不设置串口的波特率,数据位,停止位,校验位的情况下,Linux下默认设置的属性值为:

波特率:9600

数据位:8

校验位:n(表示无)

停止位:1

在不设置串口属性值的情况下,也可以读写串口值。

3、读写串口

使用readwrite函数即可,例如:

 

以上例程展现的是往串口写入一个数据,串口就会回复一个数据,也就是自发自收。

完整例程:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <asm/termios.h>

#define DEV_NAME  "/dev/ttyS1"


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


	len = write(fd, buf, sizeof(buf));
	if (len < 0) {
		printf("write data error \n");
	}
	
	len = read(fd, buf, sizeof(buf));
        if (len < 0) {
                printf("read error \n");
                return -1;
        }

	printf("%s", buf);

	return(0);
}

  上面给出的例程是串口驱动的默认属性值(9600,8n1,无流控),在实际产品开发过程中,还是会根据不同的应用场景来设置串口的属性。操作串口属性需要设置对应的标志,在POSIX终端已经帮我们实现了若干结构体以及相应的标志位,我们只要熟练使用它即可,非常简单。

  最重要的struct termios结构体:



1、设置串口波特率


.

例程:

static void set_baudrate (struct termios *opt, unsigned int baudrate)
{
	cfsetispeed(opt, baudrate);
	cfsetospeed(opt, baudrate);
}

2、设置数据位

  数据位指的是每字节中实际数据所占的比特数。要修改数据位可以通过修改termios结构体中c_cflag成员来实现。CS5CS6CS7CS8分别表示数据位为5678。值得注意的是,在设置数据位时,必须先使用CSIZE做位屏蔽。

例程:

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

3、设置校验位

  奇偶校验可以选择偶校验、奇校验、空格等方式,也可以不使用校验。如果要设置为偶校验的话,首先要将termios结构体中c_cflag设置PARENB标志,并清除PARODD标志。如果要设置奇校验,要同时设置termios结构体中c_cflag设置PARENB标志和PARODD标志。如果不想使用任何校验的话,清除termios结构体中c_cflag的PARENB位。表6.12所示为设置奇偶校验的具体方法。


例程:

static void set_parity (struct termios *opt, char parity)
{
    switch (parity) {
    case 'N':                  /* no parity check */
        opt->c_cflag &= ~PARENB;
        break;
    case 'E':                  /* even */
        opt->c_cflag |= PARENB;
        opt->c_cflag &= ~PARODD;
        break;
    case 'O':                  /* odd */
        opt->c_cflag |= PARENB;
        opt->c_cflag |= ~PARODD;
        break;
    default:                   /* no parity check */
        opt->c_cflag &= ~PARENB;
        break;
    }
}

4、设置停止位

 设置串口停止位是在 termios 对象的 c_cflag 成员上设置,需要用到的选项标志为

CSTOPB(2 位停止位,否则为 1 位)。

例程:

static void set_stopbit (struct termios *opt, const char *stopbit)
{
    if (0 == strcmp (stopbit, "1")) {
        opt->c_cflag &= ~CSTOPB; /* 1 stop bit */
    }	else if (0 == strcmp (stopbit, "1")) {
        opt->c_cflag &= ~CSTOPB; /* 1.5 stop bit */
    }   else if (0 == strcmp (stopbit, "2")) {
        opt->c_cflag |= CSTOPB;  /* 2 stop bits */
    } else {
        opt->c_cflag &= ~CSTOPB; /* 1 stop bit */
    }
}

于是我们就可以将串口这三样基本的设置写成一个函数,以后用的时候就调用它即可。


//串口设置
int  Serial_Handle::set_port_attr (
              int fd,
              int  baudrate,          // B1200 B2400 B4800 B9600 .. B115200
              int  databit,           // 5, 6, 7, 8
              const char *stopbit,    //  "1", "1.5", "2"
              char parity,            // N(o), O(dd), E(ven)
              int vtime,
              int vmin )
{
     struct termios opt;
     tcgetattr(fd, &opt);
     //设置波特率
     set_baudrate(&opt, baudrate);
     opt.c_cflag 		 |= CLOCAL | CREAD;      /* | CRTSCTS */
     //设置数据位
     set_data_bit(&opt, databit);
     //设置校验位
     set_parity(&opt, parity);
     //设置停止位
     set_stopbit(&opt, stopbit);
     //其它设置
     opt.c_oflag 		 = 0;
     opt.c_lflag            	|= 0;
     opt.c_oflag          	&= ~OPOST;
     opt.c_cc[VTIME]     	 = vtime;
     opt.c_cc[VMIN]         	 = vmin;
     tcflush (fd, TCIFLUSH);
     return (tcsetattr (fd, TCSANOW, &opt));
}

以后在使用串口的时候即是要遵循以下的顺序才能使用。

1、打开串口设备

2、设置串口的波特率,数据位,校验位,停止位以及其它设置

3、写数据

4、读出数据

5、关闭串口


参考文献:

1、http://book.51cto.com/art/200711/59758.htm

2、周立功=====>【开发指南】M6G2C&A6G2C系列核心板软件开发指南_V1.05







猜你喜欢

转载自blog.csdn.net/morixinguan/article/details/80898172