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

【经验分享】STM32F103:CAN总线通信——初始化/波特率

[复制链接]
STMCU小助手 发布时间:2022-5-4 22:00
一、CAN总线通信初始化配置' C- ^- V6 A! }& F9 C( z
1. CAN总线通信初始化配置流程

* s& [, ^0 y! H1 HCAN总线GPIO和时钟配置  ~* j. ~1 B3 @, @+ Z
CAN总线接收中断优先级配置# P' d. p# F4 `) V) i
CAN总线初始化配置
" W7 ~& K4 p6 s4 Y2. CAN总线GPIO和时钟配置
" S7 _# @$ b, C# |  |CAN引脚配置+ z- v" c8 f) U. Q0 u& T9 p  S8 A
- h( k. O0 G$ q( ]4 w
${BDSWRF4[GB%I%MZOLXC@3.png : Y) u, f% h, r* ]+ W
P10HG5ZV(V(V~N6$YL1(]ES.png
3 W/ f( m) u% G, z
+ [! c  l! Y7 P3 g7 G/ e. [: I/ j6 y3 m2 V7 @, ~, h
CAN时钟配置:

; c5 Q5 b3 p: w/ _/ z+ c4 I, W4 V- ]8 K  j0 n2 F- j. p
NO5_I7]74%~`$QQWH_NT{EA.png
( H7 w0 T$ ~/ S; M; x- @) A& s4 k1 i/ \- Z/ h
W3B$Z~7_)%U47070WW%_AUY.png
, h1 d+ v: k& L# F  y7 ?
9 U  C) B6 d6 x9 h7 q
; a7 _  W% Z% b4 W0 @8 jPA11和PA12引脚,CAN GPIO初始化,具体代码如下:
) P& `- f9 u2 F0 ~6 I5 [( u+ A, Q- k3 R" V$ S
  1. /*CAN GPIO 和时钟配置 */
    9 e& i3 d! G7 I$ W
  2. void CAN_GPIO_Config(void)
    # |  {" w) x) m: M$ _8 M, D
  3. {
    ; B+ r0 u' d6 h, T% n+ Z- `1 c
  4.         GPIO_InitTypeDef GPIO_InitStructure; ' C3 B0 q  J; F- q$ |$ N, s
  5.         /*GPIOA端口时钟使能*/         2 P% _' @4 \, [0 q+ `/ u& M
  6.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);                                                                                                                         . c. \% \" j* N9 k. m% b
  7.         /* CAN1 模块时钟使能 */
      Q0 a+ i0 n9 B2 p7 \
  8.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
    ! ?  x" ~3 g; b$ c* n; H) Q* L

  9. 0 P( V% b" x' M( o) ~3 q! z* e
  10.         /* Configure CAN pin: RX */         // PA112 S6 S0 [7 l  e; s9 G0 w( F
  11.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;( v" ?: q2 p# ~6 e% |
  12.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;         // 上拉输入6 S4 e, j% E2 |# Z
  13.         GPIO_Init(GPIOA, &GPIO_InitStructure);  m: e9 Y7 }' W" W
  14. 7 Y5 \4 r, }4 k
  15.         /* Configure CAN pin: TX */   // PA12
    - |- j9 ?7 B/ O. Z' W9 {
  16.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    ; g3 `% l! f  \/ v- k  s2 |
  17.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
    9 K/ R( j( }; e) K
  18.         GPIO_Init(GPIOA, &GPIO_InitStructure);
    * u& U8 o+ [& L! u; h& G
  19. }
复制代码
7 J' v# p7 E" g1 A1 ]6 Q+ b& a
PB8和PB9引脚,CAN GPIO初始化,具体代码如下:
* F3 i4 _7 e' I0 ^6 x$ b
8 y% T9 N5 F3 {. k
  1. /*CAN GPIO 和时钟配置 */
    4 H  `$ l) ?$ H" S, ~, w
  2. void CAN_GPIO_Config(void)
    * ~; [( \; d$ |  ~# F- N
  3. {
    & d) ^- F3 \) B4 u* l- ?% o4 l: g
  4.         GPIO_InitTypeDef GPIO_InitStructure;
    ' P$ }3 l- G* m$ J6 G
  5.         /* 复用功能和GPIOB端口时钟使能*/         6 M; F' g* ?& F% t0 l) N" d& ^8 l
  6.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE);                                                                                                                         : A# y- w2 o$ G9 S
  7. % \% |3 h: z2 j" O5 O+ Y3 J" a7 V) x
  8.         /* CAN1 模块时钟使能 */
    2 E( Y$ {) [" |1 U. i8 ^" j
  9.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); 8 @& Z1 w1 E5 x! O5 `; j

  10. " l) U5 O/ W* j0 y  h, ?
  11.         /* Configure CAN pin: RX */         // PB8
    5 [( i# ?  z5 _9 [. z- @5 L
  12.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    1 Y( o0 P2 [: U% |
  13.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;         // 上拉输入+ q+ R" c3 Q+ r' h7 g( @3 }
  14.         GPIO_Init(GPIOB, &GPIO_InitStructure);# K0 K3 S) u9 X5 I
  15. 8 R! u: R' P9 B  Z
  16.         /* Configure CAN pin: TX */   // PB9
    . [5 X# X2 k6 l3 K2 \6 Q
  17.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    * |. K7 M/ A! P9 ]
  18.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
    9 R1 e/ V2 O0 ?
  19.         GPIO_Init(GPIOB, &GPIO_InitStructure);
    5 \& Z0 F5 g$ j# \2 O
  20. ! K/ f5 g, x8 l
  21.         //#define GPIO_Remap_CAN    GPIO_Remap1_CAN1 % h+ ]9 w3 J2 T* x' M
  22.         GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);  9 t- @3 q4 N$ K; E8 Y0 W
  23. }
复制代码
* n; I# w7 L" n5 d2 E/ ^2 r
3. CAN总线接收中断优先级配置5 K4 ~* Y8 q' t9 Z: ^1 s
具体代码如下:/ y( b: y5 F1 E5 I( {/ @
" N, t3 r: M" R' c* T
  1. /*CAN RX0 中断优先级配置  */
    : H0 c( b. y& K8 J  z
  2. void CAN_NVIC_Configuration(void)
    9 W( k, _- Q) ~" M4 k
  3. {
    . i. n! ?. m# j( U' J0 o" E
  4.     NVIC_InitTypeDef NVIC_InitStructure;
    + \  u4 ]7 C3 L! V5 n3 o
  5.           /* Configure the NVIC Preemption Priority Bits */  " z0 v3 U9 W  Z
  6.           NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);, @  g# q3 o- u0 `8 a
  7. : d3 ?8 i8 f7 g6 Z4 G1 C
  8.         /* enabling interrupt */% r3 ^" v0 {* a$ X
  9.           NVIC_InitStructure.NVIC_IRQChannel=USB_LP_CAN1_RX0_IRQn;;5 Y2 ~; f4 Q2 Y4 B/ b" S
  10.           NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    5 u2 Q% K: m( Y- m1 a" x. G* I
  11.           NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;& R" }; }1 A, W& D: y
  12.           NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    2 @. S5 S8 v1 L" A% Q$ M, D" }
  13.           NVIC_Init(&NVIC_InitStructure);
    0 J( C1 ?8 Z5 _/ ~
  14. }
复制代码
! K5 v) a: }  ]; u9 q
4. CAN总线初始化配置
% M+ @9 G4 N2 y$ D: B/ w. C/ L
具体代码如下:: Y2 r1 }/ d. ~) Y  _+ k

