打印
[方案相关]

HC32F460通过USB与matlab通讯简单例程

[复制链接]
3163|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
纪国圣|  楼主 | 2021-10-31 17:06 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
这个例程只是实现了HC32F460通过USB与matlab数据回环交换,更复杂的例子比如实时采集数据可以在此基础上通过Timer定时读取Read函数实现。
1.准备好之前HC32F460的WINUSB例程与其上位机,并简单测试HC32F460能否每秒发送一次数据:


HC32F460_WINUSB MS_OS_20.zip (6.66 MB)
win_usb.zip (23.4 KB)
2.替换文件:
将下图文件放入工程中:

工程目录由

替换为

其中USB.cpp和USB_Dll.cpp主要是对WINUSB开启、读写、关闭做进一步的封装,方便matlab调用。
USB_Dll.h
#ifndef USB_Dll_H
#define USB_Dll_H

#ifdef __cplusplus
extern"C"
{
#endif

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

#ifdef __cplusplus
}
#endif

#endif
USB_Dll.cpp
#include "WUSB.h"
#include "USB_Dll.h"

#include <cfgmgr32.h>

DEVICE_DATA deviceData;
PIPE_ID PipeID;

unsigned char Connect()
{
        BOOL bResult = TRUE;
        unsigned char result;

        bResult = USB_Init(&deviceData, &PipeID);
        if (bResult == FALSE)
        {
                result = 0;
        }
        else
        {
                result = 1;
        }

        return result;
}

unsigned char Read(unsigned char* ptr, const int len)
{
        BOOL bResult = TRUE;
        unsigned char result;

        bResult = ReadFromBulkEndpoint(deviceData.WinusbHandle, &PipeID.PipeInId, len, ptr);
        if (bResult == FALSE)
        {
                CloseDevice(&deviceData);
                result = 0;
        }
        else
        {
                result = 1;
        }

        return result;
}

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

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

        if (bResult == FALSE)
        {
                CloseDevice(&deviceData);
                result = 0;
        }
        else
        {
                result = 1;
        }

        return result;
}

void Close()
{
        CloseDevice(&deviceData);
}
USB.c
#include <stdio.h>
#include "WUSB.h"

BOOL GetUSBDeviceSpeed(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pDeviceSpeed)
{
    if (!pDeviceSpeed || hDeviceHandle == INVALID_HANDLE_VALUE)
    {
        return FALSE;
    }

    BOOL bResult = TRUE;

    ULONG length = sizeof(UCHAR);

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

    if (*pDeviceSpeed == LowSpeed)
    {
        printf("Device speed: %d (Low speed).\n", *pDeviceSpeed);
        goto done;
    }
    if (*pDeviceSpeed == FullSpeed)
    {
        printf("Device speed: %d (Full speed).\n", *pDeviceSpeed);
        goto done;
    }
    if (*pDeviceSpeed == HighSpeed)
    {
        printf("Device speed: %d (High speed).\n", *pDeviceSpeed);
        goto done;
    }

done:
    return bResult;
}

BOOL QueryDeviceEndpoints(WINUSB_INTERFACE_HANDLE hDeviceHandle, PIPE_ID* pipeid)
{
    if (hDeviceHandle == INVALID_HANDLE_VALUE)
    {
        return FALSE;
    }

    BOOL bResult = TRUE;

    USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
    ZeroMemory(&InterfaceDescriptor, sizeof(USB_INTERFACE_DESCRIPTOR));

    WINUSB_PIPE_INFORMATION  Pipe;
    ZeroMemory(&Pipe, sizeof(WINUSB_PIPE_INFORMATION));


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

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

            if (bResult)
            {
                if (Pipe.PipeType == UsbdPipeTypeControl)
                {
                    printf("Endpoint index: %d Pipe type: %d Control Pipe ID: %d.\n", index, Pipe.PipeType, Pipe.PipeId);
                }
                if (Pipe.PipeType == UsbdPipeTypeIsochronous)
                {
                    printf("Endpoint index: %d Pipe type: %d Isochronous Pipe ID: %d.\n", index, Pipe.PipeType, Pipe.PipeId);
                }
                if (Pipe.PipeType == UsbdPipeTypeBulk)
                {
                    if (USB_ENDPOINT_DIRECTION_IN(Pipe.PipeId))
                    {
                        printf("Endpoint index: %d Pipe type: %d Bulk Pipe ID: %d.\n", index, UsbdPipeTypeBulk, Pipe.PipeId);
                        pipeid->PipeInId = Pipe.PipeId;
                    }
                    if (USB_ENDPOINT_DIRECTION_OUT(Pipe.PipeId))
                    {
                        printf("Endpoint index: %d Pipe type: %d Bulk Pipe ID: %d.\n", index, Pipe.PipeType, Pipe.PipeId);
                        pipeid->PipeOutId = Pipe.PipeId;
                    }

                }
                if (Pipe.PipeType == UsbdPipeTypeInterrupt)
                {
                    printf("Endpoint index: %d Pipe type: %d Interrupt Pipe ID: %d.\n", index, Pipe.PipeType, Pipe.PipeId);
                }
            }
            else
            {
                continue;
            }
        }
    }

