|
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计算过程
! \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
- ( j) q- F& Q% { t
- 波特率 = 1 / 位时间
4 U5 I, e# l& H: x - / l4 e; ^% `! C
- 位时间 = (1*tq + tbs1 + tbs2),注意,这里与 CAN_SJW_1tq 无关!!0 g) U* m; Q/ ?: I, s
-
8 K1 t5 v3 c7 c+ P - 如果:tbs1 = 2 , tbs2 = 1,则:位时间 = (1+2+1)tq = 4 tq。# _0 j5 }3 T) ~/ ?+ ]! V
- , G% [0 [" d2 ~
- 注意:这里,还有个分频, 分频分的不是主频(71MHz),是CAN总线的APB1 频率,手册上写着,36MHz,也就是 主频的2分频。. t) b! w( L# U
- $ L& T6 A8 `! q. B- Q2 \, g% C+ Z! ?
- 系统默认初始化后,APB1总线频率,设置为 36MHz。& U) T0 ]* R. p
-
9 {" s" X1 ]0 {8 y - 这里CAN控制器,可以把APB1 继续分频,如 18,那么,CAN控制器频率:36Mhz / 18 = 2 Mhz。+ P- F1 y _0 O- T: J0 s, o
-
: k+ }5 G4 i* A! l6 D# f. a - 波特率:= 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 |