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

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

[复制链接]
STMCU小助手 发布时间:2022-5-4 22:00
一、CAN总线通信初始化配置( j* T" Z( r3 g! N$ @
1. CAN总线通信初始化配置流程

. ~2 t5 N. h, |5 _% I. RCAN总线GPIO和时钟配置! A0 L5 u, }% x! b* l: \
CAN总线接收中断优先级配置
" B2 a+ I( o: V4 O. RCAN总线初始化配置$ r2 C2 E& A1 Q- c# Z) ^5 f
2. CAN总线GPIO和时钟配置
* z% L+ y3 F1 a" H' F8 FCAN引脚配置- t6 z9 e" o# t' O- {

& F0 l) r" T7 A% ?; y; W ${BDSWRF4[GB%I%MZOLXC@3.png 9 V/ {( B4 u2 e
P10HG5ZV(V(V~N6$YL1(]ES.png ; n3 ^3 y6 o4 k/ d
) }9 n1 v( z0 ]3 u" U
$ G9 d( R1 x. e
CAN时钟配置:
3 ^# E6 K: u- U8 J9 M1 I

# G/ d% r" q3 n+ U; J6 F0 n5 ~ NO5_I7]74%~`$QQWH_NT{EA.png ( k) b' h( O" f
- |1 s( N& H4 c, Z
W3B$Z~7_)%U47070WW%_AUY.png + j& Z. o4 w" ?( r. h
; E( H# ]& z9 H  c0 q! G! r
# f; S( Y# O9 V( m' P" I2 L
PA11和PA12引脚,CAN GPIO初始化,具体代码如下:
1 O  U! g' i7 N( o1 a1 t# x6 |7 I5 N" u6 y; y
  1. /*CAN GPIO 和时钟配置 */
    + M. {7 m( _, P8 N5 ]
  2. void CAN_GPIO_Config(void)% W9 @4 R. }) p% w6 B0 Q
  3. {
    % a' |/ ]+ d/ w4 s* F8 i. [' y
  4.         GPIO_InitTypeDef GPIO_InitStructure;   _  [- Y9 E  j, r0 K# B% u) e& d7 X
  5.         /*GPIOA端口时钟使能*/         
    / Q( K/ T7 L& G) S6 F6 H9 F! b5 x
  6.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);                                                                                                                        
    % Z  @" n+ f  U3 c
  7.         /* CAN1 模块时钟使能 */6 y) i1 ]) q' G, {3 N% ~
  8.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); ; q" s/ c5 K% q# J2 U1 l' i
  9. . ~- ~: v" J* {0 l
  10.         /* Configure CAN pin: RX */         // PA110 w% q( F5 P9 F% s* z1 r- z
  11.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;; L) c; y5 D8 [* `
  12.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;         // 上拉输入7 i8 I/ v; r" L- H
  13.         GPIO_Init(GPIOA, &GPIO_InitStructure);; G6 ^, N" }% ^. s

  14. 0 T, t) s* O3 k0 n  N, p4 L
  15.         /* Configure CAN pin: TX */   // PA12
    ) w( M9 [2 L9 O9 C2 g% T
  16.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;8 t9 G% P* m6 l
  17.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
    7 x. j: B# B% _( ]
  18.         GPIO_Init(GPIOA, &GPIO_InitStructure);
    8 e$ Z- x' V9 C- I+ _! e
  19. }
复制代码
- e+ D4 q* A+ w8 ^- P
PB8和PB9引脚,CAN GPIO初始化,具体代码如下:
2 V( i2 C* e' T3 t0 l: B4 V# K# u4 h
  1. /*CAN GPIO 和时钟配置 */. m, e- S) l6 M2 N# p) ~
  2. void CAN_GPIO_Config(void)8 ~$ E/ T5 b8 i* Z) F
  3. {' O# C; \* t3 C0 u' h
  4.         GPIO_InitTypeDef GPIO_InitStructure; - z  r, c2 z/ O, `6 P
  5.         /* 复用功能和GPIOB端口时钟使能*/         7 A7 T7 b3 {. A: _+ K4 T
  6.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE);                                                                                                                         ( O0 _. I" W' Q
  7. ( d6 j8 M. S, {$ J% V7 k
  8.         /* CAN1 模块时钟使能 */
    1 Q7 T. Q) _" {+ b2 E2 j( H! M
  9.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); 6 U; P6 a: `& ?& O; r& R: M

  10. 3 y& h0 R6 L3 Q- A, L  Z+ G
  11.         /* Configure CAN pin: RX */         // PB8
    # Z7 A  H$ P- k- l  ?
  12.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;* `' B: `& F& o7 x8 v$ X
  13.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;         // 上拉输入
    - i+ w6 x4 e: L$ e; i, z# U% Y
  14.         GPIO_Init(GPIOB, &GPIO_InitStructure);. p3 t) B9 @  |; I4 c2 q! w
  15. 8 m2 E  m0 c9 K; Q1 |: Z) Y
  16.         /* Configure CAN pin: TX */   // PB9# ~) L; }, F' u# K3 U
  17.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    ! z3 Y- X* L* y
  18.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
    1 ^* s0 \7 |# K6 p2 v7 |% s
  19.         GPIO_Init(GPIOB, &GPIO_InitStructure);( a" f2 O4 B6 P9 J: k9 Z: f
  20. / Y" D2 y4 F: W' j. }/ P
  21.         //#define GPIO_Remap_CAN    GPIO_Remap1_CAN1 7 Z6 \8 A/ [3 w
  22.         GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);  
    7 f9 b2 n5 Y$ C
  23. }
