搜索
bottom↓
回复: 10

STM32F4 USB 总结

[复制链接]

出0入0汤圆

发表于 2015-9-2 18:44:45 | 显示全部楼层 |阅读模式
STM32F4  USBD_CDC总结
库版本号及各个文件介绍
(在文件中都有说明,仅仅翻译或加入自己理解)
版本号
  * @version V1.1.0
  * @date    19-March-2012
usb_bsp.c
usb硬件初始化(io口,高速全速设置、时钟、中断设置等)
usb_core.c
usb_otg,基本驱动功能,函数中都与寄存器直接打交道,对硬件进行操作
如:通过操作寄存器读写数据,读取硬件状态,模式等
usbd_core.c
设备基本功能,USBD_Init函数选择好枚举所需资料,通信所需类及接口。
该文件起承上启下作用,底层调用usb_core,上层完成对类接口的支持。
usbd_cdc_core.c
配置描述符枚举为CDC类设备,设置通信端点,提供了发送和接收数据时会调用的函数接口。
usb_dcd.c
外设接口,通信端点的打开关闭、发送、准备接收功能,设备的连接、断开功能
usb_dcd_int.c
外设中断服务处理,包括枚举及通信过程的中断,会根据类型调用相应的各层函数完成功能。
usbd_ioreq.c
控制端点接口
usbd_req.c
完成标准USB请求,第九章。
设备枚举所用,提供描述符、设置地址、配置等。
usbd_desc.c
定义设备描述符及字符串描述符
初始化
USBD_Init()
USB库的使用绝妙之处就在此处,从主程序中仅仅加入这个函数,然后后续就可以进行通信了,然而这个函数已经运筹帷幄,为所有做好布局了。
该函数仅仅是bsp初始化,对端点初始化、配置好中断;再就是指定描述符、类、用户的信息;然后等中断产生,由于早指定好了,自然会取到所需信息进行回复,或者调用所需函数进行发送接收。
入参一:USB_OTG_CORE_HANDLE *pdev,
总操作句柄,无论读写;只这一个全局结构体,囊括多如牛毛的寄存器、变量、函数、指针等均在内;不用再为满文件,满工程的全局变量而发愁。
入参二: USB_OTG_CORE_ID_TypeDef coreID,
全速还是高速。
入参三:USBD_DEVICE *pDevice,
指定设备描述符,字符串描述符;为后续枚举过程准备。   
入参四:USBD_Class_cb_TypeDef *class_cb,
                指定类回调函数结构,为后续通信铺垫。
USBD_Usr_cb_TypeDef *usr_cb
指定用户回调接口,比方说USB复位时,用户需要做什么呢,那么就会调用这里的函数,用户添加自己在usb复位时要做的动作即可。
描述符
(内容资料很多自己看,该描述符根据自己需要填写)
设备描述符
在usbd_desc.c中,枚举第一步就是要该描述符
配置描述符
在usbd_cdc_core.c中,usbd_cdc_CfgDesc该描述符包含所有的,包括配置描述符,接口描述符,端点描述符等。
            关于描述符,只需写好这两个就能枚举成功,且正常使用。
枚举大致中断过程
调用初始化函数后,然后等待中断
插入USB线(假设上位机驱动程序已安装好),会产生端点0中断,按默认地址通信。
中断查询设备描述符,由于早指定好了,所以会直接回复usbd_desc.c文件的USBD_DeviceDesc结构。
设置USB设备地址。
中断查询配置描述符,由于早指定好了,所以会直接回复usbd_cdc_core.c文件的usbd_cdc_CfgDesc结构。
由于USB通信主动权在主机,这样主机要什么我们就回复什么,由于早指定好了,在不知不觉中就完成了,期间可能出现,主机由于不知道描述符多长,那么第一次要前8个字节,然后再根据长度再获取一次全部要,通过监听通信,有时候出现来回几次要描述符,这都是正常的。
数据长度,及传输大致过程
端点最大长度,full模式为8、16、32、64,高速为512.
库里有个问题就是吧cdc数据包长度也设为64,那么每次通信最大为64了。
#define CDC_DATA_MAX_PACKET_SIZE       64 /* Endpoint IN & OUT Packet size */
#define CDC_DATA_OUT_PACKET_SIZE   CDC_DATA_MAX_PACKET_SIZE
我改掉了,就是用户不管底层每次传多少,不能限制我传输字节的数量,改为
   #define CDC_DATA_OUT_PACKET_SIZE   4096
           这样,我使用接收时,准备接收设置为:
  DCD_EP_PrepareRx(pdev, epnum,//CDC_OUT_EP1,
                   (uint8_t*)(USB_Rx_Buffer2),
                   CDC_DATA_OUT_PACKET_SIZE);
等接到4096或上位机发送一帧完成后才产生一次中断,而不是接收64字节就产生一次中断;这样收到一帧就是上位机发送的完整帧,就可以给应用层处理了
对于IN事物,可以直接调用
   DCD_EP_Tx (pdev,epnum,   (uint8_t*)USB_Tx_Buffer2,    USB_tx-len);
   发送任意长度数据。

