GD32F4上使用Cube生成的HAL库实现USB虚拟串口调试总结

之前在项目中使用ST的芯片,为快速实现驱动,都是使用的stm32 cube直接创建项目工程,所以工程上都是基于HAL库开发的。最近在调试gd32f4xx芯片调试usb驱动,发现通过cube生成的工程无法在GD32上识别到USB设备,上电后出现:"设备描述符请求失败"的问题,所以,只能通过gd32的usb库进行移植,下面是记录基于stm32的HAL库工程去移植GD32提供的usb库过程:
第一部分:相关环境

  • 硬件芯片:GD32F425xx
  • 工具:STM32 Cube

第二部分:实现流程

  • 先通过stm32 cube生成一份基础工程,按以下步骤:
    1)打开cube,选择芯片型号:
    在这里插入图片描述
    选择调试模式,时钟源,配置好各总线时钟:
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述
    配置USB为从设备,因为板子硬件使用的是USB-HS口,所以在选择为USB-OTG_HS为从设备:

在这里插入图片描述
如果有使用到VBUS脚,就直接勾选:
在这里插入图片描述在USB_DEVICE下选择使用虚拟串口:
在这里插入图片描述同时,在选择对应的USB设备后,时钟配置界面也会相应的生效,需要进行调整,确保48MHZ时钟源,如下:
在这里插入图片描述
最后,在项目管理界面中填写目录路径,目录名称,选择打开工具,填写对应的堆栈大小(这里因用到USB库,需要调大):
在这里插入图片描述
选择需要添加库文件,是否分开源文件和头文件,再点击生成代码,完成编译即可。
在这里插入图片描述在这里插入图片描述
从GD官网上下载标定固件库:
https://www.gd32mcu.com/cn/download?kw=GD32F4xx_Firmware&lan=cn

2)把USB库有ST的替换成GD32的
把工程中根据ST相关的USB库删除(包括工程中的源文件及头文件目录),同时把GD32跟USB相关的文件直接加入到工程中:
在这里插入图片描述
在这里插入图片描述加进来后,肯定会报错误,包括工程中的睡眠模式相关函数pmu_to_deepsleepmode及微秒延时函数usb_udelay/usb_mdelay函数:
pmu_to_deepsleepmode是根usb进入休眠相关,可以直接注释掉。
usb_udelay:是us延时函数,直接自定义下,在函数里面加入几个__NOP();即可
usb_mdelay;是ms延时函数,直接用HAL_Delay代替
在这里插入图片描述
同时,usb_conf.h文件中也会报错,错误地方直接用下面方式代替:
在这里插入图片描述
其中,gd32f4xx_compat.h文件需要自定义,里面内容如下:
在这里插入图片描述

#ifndef GD32F4XX_COMPAT_H
#define GD32F4XX_COMPAT_H

/* bit operations */
#define REG32(addr)                  (*(volatile uint32_t *)(uint32_t)(addr))
#define REG16(addr)                  (*(volatile uint16_t *)(uint32_t)(addr))
#define REG8(addr)                   (*(volatile uint8_t *)(uint32_t)(addr))
#define BIT(x)                       ((uint32_t)((uint32_t)0x01U<<(x)))
#define BITS(start, end)             ((0xFFFFFFFFUL << (start)) & (0xFFFFFFFFUL >> (31U - (uint32_t)(end)))) 
#define GET_BITS(regval, start, end) (((regval) & BITS((start),(end))) >> (start))

#endif

对与入口main.c文件中,按如下修改:
添加头文件:
在这里插入图片描述

#include "stm32f4xx_hal_pcd.h"
#include "stm32f4xx_ll_usb.h"
#include "cdc_acm_core.h"

定义关于USB的全局变量:
在这里插入图片描述

PCD_HandleTypeDef hpcd_USB_OTG_HS;
usb_core_driver cdc_acm;

定义初始化USB口引脚的函数,调用GD提供的usb初始化协议库:
在这里插入图片描述

