波特率设置函数:int cfsetispeed(const struct termios *termios_p, speed_t speed);
int cfsetospeed(const struct termios *termios_p, speed_t speed);
清空串口BUFFER中的数据函数:int tcflush(int fd, int queue_selector);
-TCIFLUSH清除正收到的数据,且不会读取出来;
-TCOFLUSH清除正写入的数据,且不会发送至终端;
设置串口参数函数:int tcsetattr(int fd, int optional_actions, const struct termios *termios_p);
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
int uart_set(int fd, int baudrate, int bits, int stop, char parity, char flow)
{
int ret;
speed_t uart_speed;
struct termios termios_uart;
memset(&termios_uart, 0, sizeof(termios_uart));
//读取当前串口参数值
ret = tcgetattr(fd, &termios_uart);
if(ret < 0)
{
perror("tcgetattr error");
return -1;
}
//设置波特率
switch(baudrate)
{
case 9600:
cfsetspeed(&termios_uart, B9600); break;
case 38400:
cfsetspeed(&termios_uart, B38400); break;
case 115200:
cfsetspeed(&termios_uart, B115200); break;
case 230400:
cfsetspeed(&termios_uart, B230400); break;
default:
printf("Baudrate not supported \n"); return -1;
}
//设置数据位
switch(bits)
{
case 6:
termios_uart.c_cflag &= ~CSIZE;
termios_uart.c_cflag |= CS6;
break;
case 7:
termios_uart.c_cflag &= ~CSIZE;
termios_uart.c_cflag |= CS7;
break;
case 8:
termios_uart.c_cflag &= ~CSIZE;
termios_uart.c_cflag |= CS8;
break;
default:
printf("Data bits not supported \n");
return -1;
}
//设置停止位
switch(stop)
{
case 1:
termios_uart.c_cflag &= ~CSTOPB; break;
case 2:
termios_uart.c_cflag |= CSTOPB; break;
default:
printf("Stop bits not supported\n"); return -1;
}
//设置校验位
switch(parity)
{
case 'n': //无校验
case 'N':
termios_uart.c_cflag &= ~PARENB;
termios_uart.c_iflag &= ~INPCK;
break;
case 'o': //奇校验
case 'O':
termios_uart.c_cflag |= PARENB;
termios_uart.c_cflag |= PARODD;
termios_uart.c_iflag |= INPCK;
termios_uart.c_iflag |= ISTRIP;
break;
case 'e': //偶校验
case 'E':
termios_uart.c_cflag |= PARENB;
termios_uart.c_cflag &= ~PARODD;
termios_uart.c_iflag |= INPCK;
termios_uart.c_iflag |= ISTRIP;
break;
default:
printf("Parity not supported\n");
return -1;
}
//设置流控
switch(flow)
{
case 'n': //无流控
case 'N':
termios_uart.c_cflag &= ~CRTSCTS;
termios_uart.c_iflag &= ~(IXON | IXOFF | IXANY);
break;
case 'h': //硬件流控
case 'H':
termios_uart.c_cflag |= CRTSCTS;
termios_uart.c_iflag &= ~(IXON | IXOFF | IXANY);
break;
case 's': //软件流控
case 'S':
termios_uart.c_cflag &= ~CRTSCTS;
termios_uart.c_iflag |= (IXON | IXOFF | IXANY);
break;
default:
printf("Flow control parameter error\n");
return -1;
}
//其他设置
termios_uart.c_cflag |= CLOCAL; //忽略modem(调制解调器)控制线
termios_uart.c_cflag |= CREAD; //使能接收
//禁能执行定义(implementation-defined)输出处理,意思就是输出的某些特殊数据会作特殊处理,如果禁能的话那么就按原始数据输出
termios_uart.c_oflag &= ~OPOST;
/*
* 设置本地模式位原始模式
* ICANON:规范输入模式,如果设置了那么退格等特殊字符会产生实际动作
* ECHO:则将输入字符回送到终端设备
* ECHOE:如果ICANON也设置了,那么收到ERASE字符后会从显示字符中擦除一个字符(通俗点理解就是收到退格键后显示内容会往回删一个字符)
* ISIG:使终端产生的信号起作用(比如按ctrl+c可以使程序退出)
*/
termios_uart.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
/*
* 设置等待时间和最小接收字符
* 这两个值只有在阻塞模式下有意义,也就是说open的时候不能传入O_NONBLOCK,如果经过了c_cc[VTIME]这么长时间,缓冲区内有数据,但是还没达到c_cc[VMIN]个
* 数据,read也会返回。而如果当缓冲区内有了c_cc[VMIN]个数据时,无论等待时间是否到了c_cc[VTIME],read都会返回,但返回值可能比c_cc[VMIN]还大。如果将
* c_cc[VMIN]的值设置为0,那么当经过c_cc[VTIME]时间后read也会返回,返回值为0。如果将c_cc[VTIME]和c_cc[VMIN]都设置为0,那么程序运行的效果与设置
* O_NONBLOCK类似,不同的是如果设置了O_NONBLOCK,那么在没有数据时read返回-1,而如果没有设置O_NONBLOCK,那么在没有数据时read返回的是0。
*/
termios_uart.c_cc[VTIME] = 1; //设置等待时间,单位1/10秒
termios_uart.c_cc[VMIN] = 1; //最少读取一个字符
tcflush(fd, TCIFLUSH); //清空读缓冲区
//写入配置
ret = tcsetattr(fd, TCSANOW, &termios_uart);
if(ret == -1)
{
printf("tcsetattr failed\n");
}
return ret;
}
int main(int argc, char *argv[])
{
int fd;
int len;
char *filename;
char buf[512];
char *buffer = "hello lianmeng!\n";
memset(buf, 0, sizeof(buf));
filename = argv[1];
fd = open(filename, O_RDWR | O_NONBLOCK);
if(fd < 0)
{
printf("can't open file %s \r\n", filename);
return -1;
}
uart_set(fd, 115200, 8, 1, 'N', 'N');
while(1)
{
len = read(fd, buf, sizeof(buf));
if(len > 0)
{
write(fd, buf, len);
}
}
close(fd);
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步