imx6ul uart8路串口调试(代码)

 uart这里的调试要注意的是管脚的功能配置,需要更改设备树文件;

更改设备树文件:https://blog.csdn.net/cao849861802/article/details/111604277

其他问题:这里是操作的232的配置,如果想做485的最好用硬件来直接做485,因为我这边用软件尝试了几次都未成功。

#include <stdio.h>        //标准输入输出,如printf、scanf以及文件操作
#include <stdlib.h>        //标准库头文件,定义了五种类型、一些宏和通用工具函数
#include <unistd.h>        //定义 read write close lseek 等Unix标准函数
#include <sys/types.h>    //定义数据类型,如 ssiz e_t off_t 等
#include <sys/stat.h>    //文件状态
#include <fcntl.h>        //文件控制定义
#include <termios.h>    //终端I/O
#include <errno.h>        //与全局变量 errno 相关的定义
#include <getopt.h>        //处理命令行参数
#include <string.h>        //字符串操作
#include <time.h>        //时间
#include <sys/select.h>    //select函数


#include <sys/ioctl.h>
#include <net/if.h>
#include <pthread.h>


int uartfd[7];


int setOpt(int fd, int nSpeed, int nBits, int nParity, int nStop)
{
    struct termios newtio, oldtio;

    // 保存测试现有串口参数设置,在这里如果串口号等出错,会有相关的出错信息
    if (tcgetattr(fd, &oldtio) != 0)
    {
        perror("SetupSerial 1");
        return -1;
    }

    bzero(&newtio, sizeof(newtio));        //新termios参数清零
    newtio.c_cflag |= CLOCAL | CREAD;    //CLOCAL--忽略 modem 控制线,本地连线, 不具数据机控制功能, CREAD--使能接收标志
    // 设置数据位数
    newtio.c_cflag &= ~CSIZE;    //清数据位标志
    switch (nBits)
    {
        case 7:
            newtio.c_cflag |= CS7;
        break;
        case 8:
            newtio.c_cflag |= CS8;
        break;
        default:
            fprintf(stderr, "Unsupported data size\n");
            return -1;
    }
    // 设置校验位
    switch (nParity)
    {
        case 'o':
        case 'O':                     //奇校验
            newtio.c_cflag |= PARENB;
            newtio.c_cflag |= PARODD;
            newtio.c_iflag |= (INPCK | ISTRIP);
            break;
        case 'e':
        case 'E':                     //偶校验
            newtio.c_iflag |= (INPCK | ISTRIP);
            newtio.c_cflag |= PARENB;
            newtio.c_cflag &= ~PARODD;
            break;
        case 'n':
        case 'N':                    //无校验
            newtio.c_cflag &= ~PARENB;
            break;
        default:
            fprintf(stderr, "Unsupported parity\n");
            return -1;
    }
    // 设置停止位
    switch (nStop)
    {
        case 1:
            newtio.c_cflag &= ~CSTOPB;
        break;
        case 2:
            newtio.c_cflag |= CSTOPB;
        break;
        default:
            fprintf(stderr,"Unsupported stop bits\n");
            return -1;
    }
    // 设置波特率 2400/4800/9600/19200/38400/57600/115200/230400
    switch (nSpeed)
    {
        case 2400:
            cfsetispeed(&newtio, B2400);
            cfsetospeed(&newtio, B2400);
            break;
        case 4800:
            cfsetispeed(&newtio, B4800);
            cfsetospeed(&newtio, B4800);
            break;
        case 9600:
            cfsetispeed(&newtio, B9600);
            cfsetospeed(&newtio, B9600);
            break;
        case 19200:
            cfsetispeed(&newtio, B19200);
            cfsetospeed(&newtio, B19200);
            break;
        case 38400:
            cfsetispeed(&newtio, B38400);
            cfsetospeed(&newtio, B38400);
            break;
        case 57600:
            cfsetispeed(&newtio, B57600);
            cfsetospeed(&newtio, B57600);
            break;
        case 115200:
            cfsetispeed(&newtio, B115200);
            cfsetospeed(&newtio, B115200);
            break;
        case 230400:
            cfsetispeed(&newtio, B230400);
            cfsetospeed(&newtio, B230400);
            break;
        default:
            printf("\tSorry, Unsupported baud rate, set default 9600!\n\n");
            cfsetispeed(&newtio, B9600);
            cfsetospeed(&newtio, B9600);
            break;
    }
    // 设置read读取最小字节数和超时时间
    newtio.c_cc[VTIME] = 1;     // 读取一个字符等待1*(1/10)s
    newtio.c_cc[VMIN] = 1;        // 读取字符的最少个数为1

    tcflush(fd,TCIFLUSH);         //清空缓冲区
    if (tcsetattr(fd, TCSANOW, &newtio) != 0)    //激活新设置
    {
	perror("SetupSerial 3");
	return -1;
    }
    printf("Serial set done!\n");
    return 0;
}



