【elfboard linux开发板】6. uart 实现串口收发功能

1. 硬件连线

准备一个usb转ttl的模块, 对应的引脚的连接分为:
VCC - 3V3; GND - GND; RXD - TXD2; TXD - RXD2 ;
连接方式如下图,并且将ttl模块连接至电脑usb口:
【elfboard linux开发板】6. uart 实现串口收发功能_第1张图片

2.发送功能实现(uart_send.c)

a. 初始化说明
open终端文件时,带上如下参数 O_RDWR, O_NOCTTY, O_NONBLOCK;

b. 程序说明:

编译生成uart_send_arm发送到开发板:

$CC uart_send.c -o uart_send_arm
scp uart_send_arm [email protected]:/home/root/
ssh  [email protected]

使用方式:
./uart_send_arm tty设备号 -b 波特率 -w 字符

补充说明:
发送的字符列表需要全部先置0,以防止乱码
需要使用tcflush(fd,TCIOFLUSH)将前面没读取和传输完的列表清空;

c. 实现

#include 
#include 
#include 
#include 
#include 
#include 

#define tty_len 	1024
#define w_len		1024

int main(int argc,char*argv[]){
	if(argc<2|| strncmp(argv[1],"tty",3))
	{
		perror("请输入\"tty\"设备的参数\n");
		exit(1);
	}
	char dev[tty_len];
	char w_data[w_len];
	struct termios *tio = malloc(sizeof(struct termios));
	
	strcpy(dev, "/dev/");
	strcat(dev,argv[1]);
	
	int fd = open(dev, O_RDWR|O_NONBLOCK|O_NOCTTY);
	if(fd<1){
		perror("open 错误");
		exit(1);
	}
	printf("成功打开设备%s\n",dev);
	
	for(int i = 2;i<argc;i++)
	{
		// 参数 == -b : 输入波特率
		if(!strcmp(argv[i], "-b"))
		{
			i++;
			if(i >= argc){
				printf("-b 后要接波特率\n");
				exit(0);
			}
			switch(atol(argv[i])){
				case 115200:
					cfsetispeed(tio,B115200);
					cfsetospeed(tio,B115200);
					break;
				case 1200:
					cfsetispeed(tio,B1200);
					cfsetospeed(tio,B1200);
					break;
				case 4800:
					cfsetispeed(tio,B4800);
					cfsetospeed(tio,B4800);
					break;
				case 9600:
					cfsetispeed(tio,B9600);
					cfsetospeed(tio,B9600);
					break;
				default:
					cfsetispeed(tio,B9600);
					cfsetospeed(tio,B9600);
					break;
			}
		}
		// 参数 == -w : 输入需要发送的字符串
		if(!strcmp(argv[i],"-w"))
		{
			i++;
			if(i >= argc){
				printf("-w 后要接写入的字符串\n");
				exit(0);
			}
			memset(w_data,0,sizeof(w_data));
			strcpy(w_data,argv[i]);
		}
	}
	
	/*termios 配置*/
	// memset(tio,0,sizeof(&tio));
	bzero(tio,sizeof(struct termios));
	// c_cflag 用于控制终端设备的硬件设置
	tio->c_cflag |= CSIZE; 				// charater size mask
	tio->c_cflag |= CS8;
	tio->c_cflag &= ~(CSTOPB); 			//set one stop bit
	tio->c_cflag |= PARENB;	 			//enable parity generation on output
	tio->c_cflag |= PARODD;				//parity is odd	
	tio->c_cflag |= CLOCAL;				// ignore modem control lines
	tcflush(fd,TCIOFLUSH);
	if((tcsetattr(fd,TCSANOW,tio))<0)
	{
		perror("tcsetattr error");
		exit(1);
	}
	printf("设置termios成功\n");
	
	while(1){
		if(sizeof(w_data)<=0||write(fd,w_data,sizeof(w_data))< 0)
			continue;
		printf("write 成功\n");
		sleep(1);
	}
	free(tio);
	close(fd);
	return 0;
}

