linux下通过代码的方式在终端模拟串口信息的接收与发送

这里贴上代码可以取名为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运行程序。此外,确保串口设备没有被其他进程占用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值