复制代码

. p' Q. x7 a" L1 m2 g( a3. CAN总线接收中断优先级配置) i4 g; q4 w" B  Q6 V
具体代码如下:
2 _# i" y" u# |- L1 c4 e1 w" v' K" G  J# p# L+ D
  1. /*CAN RX0 中断优先级配置  */* Q; D4 O, K; t. M. D
  2. void CAN_NVIC_Configuration(void)
    : \( z2 b! n% T9 R0 t
  3. {: i9 E) k( w* s% P7 Y/ N. p, G5 k2 E# M
  4.     NVIC_InitTypeDef NVIC_InitStructure;
    5 x6 l* x& q  _/ J9 J  N% K8 U
  5.           /* Configure the NVIC Preemption Priority Bits */  
    , c  e* d$ O: L& ]$ w4 S' I4 I  V
  6.           NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);4 a: x3 X% Z9 U5 C

  7. 9 g+ [! H4 z( D5 \
  8.         /* enabling interrupt */9 ~1 g8 \6 ?/ R; c0 c! q
  9.           NVIC_InitStructure.NVIC_IRQChannel=USB_LP_CAN1_RX0_IRQn;;) H4 D9 `8 y. e7 S5 u) C
  10.           NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    6 p& [5 H, C) N) u2 [8 S
  11.           NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    & z' H) N! P  a
  12.           NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    + ?  N7 j7 ~" b# }% l
  13.           NVIC_Init(&NVIC_InitStructure);
    9 W! C! X) I2 m3 m; w
  14. }
复制代码

# [3 Q2 ~) S. q: f; G' H4. CAN总线初始化配置
3 I+ j% A3 {- F8 S7 i
具体代码如下:8 a) }7 N2 y# o( T# W8 H! F; W0 `, o3 q

. l" k: J2 H; i+ c8 ^) d' a9 Y/ T
  1. void CAN_INIT(void) / \. x5 i* d" Z2 y' k( e2 l; H
  2. {* G3 O% w; y& Q2 O5 P  k0 A# C5 G9 v5 y
  3.         CAN_InitTypeDef        CAN_InitStructure;8 N) f6 Y' F% e7 [' \) i# ?2 P
  4.         CAN_FilterInitTypeDef  CAN_FilterInitStructure;8 F9 g6 o' v2 v! Z3 h+ C

  5.   y+ R8 L  l" f/ q" B' p
  6.         /* CAN register init */
    1 G) ?, @  A) q4 Y2 J5 P5 Z
  7.         CAN_DeInit(CAN1);        //将外设CAN的全部寄存器重设为缺省值
    - }+ d7 \5 }+ m5 }0 V0 k
  8.         CAN_StructInit(&CAN_InitStructure);//把CAN_InitStruct中的每一个参数按缺省值填入# X+ ^  D1 _8 O( b
  9. ) O: y+ b7 E8 D9 ?" I2 m" e
  10.         /* CAN cell init */
    7 c& W  q- E; u7 d
  11.         CAN_InitStructure.CAN_TTCM=DISABLE;//没有使能时间触发模式6 \: }7 h7 l9 N) {6 K) G, O
  12.         CAN_InitStructure.CAN_ABOM=DISABLE;//没有使能自动离线管理
    $ T2 m( u7 ~* w
  13.         CAN_InitStructure.CAN_AWUM=DISABLE;//没有使能自动唤醒模式, h6 f) m2 H3 R- J
  14.         CAN_InitStructure.CAN_NART=DISABLE;//没有使能非自动重传模式
    ) J" }$ h( K) @& C
  15.         CAN_InitStructure.CAN_RFLM=DISABLE;//没有使能接收FIFO锁定模式: Q+ U0 U' j5 y; g' \
  16.         CAN_InitStructure.CAN_TXFP=DISABLE;//没有使能发送FIFO优先级$ }1 F, e6 r1 b
  17.         CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;        //CAN设置为正常模式  c$ ]8 ~3 [5 R2 i7 A
  18.         CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;                 //重新同步跳跃宽度1个时间单位
    : o* L- i4 G, B& i0 e
  19.         CAN_InitStructure.CAN_BS1=CAN_BS1_3tq;                 //时间段1为3个时间单位1 ]6 W4 }$ ?" p3 Z
  20.         CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;                 //时间段2为2个时间单位
    . M" Y, L& v3 x3 R
  21.         CAN_InitStructure.CAN_Prescaler=24;                  //时间单位长度为24           250k
    $ b$ Z4 M3 g+ r$ d
  22.         CAN_Init(CAN1,&CAN_InitStructure);9 r8 A; a/ u; w4 a2 |: ]
  23.                                                       //波特率为:36M/24(1+3+2)=0.25 即250K6 f4 x0 I3 f' @

  24. ; r! k8 Z% Q% p: l0 v# B4 b/ A
  25.         /* CAN filter init */& }& P7 L0 T# Z3 L# {* S, P
  26.         CAN_FilterInitStructure.CAN_FilterNumber=1;//指定过滤器为19 R" d) T) i  C/ [' n1 F% m
  27.         CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;//指定过滤器为标识符屏蔽位模式- a; V2 x' q3 D8 D
  28.         CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;//过滤器位宽为32位; \+ e/ b7 h4 X! `0 D: o3 j
  29.         CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;// 过滤器标识符的高16位值
    ! @0 f/ Y% ^- q3 D5 C# e; A
  30.         CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;//         过滤器标识符的低16位值
    ( K  }( l& ~4 o5 D% m
  31.         CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//过滤器屏蔽标识符的高16位值
    : y3 B# T# x3 O
  32.         CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;//        过滤器屏蔽标识符的低16位值: O$ X: G9 _9 w
  33.         CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;// 设定了指向过滤器的FIFO为0
    2 c) g6 B0 k4 Y% K: v
  34.         CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;// 使能过滤器
    9 G3 {# y3 `1 ^5 }1 D% N
  35.         CAN_FilterInit(&CAN_FilterInitStructure);//        按上面的参数初始化过滤器2 C" n! v. n- B) t3 s

  36. 9 |" W& L0 G3 e( g
  37.         /* CAN FIFO0 message pending interrupt enable */ 2 ^$ E$ j0 `$ q7 [8 q' ^
  38.         CAN_ITConfig(CAN1,CAN_IT_FMP0, ENABLE); //使能FIFO0消息挂号中断4 A: u6 I7 p) M5 m6 T
  39. }  
复制代码
: I6 w# `3 r/ x$ D: i' Q, z, Y( O
二、CAN总线通信——波特率计算
& O( J. L  D5 c& P1. CAN总线时间特性
! }* j% ^0 g% {3 P' T' n4 X4 l同步段(SYNC_SEG):通常期望位的变化发生在该时间段内。其值固定为1个时间单元(1 x tCAN)。
; o$ H" h, N8 b$ s时间段1(BS1):定义采样点的位置。它包含CAN标准里的PROP_SEG和PHASE_SEG1。其值可以编程为1到16个时间单元,但也可以被自动延长,以补偿因为网络中不同节点的频率差异所造成的相位的正向漂移。4 [" X( c3 _) N: D
时间段2(BS2):定义发送点的位置。它代表CAN标准里的PHASE_SEG2。其值可以编程为1到8个时间单元,但也可以被自动缩短以补偿相位的负向漂移。
3 w7 a. |# l8 Z4 l) {- q  ]6 m; m: G7 K
GMOO5VVLO[FLC9U6]W{ZH.png
  n, S& N' X0 R# U7 X$ M' ]
; ~) @1 H: `9 `) n2. 波特率计算公式" t* o# `  r( i3 R' v
CAN波特率=APB1时钟频率/BRP分频器/(1+tBS1+tBS2)$ O( [+ S& q; v/ q- q2 |, O
( E' h1 A. G, T
一般APB1时钟频率为36Mhz。如下图常见CAN总线的波特率设置。! ], e1 c" x4 Z! ?0 l; N# ?
) Y6 T5 _( c% R! K; q$ o! H( N
KPILTGAY5}$UF_PKKT5NJLU.png ! e  g8 T& q  v" f4 Y
Z[5DG6T[ZC]06389K9H3}QI.png . |' _, Z% j( B- R1 Q

% w( d) F# J+ ?3. CAN波特率有关的寄存器# |* i  p% R3 r: ?2 H

" T% D8 d; X3 p' F %JE[TE(VB2MHP0~NY)O$QUG.png 2 k. ~( u$ U- d2 x: k$ _! U3 `
- C4 k- X# S. w+ n
C2JRU3{U}`BHN)[4D(KIZN1.png 3 d2 o- ?  Z/ b2 w# z
5 |; x) {1 y8 Q) `

  {* {! t9 h- p( P% Y& z$ |8 C# a; Z+ W8 Z8 ?$ q
赞 收藏 评论0 发布时间:2022-5-4 22:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版