当前位置:首页 > 单片机 > 单片机
[导读]1 前言本文将基于STM32F4DISCOVERY板,介绍如何使用USB的CDC类进行开发,以及在开发过程中碰到发送64整数倍数据时会失败的问题分析及解决方案。2 硬件介绍在创建工程之前,我们首先即将使用的硬件进行必要的介绍。图

1 前言

本文将基于STM32F4DISCOVERY板,介绍如何使用USB的CDC类进行开发,以及在开发过程中碰到发送64整数倍数据时会失败的问题分析及解决方案。

2 硬件介绍

在创建工程之前,我们首先即将使用的硬件进行必要的介绍。


图1 USB电路


如上图所示,USB电路使用PA11,PA12,全速USB OTG,当然,这里只做device,英雌只需要看上图的下面部分。


图2 按键电路


如上图,本例中将使用到1个用户按键,PA0,按下时为1电平。
另外,晶振使用的是外部HSE 8M晶振。


3 创建CubeMx工程

打开CubeMX(V4.17.0),创建一个以STM32F407VGTx的工程,使用FS-USB,并使用PA0外部输入EXIT,如下图所示:


图3 pinout


使能外部HSE,使用外部8M HSE,其时钟树如下设置:


图4 时钟树


接下来是配置参数,这里只修改USB中断优先级为1,而PA0的外部中断优先级设置为4,如下:


图5 中断优先级设置


然后再中间件将USB class设置为Communicaiton Device Class,如下:


图6 USB Class设置


最后将工程的堆设为0.5K,栈设为1.5K :


图7 堆栈设置


最后生成一个 F407_CDC_Test的工程。


4 修改工程代码

我们对生成的工程不做任何修改,直接编译后烧进开发板后是可以被PC识别为虚拟串口的,如下图所示:


图8 PC识别为虚拟串口


