调试基于STM32F429的USB功能,从通到不通再到通,花了好几个晚上,特记录一下,能帮到遇到同样问题的人就值啦!
原理图设计为STM32F429+USB3300实现高速USB串口(USB HS)。
调试时USB功能正常,设计USB Bootloader时,减化程序设计,去除了无用的外设初始化,结果发现不了USB外设。
反复调试时,还顺手发现并解决了一个Cube库中设备驱动的Bug:
USB驱动中加了软件Lock,操作时设置为1,释放时置0,避免访问冲突。
在库驱动中,初始化USB时,先置了Lock,然后初始化,之后再释放Lock。但是在初始化最后部分,先开了全局中断,再释放Lock,这在后再插入USB是没问题的,上电初始化时没有插入,不会有中断;但在调试时,设备是USB供电,USB一直是插在电脑上的,所以全局中断一开,立即进入中断,还未来得及做释放操作。中断服务函数中,在访问USB数据结构时,先判断是否Lock状态,结果因为没有释放Lock,导致服务程序运行异常,设备发现不了。
调整代码顺序,在开中断前先释放Lock,避免中断服务程序无法操作数据。
测试时发现问题依旧,单步调试,发现是STLib库在编译时,选择了优化选项,导致程序没有按照代码顺序执行,而是优化为先执行中断,再释放Lock,因为释放Lock操作在很多地方都有调用,所以被优化到统一位置执行,顺序放在了开中断之后。
将该驱动文件的编译优化选项设置为低后,该问题解决,不会再出现中断后Lock没释放的问题。
但USB不能正常工作的问题依旧,反复单步调试也查不到原因。无奈之举,重新从正常程序做减法,逐步去除无用外设的初始化,边去除边测试,直到发现USB工作不正常为止。此时发现有三个外设不能去除,一去除USB就出错。再仔细看这几个外设的初始化代码,发现里面都有使能IO Bank的操作,将这几个外设驱动中使能的IO Bank全部拿出来使能后,去除外设,再运行后USB工作正常。
结论:
仔细对比原理图与手册,设计中使用外置的USB PHY,一共使用了12个引脚,分别位于GPIOA、B、C、H、I 五个bank,但在驱动库的初始化中,只初始化了相应的引脚配置,并没有做引脚对应Bank的使能操作,导致没有使能的IO引脚没有正常工作,所以USB不正常。
此外,针对这种外置Phy的USB HS模式,由于Phy芯片使用了外置的24MHz晶振,所以没有使用MCU内部的PLL产生的48MHz时钟,因此不需要保证MCU初始化时钟时,PLL USB时钟为48MHz。
因此STM32F429可工作在180MHz主频。如果使用USB FS模式,则需要使用MCU产生的48MHz时钟,此时MCU只能工作在168MHz的降频模式,或192MHz的超频模式,不能工作在180MHz。