为了同时控制两块CYUSB3014电路板进行SlaveFifo读写,需要确保正确区分设备并独立操作其端点。以下是具体步骤和代码示例:
步骤1:正确枚举设备并创建独立实例
使用CCyUSBDevice遍历所有连接的设备,根据VID/PID筛选目标设备,并为每个设备创建独立实例。
#include
#pragma comment(lib, "CyAPI.lib")
// 定义两个设备的VID和PID
#define DEV1_VID 0x04B4
#define DEV1_PID 0x00F1
#define DEV2_VID 0x04B4
#define DEV2_PID 0x00F2
// 创建两个设备对象
CCyUSBDevice* USBDevice1 = new CCyUSBDevice(nullptr);
CCyUSBDevice* USBDevice2 = new CCyUSBDevice(nullptr);
// 查找并打开设备
bool FindAndOpenDevice(CCyUSBDevice* device, int targetVid, int targetPid) {
for (int i = 0; i < device->DeviceCount(); i++) {
device->Open(i);
if (device->VendorID == targetVid && device->ProductID == targetPid) {
return true;
}
device->Close();
}
return false;
}
// 初始化设备
bool InitDevices() {
bool dev1Found = FindAndOpenDevice(USBDevice1, DEV1_VID, DEV1_PID);
bool dev2Found = FindAndOpenDevice(USBDevice2, DEV2_VID, DEV2_PID);
return dev1Found && dev2Found;
}
步骤2:获取每个设备的SlaveFifo端点
确保为每个设备获取正确的IN/OUT端点,避免混淆。
// 获取端点指针
CCyBulkEndPoint* GetBulkEndpoint(CCyUSBDevice* device, bool isIn) {
for (int i = 0; i < device->EndPointCount(); i++) {
CCyUSBEndPoint* ep = device->EndPoints[i];
if (ep->Address == (isIn ? 0x86 : 0x02)) { // 根据实际端点地址调整
return (CCyBulkEndPoint*)ep;
}
}
return nullptr;
}
// 初始化端点
CCyBulkEndPoint* EP1_IN = GetBulkEndpoint(USBDevice1, true);
CCyBulkEndPoint* EP1_OUT = GetBulkEndpoint(USBDevice1, false);
CCyBulkEndPoint* EP2_IN = GetBulkEndpoint(USBDevice2, true);
CCyBulkEndPoint* EP2_OUT = GetBulkEndpoint(USBDevice2, false);
步骤3:独立读写操作
为每个设备分配独立的读写操作,避免资源冲突。
// 异步读取示例(设备1)
void ReadFromDevice1() {
PUCHAR buffer = new UCHAR[1024];
ULONG length = 1024;
OVERLAPPED ov = {0};
ov.hEvent = CreateEvent(nullptr, false, false, nullptr);
if (EP1_IN->Read(buffer, length, &ov)) {
WaitForSingleObject(ov.hEvent, INFINITE);
// 处理数据...
}
CloseHandle(ov.hEvent);
delete[] buffer;
}
// 异步写入示例(设备2)
void WriteToDevice2(PUCHAR data, ULONG length) {
OVERLAPPED ov = {0};
ov.hEvent = CreateEvent(nullptr, false, false, nullptr);
if (EP2_OUT->Write(data, length, &ov)) {
WaitForSingleObject(ov.hEvent, INFINITE);
}
CloseHandle(ov.hEvent);
}
步骤4:多线程处理(可选)
为避免阻塞,可为每个设备分配独立线程。
#include
// 线程函数:操作设备1
void ThreadFunc_Device1() {
while (true) {
ReadFromDevice1();
// 其他操作...
}
}
// 线程函数:操作设备2
void ThreadFunc_Device2() {
while (true) {
// 写入操作示例
UCHAR data[] = {0x01, 0x02, 0x03};
WriteToDevice2(data, sizeof(data));
}
}
// 启动线程
std::thread t1(ThreadFunc_Device1);
std::thread t2(ThreadFunc_Device2);
t1.join();
t2.join();
关键注意事项
- 设备独立性:确保每个设备的
CCyUSBDevice实例和端点指针严格分离。
- 端点地址匹配:根据固件中的SlaveFifo配置(
bEndpointAddress),确认代码中的端点地址是否正确。
- 错误处理:检查每次USB操作的返回值,处理超时或错误。
- 同步机制:使用
OVERLAPPED和事件句柄实现异步操作,避免线程冲突。
通过上述方法,应能实现同时控制两块CYUSB3014板的SlaveFifo通信。若仍存在问题,建议检查固件的端点配置或使用Cypress Suite中的Control Center验证端点行为。