完成stm32 上HID的應(yīng)用
在網(wǎng)上找了很多資料,到現(xiàn)在也只能隱約確定是stm32官方的虛擬串口庫有問題,我發(fā)現(xiàn)不同的電源板都會影響到usb虛擬串口的枚舉,于是下定決心使用其他方式來做上下位機(jī)的連接,排除了usb虛擬串口,眼前的選擇只有兩個
1)usblib,這個是針對usb的上位機(jī)庫,可以玩很多的花樣,但是需要開發(fā)者稍稍熟悉usb協(xié)議,而且這個需要在上位機(jī)上安裝usb驅(qū)動程序。
2)hid設(shè)備,這個是windows自身支持的usb設(shè)備,只支持中斷傳輸,最大的速率也就64Kb/s,上位機(jī)采用windows api編程
我估算了一下,hid方式滿足我的要求,而且是免驅(qū)動,又不用學(xué)習(xí)usblib,所以就使用hid方式實現(xiàn)了usb通信。
hid幾個注意事項:
1)對于windows API來說,讀和寫hid設(shè)備的數(shù)據(jù)包都是大小確定了,也就是說如果stm32 端口設(shè)備的hid屬性是64的話,那么讀寫都是64字節(jié)的。讀寫的最大幀是64字節(jié),我在代碼中是基于64字節(jié)做應(yīng)用層協(xié)議的。
2)hid寫速度不能太快,所以我一般在寫前會等待2ms左右,確保不會寫出錯。
確認(rèn)是是HIDAPI的代碼問題,我對寫函數(shù)修改如下,結(jié)果就好了,可以一直寫無需等待
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)上位機(jī)上的讀寫之間不能釋放hid的句柄,這個我參考百合的hid教材的時候,吃了不少苦頭。
4)我使用了HIDAPI這個庫來操作hid設(shè)備。
具體細(xì)節(jié)的東西大家可以看看網(wǎng)上找到的hid教程,我的代碼和可執(zhí)行代碼下載鏈接如下
http://pan.baidu.com/s/1qzTJw
注意:上面鏈接中的寫函數(shù)我沒有修正,請讀者自己修改
評論