最近在封装一个使用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);