void uartFdCreate()
{
	int i = 0;
	int ret = 0;
	char buf[64];
	
	for(i = 0; i < 7; i++)
	{
		memset(buf,0,sizeof(buf));
		sprintf(buf,"/dev/ttymxc%d",i+1);
		uartfd[i] = open(buf, O_RDWR | O_NOCTTY | O_NDELAY);
		if(uartfd[i] < 0)
		{
			printf("%s open failed ret = %d\r\n",buf,uartfd[i]);
			uartfd[i] = -1;
			continue;
		}
		
		ret = fcntl(uartfd[i], F_SETFL, 0);
		if(ret < 0)
		{
			printf("fcntl failed ret = %d\r\n",ret);
			close(uartfd[i]);
			uartfd[i] = -1;
			continue;
		}
		
		if (isatty(uartfd[i]) == 0)
		{
			printf("standard input is not a terminal device\r\n");
			close(uartfd[i]);
			uartfd[i] = -1;
			continue;	
		}
		
		if (setOpt(uartfd[i], 115200, 8, 'N', 1)== -1)    //设置8位数据位、1位停止位、无校验
		{
			printf("Set opt Error\r\n");
			close(uartfd[i]);
			uartfd[i] = -1;
			continue;				
		}
		
		tcflush(uartfd[i], TCIOFLUSH);    //清掉串口缓存
		fcntl(uartfd[i], F_SETFL, 0);    //串口阻塞
		
		printf("uart%d fd create ok,fd = %d\r\n",i+1,uartfd[i]);
	}
}

void *uartrecv(void *arg)
{
	int i = 0;
	unsigned int maxfd = 0;
	unsigned int ret = 0;
	struct timeval waittime;
	fd_set rfd;
	char buf[128];
	
	printf("uart recv task stat****\r\n");
	while(1)
	{
		FD_ZERO(&rfd);
		
		for(i = 0; i < 7; i++)
		{
			if(uartfd[i] != -1)
			{
				FD_SET(uartfd[i],&rfd);
				if(maxfd < uartfd[i])
				{
					maxfd = uartfd[i];
				}
			}
		}
		
		waittime.tv_sec = 1;
		waittime.tv_usec = 0;
		ret = select(maxfd + 1,&rfd,NULL,NULL,&waittime);
		if(0 >= ret)
		{
			continue;
		}
		
		for(i = 0; i < 7; i++)
		{
			if(FD_ISSET(uartfd[i],&rfd))
			{
				memset(buf,0,sizeof(buf));
				read(uartfd[i],buf,sizeof(buf) - 1);
				printf("uart%d recv buf = %s\r\n",i+1,buf);
			}
		}
	}
}




void main()
{
	int i = 0;
	int retlen = 0;
	char buf[128];
	pthread_t ntid;
	
	uartFdCreate();
	pthread_create(&ntid, NULL, uartrecv, NULL);
	while(1)
	{
		for(i = 0 ; i < 7; i++)
		{
			if(uartfd[i] != -1)
			{
				memset(buf,0,sizeof(buf));
				sprintf(buf,"this is uart%d send date",i+ 1);
				retlen = write(uartfd[i],buf,strlen(buf));
				if(retlen != strlen(buf))
				{
					tcflush(uartfd[i],TCOFLUSH);
				}
			}
		}	
		sleep(5);
	}
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值