65.9K
CodeProject 正在变化。 阅读更多。
Home

STM32 板上的 I/O 设备实现框架

starIconstarIconstarIconstarIconstarIcon

5.00/5 (9投票s)

2021 年 7 月 15 日

CPOL

3分钟阅读

viewsIcon

13546

STM32 开发板的功能概述

先决条件

要开始,您需要安装 STM32CubeIDE STM32CubeProg,之后您需要获取一个 ST-LINK V2 设备和一个 STM32F411CEU6 开发板,通常被称为 Black Pill 开发板。

特性丰富度和性能比较

  • Black pill > Blue/Red/Purple pill > Green pill > Arduino 板

基本 API 函数列表

GPIO_PIN_SETGPIO_PIN_RESET 的名称来自 SR 触发器 (learnabout-electronics.org)

  • HAL_GPIO_WritePin()
    void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin,
                           GPIO_PinState PinState);
    
    HAL_GPIO_WritePin(GPIOE, LED1_Pin, GPIO_PIN_SET);      // LED1 is turned on 
    HAL_GPIO_WritePin(GPIOE, LED1_Pin, GPIO_PIN_RESET);    // LED1 is turned off 
    
  • HAL_GPIO_ReadPin()
    GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
    
    GPIO_PinState LED1_PinState = HAL_GPIO_ReadPin(GPIOE, LED1_Pin);
    HAL_GPIO_WritePin(GPIOE, LED2_Pin, LED1_PinState);
    HAL_GPIO_WritePin(GPIOE, LED3_Pin, LED1_PinState);
    
  • HAL_Delay()
    void    HAL_Delay(uint32_t Delay);
    
    HAL_Delay(500);    // Wait 500 ms

引导加载程序编程

STM32CubeIDE 中,创建一个新项目,将 STM32F411CEU6 作为商品编号

然后按顺序执行这些操作

  1. 下一篇
  2. 项目命名
  3. 结束
  4. 等待软件包下载

您现在看到的是所选的 MCU

为了能够关注正常或编程模式,LED 可以帮助实现这一点。

左键单击 PB10 引脚,选择 GPIO_Output ,然后在 System Core 选项卡中,选择该引脚并将其输出电平设置为高电平。

在电子板上,将 LED 物理连接到 B10 引脚并将其接地。

然后我们必须设置一个时钟设备(System Core 选项卡)

之后,我们可以在 Connectivity 和 Middleware 选项卡中设置 USB 功能

我们选择 自定义 HID 类 而不是 HID 类,因为 自定义 HID 类 提供了读取 HID 数据包的可能性。

打开 Clock Configuration 选项卡,点击 Resolve Clock Issues,然后按 Ctrl-S 生成代码

单击锤子附近选择 Release 以生成 elf 格式的二进制文件。

抓住您的 STM32 板,并将其背面引脚连接到 ST-LINK V2 的相应引脚

  • 3.3V 3.3V
  • SWCLK SWCLK
  • GND GND
  • SWDIO SWDIO

完成后,将 ST-LINK V2 连接到 PC。

STM32CubeProgrammer 中,单击 Connect 按钮,然后单击 + 按钮访问 Open File

选择在创建的 STM32CubeIDE 项目的 Release 文件夹中的 *.elf 文件,然后单击 Download 按钮,然后通过 USB-C 端口将 STM32 板插入 PC。

要查看新创建的设备出现在 Windows 上,您只需按板载的 NRST 按钮,您应该看到此,由于未设置 HID 报告描述符,因此出现错误。

固件编程

回到 STM32CubeIDE,您需要修改一些数据来准备设备。

\USB_DEVICE\App\usbd_desc.c

使用这些新值更新这些定义

#define USBD_VID                        0x0001
#define USBD_PID_FS                     0x0001
#define USBD_LANGID_STRING              1033
#define USBD_MANUFACTURER_STRING        "Manufacturer Name"
#define USBD_PRODUCT_STRING_FS          "Product Name"
#define USBD_CONFIGURATION_STRING_FS    "Configuration Name"
#define USBD_INTERFACE_STRING_FS        "Interface Name"

\USB_DEVICE\App\usbd_custom_hid_if.c

CUSTOM_HID_ReportDesc_FS[] 替换为

enum HID_Helper
{
    IN_REPORT_ID     = 0x02,
    IN_REPORT_SIZE   = 8,       // Bit size of one HID packet
    IN_REPORT_COUNT  = 2,       // Number of HID packets

    OUT_REPORT_ID    = 0x01,
    OUT_REPORT_SIZE  = 8,       // Bit size of one HID packet
    OUT_REPORT_COUNT = 2,       // Number of HID packets
};

