1.设置CubeMx

STM32 HAL Custom HID

STM32 HAL Custom HID

STM32 HAL Custom HID

STM32 HAL Custom HID

STM32 HAL Custom HID

 

STM32 HAL Custom HID

STM32 HAL Custom HID

STM32 HAL Custom HID

2.代码

修改usbd_custom_hid_if.c中结构体数据:

__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END =
{
  /* USER CODE BEGIN 0 */
    0x06, 0x00, 0xff,              // USAGE_PAGE (Vendor Defined Page 1)
    0x09, 0x01,                    // USAGE (Vendor Usage 1)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x09, 0x01,                    //   USAGE (Vendor Usage 1)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
    0x95, 0x40,                    //   REPORT_COUNT (64)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0x09, 0x01,                    //   USAGE (Vendor Usage 1)
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
    0x95, 0x40,                    //   REPORT_COUNT (64)
    0x75, 0x08,                    //   REPORT_SIZE (8)
    0x91, 0x02,                    //   OUTPUT (Data,Var,Abs)
  /* USER CODE END 0 */
  0xC0    /*     END_COLLECTION                 */
};

确认下usbd_conf.h中以下三个宏定义:

/*----------输出数据长度 -----------*/

#define USBD_CUSTOMHID_OUTREPORT_BUF_SIZE     64
/*----------报文符长度,就是CUSTOM_HID_ReportDesc_FS结构体长度 -----------*/
#define USBD_CUSTOM_HID_REPORT_DESC_SIZE     34
/*----------这个是设置速度默认为5,速度可以达到16KB, 修改为1后速度为64KB -----------*/
#define CUSTOM_HID_FS_BINTERVAL     0x1

 

修改usbd_customhid.h文件中的发送与接收长度为64,原先默认值为0x02

  #define CUSTOM_HID_EPIN_SIZE                  0x40

  #define CUSTOM_HID_EPOUT_SIZE              0x40

 

USB 收到数据后会触发事件,在usbd_custom_hid_if.c中的CUSTOM_HID_OutEvent_FS函数,这里的程序将上位机发送数据后,下位机将数据发送回上位机。

static int8_t CUSTOM_HID_OutEvent_FS(uint8_t event_idx, uint8_t state)
{
  /* USER CODE BEGIN 6 */
    USBD_CUSTOM_HID_HandleTypeDef   *hhid; //定义一个指向USBD_CUSTOM_HID_HandleTypeDef结构体的指针
    hhid = (USBD_CUSTOM_HID_HandleTypeDef*)hUsbDeviceFS.pClassData;//得到USB接收数据的储存地址
    USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, hhid->Report_buf, 64);
    return (USBD_OK);
  /* USER CODE END 6 */
}

 

将程序刷入stm32.以下是上位机代码 vs2013 unicode 控制台版本。

// usb_stm32.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include <windows.h>
#include <setupapi.h>
 #include <hidsdi.h>
#include <locale.h>

#pragma comment(lib,"Setupapi.lib")
#pragma comment(lib,"Hid.lib")

#define     USB_VID         0x0483
#define     USB_PID         0x5750

void UsbOperation();
int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(LC_ALL, "chs");//设置中文显示
     UsbOperation();    
    return 0;
}

//获得设备路径,同时获取设备描述
void GetDevPath(TCHAR *pStrDevPath)
{
    TCHAR szDevPath[MAX_PATH] = { 0 };

    TCHAR szVid[20] = { 0 };
    TCHAR szPid[20] = { 0 };

    _stprintf_s(szVid, _T("vid_%04x"), USB_VID);
    _stprintf_s(szPid, _T("pid_%04x"), USB_PID);

    GUID Guid;
    HidD_GetHidGuid(&Guid);

    HDEVINFO info;
    info = SetupDiGetClassDevs(&Guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

    if (info == INVALID_HANDLE_VALUE)
    {
        return;
    }

    DWORD devIndex;
    SP_INTERFACE_DEVICE_DATA ifData;
    ifData.cbSize = sizeof(ifData);

    for (devIndex = 0; SetupDiEnumDeviceInterfaces(info, NULL, &Guid, devIndex, &ifData); ++devIndex)
    {
        DWORD needed;

        SetupDiGetDeviceInterfaceDetail(info, &ifData, NULL, 0, &needed, NULL);

        PSP_INTERFACE_DEVICE_DETAIL_DATA detail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)new BYTE[needed];
        detail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
        SP_DEVINFO_DATA did = { sizeof(SP_DEVINFO_DATA) };

        if (SetupDiGetDeviceInterfaceDetail(info, &ifData, detail, needed, NULL, &did))
        {
            if ((_tcsstr(detail->DevicePath, szVid) == NULL) || (_tcsstr(detail->DevicePath,szPid) == NULL ))
            {
                delete[](PBYTE)detail;
                continue;
            }

            _tprintf(_T("dev path: %s\r\n"), detail->DevicePath);
            _tcscpy_s(pStrDevPath, MAX_PATH, (TCHAR *)detail->DevicePath);
         
            TCHAR szProduct[MAX_PATH] = { 0 };
            if (SetupDiGetDeviceRegistryProperty(info, &did, SPDRP_DEVICEDESC, NULL, (PBYTE)szProduct, MAX_PATH, NULL))
            {
                _tprintf(_T("dev Prod: %s\r\n"), szProduct);
            }

            delete[](PBYTE)detail;
            break;
        }

        delete[](PBYTE)detail;
    }
    SetupDiDestroyDeviceInfoList(info); 
}