当然,这里的前提是必须在PC机上安装了ST发布的虚拟串口驱动(STSW-STM32102下载地址 :http://www.st.com/content/st_com/en/products/development-tools/software-development-tools/stm32-software-development-tools/stm32-utilities/stsw-stm32102.html)。


(注意:这里所说的虚拟串口主要是指其可以被当做串口来用,但其速度跟串口所设置的波特率完全没有关系,用户不要被名字所迷惑,虽然使用起来跟串口没有区别,但其本质还是USB,在初始化设置波特率不会对USB的通讯速率产生任何影响,本文档所描述的是全速USB,因此,其最大速率就固定为12M/S,这个是由全速USB外设标准48M输入时钟所决定的)

此时是没有任何具体功能的,为了更好的看到通讯的数据,我们将使用串口通讯工具来进行测试,这里我们使用的串口工具是: sscom32.

4.1 验证接收功能

我们将使用PC串口工具SSCOM32通过USB向MCU发送数据,为了能在PC端能看到MCU是否能接收到数据,我们在MCU端修改代码,让MCU一旦接收到来自PC端的数据后,立马返回一模一样的数据,因此需要在生成的源码文件usbd_cdc_if.c文件中找到到函数:CDC_Receive_FS(),添加处理函数,如下:

staticint8_tCDC_Receive_FS(uint8_t*Buf,uint32_t*Len){/*USERCODEBEGIN6*/HanldeReceiveData(Buf,*Len);USBD_CDC_SetRxBuffer(&hUsbDeviceFS,&Buf[0]);USBD_CDC_ReceivePacket(&hUsbDeviceFS);return(USBD_OK);/*USERCODEEND6*/}/*USERCODEBEGINPRIVATE_FUNCTIONS_IMPLEMENTATION*/staticvoidHanldeReceiveData(uint8_t*Buf,uint32_tLen){CDC_Transmit_FS(Buf,Len);}/*USERCODEENDPRIVATE_FUNCTIONS_IMPLEMENTATION*/12345678910111213141516171234567891011121314151617

编译后烧进板子进行验证:


图9%20MCU接收返回相同数据


如上如所示,串口工具能够收到来自MCU的返回数据,与发送数据完全一样,这说明,MCU已经接收到了PC端发送的数据,另外,PC端也能接收到MCU端发送的数据。


4.2%20验证发送功能

接下来我们来通过按键响应来主动向PC端发送数据,我们在按键回调函数内添加代码如下:

/*USERCODEBEGIN0*/staticuint8_tSendData[256]={0};voidHAL_GPIO_EXTI_Callback(uint16_tGPIO_Pin){uint16_ti;for(i=0;i

即用户按下按键,MCU则向PC端发送一次数据,这里发送的是63个字节,内容为0~62,测试后PC端的串口工具完全能收到MCU端发送的63个字节,如下图所示:


图10 PC端收到63个字节


但是当我们将代码修改为发送64个字节后 :


/*USERCODEBEGIN0*/staticuint8_tSendData[256]={0};voidHAL_GPIO_EXTI_Callback(uint16_tGPIO_Pin){uint16_ti;for(i=0;i

修改后进行验证,发现PC端串口工具不能接收到数据,,这里代码基本完全没有变化,只是发送长度之前为63,这里为64,结果却不相同,很明显,USB CDC协议栈哪里出了问题。

我们先使用USB分析仪对发送64个字节时进行USB总线监控:


图11 USB数据监控


如上图,我们发现,当发送64个字节时,由于正好是最大包长(64),按USB标准来看,应该多发一次空的transaction,但是这里,仅仅只发了一次transaction,这也就是为什么串口没有接收到数据的原因(MCU端的USB实际上是已经发送了64个字节,但由于缺少一个transaction,因此PC端的驱动会认为数据格式不完整,而放弃所有已经接收到的数据,从而使上层看起来没有接收到任何内容)。


图12 USB2.0标准对于最大包长整数倍的要求


因此,接下来的工作就是找到USB协议栈中的相应处理环节,然后将缺少的那个空的transaction补上即可。


4.3 USB CDC协议栈修改4.3.1 USB数据发送流程分析

在对USB CDC协议栈进行修改之前,我们先来梳理下USB发送的流程。
发送USB数据大概过程如下:
1> 填写DIEPTSIZ寄存器的发送包数(pakage count)和传输大小(transfer size)。
2> 使能发送断点的发送空中断(DIEPEMPMSK,利用发送空中断TXFE来将发送数据填充到DFIFO)。
3> 使能中断。
4> 后续就是中断的事了。
后续将会有3次中断:
1> USB_OTG_DIEPINT_TXFE中断:在此中断处理中,程序将发送缓冲的数据分包填充到DFIFO(不能超过最大包长,只有最后一包数据才有可能小于最大包长)。
2> USB_OTG_DIEPINT_TXFE中断: 还是TXFE中断,上次TXFE填充的发送数据全部发送完了后,最终还是会继续触发TXFE中断,也就是这次中断,在这次FXFE中断中禁止FXFE。也就是说,后续不会再有TXFE中断,除非再次使能。
3> USB_OTG_DIEPINT_XFRC中断:传输完成中断,表示到这次中断为止,传输完成。在这个中断中将回调HAL_PCD_DataInStageCallback()函数,就相当于发送中断一样。
这就是USB数据发送的流程,这里需要注意地是,对于端点0和非端点0来说,在具体流程实现上还是稍微有所差异的。究其原因,主要是端点0和非端点0的DIEPTSIZ寄存器的包大小和传输大小位宽是不一样的。如下图:


图13 端点0的DIEPTSIZ寄存器



图14 端点1~3的DIEPTSIZ寄存器


对比上图,端点0的DIEPTSIZ寄存器的XFRSIZ位宽为7,最大值为127,也就是说最多一次只能传输127个字节,按最大包长64字节来算,就是是最多两包数据。如果需要发送超过127个字节时,又该如何做呢?查看USB协议栈内核代码,发现每次端点0发送数据时,在发送代码中固定每次最多可以传输64字节,然后在传输完成中断处理时,再将剩下的数据接着传输(usb core),当然,每次传输最多也是64个字节,就这样,直到发送完所有数据为止。为什么每次传输最大设置为64?不是XFRSIZ位宽为7,理论上可以为127吗?我的理解是,这样也是可以的,只要包长控制在64个字节内就可以了,至于每次传输多少字节,只要XFRSIZ位宽够用,你可以设置127个字节范围内任何数据均可。代码中设置为64,主要为了图方便。


但是,对于非端点0,XFRSIZ位宽为19位,524288个字节,足够传输所有实际数据了,因此,在发送代码中,并没有限定传输数据的长度,在TXFE中断中也能将所有待发送的字节填入DFIFO。但是,当发送的数据刚好是64的整数倍时,按USB标准,应该继续发送一次空字节,以表示数据全部发送完毕。

4.3.2 代码修改

对比端点0的处理,发现端点0在传输完成中断(XFRC)中,有对这种情况的判断,一旦检测到这种情况,则会发送一次空传输。如下:
usb_core.c文件中的USBD_LL_DataInStage()函数 :

USBD_StatusTypeDefUSBD_LL_DataInStage(USBD_HandleTypeDef*pdev,uint8_tepnum,uint8_t*pdata){USBD_EndpointTypeDef*pep;if(epnum==0){pep=&pdev->ep_in[0];if(pdev->ep0_state==USBD_EP0_DATA_IN){if(pep->rem_length>pep->maxpacket){pep->rem_length-=pep->maxpacket;//继续发送剩余数据USBD_CtlContinueSendData(pdev,pdata,pep->rem_length);/*Prepareendpointforprematureendoftransfer*/USBD_LL_PrepareReceive(pdev,0,NULL,0);}else{/*lastpacketisMPSmultiple,sosendZLPpacket*/if((pep->total_length%pep->maxpacket==0)&&(pep->total_length>=pep->maxpacket)&&(pep->total_lengthep0_data_len)){//再多发送一次空数据USBD_CtlContinueSendData(pdev,NULL,0);pdev->ep0_data_len=0;/*Prepareendpointforprematureendoftransfer*/USBD_LL_PrepareReceive(pdev,0,NULL,0);}else{if((pdev->pClass->EP0_TxSent!=NULL)&&(pdev->dev_state==USBD_STATE_CONFIGURED)){pdev->pClass->EP0_TxSent(pdev);}USBD_CtlReceiveStatus(pdev);}}}if(pdev->dev_test_mode==1){USBD_RunTestMode(pdev);pdev->dev_test_mode=0;}}elseif((pdev->pClass->DataIn!=NULL)&&(pdev->dev_state==USBD_STATE_CONFIGURED)){pdev->pClass->DataIn(pdev,epnum);//非0端点回调CDC类的DataIn()函数处理}returnUSBD_OK;}12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364651234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