程序员

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

作者:admin 2021-06-30 我要评论

使用stm32cubeide的usb-host-cdc库驱动EC20模块 写在前面 开发环境 开始 一、使用 cubeide 创建 STM32 Project 二、修改代码 三、仿真 最后 写在前面 之前已经发...

在说正事之前,我要推荐一个福利:你还在原价购买阿里云、腾讯云、华为云服务器吗?那太亏啦!来这里,新购、升级、续费都打折,能够为您省60%的钱呢!2核4G企业级云服务器低至69元/年,点击进去看看吧>>>)

写在前面

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

本篇博文以教你使用STM32的CDC库驱动EC20模块成功为目的,不进行任何原理性说明。真正的小白操作指南,包教包会,也别发我私信RMB求代码了。我真的很缺钱,但是我也是从大家的开源代码和博文来学习和成长的。只希望你学会之后也多写一些好博文,帮助更多的单片机开发者。另外顺手帮我点个赞就好,谢谢。

开发环境:

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

开始

一、使用 cubeide 创建 STM32 Project

在这里插入图片描述
选择正点原子F407探索者使用的主芯片 STM32F407ZG,点next。

在这里插入图片描述
输入工程名称 “demo_ec20”,点Next

在这里插入图片描述
选择版本号 V1.26.1,点Finish

在这里插入图片描述
点RCC,在HSE栏选择 “Crystal/Ceramic Resonator”。

在这里插入图片描述

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

在这里插入图片描述
选择SYS,这里我用 J-link sw仿真,选择 Trace Asynchronous Sw。

在这里插入图片描述
选择下方 Connectivity 下的USART1, Mode选择Asynchronous,别的不用动

在这里插入图片描述
继续,选择 USB_OTG_FS, 选择 Host_Only,别的不用动。

在这里插入图片描述
选择 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

其他的不用动

在这里插入图片描述
右边找到芯片引脚 PA15,配置为GPIO_Output。

在这里插入图片描述
然后点左边GPIO,配置PA15引脚输出电平为高电平(USB供电引脚,高电平有效)

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

二、修改代码

在这里插入图片描述
第一步,找到usbh_cdc.h,第53行,修改为0xFFU

在这里插入图片描述
第二步,找到usbh_cdc.c,第158行修改部分如图所示

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

在这里插入图片描述
第三步,还是 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;
  }

在这里插入图片描述
第四步,依然是 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;

在这里插入图片描述
第五步,换 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);
	}
}

在这里插入图片描述
第六步, 不换文件,找到 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);
    	}
    }
}

在这里插入图片描述
第七步,修改代码的最后一步,在红框位置加一句代码

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

三、仿真

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述
第四步,看到EC20回复的信息 AT\r\nOK\r\n。

最后

附上本次实验创建的工程
链接: https://pan.baidu.com/s/1JG_861TkSUP_j2XnuWlmmw 提取码: f1nv

;原文链接:https://blog.csdn.net/gyzw_mx/article/details/115642075

版权声明:本文转载自网络,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本站转载出于传播更多优秀技术知识之目的,如有侵权请联系QQ/微信:153890879删除

相关文章
  • 阿里巴巴DevOps实践指南(八)| 以特性

    阿里巴巴DevOps实践指南(八)| 以特性

  • 阿里巴巴DevOps实践指南(五)| 业务驱

    阿里巴巴DevOps实践指南(五)| 业务驱

  • RISC-V工具链简介

    RISC-V工具链简介

  • 变局时代:RISC-V处理器架构的技术演变

    变局时代:RISC-V处理器架构的技术演变

腾讯云代理商
海外云服务器