这段时间在研究机械故障诊断相关的内容,于是想做一个小型的加速度仪,拟设计采用STM32F1作为主控。本来是有外部晶振作为主时钟提供给STM32作为主时钟,但是为了进一步减小板子的尺寸,于是想了想把晶振去掉了,采用内部HSI作为晶振主控。

  但恰恰是这个设计,导致USB直接无法工作,果然是坏人绞尽脑汁,不如“蠢人”灵机一动。

  本期我们就来看看参考手册中的STM32的USB时钟部分描述。

STM32的USB接口

  STM32的USB接口是连接USB2.0到APB1总线的接口,并且强调,USB和CAN共用一块SRAM接口,所以不能和CAN同时使用。

  USB和CAN可以同时存在,但不能同时使用。

 STM32的USB接口是连接USB2.0到APB1总线的接口,并且强调,USB和CAN共用一块SRAM接口,所以不能和CAN同时使用。

  USB和CAN可以同时存在,但不能同时使用。

 USB外设部分的主时钟由PCLK1提供,并且要确保USB的时钟是48MHZ。有些人的USB不工作,就有可能是因为因为设计的时候时钟没对应。在STM32CubeMX中Clock的HSE默认是8MHZ,但是使用者如果设计了例如12MHZ的晶振,那么虽然在CubeMX中显示为USB时钟是48MHZ,但是实际的USB时钟是64MHZ导致USB不工作。 因此需要把HSE的时钟修改为真实的时钟,才能确保USB外设的正常工作。 USB的时钟来自于PLLCLK,而手册中也强调了HSI的时钟误差大,因此要采用HSE作为USB的时钟。

  这也是导致USB外设要用HSE的必要性。

USB的工作流程

 USB外设作为全速设备接口的工作始于硬件初始化阶段,首先通过RCC寄存器使能USB时钟,配置USB控制寄存器设置设备基本参数,并建立端点缓冲区描述符表以定义端点类型和双缓冲机制。设备上电后自动进入默认地址0状态,等待主机发起枚举流程——主机通过控制传输请求设备描述符,设备固件解析USB_EP0R寄存器的SETUP标志后,从Flash中读取预存的描述符,通过端点0的IN事务返回数据包,完成地址分配和配置切换。(文档23.4.1节)。

  进入运行状态后,数据传输由中断驱动。当主机发起IN/OUT事务时,USB外设触发传输完成中断,固件读取USB_ISTR寄存器识别事件源端点,随后操作对应端点的USB_EPnR寄存器:对于批量传输端点,双缓冲机制允许在A缓冲区传输时填充B缓冲区,通过切换ADDTOG/STAT_TX位实现零延迟切换;中断传输则利用NAK重试机制保证低延迟,当数据就绪时清除EP_KIND位发送数据;等时传输直接循环写入缓冲区,无需握手包。

 接收数据时,固件检查USB_EPnR的CTR_RX位,从指定缓冲区地址提取数据并重置缓冲区所有权。错误处理模块实时监测CRC错误或时钟失效,触发自动切换至HSI时钟恢复通信。

  总线空闲超过3ms时,USB外设自动进入挂起模式,关闭主时钟仅保留1.8V域供电)。此时设备可通过外部信号或远程唤醒恢复——固件设置USB_CNTR的RESUME位驱动总线K状态,主机检测到活动后重启时钟,设备在20ms内重建数据链路。整个生命周期中,描述符管理、缓冲区状态机和中断协同构成高效流水线,双缓冲设计显著提升批量传输吞吐率。

  工作流终结于软硬件协同关闭流程:固件禁用所有端点,清除USB_CNTR的PDWN位下电,最后关闭时钟。

总结

这种因为一个失误需要整个设计从头再来的错误也不是第一次了,在设计电路的时候不能用想当然,遇到问题了也不能轻言放弃。

  找到问题所在,积累经验正是电子工程师的必经之路。


嘉立创PCB

还没有评论,抢个沙发!