linux中设置串口的系统调用tcgetattr,tcsetattr,tcflush的使用总结

36 篇文章 0 订阅
31 篇文章 0 订阅

头文件:
#include <termios.h>
函数原型:
int tcsetattr(int fd, int optional_actions, const struct termios *termios_p);//设置串口属性

int tcgetattr(int fd, struct termios *termios_p);//获得串口属性

int tcflush(int fd, int queue_selector);//刷新串口的缓冲区

speed_t cfgetispeed(struct termios *termios_p);//获得输入速度

speed_t cfgetospeed(struct termios *termios_p);//获得输出速度

int cfsetispeed(struct termios *termios_p, speed_t speed);

int cfsetospeed(struct termios *temios_p, speed_t speed);

参数:

int fd:是打开的串口终端的文件描述符。如:/dev/ttyS0

 

struct termios *termios_p:存放参数的结构体的指针。

具体参见:https://baike.baidu.com/item/Termios/1467529?fr=aladdin

 

int optional_actions:用于控制修改起作用的时间,可以使用如下的取值:

TCSANOW:不等数据传输完毕立即改变属性。

TCSADRAIN:等所有的数据传输完毕才改变属性。

TCSAFLUSH:等所有的数据传输完毕,并且清空输入输出的缓冲区才改变属性。

 

int queue_selector:代表刷新的具体的缓冲区,可以有如下的取值:

TCIFLUSH:刷新输入缓冲区。

TCOFLUSH:刷新输出缓冲区。

TCIOFLUSH:刷新输入输出缓冲区。


如下为,实例;

