精华内容
下载资源
问答
  • /* * <lihf> linux串口测试代码 * * Linux版本号7 * 程序功能: linux主机UART1接收PC COM口发送过来的数据原封不动返回给PC的COM口 * 已经通过多次测试验证通过 * */ #include <termios.h> #include <stdio.h> #...
  • Linux串口测试

    千次阅读 2015-03-10 14:35:14
    Linux串口测试
    1. 打开自动回车换行\0D\0A
    

    echo "12345" > /dev/ttyS0

    2. 关闭自动回车换行\0D\0A

    echo -n "12345" > /dev/ttyS0

    3. 十六进制输入

    echo -ne "\xFF\xFF\xFF" > /dev/ttyS0

    4. 修改波特率115200 8 N 1

    stty -F /dev/ttyS0 speed 115200 cs8 -parenb -cstopb  -echo


    测试程序

    receive.c

    #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>
    
    #define TRUE 1
    
    void setTermios(struct termios * pNewtio, int uBaudRate)
    {
        bzero(pNewtio, sizeof(struct termios)); /* clear struct for new port settings */
        //8N1
        pNewtio->c_cflag = uBaudRate | CS8 | CREAD | CLOCAL;
        pNewtio->c_iflag = IGNPAR;
        pNewtio->c_oflag = 0;
        pNewtio->c_lflag = 0; //non ICANON
        /*
         initialize all control characters
         default values can be found in /usr/include/termios.h, and
         are given in the comments, but we don't need them here
         */
        pNewtio->c_cc[VINTR] = 0; /* Ctrl-c */
        pNewtio->c_cc[VQUIT] = 0; /* Ctrl-\ */
        pNewtio->c_cc[VERASE] = 0; /* del */
        pNewtio->c_cc[VKILL] = 0; /* @ */
        pNewtio->c_cc[VEOF] = 4; /* Ctrl-d */
        pNewtio->c_cc[VTIME] = 5; /* inter-character timer, timeout VTIME*0.1 */
        pNewtio->c_cc[VMIN] = 0; /* blocking read until VMIN character arrives */
        pNewtio->c_cc[VSWTC] = 0; /* '\0' */
        pNewtio->c_cc[VSTART] = 0; /* Ctrl-q */
        pNewtio->c_cc[VSTOP] = 0; /* Ctrl-s */
        pNewtio->c_cc[VSUSP] = 0; /* Ctrl-z */
        pNewtio->c_cc[VEOL] = 0; /* '\0' */
        pNewtio->c_cc[VREPRINT] = 0; /* Ctrl-r */
        pNewtio->c_cc[VDISCARD] = 0; /* Ctrl-u */
        pNewtio->c_cc[VWERASE] = 0; /* Ctrl-w */
        pNewtio->c_cc[VLNEXT] = 0; /* Ctrl-v */
        pNewtio->c_cc[VEOL2] = 0; /* '\0' */
    }
     
    #define BUFSIZE 7
    
    int main(int argc, char **argv)
    {
        int fd;
        int nread;
        char buff[BUFSIZE];
        struct termios oldtio, newtio;
        struct timeval tv;
        char *dev ="/dev/ttyS2";
        fd_set rfds; 
    	int i = 0;
    	
        if ((fd = open(dev, O_RDWR | O_NOCTTY))<0){		printf("err: can't open serial port!\n");
    		return -1;
        }
    
        tcgetattr(fd, &oldtio); /* save current serial port settings */
        setTermios(&newtio, B38400);
        tcflush(fd, TCIFLUSH);
        tcsetattr(fd, TCSANOW, &newtio);
    
    	tv.tv_sec=30;
    	tv.tv_usec=0;
    
    	while (TRUE){
    		printf("wait...\n");
    
    		FD_ZERO(&rfds);
    		FD_SET(fd, &rfds);
    
    		if (select(1+fd, &rfds, NULL, NULL, NULL)>0){
    			if (FD_ISSET(fd, &rfds)){
    				nread=read(fd, buff, BUFSIZE);		printf("readlength=%d\n", nread);
    				for (i = 0; i < BUFSIZE; i++){
    					printf ("0x%02x ", buff[i]);
    				}
    				printf("\n");
    			}
    		}
    	}
    
    	tcsetattr(fd, TCSANOW, &oldtio);
    	close(fd);
    }
    

    send.c

    #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>
    
    void setTermios(struct termios * pNewtio, int uBaudRate)
    {
        bzero(pNewtio, sizeof(struct termios)); /* clear struct for new port settings */
        //8N1
        pNewtio->c_cflag = uBaudRate | CS8 | CREAD | CLOCAL;
        pNewtio->c_iflag = IGNPAR;
        pNewtio->c_oflag = 0;
        pNewtio->c_lflag = 0; //non ICANON
        /*
         initialize all control characters
         default values can be found in /usr/include/termios.h, and
         are given in the comments, but we don't need them here
        */
        pNewtio->c_cc[VINTR] = 0; /* Ctrl-c */
        pNewtio->c_cc[VQUIT] = 0; /* Ctrl-\ */
        pNewtio->c_cc[VERASE] = 0; /* del */
        pNewtio->c_cc[VKILL] = 0; /* @ */
        pNewtio->c_cc[VEOF] = 4; /* Ctrl-d */
        pNewtio->c_cc[VTIME] = 5; /* inter-character timer, timeout VTIME*0.1 */
        pNewtio->c_cc[VMIN] = 0; /* blocking read until VMIN character arrives */
        pNewtio->c_cc[VSWTC] = 0; /* '\0' */
        pNewtio->c_cc[VSTART] = 0; /* Ctrl-q */
        pNewtio->c_cc[VSTOP] = 0; /* Ctrl-s */
        pNewtio->c_cc[VSUSP] = 0; /* Ctrl-z */
        pNewtio->c_cc[VEOL] = 0; /* '\0' */
        pNewtio->c_cc[VREPRINT] = 0; /* Ctrl-r */
        pNewtio->c_cc[VDISCARD] = 0; /* Ctrl-u */
        pNewtio->c_cc[VWERASE] = 0; /* Ctrl-w */
        pNewtio->c_cc[VLNEXT] = 0; /* Ctrl-v */
        pNewtio->c_cc[VEOL2] = 0; /* '\0' */
    }
    
    int main(int argc, char **argv)
    {
        int fd;
        int nCount, nTotal, i;
        struct termios oldtio, newtio;
    	
        char *dev ="/dev/ttyS2";
    	
        //if ((argc!=3) || (sscanf(argv[1], "%d", &nTotal) != 1)){
    	//	printf("err: need tow arg!\n");
    	//	return -1;
        //}
    
        if ((fd = open(dev, O_RDWR | O_NOCTTY))<0){		printf("err: can't open serial port!\n");
    		return -1;
        }
    
        tcgetattr(fd, &oldtio); /* save current serial port settings */
    	
        setTermios(&newtio, B38400);
        tcflush(fd, TCIFLUSH);
        tcsetattr(fd, TCSANOW, &newtio);
    
    	//for (i=0; i<nTotal; i++){
    	//	nCount=write(fd, argv[2], strlen(argv[2]));
    	//	printf("send data\n");
    	//	sleep(1);
    	//}
        char cmd[7] = {0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00};
    	
    	cmd[2] = 0x00;
    	cmd[3] = 0x04;		// 0x04, left; 0x02, right; 0x08, up; 0x10, down
    	cmd[4] = 0x2F;
    	cmd[5] = 0x00;
    	cmd[6] = ((cmd[1] + cmd[2] + cmd[3] + cmd[4] + cmd[5])) & 0xFF;	printf ("check sum: 0x%02x\n", cmd[6]);
    	int ret = write (fd, cmd, 7);
    
    	printf ("Running...\n");
    	sleep (4);	
    
    	cmd[2] = 0x00;
    	cmd[3] = 0x00;			//left and right stop
    	cmd[4] = 0x2F;
    	cmd[5] = 0x00;
    	cmd[6] = ((cmd[1] + cmd[2] + cmd[3] + cmd[4] + cmd[5])) & 0xFF;	printf ("check sum: 0x%02x\n", cmd[6]);
    	ret = write (fd, cmd, 7);
    
    	cmd[2] = 0x00;
    	cmd[3] = 0x51;			//get pos
    	cmd[4] = 0x00;
    	cmd[5] = 0x00;
    	cmd[6] = ((cmd[1] + cmd[2] + cmd[3] + cmd[4] + cmd[5])) & 0xFF;	printf ("check sum: 0x%02x\n", cmd[6]);
    	ret = write (fd, cmd, 7);
    	
    	sync();
    
    	tcsetattr(fd, TCSANOW, &oldtio);
    	close(fd);
    
        return 0;
    }
    


    展开全文
  • linux下简单易用的串口测试程序。 下载后编译如下: g++ -c SerialTest.cpp g++ -o SerialTest.out SerialTest.o
  • linux串口测试程序

    热门讨论 2010-11-21 19:05:26
    linux上的一个串口测试程序,可以修改里面的一些参数,适应自己的要求。
  • linux串口读写测试程序linux串口读写测试程序linux串口读写测试程序
  • 串口测试设置: stty -F /dev/ttyS0 speed 115200 cs8 -parenb -cstopb -echo cs8 ///////// 8bit data ////// -parenb /////// clean 校验位, 无校验 /////// -cstopb ///// 清除2 bit stop indicating bit, 1bit ...

    串口测试设置:
    stty -F /dev/ttyS0 speed 115200 cs8 -parenb -cstopb  -echo
    cs8          / 8bit data //
    -parenb   /// clean 校验位, 无校验 ///
    -cstopb   / 清除2 bit stop indicating bit,  1bit stop
    -echo      /// 关掉终端回显 //

    开两个命令终端串口分别是发送与接收:
    Terminal A: cat /dev/ttyS0  
    Terminal B: echo llllllllllll >/dev/ttyS0
     

    如果了解全部故事请下载pdf文档:
    https://download.csdn.net/download/bzhao/1250537

    展开全文
  • linux串口测试例程

    2019-06-25 11:44:33
    #例程有两种基本用法 ...##二、用电脑的串口助手进行收发测试 1、将开发板待测串口和电脑连接起来(用USB转串口连接板) 2、开发板运行例程(循环读取串口内容并回传) $ ./uart_test /dev/ttyS1 3...

    例程有两种基本用法

    一、短接tx rx,自发自收

    短接开发板待测串口的tx和rx,运行如下例程,

    $ ./uart_test  /dev/ttyS1  "ti is loop test"
    

    二、用电脑的串口助手进行收发测试

    1、将开发板待测串口和电脑连接起来(用USB转串口连接板)
    2、开发板运行例程(循环读取串口内容并回传)

    $ ./uart_test  /dev/ttyS1
    

    3、电脑串口助手打开对应的串口,发送任意数据,查看返回结果。

    使用全志的A64开发板实测,write发送字节个数几乎没有限制,一次就完成。read一次最多读32个字节。

    例程源码如下

    /*
     *	串口测试例程
     *  需要传参串口的设备文件,如/dev/ttyS2
     *  若打开串口成功,会循环读取串口读到的内容,然后回传
     */
     
    #include <stdio.h>      /*标准输入输出定义*/
    #include <stdlib.h>     /*标准函数库定义*/
    #include <string.h>
    #include <unistd.h>     /*Unix标准函数定义*/
    #include <sys/types.h>  /**/
    #include <sys/stat.h>   /**/
    #include <fcntl.h>      /*文件控制定义*/
    #include <termios.h>    /*PPSIX终端控制定义*/
    #include <errno.h>      /*错误号定义*/
    #include <sys/time.h>
    
    /*
     * %  0x25
     * ;  0x3B
     * +  0x2B
     * ?  0x3F
     */
    
    #define DEF_BAUD	115200
    #define SPEED_CNT	5
    #define BUF_SIZE	100
    
    /*用来接收轨道数据*/
    char buffer[BUF_SIZE];
    
    int speed_arr[SPEED_CNT] = {
    	B9600, B19200, B38400, 
    	B57600,	B115200
    };
    
    int name_arr[SPEED_CNT] = {
    	9600, 19200, 38400,
    	57600, 115200
    };
    
    /**
    *@brief  设置串口通信速率
    *@param  fd     类型 int  打开串口的文件句柄
    *@param  speed  类型 int  串口速度
    *@return  0 success or -1 err
    */
    int set_speed(int fd, int speed)
    {
    	int i;
    	int status;
    	struct termios opt;
    	
    	tcgetattr(fd, &opt);
    
    	for (i= 0; i<SPEED_CNT; 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 set_speed");
    				return -1;
    			}
    			
    			return 0;
         	}
    		/*清空所有正在发生的IO数据*/
    		tcflush(fd, TCIOFLUSH);
       }
       
    	printf("Cannot find suitable speed\n");
    	return -1;
    }
    
    /**
    *@brief   设置串口数据位,停止位和效验位
    *@param  fd     类型  int  打开的串口文件句柄*
    *@param  databits 类型  int 数据位   取值 为 7 或者8*
    *@param  stopbits 类型  int 停止位   取值为 1 或者2*
    *@param  parity  类型  int  效验类型 取值为N,E,O,,S
    *@return  0 success or -1 err
    */
    int set_parity(int fd, int databits, int stopbits, int parity)
    {
    
    	struct termios options;
    	if (tcgetattr(fd, &options) != 0)
    	{
    		perror("tcgetattr");
    		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 */
    			options.c_iflag &= ~(ICRNL|IGNCR);
    			options.c_lflag &= ~(ICANON );
    			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;
    
    	/* 若以O_NONBLOCK 方式open,这两个设置没有作用,等同于都为0 */
    	/* 若非O_NONBLOCK 方式open,具体作用可参考其他博客,关键词linux VTIME */
        options.c_cc[VTIME] = 10; // 1s
        options.c_cc[VMIN] = 0; 
    
    	/* 清空正读的数据,且不会读出 */
    	tcflush(fd,TCIFLUSH); 
    	
    	/*采用原始模式通讯*/
    	options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    	options.c_oflag &= ~OPOST;
    	
    	/*解决发送0x0A的问题*/
    	// options.c_iflag &= ~(INLCR | ICRNL | IGNCR);
    	// options.c_oflag &= ~(ONLCR | OCRNL | ONOCR | ONLRET);
    
    	/* Update the options and do it NOW */
    	if (tcsetattr(fd, TCSANOW, &options) != 0)
      	{
      		perror("SetupSerial 3");
    		return -1;
    	}
    
    	return 0;
    }
    
    /**
    
    *@breif 	main()
    
    */
    int main(int argc, char **argv)
    {
    	int fd;
    	int ret = -1;
    	const char *dev = NULL;
    	const char *test_string = NULL;
    	char *p_buffer = NULL;
    	int nread = 0;
    	int nwrite = 0;
    	
    	/* 1、检测传参 */
    	if (argc < 2 || argc > 3 ) {
    		printf("Usage:%s dev_name [self_loop_test_string]\n", argv[0]);
    		exit(1);
    	}
    	dev = argv[1];
    	if (NULL != argv[2]) {
    		if (strlen(argv[2]) <= BUF_SIZE) {
    			test_string = argv[2];
    		} else {
    			printf("self_loop_test_string must be smaller than %d.\n", BUF_SIZE);
    			return 0;
    		}
    	}
    	
    	/* 2、打开串口 */
    	fd = open(dev, O_RDWR | O_NOCTTY | O_NONBLOCK);
    	if (-1 == fd) {
    		printf("Cannot open %s:%s\n", dev, strerror(errno));
    		exit(1);
    	}
    	printf("==== open %s success ====\n", dev);
    	
    #if 1
    	/* 3、初始化设备 */
    	if (-1 == set_speed(fd, DEF_BAUD)) {
    		printf("Cannot set baudrate to 115200\n");
    		close(fd);
    		exit(1);
    	}
    	
      	if (-1 == set_parity(fd, 8, 1, 'N')) {
        	printf("Set Parity Error\n");
    		close(fd);
        	exit(1);
      	}
    #endif
    
    	if (NULL != test_string) {
    		/*开始自发自收测试*/
    		/* 写串口 */
    		do {
    			nwrite = write(fd, test_string, strlen(test_string));
    		} while(nwrite <= 0);
    		printf("send %d bytes data.\n", nwrite);
    
    		/* 清空buffer */
    		memset(buffer, 0, BUF_SIZE);
    		p_buffer = buffer;
    		nread = 0;
    
    		/* 读串口 */
    		do {
    			ret = read(fd, p_buffer, 64);
    			if (ret > 0) {
    				printf("read %d bytes data:%s\n", ret, p_buffer);
    				p_buffer += ret;
    				nread += ret;
    			}
    		} while(nread < nwrite);
    		printf("all read %d bytes data:%s\n", nread, buffer);
    		printf("====      test %s      ====\n", (0 == strcmp(buffer, test_string)) ? "success." : "error!!!");
    
    		close(fd);
    		return 0;
    	}
    
    	/*开始测试*/
    	/*循环读取并回写串口内容*/
    	printf("start read and pass back\n");
    	while(1) {
    		/* 清空buffer */
    		memset(buffer, 0, BUF_SIZE);
    		/* 读串口 */
    		nread = read(fd, buffer, 64);
    		if(nread > 0) {
    			printf("read %d bytes.\n", nread);
    			do {
    				ret = write(fd, buffer, nread);
    			} while(ret <= 0);
    
    			printf("write %d bytes.\n", ret);
    		}
    
    		//printf("block test.\n");
    	}
    	
    	close(fd);
    	
    	return 0;
    }
    
    展开全文
  • Linux串口测试程序及使用总结

    千次阅读 2018-12-28 22:31:25
    本程序通过传参的形式,指定串口设备节点和波特率,将串口接收到的数据原模原样的再发送出去,用来测试串口工作是否正常。同时该示例程序也为以后linux使用串口时做参考。 如下代码亲测可用,由于使用了线程循环读...

    参考博客:https://blog.csdn.net/w282529350/article/details/7378388

    本程序通过传参的形式,指定串口设备节点和波特率,将串口接收到的数据原模原样的再发送出去,用来测试串口工作是否正常。同时该示例程序也为以后linux使用串口时做参考。

    如下代码亲测可用,由于使用了线程循环读数据存放到串口缓冲区,编译时需要链接-lpthread库 。

    //串口相关的头文件
    #include<stdio.h>      /*标准输入输出定义*/
    #include<stdlib.h>     /*标准函数库定义*/
    #include<unistd.h>     /*Unix 标准函数定义*/
    #include <sys/ioctl.h>
    #include<sys/types.h>
    #include<sys/stat.h>
    #include<fcntl.h>      /*文件控制定义*/
    #include<termios.h>    /*PPSIX 终端控制定义*/
    #include<errno.h>      /*错误号定义*/
    #include<string.h>
    #include<pthread.h>
    #include <signal.h>
    
    
    //宏定义
    #define FALSE  -1
    #define TRUE   0
    #define SERIAL_BUFF_MAX_LEN 1024  /*串口缓冲区大小  1K */
    #define SERIAL_DEVICE_NAME "/dev/ttyHSL0"
    
    
    unsigned char serial_rx_buff[SERIAL_BUFF_MAX_LEN]={0};  //接受缓冲区
    int baudrate = -1; //波特率
    int serial_fd = -1;
    static int rx_start = 0;
    static int rx_end = 0;
    static int terminate = 0;
    void sig_handler(int signo)			//sig_handler:信号处理函数
    {
    	switch(signo)
    	{
    		case SIGINT:
    			printf("\nreceived SIGINT\n");
    			terminate = 1;
    			break;
    		default:
    			break;
    	}
    }
    
    /*******************************************************************
    * 名称:                  UART0_Open
    * 功能:                打开串口并返回串口设备文件描述
    * 入口参数:        fd    :文件描述符     port :串口号(ttyS0,ttyS1,ttyS2)
    * 出口参数:        正确返回为1,错误返回为0
    *******************************************************************/
    int UART0_Open(const char* port)
    {
    
        int fd = open(port, O_RDWR|O_NOCTTY|O_NDELAY);
        if( FALSE == fd )
        {
            perror("Can't Open Serial Port");
            return FALSE;
        }
    	
        //恢复串口为阻塞状态
        if(fcntl(fd, F_SETFL, 0) < 0)
        {
            printf("fcntl failed!\n");
            return(FALSE);
        }
        else
        {
            printf("fcntl=%d\n",fcntl(fd, F_SETFL,0));
        }
    	
        //测试是否为终端设备
        if(0 == isatty(STDIN_FILENO))
        {
            printf("standard input is not a terminal device\n");
            return(FALSE);
        }
        else
        {
            printf("Serial init success! fd = %d\n",fd);
        }
        return fd;
    }
    /*******************************************************************
    * 名称:                UART0_Close
    * 功能:                关闭串口并返回串口设备文件描述
    * 入口参数:        fd    :文件描述符     port :串口号(ttyS0,ttyS1,ttyS2)
    * 出口参数:        void
    *******************************************************************/
    
    void UART0_Close(int fd)
    {
        close(fd);
    }
    
    /*******************************************************************
    * 名称:                UART0_Set
    * 功能:                设置串口数据位,停止位和效验位
    * 入口参数:        fd        串口文件描述符
    *                              speed     串口速度
    *                              flow_ctrl   数据流控制
    *                           databits   数据位   取值为 7 或者8
    *                           stopbits   停止位   取值为 1 或者2
    *                           parity     效验类型 取值为N,E,O,,S
    *出口参数:          正确返回为1,错误返回为0
    *******************************************************************/
    int UART0_Set(int fd,int speed,int flow_ctrl,int databits,int stopbits,int parity)
    {
    
        int   i;
        int   status;
        int   speed_arr[] = {B2000000,B1500000,B1152000,B1000000,B921600,B576000,B500000,
    						 B460800,B230400, B115200, B19200, B9600, B4800, B2400, B1200, B300};
    	
        int   name_arr[] = {2000000,1500000,1152000,1000000,921600,576000,500000,460800,230400,
    		                115200,19200,9600,4800,2400,1200,300};
    
        struct termios options;
    
        /*tcgetattr(fd,&options)得到与fd指向对象的相关参数,并将它们保存于options,该函数还可以测试配置是否正确,该串口是否可用等。若调用成功,函数返回值为0,若调用失败,函数返回值为1.
        */
        if( tcgetattr( fd,&options)  !=  0)
        {
            perror("SetupSerial 1");
            return(FALSE);
        }
    	int seted_flag = 0;
        //设置串口输入波特率和输出波特率
        for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++)
        {
        	printf("------ baudrate Speed = %d\n",name_arr[i]);
            if  (speed == name_arr[i])
            {
                cfsetispeed(&options, speed_arr[i]);
                cfsetospeed(&options, speed_arr[i]);
    			seted_flag = 1;
    			printf("Setting baudrate!!\n");
    			break;
            }
        }
    	
    	if(seted_flag == 0)
    	{
    		printf("Unknow baudrate!!\n");
    		return FALSE;
    	}
        //修改控制模式,保证程序不会占用串口
        options.c_cflag |= CLOCAL;
        //修改控制模式,使得能够从串口中读取输入数据
        options.c_cflag |= CREAD;
    
        //设置数据流控制
        switch(flow_ctrl)
        {
    
        case 0 ://不使用流控制
            options.c_cflag &= ~CRTSCTS;
            break;
    
        case 1 ://使用硬件流控制
            options.c_cflag |= CRTSCTS;
            break;
        case 2 ://使用软件流控制
            options.c_cflag |= IXON | IXOFF | IXANY;
            break;
        }
        //设置数据位
    
        //屏蔽其他标志位
        options.c_cflag &= ~CSIZE;
        switch (databits)
        {
        case 5    :
            options.c_cflag |= CS5;
            break;
        case 6    :
            options.c_cflag |= CS6;
            break;
        case 7    :
            options.c_cflag |= CS7;
            break;
        case 8:
            options.c_cflag |= CS8;
            break;
        default:     fprintf(stderr,"Unsupported data size\n");
            return (FALSE);
        }
        //设置校验位
        switch (parity)
        {
        case 'n':
        case 'N': //无奇偶校验位。
            options.c_cflag &= ~PARENB;
            options.c_iflag &= ~INPCK;
            break;
        case 'o':
        case 'O'://设置为奇校验
            options.c_cflag |= (PARODD | PARENB);
            options.c_iflag |= INPCK;
            break;
        case 'e':
        case 'E'://设置为偶校验
            options.c_cflag |= PARENB;
            options.c_cflag &= ~PARODD;
            options.c_iflag |= INPCK;
            break;
        case 's':
        case 'S': //设置为空格
            options.c_cflag &= ~PARENB;
            options.c_cflag &= ~CSTOPB;
            break;
        default:
            fprintf(stderr,"Unsupported parity\n");
            return (FALSE);
        }
        // 设置停止位
        switch (stopbits)
        {
        case 1:
            options.c_cflag &= ~CSTOPB; break;
        case 2:
            options.c_cflag |= CSTOPB; break;
        default:
            fprintf(stderr,"Unsupported stop bits\n");
            return (FALSE);
        }
    
        //修改输出模式,原始数据输出
        options.c_oflag &= ~OPOST;
    
        options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
        //options.c_lflag &= ~(ISIG | ICANON);
    
        //设置等待时间和最小接收字符
        options.c_cc[VTIME] = 1; /* 读取一个字符等待1*(1/10)s */
        options.c_cc[VMIN] = 1; /* 读取字符的最少个数为1 */
    
        //如果发生数据溢出,接收数据,但是不再读取 刷新收到的数据但是不读
        tcflush(fd,TCIFLUSH);
    
        //激活配置 (将修改后的termios数据设置到串口中)
        if (tcsetattr(fd,TCSANOW,&options) != 0)
        {
            perror("com set error!\n");
            return (FALSE);
        }
        return (TRUE);
    }
    /*******************************************************************
    * 名称:                UART0_Init()
    * 功能:                串口初始化
    * 入口参数:        fd       :  文件描述符
    *               speed  :  串口速度
    *                              flow_ctrl  数据流控制
    *               databits   数据位   取值为 7 或者8
    *                           stopbits   停止位   取值为 1 或者2
    *                           parity     效验类型 取值为N,E,O,,S
    *
    * 出口参数:        正确返回为1,错误返回为0
    *******************************************************************/
    int UART0_Init(int fd, int speed,int flow_ctrl,int databits,int stopbits,int parity)
    {
    	return UART0_Set(fd,speed,flow_ctrl,databits,stopbits,parity);
    }
    
    /*******************************************************************
    * 名称:                  UART0_Recv
    * 功能:                接收串口数据
    * 入口参数:        fd                  :文件描述符
    *                              rcv_buf     :接收串口中数据存入rcv_buf缓冲区中
    *                              data_len    :一帧数据的长度
    * 出口参数:        正确返回为1,错误返回为0
    *******************************************************************/
    int UART0_Recv(int fd, char *rcv_buf,int data_len)
    {
        int len,fs_sel;
        fd_set fs_read;
    
        struct timeval time;
    
        FD_ZERO(&fs_read);
        FD_SET(fd,&fs_read);
    
        time.tv_sec = 10;
        time.tv_usec = 0;
    
    
        //使用select实现串口的多路通信
        fs_sel = select(fd+1,&fs_read,NULL,NULL,&time);
    //  printf("fs_sel = %d\n",fs_sel);
        if(fs_sel)
        {
            len = read(fd,rcv_buf,data_len);
            return len;
        }
        else
        {
            return FALSE;
        }
    }
    /********************************************************************
    * 名称:UART0_Send
    * 功能:   发送数据
    * 入口参数:     fd:文件描述符
    *           send_buf    :存放串口发送数据
    *           data_len    :一帧数据的个数
    * 出口参数:        正确返回为1,错误返回为0
    *******************************************************************/
    int UART0_Send(int fd, char *send_buf,int data_len)
    {
        int len = 0;
    
        len = write(fd,send_buf,data_len);
        if (len == data_len )
        {
            return len;
        }
        else
        {
    
            tcflush(fd,TCOFLUSH);
            return FALSE;
        }
    
    }
    void close_console() //将调试串口转换为工作串口
    {
        printf("change console!!\n");
        int fp = open("/dev/ttyAMA1",O_RDONLY); // 改变console
        ioctl(fp,TIOCCONS);
        close(fp);
    }
    
    
    void *Serial_Rx_Task(void *argv)
    {
    	int len = 0;
    	while (1) //循环接收数据
        {
        	unsigned char rx = 0;
    		len = UART0_Recv(serial_fd, &rx,1); //接收一个字节数据到缓冲区
            if(len == 1)
            {
            	if( (rx_end + 1)%SERIAL_BUFF_MAX_LEN == rx_start )   //缓冲区满则丢掉数据
    				continue;
            	serial_rx_buff[rx_end++] = rx;
    			rx_end %= SERIAL_BUFF_MAX_LEN;
            }
        }
    }
    
    int Serial_Avaliable()
    {
    	int len = 0;
    	len = rx_end - rx_start;
    	if(len < 0)
    		len += SERIAL_BUFF_MAX_LEN;
    	return len;
    }
    
    char Serial_Read()
    {
    	unsigned char ch = 0;
    	if(rx_end == rx_start)   //缓冲区无数据
    		return -1;
    	ch = serial_rx_buff[rx_start++];
    	rx_start %= SERIAL_BUFF_MAX_LEN;
    	return ch;
    }
    
    int Serial_Write(char *str,int  len)
    {
    	if(str == NULL)
    		return FALSE;
    	return  UART0_Send(serial_fd,str,len);
    }
    
    int Serial_Task_Init(char *device_name)
    {
    	int err = 0;
    	//close_console(); //将调试串口转换为工作串口
    	serial_fd = UART0_Open(device_name); //打开串口,返回文件描述符
    	if(serial_fd < 0)
    		return -1;
    
    	if(FALSE == UART0_Init(serial_fd,baudrate,0,8,1,'N'))
    	{	
    		printf("Error: UART0_Init failed!\n");
    		return FALSE;
    	}
    	pthread_t p_thread;
    	int ret = 0;
    	ret = pthread_create(&p_thread, NULL, Serial_Rx_Task, NULL);
        if(ret != 0)
        {
        	printf("Error: Create Serial_Rx_Task thread failed!\n");
    		return -1;
        }
    	
    	//UART0_Close(serial_fd);
    	return TRUE;
    }
    
    
    int main(int argc, char *argv[])
    {
    	char buff[1024] = {0};
    	int index =  0;
        if(argc != 3)
        {
            printf("please point device and speed!!\nExample:./test /dev/ttyHSL 921600");
        }
    	baudrate = atoi(argv[2]);
    	signal(SIGINT, sig_handler);
    	if(FALSE == Serial_Task_Init(argv[1]))
    	{
    		printf("Error: Serial_Task_Init failed!\n");
    		return FALSE;
    	}
    	while(!terminate)
    	{
    		while(Serial_Avaliable() > 0)
    		{
    			buff[index++] =  Serial_Read();
        	}
    		if(index != 0)
    		{
    			buff[index] = '\0';
    			printf("read<---:%s\n",buff);
    			Serial_Write(buff,index);
    			printf("write--->:%s\n",buff);
    			if( !strcmp(buff,"quit") ) // 如果是退出命令
    			{
    				printf("Rec quit cmd!!\n");
    				UART0_Close(serial_fd);
    				return 0;
    			}
    			index = 0;
    		}
    	}
    	UART0_Close(serial_fd);
    	printf("Exit uart test!!\n");
    	return 0;
    }
    

    使用过程中遇到的问题:

    1、struct termios 结构体说明:

    http://blog.chinaunix.net/uid-618047-id-2085318.html

    2、发送出去的串口数据中0x0D被自动替换成了0x0A。

    引起原因:串口设置中c_oflag中存在从NL-CR和CR-NL的映射。

    后面采用如下设置屏蔽:options.c_oflag &= ~(ONLCR | OCRNL);   //防止输出映射处理

    之后又查询了一些串口参数配置相关的资料,发现这篇博客总结得比较详细,供大家参考和自己备忘:https://blog.csdn.net/liudsl/article/details/79266003

    3、接收到的串口数据中0x0D被自动映射成了0x0A。

    引起原因:串口设置中c_iflag中未关闭NL-CR或CR-NL的映射。

    解决办法:添加如下代码

    options.c_iflag &= ~(INLCR|ICRNL);  //关闭字符映射
    options.c_iflag &= ~(IXON);         //关闭流控字符

     

    展开全文
  • linux 串口测试程序

    千次阅读 2018-06-07 16:42:04
    头文件: #ifndef _UART_H_ #define _UART_H_ #include #include #include /* baud rate ============= B600 B1200 B9600 B19200 B38400 B57600 B115200 ...配置串口头文件就好了
  • linux串口测试程序

    2018-10-15 11:49:45
    linux串口测试程序,收发不正常时检查配置奇偶校验的cflag和iflag是否正确配置
  • Linux串口测试应用程序

    千次阅读 2016-01-25 15:36:09
    1 Linux终端(串口) 210开发板有4个串口 2440开发板有3个串口 在2440开发板中三个串口设备对应如下  串口名字 主设备号 次设备号 s3c2410_serial0 204 64 s3c2410_serial1
  • Linux232串口测试程序

    2017-12-06 10:14:00
    能够在Linux上直接编译运行,测试RS232串口的发送与接收功能
  • 是基于嵌入式linux串口终端下源码,里面有发送和接收两个源文件,并且源码里面最重要还有一份说明文档等等,源码经测试,直接可编译使用
  • Linux串口测试工具简单程序展示

    千次阅读 2014-06-04 09:34:48
    Linux串口测试工具网上常见的版本都看起来比较烦琐,下面是一个简单一点的,这个程序功能是收到10个字节后会发前7个字节,如果所发的数据的第一个字节是9则退出。   /* rs232_send.c*/ #include #include #...
  • Linux串口测试工具简单程序代码解析

    千次阅读 2013-05-13 16:59:00
    Linux串口测试工具简单程序代码解析 2010-05-28 10:53 佚名 我要评论(0) 字号:T |T 网上常见的版本都看起来比较烦琐,今天介绍是一个简单一点的,和大家一起学习了解,以下是程序的具体代码 AD:2013...
  • linux环境下的串口收发两端测试程序 c语言实现
  • linux串口驱动的自发自收测试程序。测试可用。操作方便,运行平台在linux系统平台下,操作也很简单。可以当做串口通用模板。
  • 嵌入式Linux串口操作接口及测试代码
  • Linux 串口和USB转串口操作代码,能用于at指令测试, 可以测试ESP32和ESP8266
  • 附件是linux下的基于线程的串口测试程序,并发测试,可做压力测试。linux c语言源码。感兴趣的可以研究下
  • Linux tty串口测试程序

    千次阅读 2017-05-12 18:34:52
    在程序中,很容易配置串口的属性,这些属性定义在结构体struct termios中。...关于termios的详细介绍,可以另行查资料,或者参考:详解Linux下的串口通讯开发:http://blog.itpub.NET/24790158/viewspace-10411
  • linux串口程序,实现串口回环自发自收,测试串口
  • Linux 串口通信

    2018-07-03 11:48:13
    Linux C++串口通信技术,代码完整,附带编译说明。在centos7.4上已经测试过了
  • linux 串口程序

    2010-06-24 17:14:33
    linux下串口通讯,linux串口测试程序
  • linux测试串口的简单方法

    千次阅读 2007-10-07 16:38:00
    刚跑去linux下还不怎么习惯,相信会越来越好的需要2,3脚端接在一终端(1窗口)中输入cat /dev/ttyS0在另外一终端(2窗口)中输入echo hello>/dev/ttyS0然后在1窗口中就能看见 hello 了 这样就说明串口好使了,...
  • linux 串口编程

    2012-04-29 17:29:38
    linux平台下串口编程 包括串口波特率等设置 测试通过

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 24,519
精华内容 9,807
关键字:

linux串口测试方法

linux 订阅