[方案相关] HC32F460通过USB与matlab通讯简单例程

[复制链接]
3562|4
 楼主| 纪国圣 发表于 2021-10-31 17:06 | 显示全部楼层 |阅读模式
这个例程只是实现了HC32F460通过USB与matlab数据回环交换,更复杂的例子比如实时采集数据可以在此基础上通过Timer定时读取Read函数实现。
1.准备好之前HC32F460的WINUSB例程与其上位机,并简单测试HC32F460能否每秒发送一次数据:
1.gif
1.PNG
HC32F460_WINUSB MS_OS_20.zip (6.66 MB, 下载次数: 17)
win_usb.zip (23.4 KB, 下载次数: 11)
2.替换文件:
将下图文件放入工程中:
3.PNG
工程目录由
2.PNG
替换为
4.PNG
其中USB.cpp和USB_Dll.cpp主要是对WINUSB开启、读写、关闭做进一步的封装,方便matlab调用。
USB_Dll.h
  1. #ifndef USB_Dll_H
  2. #define USB_Dll_H

  3. #ifdef __cplusplus
  4. extern"C"
  5. {
  6. #endif

  7. __declspec(dllexport) unsigned char Connect();
  8. __declspec(dllexport) unsigned char Read(unsigned char *ptr, const int len);
  9. __declspec(dllexport) unsigned char Write(unsigned char *ptr, unsigned long* cbsize, const int len);
  10. __declspec(dllexport) void Close();

  11. #ifdef __cplusplus
  12. }
  13. #endif

  14. #endif
USB_Dll.cpp
  1. #include "WUSB.h"
  2. #include "USB_Dll.h"

  3. #include <cfgmgr32.h>

  4. DEVICE_DATA deviceData;
  5. PIPE_ID PipeID;

  6. unsigned char Connect()
  7. {
  8.         BOOL bResult = TRUE;
  9.         unsigned char result;

  10.         bResult = USB_Init(&deviceData, &PipeID);
  11.         if (bResult == FALSE)
  12.         {
  13.                 result = 0;
  14.         }
  15.         else
  16.         {
  17.                 result = 1;
  18.         }

  19.         return result;
  20. }

  21. unsigned char Read(unsigned char* ptr, const int len)
  22. {
  23.         BOOL bResult = TRUE;
  24.         unsigned char result;

  25.         bResult = ReadFromBulkEndpoint(deviceData.WinusbHandle, &PipeID.PipeInId, len, ptr);
  26.         if (bResult == FALSE)
  27.         {
  28.                 CloseDevice(&deviceData);
  29.                 result = 0;
  30.         }
  31.         else
  32.         {
  33.                 result = 1;
  34.         }

  35.         return result;
  36. }

  37. unsigned char Write(unsigned char* ptr, unsigned long *cbsize,const int len)
  38. {
  39.         BOOL bResult = TRUE;
  40.         unsigned char result;

  41.         bResult = WriteToBulkEndpoint(deviceData.WinusbHandle, &PipeID.PipeOutId, cbsize, ptr, len);

  42.         if (bResult == FALSE)
  43.         {
  44.                 CloseDevice(&deviceData);
  45.                 result = 0;
  46.         }
  47.         else
  48.         {
  49.                 result = 1;
  50.         }

  51.         return result;
  52. }

  53. void Close()
  54. {
  55.         CloseDevice(&deviceData);
  56. }
