TinkerBoardR支持两路UART扩展功能,分别对应UART0和UART4。对应的串口引脚接线如下所示
UART (Universal Asynchronous Receiver/Transmitter),以下是linux 4.4 uart驱动支持的一些特性︰
这里测试使用uart4,默认在设备树中是关闭的,需要手动在设备树中开启。注意不能和SPI1同时打开,否则会出现冲突问题
&spi1 {
status = "disabled";
max-freq = <48000000>; /* spi internal clk, don't modify */
spi_dev@0 {
compatible = "rockchip,spidev";
reg = <0>;
spi-max-frequency = <48000000>;
spi-lsb-first;
};
};
&uart4 {
status = "okay";
};
//查看串口信息
rk3399pro:/ # stty -F /dev/ttyS4
speed 9600 baud; line = 0;
hupcl clocal
-brkint ixon -imaxbel
//设置串口波特率为115200
rk3399pro:/ # stty -F /dev/ttyS4 speed 115200
9600
rk3399pro:/ # stty -F /dev/ttyS4
speed 115200 baud; line = 0;
hupcl clocal
-brkint ixon -imaxbel
//发送数据
rk3399pro:/ # echo "Message From Tinker Board R" > /dev/ttyS4
//接收数据
rk3399pro:/ # cat /dev/ttyS4
Message From My PC
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <unistd.h>
int speed_arr[] = { B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300,
B38400, B19200, B9600, B4800, B2400, B1200, B300, };
int name_arr[] = {115200, 38400, 19200, 9600, 4800, 2400, 1200, 300, 38400,
19200, 9600, 4800, 2400, 1200, 300, };
void set_speed(int fd, int speed){
int i;
int status;
struct termios Opt;
tcgetattr(fd, &Opt);
for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++) {
if (speed == name_arr[i]) {
tcflush(fd, TCIOFLUSH);
cfsetispeed(&Opt, speed_arr[i]);
cfsetospeed(&Opt, speed_arr[i]);
status = tcsetattr(fd, TCSANOW, &Opt);
if (status != 0) {
perror("tcsetattr fd1");
return;
}
tcflush(fd,TCIOFLUSH);
}
}
}
/**
*@brief 设置串口数据位,停止位和效验位
*@param fd 类型 int 打开的串口文件句柄
*@param databits 类型 int 数据位 取值 为 7 或者8
*@param stopbits 类型 int 停止位 取值为 1 或者2
*@param parity 类型 int 效验类型 取值为N,E,O,,S
*/
int set_Parity(int fd,int databits,int stopbits,int parity)
{
struct termios options;
if ( tcgetattr( fd,&options) != 0) {
perror("SetupSerial ");
printf("setup serial failurer\n");
return(-1);
}
options.c_cflag &= ~CSIZE;
switch (databits) /*设置数据位数*/
{
case 7:
options.c_cflag |= CS7;
break;
case 8:
options.c_cflag |= CS8;
break;
default:
fprintf(stderr,"Unsupported data size\n");
return (-1);
}
switch (parity)
{
case 'n':
case 'N':
options.c_cflag &= ~PARENB; /* Clear parity enable */
options.c_iflag &= ~INPCK; /* Enable parity checking */
break;
case 'o':
case 'O':
options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'e':
case 'E':
options.c_cflag |= PARENB; /* Enable parity */
options.c_cflag &= ~PARODD; /* 转换为偶效验*/
options.c_iflag |= INPCK; /* Disnable parity checking */
break;
case 'S':
case 's': /*as no parity*/
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
break;
default:
fprintf(stderr,"Unsupported parity\n");
return (-1);
}
/* 设置停止位*/
switch (stopbits)
{
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
fprintf(stderr,"Unsupported stop bits\n");
return (-1);
}
/* Set input parity option */
if (parity != 'n' && parity != 'N')
options.c_iflag |= INPCK;
tcflush(fd,TCIFLUSH);
options.c_cc[VTIME] = 150; /* 设置超时15 seconds*/
options.c_cc[VMIN] = 0; /* Update the options and do it NOW */
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/
options.c_oflag &= ~(OPOST|ONLCR|OCRNL); /*Output*/
options.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON | INLCR|IGNCR);
if (tcsetattr(fd,TCSANOW,&options) != 0)
{
perror("SetupSerial 3");
return (-1);
}
return (0);
}
int set_serial_port(int fd, speed_t speed, int databits,int stopbits,int parity)
{
int ret;
set_speed(fd, speed);
ret = set_Parity(fd, databits, stopbits, parity);
return ret;
}
int open_serial_port(char *dev_path)
{
int fd;
if (dev_path == NULL)
return -1;
fd=open(dev_path,O_RDWR | O_NOCTTY);
if(fd==-1)
{
printf("open serialport failed [%s]\n", dev_path);
perror("open serialport failed\n");
return(-1);
}
fcntl(fd, F_SETFL, 0);
return fd;
}
int init_uart(char * device_name, speed_t speed, int databits,int stopbits,int parity)
{
int ret;
int uart_fd = 0;
uart_fd = open_serial_port(device_name);
if(uart_fd<0)
{
printf("open serial port failed\n");
return -1;
}
ret=set_serial_port(uart_fd, speed, databits, stopbits, parity);
if(ret==-1)
{
printf("set serial port failed\n");
return -1;
}
return uart_fd;
}
int close_uart(int uart_fd)
{
if (uart_fd > 0)
close(uart_fd);
return 0;
}
int main()
{
int gblUartFd = -1;
int ret;
unsigned char buf[5]={0,};
gblUartFd = init_uart("/dev/ttyS4", 115200, 8, 1, 'N');
while(1)
{
ret = read(gblUartFd , buf, sizeof(char)*5);
printf("buf=%s",buf);
sleep(1);
}
close_uart(gblUartFd);
return 0;
}