USB HID通信记录
最近在封装一个使用HT42B564-x作为通信芯片的模块。
在之前的客户端中进行适配添加。
首先HT42B564-x具有全双工的异步串行通信接口,内置了UART功能。默认采用9600波特率进行通信。
如果需要改变波特率,需要采用接口进行修改。客户端底层通信使用的微软的HIDSDI的通信模块(HIDSDI.h)。提供了基础的配置接口
https://docs.microsoft.com/zh-cn/windows-hardware/drivers/ddi/_hid/
此处可以通过下面两个接口获取和设置波特率等相关的通信参数
BOOLEAN __stdcall
HidD_GetInputReport (
IN HANDLE HidDeviceObject,//通信句柄
OUT PVOID ReportBuffer,//接收数据对象的地址
IN ULONG ReportBufferLength//数据长度
);
BOOLEAN __stdcall
HidD_SetFeature (
IN HANDLE HidDeviceObject,//通信句柄
IN PVOID ReportBuffer,//设定的参数地址
IN ULONG ReportBufferLength//参数长度
);
//设置波特率 需要根据具体的通信协议设定值
BYTE buf[9] = { 0x50, 0x00, 0x00, 0x25, 0x80, 0x00, 0x00, 0x03, 0x00 };
HidD_SetFeature(_hdev, buf, sizeof(buf));
建议先用GetFeature读出来,然后在修改对应的波特率部分的参数。一般是数组第2位到第5位
例如:
可以通过下面两个接口获取和设置通信缓存区的大小(一般来说都是默认32个字节)
BOOLEAN __stdcall
HidD_GetNumInputBuffers (
IN HANDLE HidDeviceObject,//通信句柄
OUT PULONG NumberBuffers//接收缓存区大小的对象地址
);
BOOLEAN __stdcall
HidD_SetNumInputBuffers (
IN HANDLE HidDeviceObject,//通信句柄
OUT ULONG NumberBuffers//写入的具体缓存区大小
);
//配置缓存区
HidD_SetNumInputBuffers(_hdev, 64);
在查找后创建设备通信句柄时使用CreateFile,非UNICODE编码下实际就是CreateFileA,需要注意dwFlagsAndAttributes这个值的设定,用于控制异步通信模式:
CreateFileA(
__in LPCSTR lpFileName,
__in DWORD dwDesiredAccess,
__in DWORD dwShareMode,
__in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
__in DWORD dwCreationDisposition,
__in DWORD dwFlagsAndAttributes,
__in_opt HANDLE hTemplateFile
);
devHandle = CreateFile(SPDeviceInterfaceDetailData->DevicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, m_dwFlagsAndAttributes,//异步通信,定义:m_dwFlagsAndAttributes(FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED) 0);
发送数据使用WriteFile进行写入
//同样定义一个m_dwFlagsAndAttributes //同步方式 if ((m_dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED) != FILE_FLAG_OVERLAPPED) return WriteFile(_dev, _buf, _buf_len, &nWrite, nullptr) ? nWrite : UErr::Failed; //异步 需要个一个OVERLAPPED的对象 OVERLAPPED overlap; memset(&overlap, 0, sizeof(overlap)); //overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); //如果出现错误码87 可以试试打开 auto r = WriteFile(_dev, _buf, _buf_len, &nWrite, &overlap);
读取数据使用
//目前我们使用下面这个接口获取数据 //return AsynchReadThreadProc(_dev, _buf, _buf_len, _timeout); DWORD nRead = 0; chr::timer<int> tt(_timeout); //同步方式 if ((m_dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED) != FILE_FLAG_OVERLAPPED) return ReadFile(_dev, _buf, _buf_len, &nRead, nullptr) ? nRead : UErr::Failed; //异步方式 OVERLAPPED overlap; memset(&overlap, 0, sizeof(overlap)); overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); auto r = ReadFile(_dev, _buf, _buf_len, &nRead, &overlap);
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)