使用stm32cubeide的usb-host-cdc库驱动EC20模块
-
- 写在前面
- 开发环境:
- 开始
-
- 一、使用 cubeide 创建 STM32 Project
- 二、修改代码
- 三、仿真
- 最后
写在前面
之前已经发布过一篇 “使用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))
{
USBH_DbgLog("Cannot Find the interface for Data Interface Class.", phost->pActiveClass->Name);
return USBH_FAIL;
}
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;
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