nuc977 串口测试

app_uart10_nuvoton.c

/****************************************************************************
 *                                                                          *
 * 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 NUC970 EV board
 *
 * DATA STRUCTURES
 *     None
 *
 * FUNCTIONS
 *     None
 *
 * HISTORY
 *     
 *
 * REMARK
 *     None
 ****************************************************************************/
#include     
#include     
#include      
#include      
#include      
#include      
#include       
#include     
#include     
#include 	
#include    

#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");

}


/* PB12:TX     PB13:RX   */
void * process10(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 uart10 send %d bytes \n", rev2);

	rev1 = 0;
	rev2 = 0;

	while(rev2 < 100)
	{
		rev1 = read(portfd,(RxBuffer+rev2),100);
		rev2 += rev1;
	}
		
	printf("\n uart10 receive %d bytes \n", rev2);

	for(i = 0; i < 100; i++)
	{
		if(i != RxBuffer[i])
		{
			printf("\n uart10 compare Error!!");
			while(1);
		}
	}

	printf("\n uart10 compare correct!!\n");
	printf("\n uart10 test done!!\n");

}






/**
*@breif 	main()
*/
int main(int argc, char **argv)
{
	//char *dev[10]={"/dev/ttyS1", "/dev/ttyS2"};
	char *dev[10]={"/dev/ttyS10", "/dev/ttyS2"};
	unsigned int i;

	printf("\n demo uart10 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;
	}
	*/

	if((fd[0] = open_port(dev[0]))<0)
	{
		
		printf("\n open_port error ...\n");
		return -1;
	}


	pthread_create(&threads[0], NULL, process10, (void*)(fd[0]));
	pthread_join(threads[0], NULL);
	
	/*
	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 := app_uart10_nuvoton.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

直接编译不过,用makefile,里面有要添加的库

nuc977 串口测试_第1张图片

 

nuc977 串口测试_第2张图片

将PB12和PB13 短接测试,否则就是应用程序就死等

 

nuc977 串口测试_第3张图片

 

网上找到另一个例子改一下:

app_uart10.c

#include    
#include    
#include    
#include    
#include    
#include    
  
//为了保证用户输入的波特率是个正确的值,所以需要这两个数组验证,对于设置波特率时候,前面要加个B   
int speed_arr[] = { B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1200, B300,  
    B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1200, B300, };  
  
int name_arr[] = {115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200, 300,  
    115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200, 300, };  
  
/*----------------------------------------------------------------------------- 
  函数名:      set_speed 
  参数:        int fd ,int speed 
  返回值:      void 
  描述:        设置fd表述符的串口波特率 
 *-----------------------------------------------------------------------------*/  
void set_speed(int fd ,int speed)  
{  
    struct termios opt;  
    int i;  
    int status;  
  
    tcgetattr(fd,&opt);  
    for(i = 0;i < sizeof(speed_arr)/sizeof(int);i++)  
    {  
        if(speed == name_arr[i])                        //找到标准的波特率与用户一致   
        {  
            tcflush(fd,TCIOFLUSH);                      //清除IO输入和输出缓存   
            cfsetispeed(&opt,speed_arr[i]);         //设置串口输入波特率   
            cfsetospeed(&opt,speed_arr[i]);         //设置串口输出波特率   
  
            status = tcsetattr(fd,TCSANOW,&opt);    //将属性设置到opt的数据结构中,并且立即生效   
            if(status != 0)  
                perror("tcsetattr fd:");                //设置失败   
            return ;  
        }  
        tcflush(fd,TCIOFLUSH);                          //每次清除IO缓存   
    }  
}  
/*----------------------------------------------------------------------------- 
  函数名:      set_parity 
  参数:        int fd 
  返回值:      int 
  描述:        设置fd表述符的奇偶校验 
 *-----------------------------------------------------------------------------*/  
int set_parity(int fd)  
{  
    struct termios opt;  
  
    if(tcgetattr(fd,&opt) != 0)                 //或许原先的配置信息   
    {  
        perror("Get opt in parity error:");  
        return -1;  
    }  
  
    /*通过设置opt数据结构,来配置相关功能,以下为八个数据位,不使能奇偶校验*/  
    opt.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP  
                | INLCR | IGNCR | ICRNL | IXON);  
    opt.c_oflag &= ~OPOST;  
    opt.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);  
    opt.c_cflag &= ~(CSIZE | PARENB);  
    opt.c_cflag |= CS8;  
  
    tcflush(fd,TCIFLUSH);                           //清空输入缓存   
  
    if(tcsetattr(fd,TCSANOW,&opt) != 0)  
    {  
        perror("set attr parity error:");  
        return -1;  
    }  
  
    return 0;  
}  
/*----------------------------------------------------------------------------- 
  函数名:      serial_init 
  参数:        char *dev_path,int speed,int is_block 
  返回值:      初始化成功返回打开的文件描述符 
  描述:        串口初始化,根据串口文件路径名,串口的速度,和串口是否阻塞,block为1表示阻塞 
 *-----------------------------------------------------------------------------*/  
