STM32F103 CAN通信波特率的计算方法 前言
/ f/ _# e v0 F' C6 \最近看一下CAN通信,翻出来之前做过的STM32 CAN通信的项目代码,有些概念比较模糊了,如波特率是怎么计算的。+ r4 W* E6 T6 L% O) B
! K; U; I. n$ l1 H; R
Z* L8 s- n& d6 v0 O最近接触rt-thread比较多,想把之前的CAN通信的代码,移植到RTOS上。
% {8 x0 \, o5 p- D ~- d1 ~" n4 S8 J6 H" x2 C" f
+ |/ A- \7 X% N1 n7 G- X, X! o, b9 e
7 w1 U9 J, b* y+ e( ? `8 _1 L2 {CAN波特率- X8 ~; E" b( i! S3 h% S
如果主机与从机,波特率不一致,很难正常的通信。 d7 O/ f1 N H( n; q
( l1 y' F) ^/ y4 F5 b2 `+ V9 \计算方法
+ T6 v0 F b) o6 O6 D \6 w, c
: k( O4 p, Z- |! `- o这里的500Kbps,是怎么计算出来的?3 X8 T* A. ~. l9 ?7 b6 o0 b
/*4 T# h0 x- v3 s$ `, t1 q" I
* 函数名:CAN_Mode_Config- U5 u7 n/ m; b- m
* 描述 :CAN的模式 配置* W7 w( R* j4 m* G3 p
* 输入 :无1 ~, _# o, e: F3 N' h
* 输出 : 无! W" X" a) Y( B$ }
* 调用 :内部调用
2 b/ J' Y" X, A6 J5 y' e1 N */
% D6 p$ L4 [. l% S1 }5 ]- hstatic void CAN_Mode_Config(void)7 G& R, g( u( w# m9 F' c1 t; c5 n
{
( C, L, d" z& p/ H5 V. ? CAN_InitTypeDef CAN_InitStructure;
+ w" j7 Y0 M- Q2 O* X( X7 z /************************ CAN通信参数设 *********************************/
4 K& h8 M# z' T, j7 A$ o+ } /*CAN寄存器初始化*/% u; U+ O+ N/ e" V, {' G8 G. p
CAN_DeInit(CAN1);
. o8 k/ x6 Z3 {# r. x CAN_StructInit(&CAN_InitStructure); /* CAN单元初始化 */" d. w/ x) @& t
CAN_InitStructure.CAN_TTCM=DISABLE; //MCR-TTCM 关闭时间触发通信模式使能! @& ]0 a0 ?5 @. n
CAN_InitStructure.CAN_ABOM=DISABLE; //MCR-ABOM 自动离线管理 - b8 O y# \; T7 K+ V
CAN_InitStructure.CAN_AWUM=DISABLE; //MCR-AWUM 使用自动唤醒模式
' n5 w# u. G5 I( L CAN_InitStructure.CAN_NART=ENABLE; //MCR-NART 禁止报文自动重传 DISABLE-自动重传 ENABLE-不自动重传# `( P) C$ M( h2 }" _
CAN_InitStructure.CAN_RFLM=DISABLE; //MCR-RFLM 接收FIFO 锁定模式 DISABLE-溢出时新报文会覆盖原有报文
8 u. C( X7 @3 V( J. B1 \9 q CAN_InitStructure.CAN_TXFP=DISABLE; //MCR-TXFP 发送FIFO优先级 DISABLE-优先级取决于报文标示符
" j* _4 o* \, p, {& N9 z CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; //正常工作模式# o1 R1 e q. p% w O
" [ t5 w) @9 X: X& W. K- ^ /************************ CAN通信波特率设置 **********************************/
9 p) v+ ?3 x5 w #if 0
" X4 ?; J4 r3 j CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //BTR-SJW 重新同步跳跃宽度 1个时间单元# Y1 A* @- ^' h
CAN_InitStructure.CAN_BS1=CAN_BS1_5tq; //BTR-TS1 时间段1 占用了5个时间单元7 D, M- b& l1 A, ^2 l
CAN_InitStructure.CAN_BS2=CAN_BS2_3tq; //BTR-TS1 时间段2 占用了3个时间单元 ~6 F5 r# Y) O8 W" E% @1 ?4 y
CAN_InitStructure.CAN_Prescaler =4; //BTR-BRP 波特率分频器 定义了时间单元的时间长度 36/(1+5+3)/4=1Mbps5 A5 G/ s" w% G# E4 z
#endif) J x# j& D" Z7 D: ~! ]
6 `7 m, w. S. u) o3 y \
#if 0
7 b; b) q; k, u, ~ CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //BTR-SJW 重新同步跳跃宽度 1个时间单元
0 z( w6 d6 d" J+ h CAN_InitStructure.CAN_BS1=CAN_BS1_2tq; //BTR-TS1 时间段1 占用了2个时间单元
9 x( w( u i; @" S; l CAN_InitStructure.CAN_BS2=CAN_BS2_1tq; //BTR-TS1 时间段2 占用了1个时间单元0 ]& |! z1 t; w' L0 f5 T# E
CAN_InitStructure.CAN_Prescaler =9; //BTR-BRP 波特率分频器 定义了时间单元的时间长度 36/(1+2+1)/9=1Mbps
% \+ V# r7 ~% n7 W2 A7 } #endif
9 F' P2 G7 @, U, ~
5 _7 ?7 G" G# n7 W$ ~- [/ @6 R #if 1
2 G# W$ s# N0 b- o. S CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //BTR-SJW 重新同步跳跃宽度 1个时间单元$ s' f( x' y5 @$ Z& Y; c, I
CAN_InitStructure.CAN_BS1=CAN_BS1_2tq; //BTR-TS1 时间段1 占用了2个时间单元. t5 V" l H- \8 W! E- N
CAN_InitStructure.CAN_BS2=CAN_BS2_1tq; //BTR-TS1 时间段2 占用了1个时间单元
5 X( _; t- L1 W2 K7 `- c CAN_InitStructure.CAN_Prescaler =18; //BTR-BRP 波特率分频器 定义了时间单元的时间长度 36/(1+2+1)/18=0.5Mbps
& j. x1 q* Z. B1 ] #endif
' W( t; w" Q b/ O0 t) `
L# A& X2 C' d #if 07 g+ S: T9 D# a3 `" y* u) r( f& B
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //BTR-SJW 重新同步跳跃宽度 1个时间单元: m" k$ z; [' @" U, D/ P
CAN_InitStructure.CAN_BS1=CAN_BS1_3tq; //BTR-TS1 时间段1 占用了2个时间单元
/ S$ K) Z& d& V) t8 P( B3 o! ]+ i CAN_InitStructure.CAN_BS2=CAN_BS2_2tq; //BTR-TS1 时间段2 占用了3个时间单元
: H) ~* C, C: J% l+ I7 O6 C CAN_InitStructure.CAN_Prescaler =12; //BTR-BRP 波特率分频器 定义了时间单元的时间长度 36/(1+3+2)/12=0.5Mbps
& t4 K) s! g o) n #endif
6 |0 k: N* n0 K. N* x3 G3 W n
! S, |& X% b" p7 d( `
/ P, C3 H' V3 b; \. j8 G #if 0
5 i/ H8 d- f: p' D CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //BTR-SJW 重新同步跳跃宽度 1个时间单元. n: M/ {2 ]- K+ Q
CAN_InitStructure.CAN_BS1=CAN_BS1_7tq; //BTR-TS1 时间段1 占用了7个时间单元; b: P' m: c+ j( L5 k- w( b$ M
CAN_InitStructure.CAN_BS2=CAN_BS2_4tq; //BTR-TS1 时间段2 占用了4个时间单元4 Q3 \& w V( z. ^: G/ Z) z7 A1 `
CAN_InitStructure.CAN_Prescaler =6; //BTR-BRP 波特率分频器 定义了时间单元的时间长度 36/(1+7+4)/6=0.5Mbps4 _5 K3 y$ N6 [6 [8 f2 O
#endif
6 _8 a2 f" Y3 K% B5 |6 }7 T( x- [: O 3 h2 j3 }+ L0 l# o! z
#if 0
' \" F1 u! s2 L( j& h' A CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //BTR-SJW 重新同步跳跃宽度 1个时间单元5 U6 g- {* z" H2 l, N! B: F' X' m
CAN_InitStructure.CAN_BS1=CAN_BS1_13tq; //BTR-TS1 时间段1 占用了13个时间单元
* d/ {$ L! y* z& n! D CAN_InitStructure.CAN_BS2=CAN_BS2_2tq; //BTR-TS1 时间段2 占用了2个时间单元
) k' r6 m) ?( I& s CAN_InitStructure.CAN_Prescaler =9; //BTR-BRP 波特率分频器 定义了时间单元的时间长度 36/(1+13+2)/9=250Kbps
) O- D/ w Z w1 \0 B2 c$ K #endif# p* R: [# e6 x( i
: G- ^2 c3 w" ?8 X
#if 0 t* z, M8 H# T
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //BTR-SJW 重新同步跳跃宽度 1个时间单元
4 _( R) u+ s9 B0 h- b; F CAN_InitStructure.CAN_BS1=CAN_BS1_8tq; //BTR-TS1 时间段1 占用了8个时间单元
" c5 ^) P ~ ` k; w CAN_InitStructure.CAN_BS2=CAN_BS2_7tq; //BTR-TS1 时间段2 占用了7个时间单元; ~3 \6 _9 f" I: d+ r9 H
CAN_InitStructure.CAN_Prescaler =9; //BTR-BRP 波特率分频器 定义了时间单元的时间长度 36/(1+8+7)/9=250Kbps2 ~& V z) E# t% i
#endif1 O. u: @' i7 k; i1 \
1 P8 N, g% j& j& J6 @& I
#if 0
2 k5 v; L* u9 T" { if (CAN_Init(CAN1, &CAN_InitStructure) == CAN_InitStatus_Failed)
! h( f5 z8 H( [3 V# L" Z {3 P/ ^5 d* ]) {+ [
printf("Initialize CAN failed!\n\r");8 O: A2 D. t- Y# m7 I
}* Y; N/ |1 c. a- H7 j
else
5 M! H/ |& m3 \1 f0 G/ z {
% z q5 p" `5 S% a4 b printf("Initialize CAN Success!\n\r");' u6 D7 `6 K$ M9 R) h( G$ P* n
}
9 Z& U/ {' G% M+ W8 q #endif `" W7 u# m4 b7 K- p
CAN_Init(CAN1, &CAN_InitStructure);. b& p5 O, w, Z2 V
} 通过查看STM32F103 的参考手册,找到了答案
% F! k9 U& |" U$ K! m( \计算过程* h. h3 v2 r! i: z/ b2 S
. J8 _6 c1 M% `* [' L! x! w" \. g注意STM32 CAN 属于APB1总线,APB1总线,默认配置最大主频(36Mhz),而不是72Mhz。
. u1 j. M0 [. p
& L/ [ J: k8 u H9 ?- 波特率 = 1 / 位时间3 |+ h. p; x& B+ }" C! b# s
- - J5 N1 D9 Z* \! ^1 t- j' w
- 位时间 = (1*tq + tbs1 + tbs2),注意,这里与 CAN_SJW_1tq 无关!!
; O8 I _! ?' o, D; I2 N, ]2 s, _5 h* [ - 6 X. k( y& N- e( G% I& \7 I
- 如果:tbs1 = 2 , tbs2 = 1,则:位时间 = (1+2+1)tq = 4 tq。7 L9 h; r. \5 K% Z6 [! N# l, D' ]
- 6 z2 D4 G1 E7 f
- 注意:这里,还有个分频, 分频分的不是主频(71MHz),是CAN总线的APB1 频率,手册上写着,36MHz,也就是 主频的2分频。* ~+ R4 z8 L' o# ]
- # Q5 z; F- f+ t( e( ]7 |& {
- 系统默认初始化后,APB1总线频率,设置为 36MHz。5 W" n+ Z$ p1 Z [! c Z
-
/ O) B: j& _% _( t6 F - 这里CAN控制器,可以把APB1 继续分频,如 18,那么,CAN控制器频率:36Mhz / 18 = 2 Mhz。- ]0 I- R5 \8 x9 |( X+ p
- 9 n, G9 Z0 s% w: O2 R# w
- 波特率:= 1 / 4 * (1/2Mhz) = 0.5Mhz = 500 Kbps
复制代码 总结* y2 f6 H/ ^ E6 K: l: d
. y- @$ p+ y. ]CAN通信,是比较好用的串行总线,不仅用于汽车上,一些工业总线场合短距离的通信,也可以说使用。
5 X1 G" G& t5 v: A
" ^ x# Y9 }" q* v# I w; f5 n) H
2 R* s8 X3 H1 f4 R8 ICAN通信,波特率、滤波器设置,都需要清楚,才能真正用好。# M2 t) r& O& \3 S r5 }% h2 e
2 M, h, C2 y! M; G# `9 U
2 x( C8 X9 c4 F! f- M
- f p$ J& }% Z, [% J7 f/ v4 I/ j% p7 u$ e% _ s
|