如何使用widora-neo上的uart1收发数据?



  • #include <stdio.h>         //标准输入输出定义
    #include <stdlib.h>        //标准函数库定义
    #include <unistd.h>       //Unix标准函数定义
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>          //文件控制定义
    #include <termios.h>     //POSIX中断控制定义
    #include <errno.h>        //错误号定义
    
    
    #define UART1_DEV "/dev/ttyS1"
    #define UART2_DEV "/dev/ttyS2"
    
    //打开串口
    int open_port(void)
    {
    	int fd;
    	fd = open(UART1_DEV, O_RDWR | O_NOCTTY | O_NDELAY);
    	if(fd == -1)
    	{
    		perror("open_port: Unable to open /dev/ttyS1 -");
    		return(fd);
    	}
    	else
    	{
    		fcntl(fd, F_SETFL, 0);
    		printf("open ttys1 .....\n");
    		return(fd);
    	}
    }
    
    //设置波特率
    void set_speed_and_parity(int fd, int speed)
    {
    	struct termios Opt;
    	
    	if(tcgetattr(fd,&Opt)!=0)
    	{
    		perror("tcgetattr fd");
    		return;
    	}
    	tcflush(fd, TCIOFLUSH);
    	cfsetispeed(&Opt, speed);
    	cfsetospeed(&Opt, speed);
    	/*tcsetattr函数标志:
    	TCSANOW:立即执行而不等待数据发送或者接受完成。
    	TCSADRAIN:等待所有数据传递完成后执行。
    	TCSAFLUSH:Flush input and output buffers and make the change
    	*/
    	if(tcsetattr(fd, TCSANOW, &Opt) != 0)
    	{	
    		perror("tcsetattr fd");
    		return;
    	}
    	tcflush(fd, TCIOFLUSH);
    	//设置奇偶校验——默认8个数据位、没有校验位
            
    	Opt.c_cflag &= ~PARENB;
    	Opt.c_cflag &= ~CSTOPB;
    	Opt.c_cflag &= ~CSIZE;
    	Opt.c_cflag |= CS8;
    	
    	//其他的一些配置
    	//原始输入,输入字符只是被原封不动的接收
    	Opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    	//软件流控制无效,因为硬件没有硬件流控制,所以就不需要管了
    	Opt.c_iflag &= ~(IXON | IXOFF | IXANY);
    	//原始输出方式可以通过在c_oflag中重置OPOST选项来选择:
    	Opt.c_oflag |= ~OPOST;
    	//VMIN可以指定读取的最小字符数。如果它被设置为0,那么VTIME值则会指定每个字符读取的等待时间。
        Opt.c_cc[VTIME] = 0;
        Opt.c_cc[VMIN] = 0;
    
       	Opt.c_oflag &= ~(ONLCR | OCRNL);    
       	Opt.c_iflag &= ~(ICRNL | INLCR);
        
        tcflush(fd, TCIOFLUSH);
    
    }
    
    /**
      *串口发送数据函数
      *fd:串口描述符
      *data:待发送数据
      *datalen:数据长度
      */
    int serial_write(int fd ,char *data, int datalen)
    {
    	int len=0;
    	//获取实际传输数据的长度
    	len=write(fd,data,datalen);
    	printf("send data OK! datalen=%d\n",len);
    	return len;	
    }
    
    /** 
      *串口接收数据 
      *要求启动后,在pc端发送ascii文件 
      */ 
    int serial_read(int fd,char buff[],int datalen)
    {
    	int nread=0;
    	printf("Ready for receiving data...");
    	nread=read(fd,buff,datalen);
    	if(nread>0)
    	{
    		printf("readlength=%d\n",nread);
    		buff[nread]='\0';
    		printf("%s\n",buff);
    	}
    	return nread;
    }
    
    int serial_init()
    {
    	int fd;	
    	//打开串口
    	if((fd=open_port())<0)
        	{
            	perror("open_port error");
            	return 0;
        	}
    	//设置波特率和校验位
    	set_speed_and_parity(fd,115200);
    	return (fd);
    }
    
    int main(void)
    {
    	int fd;
    	int nread,i,n =0,datalen=255, len = 0;
    	char testbuff[]="Hello\r\n";
    	char readbuff[256];
    	
    	fd=serial_init();
    	printf("fd=%d\n",fd);
    	//尝试先写内容
    	len=write(fd,testbuff,datalen);
    	if(len==-1)
    	{
    		printf("write bad\n");
    	}
    	else{
    		printf("the test is ok!\n");
    	}	
    	//循环读取串口并输出
    	while(1)
    	{
    		printf("enter the while loop\n");
    		
    		//这个是重点,当时我就是这个问题出错了,每次读之前必须清空一次。
    		bzero(readbuff, sizeof(readbuff));
    		nread=serial_read(fd,readbuff,512);
    		if(nread > 0)
    		{
    			if(readbuff[0]=='O'&&readbuff[1]=='F'&&readbuff[2]=='F')
    			{
    				 break;
    			}
    			serial_write(fd,readbuff,datalen);
    		}
    	}
    }
    

    这是从网上找的源码,问题是串口并没有数据往来


  • administrators

    参考群共享的uart_test 源码



  • @mango 群在哪里啊?????


  • administrators

    @myxmouse
    QQ群:299381903
    代码名字:uart_test.c.txt



  • @mango 谢谢 马上加