使用stm32cubeide的usb-host-cdc库驱动EC20模块

使用stm32cubeide的usb-host-cdc库驱动EC20模块

    • 写在前面
    • 开发环境:
    • 开始
      • 一、使用 cubeide 创建 STM32 Project
      • 二、修改代码
      • 三、仿真
    • 最后

写在前面

之前已经发布过一篇 “使用stm32cubemx的usb-host-cdc库驱动EC20模块”,但是近期有很多小伙伴私信询问相关问题。今天抽空重新浏览了一下上一篇博客,因为自己想表述的东西太多,写的有点乱。决定重新建立一个空工程,使用最新的 1.26.1 HAL库,按照原文配置方式,删除掉干扰代码,重写一篇博客,希望可以减少大家的疑问。

本篇博文以教你使用STM32的CDC库驱动EC20模块成功为目的,不进行任何原理性说明。真正的小白操作指南,包教包会。

开发环境:

  • 开发板:正点原子F407探索者
  • IDE: STM32CubeIDE 1.6.1

开始

一、使用 cubeide 创建 STM32 Project

使用stm32cubeide的usb-host-cdc库驱动EC20模块_第1张图片
选择正点原子F407探索者使用的主芯片 STM32F407ZG,点next。

使用stm32cubeide的usb-host-cdc库驱动EC20模块_第2张图片
输入工程名称 “demo_ec20”,点Next

使用stm32cubeide的usb-host-cdc库驱动EC20模块_第3张图片
选择版本号 V1.26.1,点Finish

使用stm32cubeide的usb-host-cdc库驱动EC20模块_第4张图片
点RCC,在HSE栏选择 “Crystal/Ceramic Resonator”。

使用stm32cubeide的usb-host-cdc库驱动EC20模块_第5张图片

点上边的 Clock Configuration,按如图所示配置时钟。刚开始Main PLL 后面的 “7” 是不可选的灰色状态,下文配置完USB_OTG_FS之后可以回来重新配置。

使用stm32cubeide的usb-host-cdc库驱动EC20模块_第6张图片
选择SYS,这里我用 J-link sw仿真,选择 Trace Asynchronous Sw。

使用stm32cubeide的usb-host-cdc库驱动EC20模块_第7张图片
选择下方 Connectivity 下的USART1, Mode选择Asynchronous,别的不用动

使用stm32cubeide的usb-host-cdc库驱动EC20模块_第8张图片
继续,选择 USB_OTG_FS, 选择 Host_Only,别的不用动。

使用stm32cubeide的usb-host-cdc库驱动EC20模块_第9张图片
选择 Middleware 标签下的USB_HOST

Class For FS IP 选择图示选项 Communication Host Class (Virtual Port com)

USBH_MAX_NUM_ENP… 3
USBH_MAX_NUM_INTER… 5
USBH_MAX_NUM_SUPP… 1
USBH_MAX_NUM_CONF… 4

其他的不用动

使用stm32cubeide的usb-host-cdc库驱动EC20模块_第10张图片
右边找到芯片引脚 PA15,配置为GPIO_Output。

使用stm32cubeide的usb-host-cdc库驱动EC20模块_第11张图片
然后点左边GPIO,配置PA15引脚输出电平为高电平(USB供电引脚,高电平有效)

完成所有配置以后,ctrl + s 保存配置,自动生成代码,所有弹出框全部点 yes。

二、修改代码

使用stm32cubeide的usb-host-cdc库驱动EC20模块_第12张图片
第一步,找到usbh_cdc.h,第53行,修改为0xFFU

使用stm32cubeide的usb-host-cdc库驱动EC20模块_第13张图片
第二步,找到usbh_cdc.c,第158行修改部分如图所示

//  interface = USBH_FindInterface(phost, COMMUNICATION_INTERFACE_CLASS_CODE,
//                                 ABSTRACT_CONTROL_MODEL, COMMON_AT_COMMAND);
  interface = USBH_FindInterfaceIndex(phost, 2, 0);

使用stm32cubeide的usb-host-cdc库驱动EC20模块_第14张图片
第三步,还是 usbh_cdc.c,注释掉 interface = …这两行,然后将图中画红色框框部分的5个Ep_Desc[0]修改为 Ep_Desc[2]

