STMCU小助手
发布时间:2021-8-20 14:17
最近某项目需要用到USB与CAN:
拿到这样的需求,我们当然是先得保证通讯正常。于是我找了一个USB例程与一个CAN例程,分别调试验证。 1 b/ U' U2 |3 C8 f& F6 D 经过几番折腾已经保证了USB与上位机能正常通讯了,也能保证了CAN的正常收发(拿了两块开发板做验证)。: L3 O9 }, J& O1 _; @ 3 [/ O: |' i$ u3 ~* [ 两头都没有问题了,再加上一些数据处理就差不多完成了。USB与CAN我都是第一次用,没想到那么顺利,美滋滋,正准备放松的时候,问题就来了。这是一个整体的东西,最终都要把这两部分集合起来吧。 * m% q% N' X5 m8 I7 Z1 [, D * l& w4 f, r" C 我把CAN工程里关于CAN的部分移到USB工程里,这时候CAN竟然用不了了。这时候我就开始在怀疑自己是不是手贱误删了哪里了,于是重新来一遍,发现还是不行。 4 g; ?/ A }2 @2 U, q1 |8 }6 J/ L 查了代码很久也没找出什么错误了,于是决定先不找错误了,进度要紧,这时候觉得应该是工程哪里有问题了,先想其它办法避过这个问题。 1 ?" \0 o/ b+ [8 n4 p( z* l7 {: D 1 |0 h, r/ \" ^* y 于是乎我就换着来,我把USB的工程里关于USB的部分移到CAN工程里。大家猜一猜发生了什么?USB竟然打都打不开!要炸了。。但是这时候已经很明确肯定不是移植问题了。CAN部分首先想到了波特率是不是对不上了,USB部分首先想到USB的时钟是从哪来的,之前没用过也没仔细看。带着这两个问题去查看了参考手册与代码,果然,STM32F429的USB的时钟还真有点特殊(不知道其它芯片是不是也是这样),其来自于PLL输出,而不是我们熟知的APB1、APB2:' }6 ~7 |7 o1 O: J: V) ~
" w2 i4 e2 _" X$ h5 M0 v7 U 4 Z4 L5 C m/ E# w 从时钟树中我们可以看出:(1)的输出是系统时钟,(2)的输出是USB时钟。相关公式:
当然(2)的输出不仅仅是给USB提供时钟,还给RNG与SDIO提供时钟:
* Y2 Z8 g, |1 G" D . D* B/ u! q1 ^3 K" G; ^7 L' F 这一部分对应的代码在system_stm32f4xx.c中。下面看看USB工程、CAN工程中该文件的差别:
5 g ]4 w# c7 h+ Z3 r ( }3 g: K0 |5 S1 a: q' Y9 z 可见,问题找出来了。在USB工程中,CAN通讯不正常是因为系统时钟降为168MHz,导致APB1时钟变为42MHz,而代码中是用APB1=45MHz来计算CAN的波特率的,所以导致波特率对应不上导致CAN通讯错误。 1 ]3 _0 K- f4 ?4 m 在CAN工程中,系统时钟为180MHz,USB OTG FS时钟变为51MHz,超过了正常的48MHz,导致USB不能正常工作。 - s; K& u, Z; Q. O7 K/ e 所以,每当用到USB,都得单独配置PLLCLK = 168MHz了,这样的话其他外设可能得改变原有的配置,比如这里的CAN就得用APB1=42MHz来计算波特率了,否则就会出错。
. E+ t/ S7 i& o G3 O: N g, H) |- A* Q# N# v 0 F' @) S- |4 G |
如何在STM32和Arduino上实现卷积神经网络
STM32与51单片机差异一文速览
入门嵌入式,为什么STM32是“优选起步”?
ARM9和STM32什么关系?
F429I-DISC1体验报告(5) 滚动菜单、语言切换的实现丨国庆开发板测评活动
F429I-DISC1体验报告(4) 温度可视化动态图表的实现丨国庆开发板测评活动
STM32串口自动识别波特率的原理
STM32云连接 干货都在这里!
STM32应用过程中与电源相关的案例分享
F429I-DISC1体验报告(3) 画板线条绘制和调色功能的实现丨国庆开发板测评活动
微信公众号
手机版