int Uart0_Init(void)
{
	const char *path_utf = "/dev/ttyS0";
	printf("Open Uart0Init!! \n");
	if (uart0_fd == -1)
	{
		uart0_fd = open(path_utf, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); 
		if(uart0_fd == -1)
		{
			printf("Failed to open serial port %s, %s\n", path_utf, strerror(errno));
			return -1;
		}
		printf("Open Uart0 OK!! \n");
	}

	/* Configure device */
	
	struct termios newtio, oldtio;
    if ( tcgetattr(uart0_fd, &oldtio ) != 0) {  
        perror("tcgetattr error");
        return -1;
    }

    //tcflush(fd, TCIOFLUSH);
    bzero( &newtio, sizeof(newtio) );
    newtio.c_cflag |= CLOCAL | CREAD;
    newtio.c_cflag &= ~CSIZE;

	newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
	newtio.c_oflag &= ~OPOST;
	newtio.c_oflag &= ~(ONLCR | INLCR);
	newtio.c_iflag &= ~(ICRNL | INLCR);
	newtio.c_iflag &= ~(IXON | IXOFF | IXANY);
    //newtio.c_lflag &= ~(ICANON | ISIG | ECHO | ECHOE | IEXTEN);
    //newtio.c_oflag &= ~OPOST;
    //newtio.c_iflag &= ~(IXON | IXOFF | IXANY | ICRNL | BRKINT | INPCK | ISTRIP);
    //newtio.c_cflag &= ~CRTSCTS;
	

    newtio.c_cflag |= CS8;
    newtio.c_cflag &= ~PARENB;
 //   cfsetispeed(&newtio, B115200);
 //   cfsetospeed(&newtio, B115200);

    cfsetispeed(&newtio, B230400);
    cfsetospeed(&newtio, B230400);	
	
    newtio.c_cflag &= ~CSTOPB;
    newtio.c_cc[VTIME] = 0;
    newtio.c_cc[VMIN] = 0;

	tcflush(uart0_fd, TCIOFLUSH);
    if ((tcsetattr(uart0_fd, TCSANOW, &newtio)) != 0) {
        perror("set opt error");
        return -1;
    }

	return uart0_fd;
}
int Uart1Init(void)
{
	const char *path_utf = "/dev/ttyS1";
	int fd = -1;
//	speed_t speed = B115200;
	//speed_t speed = B230400;

	//fd = open(path_utf, O_RDWR | O_NOCTTY);
	fd = open(path_utf, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK);

	if(fd == -1)
	{
		printf("Failed to open serial --1-- port %s,\n", path_utf);
		return -1;
	}

	printf("Open Uart1 OK!! \n");
	/* Configure device */

	struct termios newtio, oldtio;
    if ( tcgetattr( fd, &oldtio ) != 0) {
        perror("tcgetattr error");
        return -1;
    }

    //tcflush(fd, TCIOFLUSH);
    bzero( &newtio, sizeof(newtio) );
    newtio.c_cflag |= CLOCAL | CREAD;
    newtio.c_cflag &= ~CSIZE;

	newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
	newtio.c_oflag &= ~OPOST;
	newtio.c_oflag &= ~(ONLCR | INLCR);
	newtio.c_iflag &= ~(ICRNL | INLCR);
	newtio.c_iflag &= ~(IXON | IXOFF | IXANY);
    //newtio.c_lflag &= ~(ICANON | ISIG | ECHO | ECHOE | IEXTEN);
    //newtio.c_oflag &= ~OPOST;
    //newtio.c_iflag &= ~(IXON | IXOFF | IXANY | ICRNL | BRKINT | INPCK | ISTRIP);
    //newtio.c_cflag &= ~CRTSCTS;

    newtio.c_cflag |= CS8;
    newtio.c_cflag &= ~PARENB;
  //  cfsetispeed(&newtio, B115200);
  //  cfsetospeed(&newtio, B115200);

    cfsetispeed(&newtio, B230400);
    cfsetospeed(&newtio, B230400);

    newtio.c_cflag &= ~CSTOPB;
    newtio.c_cc[VTIME] = 0;
    newtio.c_cc[VMIN] = 0;

	tcflush(fd, TCIOFLUSH);
    if ((tcsetattr(fd, TCSANOW, &newtio)) != 0) {
        perror("set opt error");
        return -1;
    }

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

	/**************************************************************************/
	return fd;
}

 

 

 

 

 

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Linux平台上使用C++代码通过485串口发送文件,你需要使用串口通信库来与串口进行通信,并使用文件操作库来读取文件内容并发送。下面是一个示例代码: ```cpp #include <iostream> #include <fstream> #include <string> #include <fcntl.h> #include <termios.h> #include <unistd.h> // 发送文件函数 bool sendFile(const char* portName, const char* fileName) { // 打开串口设备 int fd = open(portName, O_RDWR | O_NOCTTY); if (fd == -1) { std::cerr << "无法打开串口设备" << std::endl; return false; } // 配置串口属性 struct termios tty; if (tcgetattr(fd, &tty) != 0) { std::cerr << "无法获取串口属性" << std::endl; close(fd); return false; } // 设置波特率为9600 cfsetospeed(&tty, B9600); cfsetispeed(&tty, B9600); // 8个数据位,无奇偶校验,1个停止位 tty.c_cflag &= ~PARENB; tty.c_cflag &= ~CSTOPB; tty.c_cflag &= ~CSIZE; tty.c_cflag |= CS8; // 禁用硬件流控制 tty.c_cflag &= ~CRTSCTS; // 使能读取和写入 tty.c_cflag |= CREAD | CWRITE; // 设置输入模式为非规范模式 tty.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); // 设置输出模式为非规范模式 tty.c_oflag &= ~OPOST; // 设置字符超时时间和最小字符数 tty.c_cc[VTIME] = 10; // 1秒超时 tty.c_cc[VMIN] = 0; // 清除串口缓冲区 tcflush(fd, TCIFLUSH); // 应用新的串口设置 if (tcsetattr(fd, TCSANOW, &tty) != 0) { std::cerr << "无法设置串口属性" << std::endl; close(fd); return false; } // 打开文件用于读取数据 std::ifstream file(fileName, std::ios::binary); if (!file.is_open()) { std::cerr << "无法打开文件" << std::endl; close(fd); return false; } // 发送文件内容 char buffer[256]; while (file.read(buffer, sizeof(buffer))) { write(fd, buffer, file.gcount()); } // 关闭文件和串口设备 file.close(); close(fd); return true; } int main() { const char* portName = "/dev/ttyS0"; // 根据实际情况修改串口设备名称 const char* fileName = "file.txt"; // 根据实际情况修改文件名 if (sendFile(portName, fileName)) { std::cout << "文件发送成功" << std::endl; } else { std::cout << "文件发送失败" << std::endl; } return 0; } ``` 在上述示例,我们定义了一个`sendFile`函数,它接受串口设备名称和文件名作为参数。在函数内部,我们首先打开串口设备,并进行串口属性的配置。然后,打开要发送的文件,并逐块读取文件内容并通过串口发送。最后,关闭文件和串口设备。 在`main`函数,我们调用`sendFile`函数,并根据实际情况传递串口设备名称和文件名。如果文件发送成功,输出"文件发送成功";否则,输出"文件发送失败"。 请注意,这只是一个简单的示例,你可能需要根据具体情况进行适当的修改和完善。另外,你还需要根据实际情况设置正确的串口设备名称和文件名。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值