3 @7 \* @# u( g8 A
  1. void CAN_INIT(void)   I( N$ H6 j$ {
  2. {
    2 E" [9 d" A1 ~
  3.         CAN_InitTypeDef        CAN_InitStructure;7 [; O7 s/ p: P+ {. z2 n# z6 `2 D
  4.         CAN_FilterInitTypeDef  CAN_FilterInitStructure;" c" ~( x3 [! I, a: \
  5. - Q' J* f* k# t' J) t
  6.         /* CAN register init */
    + O, G# I9 x# Y) H7 d( g  k
  7.         CAN_DeInit(CAN1);        //将外设CAN的全部寄存器重设为缺省值) m$ i( k0 C1 ]% ^& C
  8.         CAN_StructInit(&CAN_InitStructure);//把CAN_InitStruct中的每一个参数按缺省值填入
    ) Y3 g( Q$ b3 Z/ m3 `% F$ b

  9. 5 K# S2 M7 k, d1 z
  10.         /* CAN cell init */
    6 U5 u. F) E: M
  11.         CAN_InitStructure.CAN_TTCM=DISABLE;//没有使能时间触发模式1 c) r8 q# f6 ^4 ~! I1 w) ]# |" e, i
  12.         CAN_InitStructure.CAN_ABOM=DISABLE;//没有使能自动离线管理* z& z6 \$ I6 U% m
  13.         CAN_InitStructure.CAN_AWUM=DISABLE;//没有使能自动唤醒模式
    2 O# N+ h4 _: z, ], v% D# I( X& I& P
  14.         CAN_InitStructure.CAN_NART=DISABLE;//没有使能非自动重传模式
    4 `8 [- R' p! x. n
  15.         CAN_InitStructure.CAN_RFLM=DISABLE;//没有使能接收FIFO锁定模式' Q, t6 f6 q4 q' Y+ b% `# u
  16.         CAN_InitStructure.CAN_TXFP=DISABLE;//没有使能发送FIFO优先级4 Z* P, G# C% b( F' |8 U6 F* w
  17.         CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;        //CAN设置为正常模式
    - g* ]: s3 h; a5 _& y- s' h+ U
  18.         CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;                 //重新同步跳跃宽度1个时间单位
    0 q5 V, o- C4 v8 i  B
  19.         CAN_InitStructure.CAN_BS1=CAN_BS1_3tq;                 //时间段1为3个时间单位
    ! h) w) B6 f0 s: |8 W
  20.         CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;                 //时间段2为2个时间单位  E6 S) ^1 L* q4 c9 [
  21.         CAN_InitStructure.CAN_Prescaler=24;                  //时间单位长度为24           250k1 n/ o% h- C/ p: w6 W# u7 u
  22.         CAN_Init(CAN1,&CAN_InitStructure);
    # y: a) _' \) ?/ Z$ N$ n
  23.                                                       //波特率为:36M/24(1+3+2)=0.25 即250K
    0 h. O- m6 w: ^& ]" x# f& r( r
  24. " R7 g* l8 x# T/ z+ O3 y$ M  R( A1 T
  25.         /* CAN filter init */& E3 M" |! H2 C# q' g
  26.         CAN_FilterInitStructure.CAN_FilterNumber=1;//指定过滤器为1
    2 z* j* u5 }( I2 P
  27.         CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;//指定过滤器为标识符屏蔽位模式- @: W" I* Z! t, h$ i
  28.         CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;//过滤器位宽为32位* Y4 }+ r: a( ^4 e1 m
  29.         CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;// 过滤器标识符的高16位值
    5 m: Q: O. ~8 l0 a9 [
  30.         CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;//         过滤器标识符的低16位值( E; t  ?6 ~' T4 K9 E5 R
  31.         CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//过滤器屏蔽标识符的高16位值
    ! q6 q' k, e3 n/ [2 \! B  Q) i) C
  32.         CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;//        过滤器屏蔽标识符的低16位值- F7 f# ?- q7 z
  33.         CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;// 设定了指向过滤器的FIFO为0
    & _9 F. q/ n) A. {
  34.         CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;// 使能过滤器# u. R4 Q4 Z! X1 P" i1 _
  35.         CAN_FilterInit(&CAN_FilterInitStructure);//        按上面的参数初始化过滤器* X0 O: R; W: ^8 |" Y

  36. # X$ a# ~# P0 ?# V# H) }) F- d( g9 B
  37.         /* CAN FIFO0 message pending interrupt enable */ 7 I6 s6 Y% L5 E* [
  38.         CAN_ITConfig(CAN1,CAN_IT_FMP0, ENABLE); //使能FIFO0消息挂号中断
    5 u( i. @( m7 m+ {! e8 B+ F4 C! F
  39. }  
复制代码

9 d) y3 L# \5 M, s3 a二、CAN总线通信——波特率计算, |1 _; F- r( k7 K" }. \
1. CAN总线时间特性! Q8 O7 N2 i& R& ?- i
同步段(SYNC_SEG):通常期望位的变化发生在该时间段内。其值固定为1个时间单元(1 x tCAN)。, f/ D- k0 \1 h, G& ~8 n$ }7 s: L
时间段1(BS1):定义采样点的位置。它包含CAN标准里的PROP_SEG和PHASE_SEG1。其值可以编程为1到16个时间单元,但也可以被自动延长,以补偿因为网络中不同节点的频率差异所造成的相位的正向漂移。
% a( T& M# _2 d+ o9 d时间段2(BS2):定义发送点的位置。它代表CAN标准里的PHASE_SEG2。其值可以编程为1到8个时间单元,但也可以被自动缩短以补偿相位的负向漂移。0 H* P. f' Y5 J* ]; N
5 |. G  y' e( r) D) v# Y
GMOO5VVLO[FLC9U6]W{ZH.png % W0 n, ~3 _" F
+ `0 c/ x5 K9 N! u' \+ |$ q* L1 \
2. 波特率计算公式' f9 X, H( Q6 H/ ?
CAN波特率=APB1时钟频率/BRP分频器/(1+tBS1+tBS2)! E8 F# Q+ Q( p% E7 @+ t
. L. F3 k# n0 |1 n. }- c7 U; t
一般APB1时钟频率为36Mhz。如下图常见CAN总线的波特率设置。, J7 S6 E9 \& J! U

0 v' T3 m* c. O2 ?4 I0 K. k2 l KPILTGAY5}$UF_PKKT5NJLU.png . `. k6 G* L* B, o
Z[5DG6T[ZC]06389K9H3}QI.png
; M6 B# B8 w8 R
9 c5 |) T5 ?+ E3. CAN波特率有关的寄存器
& T$ T* K0 J2 y" A8 [

+ ~& n- T1 I- r3 H3 r %JE[TE(VB2MHP0~NY)O$QUG.png 2 I( |% d5 Q/ Y; ~3 s$ W. o( D3 j  g

( f- u  i" i/ X% H  {4 h3 J0 | C2JRU3{U}`BHN)[4D(KIZN1.png
' B/ _6 j8 V6 _0 @$ X
; j2 Y- K/ w/ A) t" L& n# l+ g
$ `3 S& }4 k$ F2 O, t1 c: B& X! c/ Y" c- @/ U' ^2 F
收藏 评论0 发布时间:2022-5-4 22:00

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版