usb转串口的通信demo

发布时间 2023-12-29 16:37:27作者: uagvdu

正文之前: 

  经过这段时间的狠查资料,很感谢那些愿意分享技术的大佬们,像他们学习;

借鉴链接:https://blog.csdn.net/morixinguan/article/details/80898172

 

直接源码demo: 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <asm/termios.h>




//设置停止位
static void set_stopbit (struct termios *opt, const char *stopbit)
{
    if (0 == strcmp (stopbit, "1")) {
        opt->c_cflag &= ~CSTOPB; /* 1 stop bit */
    }	else if (0 == strcmp (stopbit, "1")) {
        opt->c_cflag &= ~CSTOPB; /* 1.5 stop bit */
    }   else if (0 == strcmp (stopbit, "2")) {
        opt->c_cflag |= CSTOPB;  /* 2 stop bits */
    } else {
        opt->c_cflag &= ~CSTOPB; /* 1 stop bit */
    }
}


//设置校验位
static void set_parity (struct termios *opt, char parity)
{
    switch (parity) {
    case 'N':                  /* no parity check */
        opt->c_cflag &= ~PARENB;
        break;
    case 'E':                  /* even */
        opt->c_cflag |= PARENB;
        opt->c_cflag &= ~PARODD;
        break;
    case 'O':                  /* odd */
        opt->c_cflag |= PARENB;
        opt->c_cflag |= ~PARODD;
        break;
    default:                   /* no parity check */
        opt->c_cflag &= ~PARENB;
        break;
    }
}


//设置数据位
static void set_data_bit(struct termios *opt, unsigned int databit)
{
    opt->c_cflag &= ~CSIZE;
    switch (databit) {
    case 8:
        opt->c_cflag |= CS8;
        break;
    case 7:
        opt->c_cflag |= CS7;
        break;
    case 6:
        opt->c_cflag |= CS6;
        break;
    case 5:
        opt->c_cflag |= CS5;
        break;
    default:
        opt->c_cflag |= CS8;
        break;
    }
}



//set 波特率
static void set_baudrate (struct termios *opt, unsigned int baudrate)
{
	cfsetispeed(opt, baudrate);
	cfsetospeed(opt, baudrate);
}


static int set_serial(int fd,struct termios* opt)
{
	set_baudrate(opt,9200);
	opt->c_cflag 		 |= CLOCAL | CREAD;

	set_data_bit(opt,8);
	set_parity(opt,'N');
	set_stopbit(opt, "1");

	//其他设置
	opt->c_oflag 		 = 0;
        opt->c_lflag            	|= ICANON;
        opt->c_oflag          	&= ~OPOST;
	opt->c_cc[VTIME] = 0;  // 规范模式
	opt->c_cc[VMIN]  = 0;  // 规范模式

	tcflush (fd, TCIOFLUSH);

	return (tcsetattr (fd, TCSANOW, opt));

}

int main (int argc, char *argv[])
{
	int fd;
	int len, i,ret;
	char rbuf[1024]={0};;
	char wbuf[] = "hello!\n";    //此处的"\n"作用是让read每次收到数据就显示

	const char* DEV_NAME;
	//linux串口驱动的默认属性值(9600,8n1,无流控)
	
	struct termios termios_opt;

	//可读可写
#ifdef WRITE 
	 DEV_NAME =  "/dev/ttyACM0";           //A设备

#elif READ
	 DEV_NAME =  "/dev/ttyGS0";                //B设备
	
#endif

	fd = open(DEV_NAME, O_RDWR | O_NOCTTY);
	if(fd < 0) {
		perror(DEV_NAME);
		return -1;
	}

	//设置串口信息
	ret = set_serial(fd, &termios_opt);
	printf("set serial:%d\n",ret);


#ifdef WRITE
	len = write(fd, wbuf, sizeof(wbuf));
	if (len < 0) {
		printf("write data error \n");
	}
	printf("write data success: %d \n",len);
	

#elif READ
	while(1){
		tcflush (fd, TCIOFLUSH);                         //清空串口的read缓冲区-底层
		memset(rbuf, 0, sizeof(rbuf));                 //置0, ----应用层,避免上次buf数据干扰
		len = read(fd, rbuf, sizeof(rbuf));
		if (len < 0) {
			printf("read error \n");
			return -1;
		}

		printf("%d: %s", len, rbuf);
	}

#endif

	close(fd);

	return(0);
}