打开串口工具,将串口工具的串口、波特率、停止位、数据位、奇偶校验保持和程序中设置的一致,然后打开串口,接着在嵌入式Linux上启动程序;串口工具可以收到数据。
发送字符串的实现效果如下:
【elfboard linux开发板】6. uart 实现串口收发功能_第2张图片
【elfboard linux开发板】6. uart 实现串口收发功能_第3张图片

3. 接收功能实现(uart_receive.c)

a. 初始化补充说明
termios结构体中c_iflag的INPCK位需要被设置 : 使能输入校验码检测
termios_t->c_iflag |= INPCK;
termios中c_cflag中的CREAD位需要设置:
termios_t->c_cflag |= CREAD;

b. 具体程序

#include 
#include 
#include 
#include 
#include 
#include 

#define tty_len 1024
#define r_len           1024

int main(int argc,char*argv[]){
        if(argc<2|| strncmp(argv[1],"tty",3))
        {   
                perror("请输入\"tty\"设备的参数\n");
                exit(1);
        }
        char dev[tty_len];
        char r_data[r_len];
        struct termios *tio = malloc(sizeof(struct termios));
    
        strcpy(dev, "/dev/");
        strcat(dev,argv[1]);
    
        int fd = open(dev, O_RDWR|O_NONBLOCK|O_NOCTTY);
        if(fd<1){
                perror("open 错误");
                                exit(1);
        }
        printf("成功打开设备%s\n",dev);

        for(int i = 2;i<argc;i++)
        {
                // 参数 == -b : 输入波特率
                if(!strcmp(argv[i], "-b"))
                {
                        i++;
                        if(i >= argc){
                                printf("-b 后要接波特率\n");
                                exit(0);
                        }
                        switch(atol(argv[i])){
                                case 115200:
                                        cfsetispeed(tio,B115200);
                                        cfsetospeed(tio,B115200);
                                        break;
                                case 1200:
                                        cfsetispeed(tio,B1200);
                                        cfsetospeed(tio,B1200);
                                        break;
                                case 4800:
                                        cfsetispeed(tio,B4800);
                                                                                cfsetospeed(tio,B9600);
                                        break;
                                default:
                                        cfsetispeed(tio,B9600);
                                        cfsetospeed(tio,B9600);
                                        break;
                        }
                }
        }

        /*termios 配置*/
        // memset(tio,0,sizeof(&tio));
        bzero(tio,sizeof(struct termios));
        // c_cflag 用于控制终端设备的硬件设置
        tio->c_cflag |= CREAD;
        tio->c_cflag |= CSIZE;                          // charater size mask
        tio->c_cflag |= CS8;
        tio->c_cflag &= ~(CSTOPB);                      //set one stop bit
        tio->c_cflag |= PARENB;                         //enable parity generation on output
        tio->c_cflag |= PARODD;                         //parity is odd 
        tio->c_cflag |= CLOCAL;                         // ignore modem control lines

        tio->c_iflag |= INPCK;
        tcflush(fd,TCIOFLUSH);
        
        if((tcsetattr(fd,TCSANOW,tio))<0)
        {
                perror("tcsetattr error");
                exit(1);
        }
        printf("设置termios成功\n");

        int len_c;
        while(1){
                memset(r_data,0,sizeof(r_data));
                len_c = read(fd,r_data,sizeof(r_data));
                if(len_c < 0){
                        perror("read error");
                        continue;
                }else if(len_c > 0){
                        printf("%s",r_data);
                }
                sleep(1);
        }
        free(tio);
        close(fd);
        return 0;
}

                                        

                

c. 效果
嵌入式Linux上运行程序,然后在串口工具发送数据,嵌入式终端上收到发送的数据:
【elfboard linux开发板】6. uart 实现串口收发功能_第4张图片

【elfboard linux开发板】6. uart 实现串口收发功能_第5张图片

你可能感兴趣的:(linux,单片机)