之前已经发布过一篇 “使用stm32cubemx的usb-host-cdc库驱动EC20模块”,但是近期有很多小伙伴私信询问相关问题。今天抽空重新浏览了一下上一篇博客,因为自己想表述的东西太多,写的有点乱。决定重新建立一个空工程,使用最新的 1.26.1 HAL库,按照原文配置方式,删除掉干扰代码,重写一篇博客,希望可以减少大家的疑问。
本篇博文以教你使用STM32的CDC库驱动EC20模块成功为目的,不进行任何原理性说明。真正的小白操作指南,包教包会。
选择正点原子F407探索者使用的主芯片 STM32F407ZG,点next。
点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,别的不用动。
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
其他的不用动
然后点左边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.zip