//done:
    return bResult;
}

BOOL SendDatatoDefaultEndpoint(WINUSB_INTERFACE_HANDLE hDeviceHandle)
{
    if (hDeviceHandle == INVALID_HANDLE_VALUE)
    {
        return FALSE;
    }

    BOOL bResult = TRUE;


    UCHAR bars = 0;

    WINUSB_SETUP_PACKET SetupPacket;
    ZeroMemory(&SetupPacket, sizeof(WINUSB_SETUP_PACKET));
    ULONG cbSent = 0;

    //Set bits to light alternate bars
    for (short i = 0; i < 7; i += 2)
    {
        bars += 1 << i;
    }

    //Create the setup packet
    SetupPacket.RequestType = 0;
    SetupPacket.Request = 0xD8;
    SetupPacket.Value = 0;
    SetupPacket.Index = 0;
    SetupPacket.Length = sizeof(UCHAR);

    bResult = WinUsb_ControlTransfer(hDeviceHandle, SetupPacket, &bars, sizeof(UCHAR), &cbSent, 0);
    if (!bResult)
    {
        goto done;
    }

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


done:
    return bResult;

}

BOOL WriteToBulkEndpoint(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pID, ULONG* pcbWritten, UCHAR* szBuffer, ULONG cbSize)
{
    if (hDeviceHandle == INVALID_HANDLE_VALUE || !pID || !pcbWritten)
    {
        return FALSE;
    }

    BOOL bResult = TRUE;

    ULONG cbSent = 0;

    bResult = WinUsb_WritePipe(hDeviceHandle, *pID, szBuffer, cbSize, &cbSent, 0);
    if (!bResult)
    {
        goto done;
    }

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


done:
    return bResult;

}

BOOL ReadFromBulkEndpoint(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pID, ULONG cbSize, UCHAR* szBuffer)
{
    if (hDeviceHandle==INVALID_HANDLE_VALUE)
    {
        return FALSE;
    }

    BOOL bResult = TRUE;
   
    ULONG cbRead = 0;

    bResult = WinUsb_ReadPipe(hDeviceHandle, *pID, szBuffer, cbSize, &cbRead, 0);
    if(!bResult)
    {
        goto done;
    }

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


done:
    LocalFree(szBuffer);
    return bResult;

}

BOOL USB_Init(DEVICE_DATA *deviceData, PIPE_ID *PipeID)
{
    HRESULT hr;
    BOOL noDevice;
    BOOL bResult;
    USB_DEVICE_DESCRIPTOR deviceDesc;
    UCHAR DeviceSpeed;
    ULONG lengthReceived;

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

    if (FAILED(hr)) {

        if (noDevice) {

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

        }
        else {

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

        return FALSE;
    }

    //
    // Get device descriptor
    //
    bResult = WinUsb_GetDescriptor(deviceData->WinusbHandle,
        USB_DEVICE_DESCRIPTOR_TYPE,
        0,
        0,
        (PBYTE)&deviceDesc,
        sizeof(deviceDesc),
        &lengthReceived);

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

        wprintf(L"Error among LastError %d or lengthReceived %d\n",
            FALSE == bResult ? GetLastError() : 0,
            lengthReceived);
        CloseDevice(deviceData);
        return FALSE;
    }

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


    bResult = GetUSBDeviceSpeed(deviceData->WinusbHandle, &DeviceSpeed);
    if (!bResult)
    {
        CloseDevice(deviceData);

        return FALSE;
    }

    bResult = QueryDeviceEndpoints(deviceData->WinusbHandle, PipeID);
    if (!bResult)
    {
        CloseDevice(deviceData);

        return FALSE;
    }

    return TRUE;
}

3.编译生成DLL文件:

修改工程属性:

编译生成DLL文件:


win_usb_dll.zip (784.96 KB)
4.将生成的DLL与.h文件拷贝至matlab工作环境,打开matlab,切换工作环境至DLL所在文件夹中:

在命令行中使用如下函数,加载DLL与查看:

可以看到DLL加载成功。
编写m文件,简单测试回环通信:
clc

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

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

if(state == 1)
    disp('USB Connect')
   
str = [1 2 3 4 5]
    len = 0;
    wptr = libpointer('uint8Ptr',str);
    n_ptr = libpointer('uint32Ptr',len);
    state = calllib('USB_Dll','Write',wptr,n_ptr,length(str));
    if(state == 0)
        disp('USB error')
    else
        rptr = libpointer('uint8Ptr',zeros(1,64));
        state = calllib('USB_Dll','Read',rptr,63);
        if(state == 0)
            disp('USB error')
        else
            char(rptr.Value)
            calllib('USB_Dll','Close');
            disp('USB Disonnect')
        end
    end
else
    disp('USB do not open')  
end
一切正常:



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还能这样玩~~

使用特权

评论回复
5
duo点| | 2022-1-21 17:11 | 只看该作者
厉害,非常赞

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

77

主题

407

帖子

5

粉丝