stm32F103zet6 custom hid usb 分包发送大容量数据的方法

本文介绍如何使用STM32F103ZET6单片机通过USB定制HID设备发送大容量数据。通过CubeMX配置相关参数,实现数据拆包分包发送。注意静态内存分配和40ms的延时以避免数据丢失。提供分包发送的代码示例。

目标:利用cube MX 工具生成custom hid usb设备代码,配置相关参数,实现利用custom hid usb传送大容量数据的功能

实现思路:stm32f103zet6单片机内置usb2.0模块,每次上传数据最大64字节一包,所以如果想要上传一个比如1024字节的数组,那么就需要进行拆包,然后分包发送。

注意事项:

  1. 我在调试过程中,把自定义的uint8_t array[1000];数组放到了main函数中, 结果程序下载完毕,单片机直接卡死,改成static uint8_t array[1000];即可。

  1. 每发送一包后要有一个40ms的延时,如果延时过低,那么就会在上位机没取完缓冲区的数据的情况下继续发送下包导致数据发送缺失的情况出现

  1. 发送每一包之前都要线清空一下发送缓冲区

分包发送代码如下

#define USB_TX_BUFFER_SIZE 64
uint8_t USB_Tx_Buffer[USB_TX_BUFFER_SIZE];
void USB_send_data_split(uint8_t* data, uint32_t len)
{
    uint32_t sent = 0;
    while (sent < len) 
    {
        uint32_t to_send = MIN(len - sent, USB_TX_BUFFER_SIZE);//计算每一包的长度(即指针每一次移动的距离),针对最后一包长度不足USB_TX_BUFFER_SIZE的情况
        memset(USB_Tx_Buffer, 0, sizeof(USB_Tx_Buffer));//清空发送缓冲区
        memcpy(USB_Tx_Buffer, data+sent, to_send);//把一包数据放到发送缓冲区上
        //HAL_UART_Transmit_DMA(&huart1,USB_Tx_Buffer,sizeof(USB_Tx_Buffer));//串口输出检查分包是否正确
        while (USBD_CUSTOM_HID_SendReport_FS(USB_Tx_Buffer, USB_TX_BUFFER_SIZE) != USBD_OK) ;//发送数据等待发送完毕继续
         
        sent += to_send;//指针移动to_send个数据,指向下一包首地址
        HAL_Delay(40);//不加这个延时,可能会造成上位机接收不全信息的情况
    }
}

头文件包含该函数

void USB_send_data_split(uint8_t* data, uint32_t len);

主函数代码如下

int main(void)
{
  /* USER CODE BEGIN 1 */
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_RTC_Init();
  MX_USB_DEVICE_Init();
  MX_USART1_UART_Init();
  MX_ADC1_Init();
  /* USER CODE BEGIN 2 */
    //srand((unsigned int)time(NULL));//生成随机数种子
    //uint8_t random = rand() % 61+40;//随机数生成,范围为40~(61+40)
    custom_printf ("开始\n");
    uint16_t AD1_VALUE;//定义ad采样值变量
    static uint8_t array[1000];
    for(uint16_t  i=0;i<sizeof(array);i++)
    {
        array[i] = i & 0xff;
    }
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
        HAL_GPIO_TogglePin(LED1_GPIO_Port , LED1_Pin);//LED闪烁
      USB_send_data_split(array,sizeof(array));//通过usb发送array数组
      //AD1_VALUE = Get_AD1_VALUE();//通过dma通道获取ad采样的值
      //custom_printf("Random number: %d\r\n", AD1_VALUE);
    //USBD_CUSTOM_HID_SendReport_FS(array,64);//hid usb发送数据a
      //HAL_UART_Transmit_DMA(&huart1,array,sizeof(array));
      
      
        HAL_Delay(1000);
  }
  /* USER CODE END 3 */
}

可以正确接收数组的值

程序工程文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值