串口使用详解

在配置完串口的相关属性后,就可以对串口进行打开、读写操作了。它所使用的函数和普通文件读写的函数一样,都是open、write和read,由于串口是一个终端设备,因此在函数的具体参数的选择时会有一些区别,另外,这里会用到一些附加的函数,用于测试终端设备的连接情况等,下面对其进行具体讲解。

1、打开串口

打开串口和打开普通文件一样,使用的函数同打开普通文件是一样的,都是open函数,如下所示:

fd = open("/dev/ttyS0",O_RDWR|O_NOCTTY|O_NDELAY);

可以看到,这里除了普通的读写参数外,还有两个参数O_NOCTTY和O_NDELAY.

O_NOCTTY标志用于通知Linux系统这个程序不会成为对应这个端口的控制终端。如果没有指定这个标志,那么任何一个输入(诸如键盘终止信号等)都将影响用户的进程。

O_NDELAY标志通知Linux系统这个程序不关心DCD信号线所处的状态(端口的另一端是否激活或者停止)。如果用户指定了这个标志,则进程将会一直处于睡眠态,直到DCD信号线被激活。

接下来可恢复串口的状态为阻塞状态,用于等待串口数据的读入,可用fcntl函数实现,如下所示:

fcntl(fd,F_SETFL,0);

再接下来可以测试打开文件描述符是否引用一个终端设备,以进一步确认串口是否正确打开,如下所示:

isatty(STDIN_FILEN0);

该函数调用成功则返回0,若失败则返回-1.

这时,一个串口就已经成功打开了。接下来就可以对这个串口进行读、写操作。

下面给出了一个完整的打开串口的函数,同样写考虑到了各种不同的情况,程序如下所示:

/*打开串口函数*/

int open_port(int fd,int comport){

        char *dev[]={"/dev/ttyS0","/dev/ttyS1","/dev/ttyS2"};

        long vdisable;

        if(comport==1){

                 fd = open("dev/ttyS0",O_RDWR|O_NOCTTY)|O_NDELAY);

                 if(-1 == fd){

                           perror("Can't Open Serial Port");

                           return (-1);

                }

         }

         else if(comport==2){

                 fd = open("dev/ttyS1",O_RDWR|O_NOCTTY)|O_NDELAY);

                 if(-1 == fd){

                           perror("Can't Open Serial Port");

                           return (-1);

                }

         }

         if(comport==3){

                 fd = open("dev/ttyS3",O_RDWR|O_NOCTTY)|O_NDELAY);

                 if(-1 == fd){

                           perror("Can't Open Serial Port");

                           return (-1);

                }

         }

        

       /*恢复串口为阻塞状态*/

         if(fcntl(fd,F_SETFL,0)<0)

                 printf("fcntl failed!/n");

         else printf("fcntl=%d/n",fcntl(fd,F_SETFL,0));

      /*测试是否为终端设备*/

         if(isatty(STDIN_FILENO) == 0)

                printf("standard input is not a terminal device/n");

         else printf("isatty success!/n");

         printf("fd-open=%d/n",fd);

         return fd;

}

 

2、读写串口

读写串口的操作和读写普通文件一样,使用read、write函数即可,如下所示:

write(fd,buff,8);

read(fd,buff,8);

下面两个实例给出了串口读和写的两个程序的main函数部分,这里用到的函数有前面讲述到的open_port和set_opt函数。

/*写串口程序*/

#include

#include

#include

#include

#include

#include

#include

#include

#include

/*读串口程序*/

int main(){

        int fd;

        int nread,i;

        char buff[]="Hello/n";

 

        if((fd=open_port(fd,1))<0){

                perror("open_port error");

                return;

         }

         if((i=set_opt(fd,115200,8,'N',1))<0){

                perror("set_opt error");

                return;

         }

         printf("fd=%d/n",fd);

         nread=read(fd,buff,8);

         printf("nread=%d","%s/n",nread,buff);

         close(fd);

         return;

}

这里的读串口程序使用select函数实现多路复用式串口读写。读者在这里可以进一步了解select函数的使用方法。

/*读串口*/

#include

#include

#include

#include

#include

#include

#include

#include

#include

 

int main(){

       int fd;

       int nread,nwrite,i;

       char buff[8];

       fd_set rd;

       /*打开串口*/

       if((fd=open_port(fd,1))<0){

                perror("open_port error");

                return;

       }

      /*设置串口*/

       if((i=set_opt(fd,115200,8,'N',1))<0){

                perror("set_opt error");

                return;

       }

       /*利用select函数来实现多个串口的读写*/

       FD_ZERO(&rd);

       FD_SET(fd,&rd);

       while(FD_ISSET(fd,&rd)){

        if(select(fd+1,&rd,NULL,NULL,NULL)<0)

               perror("select");

        else{

               while((nread = read(fd,buff,8))>0){

                        printf("nread=%d,%s/n",nread,buff);

                }

        }

        close(fd);

        return;

}}

读者可以将该程序在宿主机上运行,然后用串口线将目标板和宿主机连接起来,之后将目标板上电,就可以看到宿主机上有目标板的串口输出。

[root@(none) 1]# ./write

fcntl=0

isatty success!

fd-open=3

set done

fd=3

你可能感兴趣的:(串口使用详解)