这个是公司的项目,曾经根据usb的虚拟串口来做上下位机通讯,因为usb平常也就刷参数和调试之用,也不很常用,外面反响usb有时会连不上stm32控制器,心里一向以为不是大问题,后来反响的多了,就注重这个工作了,尽管usb平常不必,可是用的时分只需出现异常掉线,就再也连不上去了,特别影响用户对咱们产品的决心。
在网上找了许多材料,到现在也只能模糊确认是stm32官方的虚拟串口库有问题,我发现不同的电源板都会影响到usb虚拟串口的枚举,所以下定决心运用其他方法来做上下位机的衔接,排除了usb虚拟串口,眼前的挑选只要两个
1)usblib,这个是针对usb的上位机库,能够玩许多的把戏,可是需求开发者稍稍了解usb协议,并且这个需求在上位机上装置usb驱动程序。
2)hid设备,这个是windows本身支撑的usb设备,只支撑中止传输,最大的速率也就64Kb/s,上位机选用windows api编程
我估算了一下,hid方法满意我的要求,并且是免驱动,又不必学习usblib,所以就运用hid方法完成了usb通讯。
hid几个留意事项:
1)关于windows API来说,读和写hid设备的数据包都是巨细确认了,也就是说假如stm32 端口设备的hid特点是64的话,那么读写都是64字节的。读写的最大帧是64字节,我在代码中是根据64字节做应用层协议的。
2)hid写速度不能太快,所以我一般在写前会等候2ms左右,保证不会写犯错。
确认是是HIDAPI的代码问题,我对写函数批改如下,成果就好了,能够一向写无需等候
int HID_API_EXPORT HID_API_CALL hid_write(hid_device *dev, const unsigned char *data, size_t length)
{
DWORD bytes_written;
BOOL res;
BOOL bResult;
OVERLAPPED ol;
HANDLE ReportEvent;
ReportEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
ResetEvent(ReportEvent);
memset(&ol, 0, sizeof(ol));
ol.hEvent = ReportEvent;
//res = WriteFile(dev->device_handle, data, 23, NULL, &ol);
res = WriteFile(dev->device_handle, data, length, NULL, &ol);
if (!res) {
int errcode = GetLastError();
if (errcode != ERROR_IO_PENDING) {
// WriteFile() failed. Return error.
register_error(dev, “WriteFile”);
return -1;
}
}
bResult = WaitForSingleObject(ReportEvent, 50);
if(bResult == WAIT_TIMEOUT || bResult == WAIT_ABANDONED)
{
register_error(dev, “WriteFile”);
CancelIo(&(dev->device_handle));
return -1;
}
// Wait here until the write is done. This makes
// hid_write() synchronous.
res = GetOverlappedResult(dev->device_handle, &ol, &bytes_written, TRUE);
if (!res) {
// The Write operation failed.
register_error(dev, “WriteFile”);
return -1;
}
return bytes_written;
}
3)上位机上的读写之间不能开释hid的句柄,这个我参阅百合的hid教材的时分,吃了不少苦头。
4)我运用了HIDAPI这个库来操作hid设备。
详细细节的东西我们能够看看网上找到的hid教程,我的代码和可执行代码下载链接如下
http://pan.baidu.com/s/1qzTJw
留意:上面链接中的写函数我没有批改,请读者自己批改