你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F103 CAN通信波特率的计算方法

[复制链接]
STMCU-管管 发布时间:2021-2-20 13:29
STM32F103 CAN通信波特率的计算方法
前言. y$ T0 x$ O* C
最近看一下CAN通信,翻出来之前做过的STM32 CAN通信的项目代码,有些概念比较模糊了,如波特率是怎么计算的。
$ S0 p! {- C7 z
6 x0 q. M3 f4 I: B) c7 [

' h* s5 P+ ~% f0 f最近接触rt-thread比较多,想把之前的CAN通信的代码,移植到RTOS上。/ w3 _5 q3 V& q: t
$ `9 Z  ?9 [: N8 |5 \9 m

- L/ g4 ?( X; D; p
$ q* |* U$ C( ~- c% I# ?6 P* PCAN波特率
/ z6 ]2 N1 S# C: _如果主机与从机,波特率不一致,很难正常的通信。
5 [& c  w. b1 T6 n) G0 X. `, S+ r) h& x9 L  P
计算方法5 W6 m% i8 c  Y, U7 d

% q$ D3 j) T0 w; q这里的500Kbps,是怎么计算出来的?4 R7 ^' V$ l9 G) M' ?
/*& c% A4 u4 i  @$ P) c% q
* 函数名:CAN_Mode_Config: F' G. T) m' T
* 描述  :CAN的模式 配置
! A1 `- N# B# I- P" o; V * 输入  :无
/ D' \& q) w8 t0 _1 i * 输出  : 无
6 q2 Z: N3 O$ F( z+ w2 t * 调用  :内部调用' ?- j5 `. {& @3 j$ u0 s$ W$ V+ U/ c3 x
*/
) A8 \+ Q2 R8 f1 ^static void CAN_Mode_Config(void)
' f: D& @0 S' b) c" G% V+ g2 F( I{
. X# n( C  O! i  }0 b8 N1 d8 c; P. o, a9 S    CAN_InitTypeDef        CAN_InitStructure;
8 d) w3 h' Z: q- U/ s    /************************ CAN通信参数设  *********************************/
- j2 c2 l$ U; t0 O9 T5 j- [* o. y    /*CAN寄存器初始化*/9 k5 J) j! _& N* H( J
    CAN_DeInit(CAN1);- I7 x0 J. N. F; |1 e
    CAN_StructInit(&CAN_InitStructure);         /* CAN单元初始化 */
+ @- a# b. ]/ g, C2 i+ e8 }    CAN_InitStructure.CAN_TTCM=DISABLE;         //MCR-TTCM  关闭时间触发通信模式使能
( I$ y% |$ Z# T5 h9 j: _0 N4 g- S1 K    CAN_InitStructure.CAN_ABOM=DISABLE;         //MCR-ABOM  自动离线管理 & ?# O9 S, }  [4 k
    CAN_InitStructure.CAN_AWUM=DISABLE;         //MCR-AWUM  使用自动唤醒模式
/ F( Y, \5 ?$ Y8 g$ w4 P    CAN_InitStructure.CAN_NART=ENABLE;          //MCR-NART  禁止报文自动重传 DISABLE-自动重传   ENABLE-不自动重传
. m9 M- d4 |7 h2 f) A" S    CAN_InitStructure.CAN_RFLM=DISABLE;         //MCR-RFLM  接收FIFO 锁定模式 DISABLE-溢出时新报文会覆盖原有报文  ( q: K; o# T6 h
    CAN_InitStructure.CAN_TXFP=DISABLE;         //MCR-TXFP  发送FIFO优先级 DISABLE-优先级取决于报文标示符 ( ^6 X  O2 l3 i0 {' w7 V% ~7 H
    CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;    //正常工作模式
' z; a# D/ n  d" ^. d 1 C8 J+ d- R, P. }: t6 {# R
    /************************ CAN通信波特率设置 **********************************/
% v! m3 ^" m% U5 K. m) l, L0 W    #if 0
$ m/ B) H# W1 ]+ W* g5 [, C    CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;      //BTR-SJW 重新同步跳跃宽度 1个时间单元5 t+ l8 E, }- f3 W. {
    CAN_InitStructure.CAN_BS1=CAN_BS1_5tq;      //BTR-TS1 时间段1 占用了5个时间单元
" @; b- ~/ s+ Y$ ?6 b* ]# U    CAN_InitStructure.CAN_BS2=CAN_BS2_3tq;      //BTR-TS1 时间段2 占用了3个时间单元# s6 f! t5 g, W1 z3 E
    CAN_InitStructure.CAN_Prescaler =4;         //BTR-BRP 波特率分频器  定义了时间单元的时间长度 36/(1+5+3)/4=1Mbps
& V$ b. K" S" W/ c    #endif) s$ E- ~# O1 w; W

2 O$ n/ F' q; W& T8 ?4 x9 h9 ^    #if 0* \$ l9 f3 o  D8 k0 k) G- ^& l, _
    CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;      //BTR-SJW 重新同步跳跃宽度 1个时间单元
3 ^7 f0 [# H: @7 a    CAN_InitStructure.CAN_BS1=CAN_BS1_2tq;      //BTR-TS1 时间段1 占用了2个时间单元
& n6 a; e9 \, r3 {$ Y. H    CAN_InitStructure.CAN_BS2=CAN_BS2_1tq;      //BTR-TS1 时间段2 占用了1个时间单元% ]% V% I9 i; R& ~9 I! D/ P& o
    CAN_InitStructure.CAN_Prescaler =9;         //BTR-BRP 波特率分频器  定义了时间单元的时间长度 36/(1+2+1)/9=1Mbps" `2 r' n" C! a3 i4 i; `
    #endif, Z# c" R3 v: t: ~* [, D3 i
3 O/ t0 O; D; O4 M' ~3 o
    #if 1
  `  Y- @8 k- W* D2 O+ V3 O    CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;      //BTR-SJW 重新同步跳跃宽度 1个时间单元2 w6 i0 G/ A1 Z( Q+ ~2 z  z) V
    CAN_InitStructure.CAN_BS1=CAN_BS1_2tq;      //BTR-TS1 时间段1 占用了2个时间单元4 o/ n; g+ q3 u0 ?" z, ~2 b
    CAN_InitStructure.CAN_BS2=CAN_BS2_1tq;      //BTR-TS1 时间段2 占用了1个时间单元( f, G0 O; I7 e3 [1 |
    CAN_InitStructure.CAN_Prescaler =18;        //BTR-BRP 波特率分频器  定义了时间单元的时间长度 36/(1+2+1)/18=0.5Mbps; T! M( b: F! H1 `; t/ U
    #endif" h! R4 o0 j0 `( i" J
& p- U( a. M5 B3 ?% t
    #if 0( c, V' X2 ^9 J7 i* I
    CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;      //BTR-SJW 重新同步跳跃宽度 1个时间单元
$ t8 N4 f: {, ?, i$ X    CAN_InitStructure.CAN_BS1=CAN_BS1_3tq;      //BTR-TS1 时间段1 占用了2个时间单元7 Q$ p, b( Y* K  X7 S/ A
    CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;      //BTR-TS1 时间段2 占用了3个时间单元
  T7 s. p' \3 H3 V    CAN_InitStructure.CAN_Prescaler =12;        //BTR-BRP 波特率分频器  定义了时间单元的时间长度 36/(1+3+2)/12=0.5Mbps3 F) Y) i( c" _# l6 D- v  [6 W
    #endif( z& z: D2 l# P( Q" x1 U$ ?1 F; \/ R
+ S% a. S5 x: Z- A  z9 D
( e: `! \( R% z7 O+ v+ P( V/ K
    #if 07 g# O/ c& X  [* ?) x: g# U* {2 V4 \
    CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;      //BTR-SJW 重新同步跳跃宽度 1个时间单元
' h) Q) V6 {( _7 w7 B8 ?    CAN_InitStructure.CAN_BS1=CAN_BS1_7tq;      //BTR-TS1 时间段1 占用了7个时间单元
7 H; s6 Y0 h# n    CAN_InitStructure.CAN_BS2=CAN_BS2_4tq;      //BTR-TS1 时间段2 占用了4个时间单元
4 Z) j. i5 `. ]" l/ D$ p# g. W    CAN_InitStructure.CAN_Prescaler =6;         //BTR-BRP 波特率分频器  定义了时间单元的时间长度 36/(1+7+4)/6=0.5Mbps. @; `9 l( y1 k) g7 v$ Q. G; ^( O+ s# i
    #endif
6 S2 c: Y1 c3 D6 K- A
3 T" z6 G7 u; [" p0 e! s$ |7 b/ E    #if 0
. U% F2 [, F3 [1 v/ d2 t    CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;      //BTR-SJW 重新同步跳跃宽度 1个时间单元
' p% ]- F/ K) V! M7 x% `    CAN_InitStructure.CAN_BS1=CAN_BS1_13tq;     //BTR-TS1 时间段1 占用了13个时间单元
* r0 \/ S! ^4 q& h) ]5 E- s    CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;      //BTR-TS1 时间段2 占用了2个时间单元
8 t  I! d7 |% ]: i+ Q5 s% H8 N    CAN_InitStructure.CAN_Prescaler =9;         //BTR-BRP 波特率分频器  定义了时间单元的时间长度 36/(1+13+2)/9=250Kbps
# u3 k6 k/ {' }5 n, U    #endif
5 {/ D/ |9 a  W: L2 {
2 E- D0 |& W  j9 j  P    #if 0
5 @2 g% _1 D$ R0 Z  p3 o: L8 g& K    CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;      //BTR-SJW 重新同步跳跃宽度 1个时间单元
2 n  [' Y4 N" ~    CAN_InitStructure.CAN_BS1=CAN_BS1_8tq;      //BTR-TS1 时间段1 占用了8个时间单元- W$ y0 x! w8 n4 D# x: \& n# p3 N  e
    CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;      //BTR-TS1 时间段2 占用了7个时间单元, r" r3 G7 f( H. B) T, X/ N/ ]
    CAN_InitStructure.CAN_Prescaler =9;         //BTR-BRP 波特率分频器  定义了时间单元的时间长度 36/(1+8+7)/9=250Kbps7 z: C3 M! W: l- H+ k0 W6 p/ U$ u0 q
    #endif: y; {! r" j1 g: J0 y# h
+ X, s7 W7 [1 \+ X1 \
    #if 0
; y; Z" V6 g6 Q) a0 g4 U( r    if (CAN_Init(CAN1, &CAN_InitStructure) == CAN_InitStatus_Failed)5 i2 ~& D, V, j+ J
    {8 w$ ^0 J' W* n2 u" T9 y* q/ C; C# C
        printf("Initialize CAN failed!\n\r");% m: I' P% g3 V9 F5 w- r1 o  Z& g
    }
% m3 J& T8 a7 R    else
6 g& e. N1 ?6 t. Z( [    {
/ q- K  o2 A6 [6 R9 u, ^: ~) o        printf("Initialize CAN Success!\n\r");
* F/ ]/ P$ B7 {) k0 c    }
3 x4 t5 w3 c7 E# _" W  R8 _1 T8 D3 {    #endif$ J6 \9 N( m; h! w3 h2 u4 C; L% ~
    CAN_Init(CAN1, &CAN_InitStructure);
5 ~1 [8 L, C5 R) D& A6 x7 @) E}
通过查看STM32F103 的参考手册,找到了答案
& X' H& X) J- d, T
21.png
计算过程
! \0 v1 @; h7 N1 b' U$ l ! l/ ^: O9 }9 |4 }) ^4 A
注意STM32 CAN 属于APB1总线,APB1总线,默认配置最大主频(36Mhz),而不是72Mhz。  x: q, y& b) M3 V4 R& L: g
22.png
  1. ( j) q- F& Q% {  t
  2. 波特率 = 1 / 位时间
    4 U5 I, e# l& H: x
  3. / l4 e; ^% `! C
  4. 位时间 = (1*tq + tbs1 + tbs2),注意,这里与 CAN_SJW_1tq 无关!!0 g) U* m; Q/ ?: I, s

  5. 8 K1 t5 v3 c7 c+ P
  6. 如果:tbs1 = 2 , tbs2 = 1,则:位时间 =  (1+2+1)tq = 4 tq。# _0 j5 }3 T) ~/ ?+ ]! V
  7. , G% [0 [" d2 ~
  8. 注意:这里,还有个分频, 分频分的不是主频(71MHz),是CAN总线的APB1 频率,手册上写着,36MHz,也就是 主频的2分频。. t) b! w( L# U
  9. $ L& T6 A8 `! q. B- Q2 \, g% C+ Z! ?
  10. 系统默认初始化后,APB1总线频率,设置为 36MHz。& U) T0 ]* R. p

  11. 9 {" s" X1 ]0 {8 y
  12. 这里CAN控制器,可以把APB1 继续分频,如 18,那么,CAN控制器频率:36Mhz / 18 = 2 Mhz。+ P- F1 y  _0 O- T: J0 s, o

  13. : k+ }5 G4 i* A! l6 D# f. a
  14. 波特率:=  1 /  4 * (1/2Mhz) = 0.5Mhz = 500 Kbps
复制代码
总结, m/ V' i7 z5 J* A1 B$ _  U1 U

+ h% R/ `; F! k) aCAN通信,是比较好用的串行总线,不仅用于汽车上,一些工业总线场合短距离的通信,也可以说使用。2 `# T5 a% _- |1 Q& S/ X
& O. S4 f* s, r

" v% M( v4 U" l- R+ P; ICAN通信,波特率、滤波器设置,都需要清楚,才能真正用好。
, B3 x( F& @( b+ r  Z1 V' Q% s4 ^8 s. t2 c7 F3 l$ Z

- C5 h5 u0 J% K0 m
6 o3 T( q7 S( n. Q# b! E0 |
# Z2 Q4 R8 ]8 r1 h7 ?) A5 j" ^/ e
赞 收藏 1 评论1 发布时间:2021-2-20 13:29

举报

1个回答
小小超 回答时间:2021-2-20 13:41:30
谢谢分享!
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版