1、前言
本篇代码是配置串口的一些基本配置:波特率、校验位、数据位等。前提是内核中有对应的设备节点,可以在各自的开发板开发手册中找到串口所对应的设备节点。也是找了很多篇博主的文章参照,不过一开始配置的时候有问题打不开,最终还是一个一个配出来了。
2、代码
如果不能成功打开设备,使用则 ls /dev/ 命令看设备是否存在,若存在,可以用sudo chmod 666 /dev/tty 修改文件权限后重新运行程序。需要改变的该串口设备节点的权限
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int uart_open(const char *p_path)
{
return open(p_path, O_RDWR | O_NOCTTY);
}
/**
* 设置串口属性
* fd:打开的串口设备的文件描述符
* baudrate:波特率
* {0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800,
* 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400}
* bits:数据位
* #{5, 6, 7, 8}
* parity:校验
* #'n'/'N':无校验
* #'o'/'O':奇校验
* #'e','E':偶校验
* stop:停止位
* #1:1个停止位
* #2:2个停止位
* flow:流控
* #'n'/'N':不使用流控
* #'h'/'H':使用硬件流控
* #'s'/'S':使用软件流控
*/
int uart_set(int fd, int baudrate, int bits, char parity, int stop, char flow)
{
struct termios termios_uart;
int ret = 0;
speed_t uart_speed = 0;
/* 获取串口属性 */
memset(&termios_uart, 0, sizeof(termios_uart));
ret = tcgetattr(fd, &termios_uart);
if (ret == -1) {
printf("tcgetattr failed\n");
return -1;
}
//__print_termios(&termios_uart);
/* 设置波特率 */
switch (baudrate) {
case 0: uart_speed = B0; break;
case 50: uart_speed = B50; break;
case 75: uart_speed = B75; break;
case 110: uart_speed = B110; break;
case 134: uart_speed = B134; break;
case 150: uart_speed = B150; break;
case 200: uart_speed = B200; break;
case 300: uart_speed = B300; break;
case 600: uart_speed = B600; break;
case 1200: uart_speed = B1200; break;
case 1800: uart_speed = B1800; break;
case 2400: uart_speed = B2400; break;
case 4800: uart_speed = B4800; break;
case 9600: uart_speed = B9600; break;
case 19200: uart_speed = B19200; break;
case 38400: uart_speed = B38400; break;
case 57600: uart_speed = B57600; break;
case 115200: uart_speed = B115200; break;
case 230400: uart_speed = B230400; break;
default: printf("Baud rate not supported\n"); return -1;
}
cfsetspeed(&termios_uart, uart_speed);
/* 设置数据位 */
switch (bits) {
case 5: /* 数据位5 */
termios_uart.c_cflag &= ~CSIZE;
termios_uart.c_cflag |= CS5;
break;
case 6: /* 数据位6 */
termios_uart.c_cflag &= ~CSIZE;
termios_uart.c_cflag |= CS6;
break;
case 7: /* 数据位7 */
termios_uart.c_cflag &= ~CSIZE;
termios_uart.c_cflag |= CS7;
break;
case 8: /* 数据位8 */
termios_uart.c_cflag &= ~CSIZE;
termios_uart.c_cflag |= CS8;
break;
default:
printf("Data 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 (stop) {
case 1: termios_uart.c_cflag &= ~CSTOPB; break; /* 1个停止位 */
case 2: termios_uart.c_cflag |= CSTOPB; break; /* 2个停止位 */
default: printf("Stop bits not supported\n");
}
/* 设置流控 */
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; /* 使能接收 */
termios_uart.c_oflag &= ~OPOST;
termios_uart.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);//设置本地模式位原始模式
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, const char *argv[])
{
unsigned char buf[100];
/* 打开串口设备 */
int fd = uart_open("/dev/ttyUSB0");
if (fd < 0) {
printf("open %s failed\n", UART_DEV_PATH);
return 0;
}
int ret = uart_set(fd, 9600, 8, 'n', 1, 'n');
if (ret == -1) {
return 0;
}
int i = 0;
int read_num = 0;
int x = 0;
while(1)
{
int num = read(fd, buf, sizeof(buf));
write(fd, buf, sizeof(buf));
}
close(fd);
return 0;
}