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计算过程
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- - {7 \: e( t1 Y
- 波特率 = 1 / 位时间/ Q" ?6 N9 k0 f2 \( j$ S9 r1 r
- ; {* M _: ~% r
- 位时间 = (1*tq + tbs1 + tbs2),注意,这里与 CAN_SJW_1tq 无关!!
4 {1 i3 R+ N! |$ G! I -
. r4 f$ N7 g/ s, C% o6 R - 如果:tbs1 = 2 , tbs2 = 1,则:位时间 = (1+2+1)tq = 4 tq。
) n, w" g& y, @$ v% P -
; j. N* r+ u# p1 G - 注意:这里,还有个分频, 分频分的不是主频(71MHz),是CAN总线的APB1 频率,手册上写着,36MHz,也就是 主频的2分频。3 r+ q% a8 z2 {
- ) _9 E, ]' P& |4 {# [
- 系统默认初始化后,APB1总线频率,设置为 36MHz。1 X: @6 P0 t0 u& [
- * R3 K- D3 ^" u& K o3 e
- 这里CAN控制器,可以把APB1 继续分频,如 18,那么,CAN控制器频率:36Mhz / 18 = 2 Mhz。' \6 o0 `6 J5 S1 t
- . U" K: v7 F8 }2 \
- 波特率:= 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 |