int serial_init(char *dev_path,int speed,int is_block)  
{  
    int fd;  
    int flag;  
  
    flag = 0;  
    flag |= O_RDWR;                     //设置为可读写的串口属性文件   
    if(is_block == 0)  
        flag |=O_NONBLOCK;              //若为0则表示以非阻塞方式打开   
  
    fd = open(dev_path,flag);               //打开设备文件   
    if(fd < 0)  
    {  
        perror("Open device file err:");  
        close(fd);  
        return -1;  
    }  
  
    /*打开设备文件后,下面开始设置波特率*/  
    set_speed(fd,speed);                //考虑到波特率可能被单独设置,所以独立成函数   
  
    /*设置奇偶校验*/  
    if(set_parity(fd) != 0)  
    {  
        perror("set parity error:");  
        close(fd);                      //一定要关闭文件,否则文件一直为打开状态   
        return -1;  
    }  
  
    return fd;  
}  
/*----------------------------------------------------------------------------- 
  函数名:      serial_send 
  参数:        int fd,char *str,unsigned int len 
  返回值:      发送成功返回发送长度,否则返回小于0的值 
  描述:        向fd描述符的串口发送数据,长度为len,内容为str 
 *-----------------------------------------------------------------------------*/  
int serial_send(int fd,char *str,unsigned int len)  
{  
    int ret;  
  
    if(len > strlen(str))                    //判断长度是否超过str的最大长度   
        len = strlen(str);  
  
    ret = write(fd,str,len);  
    if(ret < 0)  
    {  
        perror("serial send err:");  
        return -1;  
    }  
  
    return ret;  
}  
  
/*----------------------------------------------------------------------------- 
  函数名:      serial_read 
  参数:        int fd,char *str,unsigned int len,unsigned int timeout 
  返回值:      在规定的时间内读取数据,超时则退出,超时时间为ms级别 
  描述:        向fd描述符的串口接收数据,长度为len,存入str,timeout 为超时时间 
 *-----------------------------------------------------------------------------*/  
int serial_read(int fd, char *str, unsigned int len, unsigned int timeout)  
{  
    fd_set rfds;  
    struct timeval tv;  
    int ret;                                //每次读的结果   
    int sret;                               //select监控结果   
    int readlen = 0;                        //实际读到的字节数   
    char * ptr;  
  
    ptr = str;                          //读指针,每次移动,因为实际读出的长度和传入参数可能存在差异   
  
    FD_ZERO(&rfds);                     //清除文件描述符集合   
    FD_SET(fd,&rfds);                   //将fd加入fds文件描述符,以待下面用select方法监听   
  
    /*传入的timeout是ms级别的单位,这里需要转换为struct timeval 结构的*/  
    tv.tv_sec  = timeout / 1000;  
    tv.tv_usec = (timeout%1000)*1000;  
  
    /*防止读数据长度超过缓冲区*/  
    //if(sizeof(&str) < len)   
    //  len = sizeof(str);   
  
  
    /*开始读*/  
    while(readlen < len)  
    {  
        sret = select(fd+1,&rfds,NULL,NULL,&tv);        //检测串口是否可读   
  
        if(sret == -1)                              //检测失败   
        {  
            perror("select:");  
            break;  
        }  
        else if(sret > 0)                       
        {  
            ret = read(fd,ptr,1);  
            if(ret < 0)  
            {  
                perror("read err:");  
                break;  
            }  
            else if(ret == 0)  
                break;  
  
            readlen += ret;                             //更新读的长度   
            ptr     += ret;                             //更新读的位置   
        }  
        else                                                    //超时   
        {  
            printf("timeout!\n");  
            break;  
        }  
    }  
  
    return readlen;  
}  
int main()  
{  
    int fd;  
    int ret;  
    char str[]="hello linux serial!";  
    char buf[100];  
  
  
    fd =  serial_init("/dev/ttyS10",115200,1);  
    if(fd < 0)  
    {  
        perror("serial init err:");  
        return -1;  
    }  
  
    ret = serial_send(fd,str,22);  
    printf("send %d bytes!\n",ret);  
    serial_read(fd,buf,100,5000);  
    printf("the buf is :%s\n",buf);  
    close(fd);  
    return 0;  
}  


nuc977 串口测试_第4张图片

nuc977 串口测试_第5张图片

你可能感兴趣的:(NUC977,Linux)