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

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

[复制链接]
STMCU小助手 发布时间:2022-5-4 22:00
一、CAN总线通信初始化配置/ b1 E; H" A7 ~
1. CAN总线通信初始化配置流程
- q3 l5 n: d6 [3 ?( r2 h
CAN总线GPIO和时钟配置
' \+ `& c! G, J# \- g' x; h2 VCAN总线接收中断优先级配置, j! W- ]6 j# D2 B
CAN总线初始化配置
- \- K6 m2 Q9 R' X  D2. CAN总线GPIO和时钟配置
2 i; k& A& h* X% qCAN引脚配置
+ }1 ~4 h# C- y( H- x% r6 s8 S
3 d' j5 q4 K/ ^& g. c3 n% |5 h3 x! n ${BDSWRF4[GB%I%MZOLXC@3.png
8 q' V, u* M3 N9 Y# E% A P10HG5ZV(V(V~N6$YL1(]ES.png $ Y4 k6 x6 c5 y; R
+ W9 U2 h8 w; d; h
7 C! W) e  O1 O) N' R/ N0 {
CAN时钟配置:
+ D: B: A: a% b  W' k: \
+ X' C7 ^4 b2 l& M# g3 f1 i4 B
NO5_I7]74%~`$QQWH_NT{EA.png   P" v5 u2 t( |8 a7 \- D4 a2 f

! y+ T" S7 k+ ]$ L6 h0 s W3B$Z~7_)%U47070WW%_AUY.png
% x' n$ ], L7 ?& @4 Z' G6 M1 [2 m1 \: a- e" M3 p" h8 z
& y: j- b: [. Q& p$ M( J) w7 s" k2 J
PA11和PA12引脚,CAN GPIO初始化,具体代码如下:
5 T% I) @  O, A2 @& _
& l5 ^" Y+ _$ l0 W& m/ Y
  1. /*CAN GPIO 和时钟配置 */& r. g# x! p) A! ^. [; n6 u+ S$ l0 r
  2. void CAN_GPIO_Config(void)3 X3 [: s" y1 l$ P; G
  3. {* _) C! w5 M4 `1 S/ y
  4.         GPIO_InitTypeDef GPIO_InitStructure;   o6 r+ k7 L$ G0 M$ l0 s
  5.         /*GPIOA端口时钟使能*/         
    4 v2 u2 W3 n4 J* O$ H
  6.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);                                                                                                                         2 t* Q3 a$ D9 o# D3 W" h
  7.         /* CAN1 模块时钟使能 */, h: i! Q8 D( @6 q0 X
  8.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
    7 u9 w% H' F) W& w
  9. 7 l! m" A9 f5 @5 r
  10.         /* Configure CAN pin: RX */         // PA11
    ; f) x7 V& c- f
  11.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;8 }. H1 i8 W+ t# _
  12.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;         // 上拉输入0 {) O! O5 g. _3 Y3 ?3 m9 U
  13.         GPIO_Init(GPIOA, &GPIO_InitStructure);
    # K  j! r$ b9 _. E
  14. 9 Z" O5 ], ^' U! X3 a! U( u
  15.         /* Configure CAN pin: TX */   // PA12
    3 C6 d* O3 }( s# e' i  j+ v8 G
  16.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;# v+ l: q1 B8 W3 y2 G
  17.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出  b' U/ }# j, F  V
  18.         GPIO_Init(GPIOA, &GPIO_InitStructure);
    5 t7 T0 s5 S, K: t
  19. }
复制代码
& C: M6 k' p! G( J
PB8和PB9引脚,CAN GPIO初始化,具体代码如下:, f9 k5 F. ^* K% K" [
' U9 \6 \# i1 i4 x! Y
  1. /*CAN GPIO 和时钟配置 */3 J. z9 J  b* `9 _5 p
  2. void CAN_GPIO_Config(void)
    8 _; q6 G% ]+ f/ M. u6 c/ z
  3. {
    8 g# i; I7 z2 {5 Q* G/ r
  4.         GPIO_InitTypeDef GPIO_InitStructure;
    + i# ]4 X) y/ b. L0 z
  5.         /* 复用功能和GPIOB端口时钟使能*/         
    " ?6 C$ Y( K. J* p( p! |! E: B
  6.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE);                                                                                                                        
    : R: _6 n/ S8 ~! n

  7. # B5 T  _- i! H
  8.         /* CAN1 模块时钟使能 */
    , b; \$ {! V+ e* w. \3 y
  9.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
    9 B" ~" n* W  B6 L% G8 i6 \' t$ ^

  10. 9 ^( G% O5 G; `3 z& Z# {
  11.         /* Configure CAN pin: RX */         // PB8) u$ b" T/ e) B/ L- D+ S4 y. W
  12.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    * a$ i5 [" [$ `" C) ]( u
  13.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;         // 上拉输入, o8 b9 W" j1 q" K  q* s
  14.         GPIO_Init(GPIOB, &GPIO_InitStructure);
    1 D/ X7 W# n3 x- y4 Q* v! a
  15. - b$ [3 f" V- O9 l
  16.         /* Configure CAN pin: TX */   // PB9
    * |; D0 d3 \5 c) Y7 V+ `0 r- }
  17.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;" @: _. W" Z: H  t/ e  s
  18.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
    $ S8 |) }, ]: J- p* W
  19.         GPIO_Init(GPIOB, &GPIO_InitStructure);
    0 A0 m1 i/ U! b8 j- Y1 I

  20. 6 H: K4 E, X; U4 o
  21.         //#define GPIO_Remap_CAN    GPIO_Remap1_CAN1 $ {/ m7 ?, U+ Q6 M0 U
  22.         GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);  
    ; w( J' X2 C# T9 o# Z3 `
  23. }