USB.c
  1. #include <stdio.h>
  2. #include "WUSB.h"

  3. BOOL GetUSBDeviceSpeed(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pDeviceSpeed)
  4. {
  5.     if (!pDeviceSpeed || hDeviceHandle == INVALID_HANDLE_VALUE)
  6.     {
  7.         return FALSE;
  8.     }

  9.     BOOL bResult = TRUE;

  10.     ULONG length = sizeof(UCHAR);

  11.     bResult = WinUsb_QueryDeviceInformation(hDeviceHandle, DEVICE_SPEED, &length, pDeviceSpeed);
  12.     if (!bResult)
  13.     {
  14.         printf("Error getting device speed: %d.\n", GetLastError());
  15.         goto done;
  16.     }

  17.     if (*pDeviceSpeed == LowSpeed)
  18.     {
  19.         printf("Device speed: %d (Low speed).\n", *pDeviceSpeed);
  20.         goto done;
  21.     }
  22.     if (*pDeviceSpeed == FullSpeed)
  23.     {
  24.         printf("Device speed: %d (Full speed).\n", *pDeviceSpeed);
  25.         goto done;
  26.     }
  27.     if (*pDeviceSpeed == HighSpeed)
  28.     {
  29.         printf("Device speed: %d (High speed).\n", *pDeviceSpeed);
  30.         goto done;
  31.     }

  32. done:
  33.     return bResult;
  34. }

  35. BOOL QueryDeviceEndpoints(WINUSB_INTERFACE_HANDLE hDeviceHandle, PIPE_ID* pipeid)
  36. {
  37.     if (hDeviceHandle == INVALID_HANDLE_VALUE)
  38.     {
  39.         return FALSE;
  40.     }

  41.     BOOL bResult = TRUE;

  42.     USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
  43.     ZeroMemory(&InterfaceDescriptor, sizeof(USB_INTERFACE_DESCRIPTOR));

  44.     WINUSB_PIPE_INFORMATION  Pipe;
  45.     ZeroMemory(&Pipe, sizeof(WINUSB_PIPE_INFORMATION));


  46.     bResult = WinUsb_QueryInterfaceSettings(hDeviceHandle, 0, &InterfaceDescriptor);

  47.     if (bResult)
  48.     {
  49.         for (UCHAR index = 0; index < InterfaceDescriptor.bNumEndpoints; index++)
  50.         {
  51.             bResult = WinUsb_QueryPipe(hDeviceHandle, 0, index, &Pipe);

  52.             if (bResult)
  53.             {
  54.                 if (Pipe.PipeType == UsbdPipeTypeControl)
  55.                 {
  56.                     printf("Endpoint index: %d Pipe type: %d Control Pipe ID: %d.\n", index, Pipe.PipeType, Pipe.PipeId);
  57.                 }
  58.                 if (Pipe.PipeType == UsbdPipeTypeIsochronous)
  59.                 {
  60.                     printf("Endpoint index: %d Pipe type: %d Isochronous Pipe ID: %d.\n", index, Pipe.PipeType, Pipe.PipeId);
  61.                 }
  62.                 if (Pipe.PipeType == UsbdPipeTypeBulk)
  63.                 {
  64.                     if (USB_ENDPOINT_DIRECTION_IN(Pipe.PipeId))
  65.                     {
  66.                         printf("Endpoint index: %d Pipe type: %d Bulk Pipe ID: %d.\n", index, UsbdPipeTypeBulk, Pipe.PipeId);
  67.                         pipeid->PipeInId = Pipe.PipeId;
  68.                     }
  69.                     if (USB_ENDPOINT_DIRECTION_OUT(Pipe.PipeId))
  70.                     {
  71.                         printf("Endpoint index: %d Pipe type: %d Bulk Pipe ID: %d.\n", index, Pipe.PipeType, Pipe.PipeId);
  72.                         pipeid->PipeOutId = Pipe.PipeId;
  73.                     }

  74.                 }
  75.                 if (Pipe.PipeType == UsbdPipeTypeInterrupt)
  76.                 {
  77.                     printf("Endpoint index: %d Pipe type: %d Interrupt Pipe ID: %d.\n", index, Pipe.PipeType, Pipe.PipeId);
  78.                 }
  79.             }
  80.             else
  81.             {
  82.                 continue;
  83.             }
  84.         }
  85.     }

  86. //done:
  87.     return bResult;
  88. }

  89. BOOL SendDatatoDefaultEndpoint(WINUSB_INTERFACE_HANDLE hDeviceHandle)
  90. {
  91.     if (hDeviceHandle == INVALID_HANDLE_VALUE)
  92.     {
  93.         return FALSE;
  94.     }

  95.     BOOL bResult = TRUE;


  96.     UCHAR bars = 0;

  97.     WINUSB_SETUP_PACKET SetupPacket;
  98.     ZeroMemory(&SetupPacket, sizeof(WINUSB_SETUP_PACKET));
  99.     ULONG cbSent = 0;

  100.     //Set bits to light alternate bars
  101.     for (short i = 0; i < 7; i += 2)
  102.     {
  103.         bars += 1 << i;
  104.     }

  105.     //Create the setup packet
  106.     SetupPacket.RequestType = 0;
  107.     SetupPacket.Request = 0xD8;
  108.     SetupPacket.Value = 0;
  109.     SetupPacket.Index = 0;
  110.     SetupPacket.Length = sizeof(UCHAR);

  111.     bResult = WinUsb_ControlTransfer(hDeviceHandle, SetupPacket, &bars, sizeof(UCHAR), &cbSent, 0);
  112.     if (!bResult)
  113.     {
  114.         goto done;
  115.     }

  116.     printf("Data sent: %d \nActual data transferred: %d.\n", bars, cbSent);


  117. done:
  118.     return bResult;

  119. }

  120. BOOL WriteToBulkEndpoint(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pID, ULONG* pcbWritten, UCHAR* szBuffer, ULONG cbSize)
  121. {
  122.     if (hDeviceHandle == INVALID_HANDLE_VALUE || !pID || !pcbWritten)
  123.     {
  124.         return FALSE;
  125.     }

  126.     BOOL bResult = TRUE;

  127.     ULONG cbSent = 0;

  128.     bResult = WinUsb_WritePipe(hDeviceHandle, *pID, szBuffer, cbSize, &cbSent, 0);
  129.     if (!bResult)
  130.     {
  131.         goto done;
  132.     }

  133.     printf("Wrote to pipe %d: %s \nActual data transferred: %d.\n", *pID, szBuffer, cbSent);
  134.     *pcbWritten = cbSent;


  135. done:
  136.     return bResult;

  137. }

  138. BOOL ReadFromBulkEndpoint(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pID, ULONG cbSize, UCHAR* szBuffer)
  139. {
  140.     if (hDeviceHandle==INVALID_HANDLE_VALUE)
  141.     {
  142.         return FALSE;
  143.     }

  144.     BOOL bResult = TRUE;
  145.    
  146.     ULONG cbRead = 0;

  147.     bResult = WinUsb_ReadPipe(hDeviceHandle, *pID, szBuffer, cbSize, &cbRead, 0);
  148.     if(!bResult)
  149.     {
  150.         goto done;
  151.     }

  152.     printf("Read from pipe %d: %s \nActual data read: %d.\n", *pID, szBuffer, cbRead);


  153. done:
  154.     LocalFree(szBuffer);
  155.     return bResult;

  156. }

  157. BOOL USB_Init(DEVICE_DATA *deviceData, PIPE_ID *PipeID)
  158. {
  159.     HRESULT hr;
  160.     BOOL noDevice;
  161.     BOOL bResult;
  162.     USB_DEVICE_DESCRIPTOR deviceDesc;
  163.     UCHAR DeviceSpeed;
  164.     ULONG lengthReceived;

  165.     //
  166.     // Find a device connected to the system that has WinUSB installed using our
  167.     // INF
  168.     //
  169.     hr = OpenDevice(deviceData, &noDevice);

  170.     if (FAILED(hr)) {

  171.         if (noDevice) {

  172.             wprintf(L"Device not connected or driver not installed\n");

  173.         }
  174.         else {

  175.             wprintf(L"Failed looking for device, HRESULT 0x%x\n", hr);
  176.         }

  177.         return FALSE;
  178.     }

  179.     //
  180.     // Get device descriptor
  181.     //
  182.     bResult = WinUsb_GetDescriptor(deviceData->WinusbHandle,
  183.         USB_DEVICE_DESCRIPTOR_TYPE,
  184.         0,
  185.         0,
  186.         (PBYTE)&deviceDesc,
  187.         sizeof(deviceDesc),
  188.         &lengthReceived);

  189.     if (FALSE == bResult || lengthReceived != sizeof(deviceDesc)) {

  190.         wprintf(L"Error among LastError %d or lengthReceived %d\n",
  191.             FALSE == bResult ? GetLastError() : 0,
  192.             lengthReceived);
  193.         CloseDevice(deviceData);
  194.         return FALSE;
  195.     }

  196.     //
  197.     // Print a few parts of the device descriptor
  198.     //
  199.     wprintf(L"Device found: VID_%04X&PID_%04X; bcdUsb %04X\n",
  200.         deviceDesc.idVendor,
  201.         deviceDesc.idProduct,
  202.         deviceDesc.bcdUSB);


  203.     bResult = GetUSBDeviceSpeed(deviceData->WinusbHandle, &DeviceSpeed);
  204.     if (!bResult)
  205.     {
  206.         CloseDevice(deviceData);

  207.         return FALSE;
  208.     }

  209.     bResult = QueryDeviceEndpoints(deviceData->WinusbHandle, PipeID);
  210.     if (!bResult)
  211.     {
  212.         CloseDevice(deviceData);

  213.         return FALSE;
  214.     }

  215.     return TRUE;
  216. }

