Windows下 串口编程 代码

粗略的对windows下串口的编程写了常用的封装函数(包含打开 关闭 初始化 读写),测试过的


HANDLE CUART::uart_open(const char *uart_str) {
	HANDLE hCom1 = CreateFile(uart_str,
		GENERIC_READ | GENERIC_WRITE, //允许读和写
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL,
		OPEN_EXISTING, //打开而不是创建
		0,
		NULL);

	if (hCom1 == INVALID_HANDLE_VALUE) {
		printf("打开COM失败!\n");
		return 0;
	}
	//FILE_SHARE_READ| FILE_SHARE_WRITE
	printf("COM打开成功!\n");
	SetupComm(hCom1, 4096, 4096); //输入缓冲区和输出缓冲区的大小都是4096
	return hCom1;
}

int CUART::uart_init(HANDLE uart_fd, DWORD BAUD, BYTE DATABITS, BYTE PARITY, BYTE STOPBIT) {
	COMMTIMEOUTS TimeOuts;
	//设定读超时 间隔超时是指读取两个字符之间的延时,总超时是指读写操作总共花费的时间。写操作只支持总超时,读操作两种超时都支持
	// 单位为ms
	TimeOuts.ReadIntervalTimeout = 0;         //读间隔超时
	TimeOuts.ReadTotalTimeoutMultiplier = 10; //读时间系数
	TimeOuts.ReadTotalTimeoutConstant = 5000; //读时间常量
	//设定写超时
	TimeOuts.WriteTotalTimeoutMultiplier = 10; //写时间系数
	TimeOuts.WriteTotalTimeoutConstant = 5000; //写时间常量
	SetCommTimeouts(uart_fd, &TimeOuts);       //设置超时
	DCB dcb;
	GetCommState(uart_fd, &dcb);
	dcb.BaudRate = BAUD;     //波特率
	dcb.ByteSize = DATABITS;     //数据位
	dcb.Parity = PARITY;     //奇偶校验
	dcb.StopBits = STOPBIT; // 停止位
	SetCommState(uart_fd, &dcb);
	return 0;
	// ReadIntervalTimeout:两相邻字符之间最大的延时。当读串口数据时,一旦两个字符传输的时间间隔超过该时间,读函数将返回现有的数据。设置为0表示该参数不起作用。

	// ReadTotalTimeoutMultiplier:读操作总的超时事件的系数。
	// 这个变量是不能单独使用的。必须和ReadTotalTimeoutConstant一起使用才有效果。

	// ReadTotalTimeoutConstant:读操作总的超时时间的修正常量。
	// 这个变量也是不能单独使用的,必须和ReadTotalTimeoutMultiplier一起使用才有效果。

	// WriteTotalTimeoutMultiplier:写操作总的超时事件的系数。
	// 这个变量是不能单独使用的,必须和WriteTotalTimeoutConstant一起使用才有效果。

	// WriteTotalTimeoutConstant:写操作总的超时时间的修正常量。
	// 这个变量也是不能单独使用的。必须和WriteTotalTimeoutMultiplier一起使用才有效果。

	// 在整个串口的读写操作中,存在着两种超时设置。一种是间隔超时,一种是总超时。这两种超时是独立存在,互不影响的。

	// 间隔超时,只在读操作中存在,就是ReadIntervalTimeout。
	// 当读操作中,前后两个字符之间的时间间隔超过时,读操作就结束了。
	// 举例来说,你一次读取8个字符,但是在你读取了第一个字符之后,在读取第二个字符时,间隔超时了,那么读操作就结束了,这样整个操作就只读取了1个字节。
	// 即使,你的总时间没有超时。

	// 另一种超时,就是总超时。
	// 这里有一个公式。
	// 总的读 / 写超时时间 =  Read(Write) TotalTimeoutMultiplier x 要读/写的字节数
	// + Read(Write) TotalTimeoutConstant.
	// 这里要说明的一点,要读/写的字节数是从哪里来的。 这个是从ReadFile
	// 或者WriteFile函数中定义的。 在读操作时,
	// 若当前所花读取时间已经超过了总的超时设置,则读操作就结束了。
	// 即使,每两个字符之间的间隔没有超时。
	// 举例来说,若总共读取8个字节。
	// 间隔设置为8ms,总超时系数为3ms,总超时常数为3ms。
	// 则总的超时时间为3 * 8 + 3 =27ms。
	// 若每个字符读取的间隔为7ms,则这次操作总共能读取4个字符,就结束了。
	// 因为读取第5个字符时,已经需要35ms,超过总超时时间了。
	return 0;
}


void CUART::uart_close(HANDLE uart_fd) {
	CloseHandle(uart_fd); //关闭文件描述符
	return;
}

int CUART::uart_recv(HANDLE uart_fd, BYTE *recv_buf, unsigned int recv_len,DWORD* act_recv_len) {
	//返回值只是表示此次执行的结果
	struct _COMSTAT comstat;
	ClearCommError(uart_fd,NULL,&comstat);
	if(comstat.cbInQue < recv_len)
	{
		recv_len = comstat.cbInQue;
	}
	return ReadFile(uart_fd,recv_buf,recv_len,act_recv_len,NULL);
}

int CUART::uart_send(HANDLE uart_fd, BYTE *send_buf, unsigned int send_len,DWORD* act_send_len) {
	//返回值只是表示此次执行的结果
	DWORD comerr = 0;
	struct _COMSTAT comstat;
	ClearCommError(uart_fd,&comerr,&comstat);
	if(comerr != 0)
	{
		perror("uart_send err");
		return -1;
	}
	return WriteFile(uart_fd,send_buf,send_len,act_send_len,NULL);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值