复制代码
) o: m* ^/ S, m7 Z- [
3. CAN总线接收中断优先级配置
. b% K, g% i9 Q" B  C具体代码如下:
9 t  J! F: S( z8 l! L5 F5 y
5 ~& E9 Y7 b* F( o% u0 w( _  O1 k0 @
  1. /*CAN RX0 中断优先级配置  */! ?# e) R3 h5 f% L9 j
  2. void CAN_NVIC_Configuration(void)
    2 h( x  S, c+ V) Z9 s6 U* Z
  3. {
    8 r# O, N  G6 W8 u- X
  4.     NVIC_InitTypeDef NVIC_InitStructure;" E+ Y' e, H  k4 c. }
  5.           /* Configure the NVIC Preemption Priority Bits */  ( b, Z$ J% z; Y1 B  W
  6.           NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
    3 h- ^3 Q* t! z/ B+ Y

  7. ! y/ Z+ {6 c+ l, J* W5 z* q
  8.         /* enabling interrupt */- u; q6 u6 a+ |" O5 i9 H
  9.           NVIC_InitStructure.NVIC_IRQChannel=USB_LP_CAN1_RX0_IRQn;;
    * h6 C4 c+ j3 o8 _: t! r
  10.           NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;6 f4 u3 [. `8 l+ b
  11.           NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    1 z% ^$ c. i4 @* V! Q$ _
  12.           NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    * r* Z' T: _. w! X+ l, B
  13.           NVIC_Init(&NVIC_InitStructure);
    3 G; k0 ^; l1 N! e9 B. d
  14. }
复制代码

  j- o2 m6 i0 h- o* J7 Y4. CAN总线初始化配置

% I! E# R9 r% n$ e  X7 y' j具体代码如下:1 i" N, R/ ]) Z1 s2 P

' m1 @- e  p, e) S
  1. void CAN_INIT(void) ) ^' k* @, g9 t! G/ r
  2. {) X! R  z; Z8 X, O2 r
  3.         CAN_InitTypeDef        CAN_InitStructure;
    0 ?! U8 v8 u* f3 t9 I
  4.         CAN_FilterInitTypeDef  CAN_FilterInitStructure;
    ' p- q9 T% I, m  \) J4 D5 ?6 M* n

  5. 1 S# `. E5 C* v
  6.         /* CAN register init */
    8 M- ~" Q& V1 O0 f
  7.         CAN_DeInit(CAN1);        //将外设CAN的全部寄存器重设为缺省值
    + \- r& {9 T" F! L7 G
  8.         CAN_StructInit(&CAN_InitStructure);//把CAN_InitStruct中的每一个参数按缺省值填入# j6 z1 t; ^% R0 p, O
  9. ' M: i  x# w# T
  10.         /* CAN cell init */
    3 m( h7 P- P- k' s$ V
  11.         CAN_InitStructure.CAN_TTCM=DISABLE;//没有使能时间触发模式
    ) `  u. H$ p" }! p$ c
  12.         CAN_InitStructure.CAN_ABOM=DISABLE;//没有使能自动离线管理
    5 v) \2 T& }+ R/ {4 W  W
  13.         CAN_InitStructure.CAN_AWUM=DISABLE;//没有使能自动唤醒模式, r+ F+ J: a& {1 a* z
  14.         CAN_InitStructure.CAN_NART=DISABLE;//没有使能非自动重传模式
    5 o3 @! W" H0 i. w1 o9 U
  15.         CAN_InitStructure.CAN_RFLM=DISABLE;//没有使能接收FIFO锁定模式4 u; Q- G4 Z+ d1 N, Y
  16.         CAN_InitStructure.CAN_TXFP=DISABLE;//没有使能发送FIFO优先级
    ( B# {- j7 ?& j8 z
  17.         CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;        //CAN设置为正常模式& D) S2 a* t2 ~
  18.         CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;                 //重新同步跳跃宽度1个时间单位
    ) F% Y4 ^9 \! r3 G
  19.         CAN_InitStructure.CAN_BS1=CAN_BS1_3tq;                 //时间段1为3个时间单位
    & g' o5 _, `1 C' x3 X# E
  20.         CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;                 //时间段2为2个时间单位& o& I/ O- t- W( B4 \& \  T
  21.         CAN_InitStructure.CAN_Prescaler=24;                  //时间单位长度为24           250k
    . N/ v$ |; r8 f7 k) ^# {
  22.         CAN_Init(CAN1,&CAN_InitStructure);
    ' K: \% G( J) `3 S3 h  N
  23.                                                       //波特率为:36M/24(1+3+2)=0.25 即250K
    ) R. |' `; m5 Y4 k- c: v9 U* R5 E

  24. + }2 R/ G# q8 K% L
  25.         /* CAN filter init */3 e+ V3 P* U: R/ V! g/ O' Q. Z- e
  26.         CAN_FilterInitStructure.CAN_FilterNumber=1;//指定过滤器为1# q: M) S- G0 j' [& Y: y$ T/ u
  27.         CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;//指定过滤器为标识符屏蔽位模式' @% ?3 }& K5 X2 N( s! {: l
  28.         CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;//过滤器位宽为32位* ]* A9 v% |! B& `
  29.         CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;// 过滤器标识符的高16位值, q# z% A7 x6 _! m. ?( Y
  30.         CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;//         过滤器标识符的低16位值
    5 l# o* s6 r; s& @9 ?6 q/ h# W7 k. k4 C
  31.         CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//过滤器屏蔽标识符的高16位值
    . g& i# ^: ^! x0 f3 V
  32.         CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;//        过滤器屏蔽标识符的低16位值7 n0 p7 G3 b5 ^
  33.         CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;// 设定了指向过滤器的FIFO为05 p- b+ P1 \0 g8 Z
  34.         CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;// 使能过滤器
    5 {! O% R; j; Y$ m
  35.         CAN_FilterInit(&CAN_FilterInitStructure);//        按上面的参数初始化过滤器9 X% o" [5 v* O4 I

  36. 0 t9 g; o) ~9 B1 _
  37.         /* CAN FIFO0 message pending interrupt enable */
    ! b1 _& T. F  z! {- B7 a
  38.         CAN_ITConfig(CAN1,CAN_IT_FMP0, ENABLE); //使能FIFO0消息挂号中断
    5 k8 l( ~6 o7 J! S9 Q4 N
  39. }  
复制代码

* N: b% C( \  q+ f二、CAN总线通信——波特率计算
6 Z8 g. c( g8 b* i: c' M0 B8 f: e1. CAN总线时间特性
' k8 W1 y9 Z& x, `  o* _% I/ a同步段(SYNC_SEG):通常期望位的变化发生在该时间段内。其值固定为1个时间单元(1 x tCAN)。
7 q8 y0 ^: H( G2 J时间段1(BS1):定义采样点的位置。它包含CAN标准里的PROP_SEG和PHASE_SEG1。其值可以编程为1到16个时间单元,但也可以被自动延长,以补偿因为网络中不同节点的频率差异所造成的相位的正向漂移。
0 r! d2 ~& }) K/ n时间段2(BS2):定义发送点的位置。它代表CAN标准里的PHASE_SEG2。其值可以编程为1到8个时间单元,但也可以被自动缩短以补偿相位的负向漂移。1 K* z( L. k) V6 m$ w/ V; j3 A
- n9 i9 q1 b7 \2 _' }' ?& P3 R% U
GMOO5VVLO[FLC9U6]W{ZH.png + i4 I2 P! D+ Q) E3 ~6 M

1 `" R) w5 i! W- z2. 波特率计算公式5 T6 ^: j  @" K7 k4 F& Z
CAN波特率=APB1时钟频率/BRP分频器/(1+tBS1+tBS2)
- P* ?1 k+ N* @5 ~, i; h6 S9 w* R+ C0 l8 E
一般APB1时钟频率为36Mhz。如下图常见CAN总线的波特率设置。
/ C2 Z1 ^, \- k/ P! B
5 B/ N  c4 L0 N& } KPILTGAY5}$UF_PKKT5NJLU.png & H3 I2 F- n2 D. S
Z[5DG6T[ZC]06389K9H3}QI.png # ]3 }; g5 e4 x! W  @! b
$ N+ z8 j2 U6 ~7 W3 p: N
3. CAN波特率有关的寄存器! O5 d' n! S. h% N* Y

, V8 j& Y( n+ O+ \% S" A& c& D- z0 L %JE[TE(VB2MHP0~NY)O$QUG.png $ \# M8 A; B8 S

3 v# l9 T/ {% Y# G! |$ _8 Z" x4 E C2JRU3{U}`BHN)[4D(KIZN1.png
" S& j8 y. p" z! k! a
- H" s% Q& K4 {: X; m# ?
* x. A8 I+ V' V) ?2 o; C  V' m& H  s$ I# C) @) m; h
收藏 评论0 发布时间:2022-5-4 22:00

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版