一、串口设备查看
查看串口 (/dev)
ls /dev/tty*
查看串口(或串口终端)属性 ( /proc)
cat /proc/tty/driver/serial 或
cat /proc/tty/drivers
二、串口自测指令
测试打印口
echo haha > /dev/ttyS0
测试串口4
使用usb转ttl连接串口4,配置串口4波特率为9600,打开上位机串口软件循环发送数据。开发板使用指令
cat /dev/ttyS4
开启输出显示,可在调试串口看到串口4接收到上位机发送的数据.
三、串口测试参考程序
连接方式:以nuc980开发板为例,将串口1和串口2的收、发线交叉连接。
nuc980官方uart测试程序
/****************************************************************************
* *
* Copyright (c) 2014 Nuvoton Technology Corp. All rights reserved. *
* *
****************************************************************************/
/****************************************************************************
*
* FILENAME
* uart_test.c
*
* VERSION
* 1.0
*
* DESCRIPTION
* This is the test program used to test the UARTs on NUC980 EV board
*
* DATA STRUCTURES
* None
*
* FUNCTIONS
* None
*
* HISTORY
*
*
* REMARK
* None
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <pthread.h>
#define FALSE 0
#define TRUE 1
int fd[2];
pthread_t threads[10];
char buff[101];
static struct termios newtios,oldtios; /*termianal settings */
static int saved_portfd=-1; /*serial port fd */
static void reset_tty_atexit(void)
{
if(saved_portfd != -1)
{
tcsetattr(saved_portfd,TCSANOW,&oldtios);
}
}
/*cheanup signal handler */
static void reset_tty_handler(int signal)
{
if(saved_portfd != -1)
{
tcsetattr(saved_portfd,TCSANOW,&oldtios);
}
_exit(EXIT_FAILURE);
}
static int open_port(const char *portname)
{
struct sigaction sa;
int portfd;
printf("opening serial port:%s\n",portname);
/*open serial port */
if((portfd=open(portname,O_RDWR | O_NOCTTY)) < 0 )
{
printf("open serial port %s fail \n ",portname);
return portfd;
}
/*get serial port parnms,save away */
tcgetattr(portfd,&newtios);
memcpy(&oldtios,&newtios,sizeof newtios);
/* configure new values */
cfmakeraw(&newtios); /*see man page */
newtios.c_iflag |=IGNPAR; /*ignore parity on input */
newtios.c_oflag &= ~(OPOST | ONLCR | OLCUC | OCRNL | ONOCR | ONLRET | OFILL);
newtios.c_cflag = CS8 | CLOCAL | CREAD;
newtios.c_cc[VMIN]=1; /* block until 1 char received */
newtios.c_cc[VTIME]=0; /*no inter-character timer */
/* 115200 bps */
cfsetospeed(&newtios,B115200);
cfsetispeed(&newtios,B115200);
/* register cleanup stuff */
atexit(reset_tty_atexit);
memset(&sa,0,sizeof sa);
sa.sa_handler = reset_tty_handler;
sigaction(SIGHUP,&sa,NULL);
sigaction(SIGINT,&sa,NULL);
sigaction(SIGPIPE,&sa,NULL);
sigaction(SIGTERM,&sa,NULL);
/*apply modified termios */
saved_portfd=portfd;
tcflush(portfd,TCIFLUSH);
tcsetattr(portfd,TCSADRAIN,&newtios);
return portfd;
}
void * process1(void* arg)
{
int portfd = (int) arg;
unsigned char i, j;
int rev1, rev2;
char RxBuffer[101];
rev1 =0;
rev2 =0;
while(rev2 < 100)
{
rev1 = write(portfd,(buff+rev2),100);
rev2 += rev1;
}
printf("\n uart1 send %d byts\n", rev2);
rev1 = 0;
rev2 = 0;
while(rev2 < 100)
{
rev1 = read(portfd,(RxBuffer+rev2),100);
rev2 += rev1;
}
printf("\n uart1 receive %d bytes\n", rev2);
for(i = 0; i < 100; i++)
{
if(i != RxBuffer[i])
{
printf("\n uart1 compare Error!!");
while(1);
}
}
printf("\n uart1 compare correct!!\n");
printf("\n uart1 test done!!\n");
}
void * process2(void* arg)
{
int portfd = (int) arg;
unsigned char i, j;
int rev1, rev2;
char RxBuffer[101];
rev1 =0;
rev2 =0;
while(rev2 < 100)
{
rev1 = write(portfd,(buff+rev2),100);
rev2 += rev1;
}
printf("\n uart2 send %d bytes \n", rev2);
rev1 = 0;
rev2 = 0;
while(rev2 < 100)
{
rev1 = read(portfd,(RxBuffer+rev2),100);
rev2 += rev1;
}
printf("\n uart2 receive %d bytes \n", rev2);
for(i = 0; i < 100; i++)
{
if(i != RxBuffer[i])
{
printf("\n uart2 compare Error!!");
while(1);
}
}
printf("\n uart2 compare correct!!\n");
printf("\n uart2 test done!!\n");
}
/**
*@breif main()
*/
int main(int argc, char **argv)
{
char *dev[10]={"/dev/ttyS1", "/dev/ttyS2"};
unsigned int i;
printf("\n demo uart1/uart2 external loop back function \n");
for(i = 0; i < 100; i++)
{
buff[i] = (i & 0xff);
}
for(i = 0; i < 2; i++)
{
if((fd[i] = open_port(dev[i]))<0)
return -1;
}
pthread_create(&threads[0], NULL, process1, (void*)(fd[0]));
pthread_create(&threads[1], NULL, process2, (void*)(fd[1]));
pthread_join(threads[0], NULL);
pthread_join(threads[1], NULL);
return 0;
}
Makefile文件
.SUFFIXES : .x .o .c .s
CC := arm-linux-gcc
STRIP := arm-linux-strip
TARGET = uart_demo
SRCS := uart.c
LIBS = -lpthread -lc -lgcc
all:
$(CC) -static $(SRCS) -o $(TARGET) $(LIBS)
$(STRIP) $(TARGET)
clean:
rm -f *.o
rm -f *.x
rm -f *.flat
rm -f *.map
rm -f temp
rm -f *.img
rm -f $(TARGET)
rm -f *.gdb
测试结果
nuc980官方rs485测试程序
/*
* Copyright (c) 2014 Nuvoton technology corporation
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <pthread.h>
#include <linux/serial.h>
#define FALSE 0
#define TRUE 1
/* Driver-specific ioctls: ...\linux-3.10.x\include\uapi\asm-generic\ioctls.h */
#define TIOCGRS485 0x542E
#define TIOCSRS485 0x542F
int fd[2];
pthread_t threads[10];
char buff[256];
static struct termios newtios,oldtios; /*termianal settings */
static int saved_portfd=-1; /*serial port fd */
/* Test GCC version, this structure is consistent in GCC 4.8, thus no need to overwrite */
#if (__GNUC__ == 4 && __GNUC_MINOR__ == 3)
struct my_serial_rs485
{
unsigned long flags; /* RS485 feature flags */
#define SER_RS485_ENABLED (1 << 0) /* If enabled */
#define SER_RS485_RTS_ON_SEND (1 << 1) /* Logical level for RTS pin when sending */
#define SER_RS485_RTS_AFTER_SEND (1 << 2) /* Logical level for RTS pin after sent*/
#define SER_RS485_RX_DURING_TX (1 << 4)
unsigned long delay_rts_before_send; /* Delay before send (milliseconds) */
unsigned long delay_rts_after_send; /* Delay after send (milliseconds) */
unsigned long padding[5]; /* Memory is cheap, new structs are a royal PITA .. */
};
#endif
static void reset_tty_atexit(void)
{
if(saved_portfd != -1)
{
tcsetattr(saved_portfd,TCSANOW,&oldtios);
}
}
/*cheanup signal handler */
static void reset_tty_handler(int signal)
{
if(saved_portfd != -1)
{
tcsetattr(saved_portfd,TCSANOW,&oldtios);
}
_exit(EXIT_FAILURE);
}
static int open_port(const char *portname)
{
struct sigaction sa;
int portfd;
#if (__GNUC__ == 4 && __GNUC_MINOR__ == 3)
struct my_serial_rs485 rs485conf;
struct my_serial_rs485 rs485conf_bak;
#else
struct serial_rs485 rs485conf;
struct serial_rs485 rs485conf_bak;
#endif
//printf("opening serial port:%s\n",portname);
/*open serial port */
if((portfd=open(portname,O_RDWR | O_NOCTTY, 0)) < 0 )
{
printf("open serial port %s fail \n ",portname);
return portfd;
}
printf("opening serial port:%s\n",portname);
/*get serial port parnms,save away */
tcgetattr(portfd,&newtios);
memcpy(&oldtios,&newtios,sizeof newtios);
/* configure new values */
cfmakeraw(&newtios); /*see man page */
newtios.c_iflag |=IGNPAR; /*ignore parity on input */
newtios.c_oflag &= ~(OPOST | ONLCR | OLCUC | OCRNL | ONOCR | ONLRET | OFILL);
newtios.c_cflag = CS8 | CLOCAL | CREAD;
newtios.c_cc[VMIN]=1; /* block until 1 char received */
newtios.c_cc[VTIME]=0; /*no inter-character timer */
/* 115200 bps */
cfsetospeed(&newtios,B9600);
cfsetispeed(&newtios,B9600);
/* register cleanup stuff */
atexit(reset_tty_atexit);
memset(&sa,0,sizeof sa);
sa.sa_handler = reset_tty_handler;
sigaction(SIGHUP,&sa,NULL);
sigaction(SIGINT,&sa,NULL);
sigaction(SIGPIPE,&sa,NULL);
sigaction(SIGTERM,&sa,NULL);
/*apply modified termios */
saved_portfd=portfd;
tcflush(portfd,TCIFLUSH);
tcsetattr(portfd,TCSADRAIN,&newtios);
if (ioctl (portfd, TIOCGRS485, &rs485conf) < 0)
{
/* Error handling.*/
printf("ioctl TIOCGRS485 error.\n");
}
/* Enable RS485 mode: */
rs485conf.flags |= SER_RS485_ENABLED;
/* Set logical level for RTS pin equal to 1 when sending: */
rs485conf.flags |= SER_RS485_RTS_ON_SEND;
//rs485conf.flags |= SER_RS485_RTS_AFTER_SEND;
/* set logical level for RTS pin equal to 0 after sending: */
rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND);
//rs485conf.flags &= ~(SER_RS485_RTS_ON_SEND);
/* Set rts delay after send, if needed: */
rs485conf.delay_rts_after_send = 0x80;
if (ioctl (portfd, TIOCSRS485, &rs485conf) < 0)
{
/* Error handling.*/
printf("ioctl TIOCSRS485 error.\n");
}
if (ioctl (portfd, TIOCGRS485, &rs485conf_bak) < 0)
{
/* Error handling.*/
printf("ioctl TIOCGRS485 error.\n");
}
else
{
printf("rs485conf_bak.flags 0x%x.\n", rs485conf_bak.flags);
printf("rs485conf_bak.delay_rts_before_send 0x%x.\n", rs485conf_bak.delay_rts_before_send);
printf("rs485conf_bak.delay_rts_after_send 0x%x.\n", rs485conf_bak.delay_rts_after_send);
}
return portfd;
}
void * process1(void* arg)
{
int portfd = (int) arg;
unsigned int i, j;
int rev1, rev2;
char RxBuffer[sizeof(buff)];
rev1 =0;
rev2 =0;
while(rev2 < sizeof(buff))
{
rev1 = write(portfd,(buff+rev2),sizeof(buff));
rev2 += rev1;
}
printf("\n uart1 send %d byts\n", rev2);
}
void * process2(void* arg)
{
int portfd = (int) arg;
unsigned int i, j;
int rev1, rev2;
char RxBuffer[sizeof(buff)];
rev1 = 0;
rev2 = 0;
while(rev2 < sizeof(RxBuffer))
{
rev1 = read(portfd,(RxBuffer+rev2),sizeof(RxBuffer) - rev2);
rev2 += rev1;
if(rev1 > 0)
printf("\n uart2 receive %d bytes \n", rev2);
}
printf("\n uart2 receive %d bytes \n", rev2);
for(i = 0; i < sizeof(RxBuffer); i++)
{
if(i != RxBuffer[i])
{
printf("\n uart2 compare Error!!");
while(1);
}
}
printf("\n uart2 compare correct!!\n");
printf("\n uart2 test done!!\n");
}
/**
*@breif main()
*/
int main(int argc, char **argv)
{
char *dev[10]={"/dev/ttyS1", "/dev/ttyS2"};
unsigned int i;
printf("\n demo uart1/uart2 external loop back function \n");
for(i = 0; i < sizeof(buff); i++)
{
buff[i] = (i & 0xff);
}
for(i = 0; i < 2; i++)
{
if((fd[i] = open_port(dev[i]))<0)
return -1;
}
pthread_create(&threads[0], NULL, process1, (void*)(fd[0]));
pthread_create(&threads[1], NULL, process2, (void*)(fd[1]));
pthread_join(threads[0], NULL);
pthread_join(threads[1], NULL);
return 0;
}
Makefile文件
.SUFFIXES : .x .o .c .s
CC := arm-linux-gcc
STRIP := arm-linux-strip
TARGET = uart_rs485
SRCS := uart.c
LIBS = -lpthread -lc -lgcc
all:
$(CC) -static $(SRCS) -o $(TARGET) $(LIBS)
$(STRIP) $(TARGET)
clean:
rm -f *.o
rm -f *.x
rm -f *.flat
rm -f *.map
rm -f temp
rm -f *.img
rm -f $(TARGET)
rm -f *.gdb