在Linux系统中如何打开串口?C语言实现 (linux c 打开串口)

当前,Linux操作系统已经成为在开发嵌入式系统、服务器以及超级计算机等领域中更流行的操作系统之一。作为一款开源系统,Linux具有强大的开放性和可定制性,同时也支持许多不同的编程语言。因此,在Linux中使用串口通信成为许多开发人员竞相使用的手段之一。下文将介绍如何在Linux系统中打开串口,以及如何基于C语言实现串口程序。

1.打开串口

在Linux系统中,对于串口设备的操作一般采用文件操作的方法,因此需要使用文件操作相关的函数打开串口设备。下面是一个基本的串口打开程序的实现,其中串口编号为/dev/ttyS0:

“`c

#include

#include

#include

int fd;

void openPort(char *portDevice)

{

fd=open(portDevice,O_RDWR|O_NOCTTY|O_NDELAY);

if(fd==-1)

{

printf(“openPort(): error when opening the device %s\n”,portDevice);

}

else

{

fcntl(fd,F_SETFL,0/*FASYNC*/);

printf(“openPort(): successfully opened the device %s\n”,portDevice);

}

}

int mn()

{

openPort(“/dev/ttyS0”);

return 0;

}

“`

在此程序中,使用了open(打开串口设备)函数打开串口设备文件,传入设备路径作为之一个参数。第二个参数使用了标准的串口设置,即O_RDWR|O_NOCTTY|O_NDELAY,可确保对设备的打开同时可以读写,不承认是否为端口控制终端设备,以及不阻塞读写。当函数返回为-1时,即表示未能成功打开该设备,否则则打印串口打开成功。

2.配置串口

串口打开后,需要进行相关的设置以配置串口。通过在Linux系统中设置来设置和控制串口的标准和速率等参数,下面的函数将串口配置为9600波特率,不使用停止位,不设置奇偶校验,不使用等待、分割和其他特殊字符。

“`c

#define BAUDRATE B9600

#define MODEMDEVICE “/dev/ttyS0”

#define _POSIX_SOURCE 1 /* POSIX compliant source */

static int set_interface_attribs (int fd, int speed, int parity)

{

struct termios tty;

memset (&tty, 0, sizeof tty);

if (tcgetattr (fd, &tty) != 0)

{

printf(“set_interface_attribs(): error from tcgetattr\n”);

return -1;

}

cfsetospeed (&tty, speed);

cfsetispeed (&tty, speed);

tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8; // 8-bit characters

// disable IGNBRK for miatched speed tests; otherwise receive break

// as \000 chars

tty.c_iflag &= ~IGNBRK; // disable break processing

tty.c_lflag = 0; // no signaling chars, no echo,

// no canonical processing

tty.c_oflag = 0; // no remapping, no delays

tty.c_cc[VMIN] = 0; // read doesn’t block

tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout

tty.c_iflag &= ~(IXON | IXOFF | IXANY); // shut off xon/xoff ctrl

tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls,

// enable reading

tty.c_cflag &= ~(PARENB | PARODD); // shut off parity

tty.c_cflag |= parity;

tty.c_cflag &= ~CSTOPB;

tty.c_cflag &= ~CRTSCTS;

if (tcsetattr (fd, TCSANOW, &tty) != 0)

{

printf(“set_interface_attribs(): error from tcsetattr\n”);

return -1;

}

return 0;

}

static void set_blocking (int fd, int should_block)

{

struct termios tty;

memset (&tty, 0, sizeof tty);

if (tcgetattr (fd, &tty) != 0)

{

printf(“set_blocking(): error from tcgetattr\n”);

return;

}

tty.c_cc[VMIN] = should_block ? 1 : 0;

tty.c_cc[VTIME] = 5; // 0.5 seconds read timeout

if (tcsetattr (fd, TCSANOW, &tty) != 0)

{

printf(“set_blocking(): error setting term attributes\n”);

}

}

“`

在此函数中,使用tcsetattr函数设置套接口参数。其中,函数的之一个参数为串口设备文件的文件描述符,以及需要设置的波特率、奇偶校验等参数。在本例中,将波特率设置为9600,停止位数为0,奇偶校验不配置。另外,方法中通过CLOCAL和CREAD标志控制本端口是否为本地串口,以及是否允许读操作。同时,将VMIN属性设置为0表示直接读取控制台中的内容,而不必等待它的输入,以达到同步操作的效果。

3.发送接收数据

在打开并设置好串口之后,需要使用C语言实现数据的读写操作。一般使用read(读取数据)和write(写入数据)函数来实现此目的。

“`c

static void send(int fd,char* text)

{

int len = strlen(text);

write(fd,text,len);

}

static void receive(int fd)

{

char buf[10];

read(fd,buf,sizeof(buf));

}

“`

在本例中,使用write函数将一个简短的文本字符串发送到串口,然后使用read函数接收数据并存储到缓冲区中,其中调用了initPort()函数。同时,读数据时可以设置超时时间以避免阻塞程序。

除此之外,还可以使用poll函数实现基于Linux系统的串口通信程序。poll函数可以同时监听多个文件描述符上的事件,或者等待指定时间。由于C库提供的函数比较原始,因此使用poll函数能够更好的控制程序的时间操作和性能。

“`c

struct pollfd fds[1];

fds[0].fd = fd;

fds[0].events = POLLIN;

while (1)

{

int ret = poll(fds, 1, 1000); // wt for up to 1000ms

if (ret

{

printf(“poll(): error during poll()\n”);

exit(-1);

}

else if (ret == 0)

{

printf(“poll(): timeout occurred, no data received\n”);

}

else

{

if (fds[0].revents & POLLIN)

{

char buf[256];

int n = read(fd, buf, sizeof buf);

if (n

{

printf(“read(): error reading input string”);

}

printf(“%.*s”,n,buf);

}

}

}

“`


数据运维技术 » 在Linux系统中如何打开串口?C语言实现 (linux c 打开串口)