3.编译生成DLL文件:

修改工程属性:
11.PNG
编译生成DLL文件:
12.PNG
13.PNG
win_usb_dll.zip (784.96 KB, 下载次数: 7)
4.将生成的DLL与.h文件拷贝至matlab工作环境,打开matlab,切换工作环境至DLL所在文件夹中:
14.PNG
在命令行中使用如下函数,加载DLL与查看:
15.PNG
可以看到DLL加载成功。
编写m文件,简单测试回环通信:
  1. clc

  2. loadlibrary('USB_Dll.dll','USB_Dll.h')

  3. state = calllib('USB_Dll','Connect');

  4. if(state == 1)
  5.     disp('USB Connect')
  6.    
  7. str = [1 2 3 4 5]
  8.     len = 0;
  9.     wptr = libpointer('uint8Ptr',str);
  10.     n_ptr = libpointer('uint32Ptr',len);
  11.     state = calllib('USB_Dll','Write',wptr,n_ptr,length(str));
  12.     if(state == 0)
  13.         disp('USB error')
  14.     else
  15.         rptr = libpointer('uint8Ptr',zeros(1,64));
  16.         state = calllib('USB_Dll','Read',rptr,63);
  17.         if(state == 0)
  18.             disp('USB error')
  19.         else
  20.             char(rptr.Value)
  21.             calllib('USB_Dll','Close');
  22.             disp('USB Disonnect')
  23.         end
  24.     end
  25. else
  26.     disp('USB do not open')  
  27. end
一切正常:
16.PNG
19.PNG

5.总结
总体来说matlab对usb通信的支持力度远没有串口的大,为了实现usb通信就不得不实现混合编程,难度挺大的。这个例子只是简单的实现matlab与HC32F460的通信,但其有很多需要完善的地方。写这篇帖子仅仅起到抛砖引玉的作用,欢迎大家提出建议。

caigang13 发表于 2021-11-2 07:40 来自手机 | 显示全部楼层
学习了,谢谢分享。
sparrow054 发表于 2021-11-2 11:56 | 显示全部楼层
这个是不是要大大的赞啊,太牛了!
foxsbig 发表于 2022-1-21 16:55 | 显示全部楼层
这个厉害,MATLAB还能这样玩~~
duo点 发表于 2022-1-21 17:11 来自手机 | 显示全部楼层
厉害,非常赞
您需要登录后才可以回帖 登录 | 注册

本版积分规则

77

主题

407

帖子

5

粉丝
快速回复 在线客服 返回列表 返回顶部