如何使用C语言配置串口
在C语言中配置串口进行通信的核心要点包括打开串口、设置串口属性、读写数据、关闭串口。其中,设置串口属性尤为重要,因为它直接影响串口通信的正确性。接下来,我们将详细描述如何在C语言中完成这些步骤。
一、打开串口
在Linux系统中,串口设备通常表示为/dev/ttyS0
、/dev/ttyS1
等。使用open()
函数来打开串口设备,并获得一个文件描述符。
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int open_serial_port(const char *device) {
int fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1) {
perror("open_serial_port: Unable to open serial port");
} else {
fcntl(fd, F_SETFL, 0); // 设置串口为阻塞模式
}
return fd;
}
二、设置串口属性
设置串口属性主要包括波特率、数据位、停止位和校验位。我们使用termios
结构和相关的函数来设置这些属性。
#include <termios.h>
#include <stdio.h>
int configure_serial_port(int fd, int baud_rate) {
struct termios options;
// 获取当前串口配置
if (tcgetattr(fd, &options) < 0) {
perror("configure_serial_port: Unable to get serial port attributes");
return -1;
}
// 设置波特率
speed_t speed;
switch (baud_rate) {
case 9600: speed = B9600; break;
case 19200: speed = B19200; break;
case 38400: speed = B38400; break;
case 115200: speed = B115200; break;
default:
fprintf(stderr, "Unsupported baud raten");
return -1;
}
cfsetispeed(&options, speed);
cfsetospeed(&options, speed);
// 设置数据位、停止位和校验位
options.c_cflag &= ~CSIZE; // 清除数据位的设置
options.c_cflag |= CS8; // 设置数据位为8位
options.c_cflag &= ~CSTOPB; // 设置停止位为1
options.c_cflag &= ~PARENB; // 禁用校验
// 配置为原始模式
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // 禁用标准输入输出
options.c_iflag &= ~(IXON | IXOFF | IXANY); // 禁用软件流控制
options.c_oflag &= ~OPOST; // 禁用输出处理
// 刷新输入输出缓冲区,并应用配置
tcflush(fd, TCIFLUSH);
if (tcsetattr(fd, TCSANOW, &options) < 0) {
perror("configure_serial_port: Unable to set serial port attributes");
return -1;
}
return 0;
}
三、读写数据
使用read()
和write()
函数进行串口数据的读写操作。
#include <unistd.h>
ssize_t read_from_serial_port(int fd, void *buffer, size_t size) {
return read(fd, buffer, size);
}
ssize_t write_to_serial_port(int fd, const void *buffer, size_t size) {
return write(fd, buffer, size);
}
四、关闭串口
使用close()
函数关闭串口设备。
void close_serial_port(int fd) {
close(fd);
}
五、完整示例
以下是一个完整的示例程序,它展示了如何使用C语言配置和使用串口进行通信。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
// 函数声明
int open_serial_port(const char *device);
int configure_serial_port(int fd, int baud_rate);
ssize_t read_from_serial_port(int fd, void *buffer, size_t size);
ssize_t write_to_serial_port(int fd, const void *buffer, size_t size);
void close_serial_port(int fd);
int main() {
const char *device = "/dev/ttyS0";
int baud_rate = 9600;
char buffer[256];
// 打开串口
int fd = open_serial_port(device);
if (fd == -1) {
return 1;
}
// 配置串口
if (configure_serial_port(fd, baud_rate) == -1) {
close_serial_port(fd);
return 1;
}
// 写入数据
const char *data = "Hello, Serial Port!";
if (write_to_serial_port(fd, data, strlen(data)) == -1) {
perror("main: Unable to write to serial port");
close_serial_port(fd);
return 1;
}
// 读取数据
ssize_t bytes_read = read_from_serial_port(fd, buffer, sizeof(buffer) - 1);
if (bytes_read == -1) {
perror("main: Unable to read from serial port");
close_serial_port(fd);
return 1;
}
// 打印读取的数据
buffer[bytes_read] = '