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

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

[复制链接]
STMCU-管管 发布时间:2021-2-20 13:29
STM32F103 CAN通信波特率的计算方法

' T  R+ k6 C; P! M最近看一下CAN通信,翻出来之前做过的STM32 CAN通信的项目代码,有些概念比较模糊了,如波特率是怎么计算的。$ D8 L/ ]. L! i' s7 D' i, k, r
3 Z& N8 `' f' ^, f) N

. d3 J3 J: v% V" N( P: l$ G+ z! |最近接触rt-thread比较多,想把之前的CAN通信的代码,移植到RTOS上。% `- G8 \5 _- f5 _8 L
  ^6 t8 x4 V; w: @, p  A

- w: I# M( s$ x4 C3 f  W
" W6 w* R9 T  CCAN波特率: s" C5 F( V) O8 d) P  `1 M0 n2 P
如果主机与从机,波特率不一致,很难正常的通信。& D" K6 R$ o8 V9 |0 R, A! x" d

7 z) s3 _, f4 ?& Z7 }计算方法
5 a$ W' U. m1 x 9 j$ f) z* c4 n) ^7 B+ h7 R
这里的500Kbps,是怎么计算出来的?8 Q) `; c; H) Y8 t7 y' ^
/*! Y, F. ^; z4 q* b: A% x4 f0 n
* 函数名:CAN_Mode_Config1 Y% y' ^" T- }) j/ M
* 描述  :CAN的模式 配置; ]5 S- r3 F& r
* 输入  :无
# L$ ^8 A  p7 a * 输出  : 无
, b/ H3 @* g! d' L * 调用  :内部调用
! C4 @/ i- I6 {+ ] */7 x9 b' _; F& B
static void CAN_Mode_Config(void)
5 S/ O7 P/ d% l% r1 R{/ J# R. I7 S  E
    CAN_InitTypeDef        CAN_InitStructure;
  d* Y6 V. X+ y1 y8 t    /************************ CAN通信参数设  *********************************/
- o; Q6 B8 }2 k0 U9 D    /*CAN寄存器初始化*/3 e* G, N  ^+ Y3 g- e
    CAN_DeInit(CAN1);
9 [" G9 d8 h/ T) W/ L" X    CAN_StructInit(&CAN_InitStructure);         /* CAN单元初始化 */
# e+ V4 W* D+ p+ s3 I    CAN_InitStructure.CAN_TTCM=DISABLE;         //MCR-TTCM  关闭时间触发通信模式使能
* r$ O: m/ q% Q1 V* }( x! i' a/ u    CAN_InitStructure.CAN_ABOM=DISABLE;         //MCR-ABOM  自动离线管理
" S! l% C3 \# F4 s; Q' p    CAN_InitStructure.CAN_AWUM=DISABLE;         //MCR-AWUM  使用自动唤醒模式
; a% q9 w+ o* }! k% i) `    CAN_InitStructure.CAN_NART=ENABLE;          //MCR-NART  禁止报文自动重传 DISABLE-自动重传   ENABLE-不自动重传
; ], H  ^. R, ~5 ?' u  y+ y6 Z    CAN_InitStructure.CAN_RFLM=DISABLE;         //MCR-RFLM  接收FIFO 锁定模式 DISABLE-溢出时新报文会覆盖原有报文  , ^' f' b1 t1 ]
    CAN_InitStructure.CAN_TXFP=DISABLE;         //MCR-TXFP  发送FIFO优先级 DISABLE-优先级取决于报文标示符
3 M0 {: [, ?- m+ G! `. Z. A# N7 a4 |    CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;    //正常工作模式4 [* U* R4 \: y  d1 I! N4 o
3 D$ o+ x2 E4 H' A
    /************************ CAN通信波特率设置 **********************************/
: `8 `7 e' o1 G* x! U  N8 J+ f    #if 0
* Z2 d! z' y9 Q    CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;      //BTR-SJW 重新同步跳跃宽度 1个时间单元
) n4 W; d/ C5 F) c7 M  H, U    CAN_InitStructure.CAN_BS1=CAN_BS1_5tq;      //BTR-TS1 时间段1 占用了5个时间单元
! l* q% s* r* H# H. D4 |0 t    CAN_InitStructure.CAN_BS2=CAN_BS2_3tq;      //BTR-TS1 时间段2 占用了3个时间单元) a5 R8 J$ b3 k( x# l
    CAN_InitStructure.CAN_Prescaler =4;         //BTR-BRP 波特率分频器  定义了时间单元的时间长度 36/(1+5+3)/4=1Mbps& I* {5 S& f5 n
    #endif
