这里贴上代码可以取名为ttyusb0.c:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <string.h>
#include <sys/select.h>
#include <errno.h>
#define SERTAL_PORT "/dev/ttyUSB0"
#define SERIAL_BAUDRATE B115200 //串口波特率
#define READ_BUF_SIZE 256 //讀取緩衝區大小
int serial_init(const char *port, speed_t baudrate){
// 打开串口设备
int fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1) {
perror("无法打开串口设备");
return -1;
}
struct termios tty;
memset(&tty, 0, sizeof(tty));
if(tcgetattr(fd, &tty) != 0){ //獲取串口屬性
perror("tcgetattr");
close(fd);
return -1;
}
cfsetispeed(&tty, baudrate); // 设置輸入波特率
cfsetospeed(&tty, baudrate);// 设置輸出波特率为
tty.c_cflag |= (CLOCAL | CREAD); // 忽略调制解调器线路状态,允许接收数据
tty.c_cflag &= ~CRTSCTS; //禁用硬件流控
tty.c_cflag &= ~PARENB; // 禁用奇偶校验
tty.c_cflag &= ~CSTOPB; // 设置停止位为1位
tty.c_cflag &= ~CSIZE; // 清除数据位设置
tty.c_cflag |= CS8; // 设置数据位为8位
tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); //設置輸入模式
tty.c_iflag &= ~(IXON | IXOFF | IXANY); // 禁用軟件流控
tty.c_oflag &= ~OPOST; // 設置輸出模式
tty.c_cc[VMIN] = 1; //最小接收字符
tty.c_cc[VTIME] = 0; //無超時
if(tcsetattr(fd, TCSANOW, &tty) != 0){ //設置串口屬性
perror("tcsetattr");
close(fd);
return -1;
}
tcflush(fd, TCIFLUSH); //刷新緩衝區
return fd;
}
int port_write(int port_fd, unsigned char *data, int length){
//fcntl(port_fd, F_SETFL, O_NONBLOCK);//設置寫爲非阻塞
int written = write(port_fd, data, length);//寫入數據到串口
if(written == -1){
perror("write");
return -1;
}
return written;
}
int port_read(int port_fd, unsigned char * buffer, int length){
//fcntl(port_fd, F_SETFL, O_NONBLOCK);//設置寫爲非阻塞
int bytes_read = read(port_fd, buffer, length);//從串口讀取數據
if(bytes_read == -1){
perror("read");
return -1;
}
return bytes_read;
}
int main(){
int fd = serial_init(SERTAL_PORT, SERIAL_BAUDRATE); //初始化串口
if(fd == -1){
fprintf(stderr, "Failed to initialize serial port.\n");
return 1;
}
fd_set readfds;
unsigned char buffer[READ_BUF_SIZE];
struct timeval timeout;
int ret;
int bytes_read;
while(1){
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
FD_SET(STDIN_FILENO, &readfds);
//設置超時時間
timeout.tv_sec = 1;//
timeout.tv_usec = 0; //
ret = select(fd+1, &readfds, NULL, NULL, &timeout); //使用select函數等待串口數據
if(ret == -1){
perror("select");
break;
}else if(ret > 0){
if(FD_ISSET(fd, &readfds)){
memset(buffer, 0, sizeof(buffer));
bytes_read = port_read(fd, buffer, sizeof(buffer));
if(bytes_read == -1){
fprintf(stderr, "Failed to read form serial port.\n");
break;
}else{
printf("%d\n", bytes_read);
buffer[bytes_read] = '\0'; //添加字符串結束符
printf("Received: %s\n", buffer);//打印字符串
}
}else if(FD_ISSET(STDIN_FILENO, &readfds)){
memset(buffer, 0, sizeof(buffer));
bytes_read = read(STDIN_FILENO, buffer, sizeof(buffer));
//printf("%d\n", n);
if (bytes_read > 0) {
// 将数据发送到串口设备
buffer[bytes_read] = '\0'; //添加字符串結束符
port_write(fd, buffer, bytes_read);
}
}
}
}
close(fd);
return 0;
}
之后终端通过gcc进行编译:
gcc -o ttyusb0 ttyusb0.c
然后运行:
./ttyusb0
我们使用select
系统调用来同时监视串口文件描述符和标准输入(stdin)。当用户在终端输入数据并按下回车键时,程序会从标准输入读取数据,并通过串口发送出去。同时,如果串口上有数据到达,程序也会读取这些数据并打印到终端。
请注意,您需要根据您的具体需求调整串口设备文件和串口参数。在运行此代码之前,请确保您有权限访问串口设备,或者使用sudo
运行程序。此外,确保串口设备没有被其他进程占用。