使用者需要关心或修改的地方
STM32最恶心的地方就是很多硬BUG。
首先就是STM32F439声称可以达到180M,但180M情况下不能分配出USB工作所需的48M 时钟,智能配置为168M,开始没注意,USB运行不稳定。
USB_OTG全速接口有问题,勘误手册里写的很明白,如果不看,就被坑,我就被坑了,手册给出的解决方法是,用高速接口的全速模式代替全速接口,也就是说画pcb前我们就应该知道,所以我现在板子还飞线呢!!!
而高速接口你要看明白,不能直接用的,要外边接片子才能用,有没有让他给骗的,说这个片子有高速接口就这么画上了。
对于这个库的使用,需要修改地方
主程序调用USBD_Init函数
修改设备描述符
修改配置描述符
看看中断服务程序定义没
如果需要修改用户回调函数
收数据在usbd_cdc_DataOut中,这是中断,可以给应用程序提示受到数据。
发数据任何地方调用DCD_EP_Tx。如果定时发研究下usbd_cdc_SOF,这个每1毫秒执行一次,你可以随便干什么,当定时器的话不太准;如果连续发可以研究下usbd_cdc_DataIn,这是发送完成进的中断。无要求的话只用DCD_EP_Tx一般也没问题,也就发出去了。
不要怀疑每1毫秒中断一次的USB_SOF会影响我们的效率,每次中断假设1000个时钟周期,那么就是1M时钟周期每秒,我们主频是168M,怕什么。
发送数据时,最好主机已经准备接收了,如果没准备好,就会出现返回nak,那么单片机会不停的发送,这会影响效率,所以上位机要知道你让单片机发数据,那你就要尽快准备好(我试验是这样,但我自己觉得这样不太合理)。
由于IN事务是由上位机主动的,但单片机又没有上位机IN事务的中断,只有发送缓冲区空中断,也就是说这次发送要建立在上次传输完成缓冲区空基础上,那么第一帧单片机是怎么发的呢?是猜的上位机要数据的时间? 现在处理方法是,上位机用OUT事务告诉我,让单片机发送什么数据,然后单片机才开始发送,更像串口通信那样(这也是我觉得不够完美的地方,不知道是理解错了)
如果设备为从设备,且有自己的电源,那么USB插入电脑时,会枚举成功,但USB线拔下时,没有特殊中断,只有一个suspend中断,但不能作为拔出依据,别的情况也会产生这个中断,我的板卡拔下再次插入不进行枚举,然后屏蔽掉这段程序,就OK了,暂时这么解决了。DCD_HandleUSBSuspend_ISR();屏蔽掉睡眠和关时钟的程序。

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2015-9-2 19:08:47 | 显示全部楼层
文档章节怎么复制到这里边就没有了,其中还有很多疑问,也请大家解答讨论,感谢了

出0入53汤圆

发表于 2015-9-3 08:57:00 | 显示全部楼层
superganbu 发表于 2015-9-2 19:08
文档章节怎么复制到这里边就没有了,其中还有很多疑问,也请大家解答讨论,感谢了 ...

直接发工程文件,然后把需要第一眼可以看到的代码 复制到“<>”里面

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2015-9-4 13:59:39 | 显示全部楼层
顺便给个USB代码下载链接过来
http://www.embed-net.com/thread-171-1-1.html
http://www.embed-net.com/thread-18-1-1.html

出0入0汤圆

发表于 2015-9-4 14:33:52 | 显示全部楼层
USB 想用一直没用的外设

出0入0汤圆

发表于 2015-9-4 14:53:14 | 显示全部楼层
不错,谢谢楼主的总结。

出0入0汤圆

发表于 2015-9-4 21:30:09 | 显示全部楼层
一直在用stm32f103的USB-HID,但不知道F4的如何?

出0入4汤圆

发表于 2015-9-13 17:56:45 | 显示全部楼层
lz提到的单片机不停发送的事情我也碰到,如果PC没有接收,单片机就挂住了。大概是在不停的发送。这个很郁闷,理论上搞个超时机制,不至于死在那里。另外我在打开0x82 endpoint的时候,发现PC主机只能发数据给stm32f4,但是无法读,也在测试。。。中

出0入0汤圆

发表于 2015-9-13 20:55:15 | 显示全部楼层
ronic 发表于 2015-9-13 17:56
lz提到的单片机不停发送的事情我也碰到,如果PC没有接收,单片机就挂住了。大概是在不停的发送。这个很郁闷 ...

要解决单片机一直发数据的问题,可以考虑在PC端开启一个线程一直读数据,然后单片机就可以一直发送数据了

出0入0汤圆

发表于 2015-9-15 09:17:23 | 显示全部楼层
"USB"爱你不容易。

出0入0汤圆

发表于 2019-5-15 10:24:17 | 显示全部楼层
mark,usb总结的很好!!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-21 23:51

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表