- l5 t/ Q* _  \& p9 d( c9 z   i: T2 P; G+ c& C- o5 M8 [3 a% M! F
    #if 0
, w5 U1 s# r: X! D    CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;      //BTR-SJW 重新同步跳跃宽度 1个时间单元% _, f. J% I& V; P/ o! ~% V6 y
    CAN_InitStructure.CAN_BS1=CAN_BS1_2tq;      //BTR-TS1 时间段1 占用了2个时间单元4 K8 q8 S% B& P2 |
    CAN_InitStructure.CAN_BS2=CAN_BS2_1tq;      //BTR-TS1 时间段2 占用了1个时间单元( T: i- c9 y. K7 q/ Y
    CAN_InitStructure.CAN_Prescaler =9;         //BTR-BRP 波特率分频器  定义了时间单元的时间长度 36/(1+2+1)/9=1Mbps& N  I0 K7 l. d. w$ e* h7 i9 x
    #endif
" \! s5 c9 s3 I# o: s- O& |0 C * V+ s& a0 T8 R1 J0 |9 ]4 h
    #if 16 Q) S; o- k% F) w3 d
    CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;      //BTR-SJW 重新同步跳跃宽度 1个时间单元, G. u' R+ v! h2 Y) C( V6 ~
    CAN_InitStructure.CAN_BS1=CAN_BS1_2tq;      //BTR-TS1 时间段1 占用了2个时间单元
' A: s; h" ^0 y, T$ @    CAN_InitStructure.CAN_BS2=CAN_BS2_1tq;      //BTR-TS1 时间段2 占用了1个时间单元# `) O% e4 |: S7 s4 Q
    CAN_InitStructure.CAN_Prescaler =18;        //BTR-BRP 波特率分频器  定义了时间单元的时间长度 36/(1+2+1)/18=0.5Mbps) r/ k* A8 m; e
    #endif
2 @- k- g+ l( t) X% Y1 \: v 5 i! e- S: w5 w: i6 a8 [# J: r
    #if 08 F- \& L' J$ W2 N+ \
    CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;      //BTR-SJW 重新同步跳跃宽度 1个时间单元6 z0 i& D! Z" I" g% O9 @: P) Y
    CAN_InitStructure.CAN_BS1=CAN_BS1_3tq;      //BTR-TS1 时间段1 占用了2个时间单元
, {0 j, Z% R7 r  p  y    CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;      //BTR-TS1 时间段2 占用了3个时间单元0 ]/ o) o& p! j1 W* C
    CAN_InitStructure.CAN_Prescaler =12;        //BTR-BRP 波特率分频器  定义了时间单元的时间长度 36/(1+3+2)/12=0.5Mbps
2 k# J; D5 _' s    #endif% H: ]/ n( A, P+ r: J$ g

3 p1 B& r& o* z9 C6 u
) K" c4 s; o" j/ y% t    #if 0
1 q+ Y1 o- J6 \; B, A0 \( j, G    CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;      //BTR-SJW 重新同步跳跃宽度 1个时间单元
. @, x9 J* F1 ]4 n( R5 m& K    CAN_InitStructure.CAN_BS1=CAN_BS1_7tq;      //BTR-TS1 时间段1 占用了7个时间单元* A: j5 r3 \( N
    CAN_InitStructure.CAN_BS2=CAN_BS2_4tq;      //BTR-TS1 时间段2 占用了4个时间单元
9 c. q: U( Q; x# R) I; S4 V    CAN_InitStructure.CAN_Prescaler =6;         //BTR-BRP 波特率分频器  定义了时间单元的时间长度 36/(1+7+4)/6=0.5Mbps
! j$ T- o6 w, v* v8 x    #endif( S* x5 e/ {$ D9 d) q: i; o' s  e
7 G5 @6 {# K2 w# e: t1 a
    #if 0
" v! i5 Q/ N) j' ^! f4 X- y8 `+ g    CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;      //BTR-SJW 重新同步跳跃宽度 1个时间单元$ ]9 a) e/ I& f1 o
    CAN_InitStructure.CAN_BS1=CAN_BS1_13tq;     //BTR-TS1 时间段1 占用了13个时间单元
9 c8 ~, `. b9 n. Z* H    CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;      //BTR-TS1 时间段2 占用了2个时间单元
$ v" j6 y3 n/ P7 n2 N% B$ X0 J    CAN_InitStructure.CAN_Prescaler =9;         //BTR-BRP 波特率分频器  定义了时间单元的时间长度 36/(1+13+2)/9=250Kbps( j  x8 x% r% }" `# K" z* r2 ~% C
    #endif
4 g8 T% q6 s- o% S/ v; h ) r; K8 [# X, I- V; `* i, [
    #if 0
: _5 x6 ?2 A$ a/ _    CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;      //BTR-SJW 重新同步跳跃宽度 1个时间单元
+ O% X$ A* W" |& e. Y+ `: f4 R    CAN_InitStructure.CAN_BS1=CAN_BS1_8tq;      //BTR-TS1 时间段1 占用了8个时间单元
8 U0 w% A, T. V2 [    CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;      //BTR-TS1 时间段2 占用了7个时间单元1 S, [& Z3 H3 G2 }" C: k5 Z3 G
    CAN_InitStructure.CAN_Prescaler =9;         //BTR-BRP 波特率分频器  定义了时间单元的时间长度 36/(1+8+7)/9=250Kbps0 g  v; P& G* G, a3 R
    #endif
' B# a/ A1 z! @# |+ P % p. Z2 o$ n  a: U# j
    #if 0) H* y' ~: ]( H% w) B
    if (CAN_Init(CAN1, &CAN_InitStructure) == CAN_InitStatus_Failed)" G3 Y7 L' Y. r0 v" u
    {* O" a$ B8 A9 g( `
        printf("Initialize CAN failed!\n\r");6 z- H& z/ ]2 r. ~, Q( U
    }, d  u; a% ?# V
    else( {2 f& D1 g4 ^; e
    {
0 W9 B: ~" q  |, @+ l8 {        printf("Initialize CAN Success!\n\r");" y4 ]  W$ K1 }2 z
    }
  z, C1 _1 e# S4 d2 ?7 M  ~    #endif
, E$ \& M' G0 L5 m    CAN_Init(CAN1, &CAN_InitStructure);! c. x# g3 S4 R' W2 f  @7 o/ J
}
通过查看STM32F103 的参考手册,找到了答案
$ f. x5 U- j8 j
21.png
计算过程
0 }: \$ U# H9 |- K& R# I
4 V+ d( g) N* i5 [4 D注意STM32 CAN 属于APB1总线,APB1总线,默认配置最大主频(36Mhz),而不是72Mhz。
. k7 a: ^; W# H% H* M7 _2 n& y
22.png
  1. - {7 \: e( t1 Y
  2. 波特率 = 1 / 位时间/ Q" ?6 N9 k0 f2 \( j$ S9 r1 r
  3. ; {* M  _: ~% r
  4. 位时间 = (1*tq + tbs1 + tbs2),注意,这里与 CAN_SJW_1tq 无关!!
    4 {1 i3 R+ N! |$ G! I

  5. . r4 f$ N7 g/ s, C% o6 R
  6. 如果:tbs1 = 2 , tbs2 = 1,则:位时间 =  (1+2+1)tq = 4 tq。
    ) n, w" g& y, @$ v% P

  7. ; j. N* r+ u# p1 G
  8. 注意:这里,还有个分频, 分频分的不是主频(71MHz),是CAN总线的APB1 频率,手册上写着,36MHz,也就是 主频的2分频。3 r+ q% a8 z2 {
  9. ) _9 E, ]' P& |4 {# [
  10. 系统默认初始化后,APB1总线频率,设置为 36MHz。1 X: @6 P0 t0 u& [
  11. * R3 K- D3 ^" u& K  o3 e
  12. 这里CAN控制器,可以把APB1 继续分频,如 18,那么,CAN控制器频率:36Mhz / 18 = 2 Mhz。' \6 o0 `6 J5 S1 t
  13. . U" K: v7 F8 }2 \
  14. 波特率:=  1 /  4 * (1/2Mhz) = 0.5Mhz = 500 Kbps
复制代码
总结# X* m& D3 m0 C( ]7 U* }: W6 S! m

) u' O6 h: O' W* dCAN通信,是比较好用的串行总线,不仅用于汽车上,一些工业总线场合短距离的通信,也可以说使用。
3 [) Q- D6 k+ I' I' _; q' o; y, N( o0 [# t0 l6 q6 O2 C
# g" A+ K) Q# ]
CAN通信,波特率、滤波器设置,都需要清楚,才能真正用好。7 Q9 {& _+ J# o# @& d
/ T' Q& K: }% a

* {0 z% F: {# M4 L* @* D; s; D" @, G: g  @
& r2 a; G' @4 W
  O( r3 k) l2 v# r) [: i
收藏 1 评论1 发布时间:2021-2-20 13:29

举报

1个回答
小小超 回答时间:2021-2-20 13:41:30
谢谢分享!

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版