//  interface = USBH_FindInterface(phost, DATA_INTERFACE_CLASS_CODE,
//                                 RESERVED, NO_CLASS_SPECIFIC_PROTOCOL_CODE);

  if ((interface == 0xFFU) || (interface >= USBH_MAX_NUM_INTERFACES)) /* No Valid Interface */
  {
    USBH_DbgLog("Cannot Find the interface for Data Interface Class.", phost->pActiveClass->Name);
    return USBH_FAIL;
  }

  /*Collect the class specific endpoint address and length*/
  if (phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[2].bEndpointAddress & 0x80U)
  {
    CDC_Handle->DataItf.InEp = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[2].bEndpointAddress;
    CDC_Handle->DataItf.InEpSize  = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[2].wMaxPacketSize;
  }
  else
  {
    CDC_Handle->DataItf.OutEp = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[2].bEndpointAddress;
    CDC_Handle->DataItf.OutEpSize  = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[2].wMaxPacketSize;
  }

使用stm32cubeide的usb-host-cdc库驱动EC20模块_第15张图片
第四步,依然是 usbh_cdc.c,找到函数 USBH_CDC_ClassRequest,按如图所示修改。

//  status = GetLineCoding(phost, &CDC_Handle->LineCoding);
  CDC_Handle->data_rx_state = CDC_IDLE;
  CDC_Handle->data_tx_state = CDC_IDLE;
  CDC_Handle->LineCoding.b.bCharFormat = 0;
  CDC_Handle->LineCoding.b.bDataBits = 8;
  CDC_Handle->LineCoding.b.bParityType = 0;
  CDC_Handle->LineCoding.b.dwDTERate = 115200;
  status = USBH_OK;

使用stm32cubeide的usb-host-cdc库驱动EC20模块_第16张图片
第五步,换 usb_host.c,在 USER CODE BEGIN 0 部分添加如下代码。

uint8_t usb_buffer[256];
extern UART_HandleTypeDef huart1;

void USBH_CDC_ReceiveCallback(USBH_HandleTypeDef *phost)
{
	uint32_t len;
	len = USBH_CDC_GetLastReceivedDataSize(phost);
	if (len > 0)
	{
		HAL_UART_Transmit(&huart1, usb_buffer, len, 1000);
	}
}

使用stm32cubeide的usb-host-cdc库驱动EC20模块_第17张图片
第六步, 不换文件,找到 MX_USB_HOST_Process,修改

void MX_USB_HOST_Process(void)
{
	CDC_HandleTypeDef *CDC_Handle = hUsbHostFS.pActiveClass->pData;
  /* USB Host Background task */
  USBH_Process(&hUsbHostFS);
  if (hUsbHostFS.gState == HOST_CLASS)
    {
    	if (CDC_Handle->data_rx_state == CDC_IDLE)
    	{
    		USBH_CDC_Receive(&hUsbHostFS, usb_buffer, 256);
    	}
    }
}

使用stm32cubeide的usb-host-cdc库驱动EC20模块_第18张图片
第七步,修改代码的最后一步,在红框位置加一句代码

case HOST_USER_CLASS_ACTIVE:
  Appli_state = APPLICATION_READY;
  USBH_CDC_Transmit(&hUsbHostFS, (uint8_t *)"AT\r\n", strlen("AT\r\n"));
  break;

三、仿真

使用stm32cubeide的usb-host-cdc库驱动EC20模块_第19张图片

第一步,打开串口工具,选择com口,配置波特率,打开串口

使用stm32cubeide的usb-host-cdc库驱动EC20模块_第20张图片

第二步,连接J-link,插入ec20模块,点击debug

使用stm32cubeide的usb-host-cdc库驱动EC20模块_第21张图片

第三步,点击小三角继续运行

使用stm32cubeide的usb-host-cdc库驱动EC20模块_第22张图片
第四步,看到EC20回复的信息 AT\r\nOK\r\n。

最后

附上本次实验创建的工程
会员太贵了,赚点分,感谢支持:ec20.zip

你可能感兴趣的:(stm32,stm32,单片机,嵌入式,usb,驱动程序)