// Set USBD_CUSTOM_HID_REPORT_DESC_SIZE to 33
__ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE]
__ALIGN_END =
{
    0x06, 0x00, 0xFF,           //  USAGE_PAGE (Vendor Specific)
    0x09, 0x01,                 //  USAGE (1)
    0xA1, 0xFF,                 //  COLLECTION (Vendor Specific)

    0x15, 0x00,                 //      LOGICAL_MINIMUM (0)
    0x26, 0xFF, 0x00,           //      LOGICAL_MAXIMUM (255 possibilities = 2 ^ 8 bits)

    0x85, IN_REPORT_ID,         //      REPORT_ID (2)
    0x75, IN_REPORT_SIZE,       //
    0x95, IN_REPORT_COUNT,      //
    0x09, 0x00,                 //      USAGE (0)
    0x81, 0x00,                 //      INPUT (Data,Ary,Abs)

    0x85, OUT_REPORT_ID,        //      REPORT_ID (1)
    0x75, OUT_REPORT_SIZE,      //
    0x95, OUT_REPORT_COUNT,     //
    0x09, 0x00,                 //      USAGE (0)
    0x91, 0x00,                 //      OUTPUT (Data,Ary,Abs)

    0xC0                        //  END_COLLECTION
};

要了解有关 HID 报告描述符的更多信息,您可以浏览 人机接口设备 (HID) 信息 | USB-IF

\Middlewares\ST\STM32_USB_Device_Library\Class\CustomHID\Src\usbd_customhid.c

USBD_CUSTOM_HID_SendReport() 之后添加以下代码

uint8_t USBD_CUSTOM_HID_SendReport(USBD_HandleTypeDef* pdev, uint8_t* report, uint16_t len)
{
    //
    // ...
    //
}

extern  USBD_HandleTypeDef hUsbDeviceFS;
void    HID_Send(uint8_t* Data, uint16_t Size)
{
    USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, Data, Size);
}

USBD_CUSTOM_HID_ReceivePacket() 之后添加以下代码

uint8_t USBD_CUSTOM_HID_ReceivePacket(USBD_HandleTypeDef *pdev)
{
    //
    // ...
    //
}

// Set USBD_CUSTOMHID_OUTREPORT_BUF_SIZE to 3
void    HID_Read(uint8_t* Data)
{
    USBD_HandleTypeDef*             pdev = &hUsbDeviceFS;
    USBD_CUSTOM_HID_HandleTypeDef*  hhid;

    hhid = (USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];

    memcpy(Data, hhid->Report_buf, USBD_CUSTOMHID_OUTREPORT_BUF_SIZE);
}

现在我们准备好开始编写固件(在该 IDE 中也称为 App)。

\Core\Src\main.c

将  main() 替换为

enum       HID_Helper
{
    RID_SIZE         = 1,    // Report ID is 1 byte size

    IN_REPORT_COUNT  = 2,
    OUT_REPORT_COUNT = 2,

    IN_REPORT_ID     = 0x02,
    OUT_REPORT_ID    = 0x01,
};

uint8_t HostOutBuffer  [RID_SIZE + OUT_REPORT_COUNT];
uint8_t HostInBuffer   [RID_SIZE + IN_REPORT_COUNT ];

uint8_t DeviceOutBuffer[RID_SIZE + OUT_REPORT_COUNT];
uint8_t DeviceInBuffer [RID_SIZE + IN_REPORT_COUNT ];

int        main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_USB_DEVICE_Init();

    while (1)
    {
        //
        // Copy data sent by the PC
        //
        HID_Read(DeviceOutBuffer);

        //
        // Build IN buffer with the data
        //
        DeviceInBuffer[0] = IN_REPORT_ID;
        DeviceInBuffer[1] = DeviceOutBuffer[1];
        DeviceInBuffer[2] = DeviceOutBuffer[2];

        //
        // and send it back to PC for feedback purpose
        //
        HID_Send(DeviceInBuffer, RID_SIZE + IN_REPORT_COUNT);

        HAL_Delay(500);
    }
}

现在,我们拥有一个 STM32 板,该板能够获取可以从 PC(也称为主机设备)配置的数据,并且能够将此数据传输回主机设备。

最后,我们可以重建并将新的二进制文件上传到 STM32 板。

为了能够与此板交互,我们可以使用两种工具。

一个 USB 嗅探器,例如 Busdog 和一个 USB HID 通信工具

FS 代表 USB 规范的全速

LS  =  Low Speed  =   1.5 Mbps
FS  = Full Speed  =  12   Mbps
HS  = High Speed  = 480   Mbps
SS  = SuperSpeed  =   5   Gbps
SS+ = SuperSpeed+ =  10   Gbps
SS+ = SuperSpeed+ =  20   Gbps

历史

  • 2021 年 7 月 16 日:初始版本
© . All rights reserved.