HANDLE OpenHidevice(TCHAR *pstrDevPath)
{
    HANDLE hidHandle = NULL;
    
    hidHandle = CreateFile(pstrDevPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    if (hidHandle != INVALID_HANDLE_VALUE)
    {
        PHIDD_ATTRIBUTES Attributes = (PHIDD_ATTRIBUTES)malloc(sizeof(HIDD_ATTRIBUTES));
        if (HidD_GetAttributes(hidHandle, Attributes))
        {
            printf("Info:  VID->0x%X PID->0x%X VersionNum->0x%X\r\n", Attributes->VendorID, Attributes->ProductID, Attributes->VersionNumber);
        }
    }
    return hidHandle;
}


void GetDeviceCapabilities(HANDLE hidDevObj, HIDP_CAPS &hidCaps)
{
    PHIDP_PREPARSED_DATA    hidPredata;
    HidD_GetPreparsedData(hidDevObj, &hidPredata);

    HidP_GetCaps(hidPredata, &hidCaps);

    printf("%s%X\r\n", "Usage Page:                      \t\t", hidCaps.UsagePage);
    printf("%s%d\r\n", "Input Report Byte Length:        \t\t", hidCaps.InputReportByteLength);
    printf("%s%d\r\n", "Output Report Byte Length:       \t\t", hidCaps.OutputReportByteLength);
    printf("%s%d\r\n", "Feature Report Byte Length:      \t\t", hidCaps.FeatureReportByteLength);
    printf("%s%d\r\n", "Number of Link Collection Nodes: \t\t", hidCaps.NumberLinkCollectionNodes);
    printf("%s%d\r\n", "Number of Input Button Caps:     \t\t", hidCaps.NumberInputButtonCaps);
    printf("%s%d\r\n", "Number of InputValue Caps:       \t\t", hidCaps.NumberInputValueCaps);
    printf("%s%d\r\n", "Number of InputData Indices:     \t\t", hidCaps.NumberInputDataIndices);
    printf("%s%d\r\n", "Number of Output Button Caps:    \t\t", hidCaps.NumberOutputButtonCaps);
    printf("%s%d\r\n", "Number of Output Value Caps:     \t\t", hidCaps.NumberOutputValueCaps);
    printf("%s%d\r\n", "Number of Output Data Indices:   \t\t", hidCaps.NumberOutputDataIndices);
    printf("%s%d\r\n", "Number of Feature Button Caps:   \t\t", hidCaps.NumberFeatureButtonCaps);
    printf("%s%d\r\n", "Number of Feature Value Caps:    \t\t", hidCaps.NumberFeatureValueCaps);
    printf("%s%d\r\n", "Number of Feature Data Indices:  \t\t", hidCaps.NumberFeatureDataIndices);
    HidD_FreePreparsedData(hidPredata);
}
 
void ReadUsbData(HANDLE hHidDevObj, DWORD dwCnt )
{
    DWORD NumberOfBytesRead;
    BYTE InputReport[256] = { 0 };
    BYTE OutputReport[256] = { 0 };
    DWORD bytes = 0;
    int Result = 0;

    for (DWORD i = 0; i < dwCnt; i++)
    {
        OutputReport[i] = (BYTE)i;
    }

    while (TRUE)
    {
        if (hHidDevObj != INVALID_HANDLE_VALUE)
        {
            //CancelIo(hHidDevObj);
            OutputReport[1] ++;//OutputReport[0]代表报告ID
            Result = WriteFile(hHidDevObj, OutputReport, dwCnt, &bytes, NULL);
            Result = ReadFile(hHidDevObj, &InputReport, dwCnt, &NumberOfBytesRead, NULL);
            for (DWORD i = 0; i < dwCnt; i++)
            {
                printf(" %d ", InputReport[i]);
            } 
        }

        Sleep(1000);
        printf("\r\n\r\n");
    }
}

void UsbOperation()
{
    TCHAR strDevicePath[MAX_PATH] = { 0 };
    HANDLE HidDeviceObject = INVALID_HANDLE_VALUE;
    HIDP_CAPS hidCap = { 0 };
    
    BYTE OutputReport[256] = { 0 };

    GetDevPath(strDevicePath);
    HidDeviceObject = OpenHidevice(strDevicePath);
    GetDeviceCapabilities(HidDeviceObject, hidCap);
    ReadUsbData(HidDeviceObject, hidCap.InputReportByteLength);
}

 

测试结果:

STM32 HAL Custom HID

相关文章:

  • 2021-12-02
  • 2021-09-25
  • 2021-12-18
  • 2021-10-26
  • 2021-11-07
  • 2021-05-03
  • 2021-07-08
  • 2022-12-23
猜你喜欢
  • 2021-07-19
  • 2021-10-10
  • 2021-04-02
  • 2021-08-28
  • 2021-07-01
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案