|
STM32F103 CAN通信波特率的计算方法 前言
+ L6 m% _6 J1 u/ C( T最近看一下CAN通信,翻出来之前做过的STM32 CAN通信的项目代码,有些概念比较模糊了,如波特率是怎么计算的。
* i5 s: |2 b0 Y: G' m5 t. o
* ?* H1 Y- b! N
$ A/ l' |; a1 Q最近接触rt-thread比较多,想把之前的CAN通信的代码,移植到RTOS上。6 t' g7 x) |0 ?! E$ y
& Q3 P* Q( I) _# l4 g/ a4 W- ^) |
4 F( [) x- A- ~CAN波特率4 D3 s9 L [& ^9 L5 L, J2 @5 J9 _
如果主机与从机,波特率不一致,很难正常的通信。
; u. \! z+ D6 G% I/ O' |8 C
/ s; B* O2 |7 Z1 F( J1 T l& W7 u计算方法
% J9 `( U% G+ n2 v) m" n# e. ]- c% U
( X2 ]& u7 _/ a* Z: }* ~这里的500Kbps,是怎么计算出来的?" V; W! h0 ?# c0 r5 ?, [5 t
/** u, T) }7 w3 C$ g, E, r
* 函数名:CAN_Mode_Config
, a- B3 ], l$ H& v% ?; \" l * 描述 :CAN的模式 配置7 D3 Z z) O/ g& z3 l. {
* 输入 :无
& q p0 m/ x; K* y$ O! B8 Q+ K7 X * 输出 : 无
! [2 G) c) t% j% [8 Y5 s' x1 l * 调用 :内部调用# M2 @' {$ Y; g: o* M9 s( I3 r$ I
*/7 s, g$ J* O0 Q1 _# ]9 x% J) k" k
static void CAN_Mode_Config(void)
c) M: P0 V# x9 v6 C8 u7 d4 S{$ ?) L, `9 g1 Z, o! _. {
CAN_InitTypeDef CAN_InitStructure;3 t& s$ f$ o, K
/************************ CAN通信参数设 *********************************/
7 i* D7 t* _( } /*CAN寄存器初始化*/3 f$ y# I4 X% a+ x3 a. a7 z
CAN_DeInit(CAN1);
% l, W6 B2 D' u2 C9 i4 w CAN_StructInit(&CAN_InitStructure); /* CAN单元初始化 */
( K: B- R0 [# g! p6 f! D0 _ CAN_InitStructure.CAN_TTCM=DISABLE; //MCR-TTCM 关闭时间触发通信模式使能+ }0 n9 ~3 x" b5 Y% u2 u/ Z
CAN_InitStructure.CAN_ABOM=DISABLE; //MCR-ABOM 自动离线管理
1 ], H9 S& q7 `6 g CAN_InitStructure.CAN_AWUM=DISABLE; //MCR-AWUM 使用自动唤醒模式
9 N# P. C) b) t8 E0 H! j6 ^) H CAN_InitStructure.CAN_NART=ENABLE; //MCR-NART 禁止报文自动重传 DISABLE-自动重传 ENABLE-不自动重传6 Z! g q" p3 B1 L' D S$ j( I' c
CAN_InitStructure.CAN_RFLM=DISABLE; //MCR-RFLM 接收FIFO 锁定模式 DISABLE-溢出时新报文会覆盖原有报文 # c; [( T' A' u
CAN_InitStructure.CAN_TXFP=DISABLE; //MCR-TXFP 发送FIFO优先级 DISABLE-优先级取决于报文标示符
0 f% c) w; B) | CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; //正常工作模式
" |7 B; T, a- F3 v& W, j
( ]. ^% y% i; x /************************ CAN通信波特率设置 **********************************/
( Q+ y# P' o1 }8 \+ ? #if 0" ] d) W8 u- q: r( M1 _
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //BTR-SJW 重新同步跳跃宽度 1个时间单元
! O4 v3 `' G& `7 z6 f& [. L: q+ y CAN_InitStructure.CAN_BS1=CAN_BS1_5tq; //BTR-TS1 时间段1 占用了5个时间单元
# c2 z, m2 x' v1 j; ? q+ l& T; Y CAN_InitStructure.CAN_BS2=CAN_BS2_3tq; //BTR-TS1 时间段2 占用了3个时间单元
2 Z7 V" l* t j" b: P CAN_InitStructure.CAN_Prescaler =4; //BTR-BRP 波特率分频器 定义了时间单元的时间长度 36/(1+5+3)/4=1Mbps
4 I0 g8 l) h; q. }- I+ T$ X, z; E- E #endif4 ?6 N/ C) v: l+ s5 i; z* A
3 O* z- @# m" N4 A& v" ~ #if 01 m; x0 i3 O4 Q5 T3 o5 E
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //BTR-SJW 重新同步跳跃宽度 1个时间单元6 X4 ~4 h. z5 l2 d" l
CAN_InitStructure.CAN_BS1=CAN_BS1_2tq; //BTR-TS1 时间段1 占用了2个时间单元
8 A9 U: K$ m( f, o$ G CAN_InitStructure.CAN_BS2=CAN_BS2_1tq; //BTR-TS1 时间段2 占用了1个时间单元9 H( }/ t$ `) o
CAN_InitStructure.CAN_Prescaler =9; //BTR-BRP 波特率分频器 定义了时间单元的时间长度 36/(1+2+1)/9=1Mbps
4 F. u& S) \( r, d( y #endif" e" {7 k( y% L3 n$ y
$ {& b- S. F o3 J! |+ G; b #if 1
2 \! f1 k$ r' b, ]: K CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //BTR-SJW 重新同步跳跃宽度 1个时间单元8 G* _! N- R# I
CAN_InitStructure.CAN_BS1=CAN_BS1_2tq; //BTR-TS1 时间段1 占用了2个时间单元, L& \( S) q5 L' @+ J. o& _
CAN_InitStructure.CAN_BS2=CAN_BS2_1tq; //BTR-TS1 时间段2 占用了1个时间单元
& I5 l- h: G+ l0 s! Y5 [; e3 M CAN_InitStructure.CAN_Prescaler =18; //BTR-BRP 波特率分频器 定义了时间单元的时间长度 36/(1+2+1)/18=0.5Mbps
% p2 ~0 w1 x, W3 }% y5 _ #endif0 ] E) p4 Q% O$ \5 f& l# \5 _
% x( H. a$ ] _: C #if 06 e% I/ i6 R3 y& Y" f7 y
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //BTR-SJW 重新同步跳跃宽度 1个时间单元0 y; \& I" U I
CAN_InitStructure.CAN_BS1=CAN_BS1_3tq; //BTR-TS1 时间段1 占用了2个时间单元 a' Z9 k5 R0 u2 i
CAN_InitStructure.CAN_BS2=CAN_BS2_2tq; //BTR-TS1 时间段2 占用了3个时间单元) Z7 E" f' \6 y" I! D
CAN_InitStructure.CAN_Prescaler =12; //BTR-BRP 波特率分频器 定义了时间单元的时间长度 36/(1+3+2)/12=0.5Mbps
0 \- @% E5 G; f5 a6 H' p #endif
+ w4 j7 n7 Z) `+ K0 ^
- K2 K) \+ w4 m- y1 ]" L; E
1 ]2 s) x1 t1 D: X #if 0
9 Y1 l6 `; w* K) K3 r CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //BTR-SJW 重新同步跳跃宽度 1个时间单元
2 `! b* b9 m! x1 e% X" G8 \9 ` CAN_InitStructure.CAN_BS1=CAN_BS1_7tq; //BTR-TS1 时间段1 占用了7个时间单元
+ l2 g9 M Z! u! T5 T CAN_InitStructure.CAN_BS2=CAN_BS2_4tq; //BTR-TS1 时间段2 占用了4个时间单元
8 r: \( H; y2 f& T3 f6 Q) s8 Q3 { CAN_InitStructure.CAN_Prescaler =6; //BTR-BRP 波特率分频器 定义了时间单元的时间长度 36/(1+7+4)/6=0.5Mbps4 G8 j6 p J0 G0 X7 @/ z( B9 a
#endif, v& k# J( O% V5 i4 }& p z
8 d) }+ F8 ?" f #if 0
, @1 W* I$ T9 @* a5 t% w CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //BTR-SJW 重新同步跳跃宽度 1个时间单元' N$ ^9 f) l2 f/ K" e0 _
CAN_InitStructure.CAN_BS1=CAN_BS1_13tq; //BTR-TS1 时间段1 占用了13个时间单元
5 F0 B) y0 \$ n5 o3 u" k9 w CAN_InitStructure.CAN_BS2=CAN_BS2_2tq; //BTR-TS1 时间段2 占用了2个时间单元1 e8 H1 f' \' h* d. M2 d
CAN_InitStructure.CAN_Prescaler =9; //BTR-BRP 波特率分频器 定义了时间单元的时间长度 36/(1+13+2)/9=250Kbps5 D* D3 H+ o& a5 i! D8 _( f c
#endif O8 O3 e/ X" Y9 _& S1 [6 w) A
6 k5 B: M+ p- {' O9 W; d$ i #if 0
2 |' j% s) y/ e( l9 Q2 m# l; T8 k CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //BTR-SJW 重新同步跳跃宽度 1个时间单元$ N- ~0 U( U5 Q+ E6 o
CAN_InitStructure.CAN_BS1=CAN_BS1_8tq; //BTR-TS1 时间段1 占用了8个时间单元8 F4 p$ o, ?+ \! I Q7 X6 N
CAN_InitStructure.CAN_BS2=CAN_BS2_7tq; //BTR-TS1 时间段2 占用了7个时间单元
& m) t2 k" X$ { CAN_InitStructure.CAN_Prescaler =9; //BTR-BRP 波特率分频器 定义了时间单元的时间长度 36/(1+8+7)/9=250Kbps: w& `8 q6 x& R% u! b; T! V+ V/ k2 r
#endif
. J$ C5 U) d* G0 M( @+ @* ]
/ U$ t+ A/ z0 ~% L/ @ #if 0: S/ O, K/ L- e4 |' l1 x
if (CAN_Init(CAN1, &CAN_InitStructure) == CAN_InitStatus_Failed)
# u/ s8 y8 r V" { {
: u) m0 `3 h3 \ G printf("Initialize CAN failed!\n\r");* S( e! L5 X5 l1 U
} p% V/ [" j0 f8 b( @3 A
else
' o8 c( |+ h! g* @. i {
$ }3 D8 h$ h% E* E4 ^* [" B' d printf("Initialize CAN Success!\n\r");! T) N7 |3 j7 H9 d
}) e R/ u4 ^" {- K7 h3 E- r
#endif
R& E# T6 E0 Y. } V% K0 i/ ` CAN_Init(CAN1, &CAN_InitStructure);
* e/ S+ N, x# P% ^. F} 通过查看STM32F103 的参考手册,找到了答案% q e5 Z- s9 f
计算过程
/ K r3 L& s0 [- @+ e# s* c0 ~
! j1 I, T" ^0 i1 ^0 I" {注意STM32 CAN 属于APB1总线,APB1总线,默认配置最大主频(36Mhz),而不是72Mhz。8 S- B+ w; }8 N5 j, _/ P# _4 ]1 W1 ` z
- ( b5 T) d$ Q! G3 T
- 波特率 = 1 / 位时间
' `. `% C2 \4 ? -
" D& n3 z, Z, t$ k2 d) l - 位时间 = (1*tq + tbs1 + tbs2),注意,这里与 CAN_SJW_1tq 无关!!. R2 m' J0 `7 I/ p- L
-
3 y! W' v& e6 o - 如果:tbs1 = 2 , tbs2 = 1,则:位时间 = (1+2+1)tq = 4 tq。/ r/ O+ T0 W6 F' j
-
' I7 A- \/ m$ M - 注意:这里,还有个分频, 分频分的不是主频(71MHz),是CAN总线的APB1 频率,手册上写着,36MHz,也就是 主频的2分频。
7 B) _4 r G* H2 t$ P2 _8 Z - 5 \" a" h' p- J4 H- q/ x; n- m* A- Z
- 系统默认初始化后,APB1总线频率,设置为 36MHz。
3 k8 o9 D; @% J! {/ q6 {; |) s -
+ q0 y, c }% u; b( ]/ y v - 这里CAN控制器,可以把APB1 继续分频,如 18,那么,CAN控制器频率:36Mhz / 18 = 2 Mhz。% ?3 T# [1 J: k* `, v
-
/ u- s$ u/ b3 y/ | - 波特率:= 1 / 4 * (1/2Mhz) = 0.5Mhz = 500 Kbps
复制代码 总结3 ]5 c2 [* t6 m/ q; M* H3 N9 |
! W" i/ m* P2 ]+ i/ f0 ~
CAN通信,是比较好用的串行总线,不仅用于汽车上,一些工业总线场合短距离的通信,也可以说使用。
6 s2 R8 W6 j0 m$ [4 f1 c2 Q7 f/ v! b; g& ?. {
- k! T; t9 q, @CAN通信,波特率、滤波器设置,都需要清楚,才能真正用好。
2 S- f# Q/ L8 g9 ?) q* k z
3 H5 o. {) |3 x" S* u+ R" s/ P+ W+ m, q" Z& A5 Q* x0 _
2 m/ N1 J* M; m9 F7 E/ z+ v
$ c _: X5 `' @8 L) O; V/ f
|