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

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

[复制链接]
STMCU-管管 发布时间:2021-2-20 13:29
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( \
21.png
计算过程* 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
22.png

  1. & L/ [  J: k8 u  H9 ?
  2. 波特率 = 1 / 位时间3 |+ h. p; x& B+ }" C! b# s
  3. - J5 N1 D9 Z* \! ^1 t- j' w
  4. 位时间 = (1*tq + tbs1 + tbs2),注意,这里与 CAN_SJW_1tq 无关!!
    ; O8 I  _! ?' o, D; I2 N, ]2 s, _5 h* [
  5. 6 X. k( y& N- e( G% I& \7 I
  6. 如果:tbs1 = 2 , tbs2 = 1,则:位时间 =  (1+2+1)tq = 4 tq。7 L9 h; r. \5 K% Z6 [! N# l, D' ]
  7. 6 z2 D4 G1 E7 f
  8. 注意:这里,还有个分频, 分频分的不是主频(71MHz),是CAN总线的APB1 频率,手册上写着,36MHz,也就是 主频的2分频。* ~+ R4 z8 L' o# ]
  9. # Q5 z; F- f+ t( e( ]7 |& {
  10. 系统默认初始化后,APB1总线频率,设置为 36MHz。5 W" n+ Z$ p1 Z  [! c  Z

  11. / O) B: j& _% _( t6 F
  12. 这里CAN控制器,可以把APB1 继续分频,如 18,那么,CAN控制器频率:36Mhz / 18 = 2 Mhz。- ]0 I- R5 \8 x9 |( X+ p
  13. 9 n, G9 Z0 s% w: O2 R# w
  14. 波特率:=  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
收藏 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 手机版