void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(pcdHandle->Instance==USB_OTG_HS)
  {
  /* USER CODE BEGIN USB_OTG_HS_MspInit 0 */

  /* USER CODE END USB_OTG_HS_MspInit 0 */

    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**USB_OTG_HS GPIO Configuration
    PB13     ------> USB_OTG_HS_VBUS
    PB14     ------> USB_OTG_HS_DM
    PB15     ------> USB_OTG_HS_DP
    */
    GPIO_InitStruct.Pin = GPIO_PIN_13;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF12_OTG_HS_FS;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* Peripheral clock enable */
    __HAL_RCC_USB_OTG_HS_CLK_ENABLE();

    /* Peripheral interrupt init */
    HAL_NVIC_SetPriority(OTG_HS_IRQn, 1, 0);
    HAL_NVIC_EnableIRQ(OTG_HS_IRQn);
  /* USER CODE BEGIN USB_OTG_HS_MspInit 1 */

  /* USER CODE END USB_OTG_HS_MspInit 1 */
  }
}

void HAL_PCD_MspDeInit(PCD_HandleTypeDef* pcdHandle)
{
  if(pcdHandle->Instance==USB_OTG_HS)
  {
  /* USER CODE BEGIN USB_OTG_HS_MspDeInit 0 */

  /* USER CODE END USB_OTG_HS_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_USB_OTG_HS_CLK_DISABLE();

    /**USB_OTG_HS GPIO Configuration
    PB13     ------> USB_OTG_HS_VBUS
    PB14     ------> USB_OTG_HS_DM
    PB15     ------> USB_OTG_HS_DP
    */
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15);

    /* Peripheral interrupt Deinit*/
    HAL_NVIC_DisableIRQ(OTG_HS_IRQn);

  /* USER CODE BEGIN USB_OTG_HS_MspDeInit 1 */

  /* USER CODE END USB_OTG_HS_MspDeInit 1 */
  }
}

static void MX_USB_HS_Init(void)
{
  hpcd_USB_OTG_HS.Instance = USB_OTG_HS;
  hpcd_USB_OTG_HS.Init.dev_endpoints = 6;
  hpcd_USB_OTG_HS.Init.speed = PCD_SPEED_FULL;
  hpcd_USB_OTG_HS.Init.dma_enable = DISABLE;
  hpcd_USB_OTG_HS.Init.phy_itface = USB_OTG_EMBEDDED_PHY;
  hpcd_USB_OTG_HS.Init.Sof_enable = DISABLE;
  hpcd_USB_OTG_HS.Init.low_power_enable = DISABLE;
  hpcd_USB_OTG_HS.Init.lpm_enable = DISABLE;
  hpcd_USB_OTG_HS.Init.vbus_sensing_enable = ENABLE;
  hpcd_USB_OTG_HS.Init.use_dedicated_ep1 = DISABLE;
  hpcd_USB_OTG_HS.Init.use_external_vbus = DISABLE;
  if (HAL_PCD_Init(&hpcd_USB_OTG_HS) != HAL_OK)
  {
    Error_Handler( );
  }
}

为实现USB模拟虚拟串口进行收发操作,在while循环中添加代码:
在这里插入图片描述

if (USBD_CONFIGURED == cdc_acm.dev.cur_status)
{
      if (0U == cdc_acm_check_ready(&cdc_acm)) {
          cdc_acm_data_receive(&cdc_acm);
      } else {
          cdc_acm_data_send(&cdc_acm);
      }
}

记录在USB_HS中断函数中添加GD相关的中断处理函数:
在这里插入图片描述
以上步骤都完成后,重新进行编译成功后,烧录到硬件上查看电脑上的虚拟串口,如下图:
在这里插入图片描述
打开串口,进行收发操作,如图:
在这里插入图片描述
到此,完成所有文件的替换,成功实现HAL库实现USB虚拟串口调试。

  • 13
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值