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

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

[复制链接]
STMCU小助手 发布时间:2022-5-4 22:00
一、CAN总线通信初始化配置
# b8 o$ e9 R5 d6 \0 C6 R1. CAN总线通信初始化配置流程

! p& S9 U  m+ g, d5 A* v' NCAN总线GPIO和时钟配置* W" A7 l9 ^; P( m. z
CAN总线接收中断优先级配置
- a1 E8 `$ u' I8 o6 o; vCAN总线初始化配置
% v" Y( n7 ]3 v2. CAN总线GPIO和时钟配置
, }3 ~5 j( P4 |. a8 CCAN引脚配置
, g/ p( |  t+ b# k. J( L4 W' u* C- c) o0 @0 S3 V
${BDSWRF4[GB%I%MZOLXC@3.png % ^& d! U) I4 V, X: V
P10HG5ZV(V(V~N6$YL1(]ES.png
$ [- z  P, Y, b0 N# b7 r  x/ B  g$ x2 C/ d
( h$ i4 w+ H" r1 D( q- N
CAN时钟配置:

" ~  }6 N6 o( w/ h& l
: Z8 v. r) ?' { NO5_I7]74%~`$QQWH_NT{EA.png
/ O/ S5 D% {, q. m* v& q6 w3 h3 A% E& _/ s4 Z
W3B$Z~7_)%U47070WW%_AUY.png + T! ~, I4 Q4 D: [6 E, D
: Y) E. N0 L. S! O% D1 y. s

" B5 N: i; ?9 V! z# K( jPA11和PA12引脚,CAN GPIO初始化,具体代码如下:% Y$ z% w% ~- K2 V& E! `4 h
$ ^& H: r0 a2 C; P
  1. /*CAN GPIO 和时钟配置 */# M- `8 Y5 V) B3 V6 z8 o# x# e
  2. void CAN_GPIO_Config(void)% d! |9 [8 p) v
  3. {4 @! Q$ w1 I7 n
  4.         GPIO_InitTypeDef GPIO_InitStructure;
    ( E) m' ^. O- h' I3 f) d- o* W
  5.         /*GPIOA端口时钟使能*/         
    ) X  y& X% x+ U( }) Z4 S6 {
  6.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);                                                                                                                         + d+ d- X9 }. c1 F+ w5 R
  7.         /* CAN1 模块时钟使能 */
    * r2 I2 F1 I2 q* w6 y
  8.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
    # z) g+ r8 X. Z5 {: {4 J: W- j
  9. 1 i0 {6 D$ l& n# ]" R
  10.         /* Configure CAN pin: RX */         // PA11
    7 B  \- Q- Y0 ]: ^1 j; H6 l
  11.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    / O6 _4 K8 t( T; u) V8 B* X8 |% @
  12.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;         // 上拉输入! v$ x5 N3 c! H. c5 w; V
  13.         GPIO_Init(GPIOA, &GPIO_InitStructure);$ o$ ~& q% J8 m6 Y
  14. . F% v- [* M; Y
  15.         /* Configure CAN pin: TX */   // PA12
    ! G# ?2 P7 |% V! D* ^% Z! n
  16.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;& `3 x% k/ e* O8 k* ]. _
  17.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
    / g' L0 o" {. V( M+ q  B, W
  18.         GPIO_Init(GPIOA, &GPIO_InitStructure);
    / V. H; a3 i/ [8 p% _, y2 b
  19. }
复制代码
# U. l- O4 Z& n# d; J; w8 v
PB8和PB9引脚,CAN GPIO初始化,具体代码如下:* G+ C' J) u# T% n$ _7 U5 G

; T5 E# Q1 w& g" Z; x* E
  1. /*CAN GPIO 和时钟配置 */
      n, M0 f( p& X! W7 ?$ E, O
  2. void CAN_GPIO_Config(void)
    ' @% T" L  O$ Z- I, n
  3. {. b0 R0 ?3 z. A
  4.         GPIO_InitTypeDef GPIO_InitStructure;
    6 v) Q# f  j5 z( T* G8 l7 @; Z
  5.         /* 复用功能和GPIOB端口时钟使能*/         1 Q  B# l$ ^: h
  6.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE);                                                                                                                        
    + k# B4 a, ^, p

  7. ; t, |; }: t0 C& |; [
  8.         /* CAN1 模块时钟使能 */
    ! j# u  x1 A) u. S& I
  9.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); ! N  n, X+ y) e! N5 u! j
  10. 3 P2 a  G* h" ^7 `5 n9 w
  11.         /* Configure CAN pin: RX */         // PB8
    7 `; Y2 c  H0 K
  12.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;9 U4 P2 I7 _, D6 k8 L$ I
  13.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;         // 上拉输入
    " o+ K' T; p3 ^3 i; l- m7 U% @" W
  14.         GPIO_Init(GPIOB, &GPIO_InitStructure);$ q- o6 f5 l- g5 [

  15. * h3 a) m0 S5 p( y5 k: k
  16.         /* Configure CAN pin: TX */   // PB9
    : T% n. V5 ~6 ?" _
  17.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    " W; q8 B1 f7 ~3 v; {9 T$ i! l
  18.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
    ) D. |2 P7 [( T* S+ N" y
  19.         GPIO_Init(GPIOB, &GPIO_InitStructure);
      ~" B& h+ D- R: d; c+ l1 H
  20. 4 _" m6 a+ o0 l7 [2 D  B
  21.         //#define GPIO_Remap_CAN    GPIO_Remap1_CAN1
    : C; m0 z4 z4 M5 W# i' f! T$ e
  22.         GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);  
    & z( P3 ]' o, i1 N- M1 q3 t; M) O
  23. }
复制代码
7 F0 b3 f" V! R2 j
3. CAN总线接收中断优先级配置
* d+ P$ `% ?9 V: z9 g具体代码如下:! O  r1 W0 p6 k# |9 J

# ~! p2 X$ \' z' E1 o
  1. /*CAN RX0 中断优先级配置  */
    ( B4 u, f1 y; k% q9 r
  2. void CAN_NVIC_Configuration(void)
    / n9 M* }5 s! W, a9 H1 z
  3. {' T4 z9 T$ L  Q' `1 z
  4.     NVIC_InitTypeDef NVIC_InitStructure;; X6 E0 I3 R6 U% Y  _
  5.           /* Configure the NVIC Preemption Priority Bits */  
    : E: [: j0 _0 X) c
  6.           NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);! g- h/ R# \# J0 p: s4 w
  7. 5 D0 a" O- E' U7 }( U
  8.         /* enabling interrupt */1 _# z3 z8 y9 _8 V' i* I
  9.           NVIC_InitStructure.NVIC_IRQChannel=USB_LP_CAN1_RX0_IRQn;;. _( ^& x1 i+ p# p' O  ^, f
  10.           NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;8 [3 L) Y. t" X
  11.           NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    2 N( D3 o. a0 D1 S
  12.           NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;+ @* j5 |) U% Z& a6 B$ o  x' }
  13.           NVIC_Init(&NVIC_InitStructure);* P, n2 J/ p8 H5 k
  14. }
复制代码

& t3 e1 ?) C, B4. CAN总线初始化配置
2 l! {- L+ p( ^
具体代码如下:
# B$ z: W- y) g# C
7 @! M3 i' N0 x
  1. void CAN_INIT(void) . k9 e8 t1 \# `1 y+ k
  2. {0 W8 r& u6 v& i2 T* b+ P
  3.         CAN_InitTypeDef        CAN_InitStructure;
    & G  P$ j1 r8 m7 g0 h( T1 \5 a
  4.         CAN_FilterInitTypeDef  CAN_FilterInitStructure;
    , z8 j+ G: C+ z! g/ M7 l$ h
  5.   |7 U1 g( e4 ?
  6.         /* CAN register init */7 x& M8 O1 E  C
  7.         CAN_DeInit(CAN1);        //将外设CAN的全部寄存器重设为缺省值
    4 Z+ }! m2 M# L' E* z  M
  8.         CAN_StructInit(&CAN_InitStructure);//把CAN_InitStruct中的每一个参数按缺省值填入" l& \) ~) H' O, w! x( m' b
  9. * t% J+ F! d9 R9 ]' l4 ^! Z1 i' g* L
  10.         /* CAN cell init */
    # z! C' q) X5 ]
  11.         CAN_InitStructure.CAN_TTCM=DISABLE;//没有使能时间触发模式% V. ?$ ^4 j; N+ x( y  x3 \
  12.         CAN_InitStructure.CAN_ABOM=DISABLE;//没有使能自动离线管理
    3 M; q* \( m; @$ d& Y
  13.         CAN_InitStructure.CAN_AWUM=DISABLE;//没有使能自动唤醒模式6 j6 H5 G  a- l9 G7 n# z
  14.         CAN_InitStructure.CAN_NART=DISABLE;//没有使能非自动重传模式
    . n, h! Y2 O: Q. U: c
  15.         CAN_InitStructure.CAN_RFLM=DISABLE;//没有使能接收FIFO锁定模式4 `% ^- q" R2 ~0 U
  16.         CAN_InitStructure.CAN_TXFP=DISABLE;//没有使能发送FIFO优先级
    ; ~; P: ^) c  N3 ?7 X5 z
  17.         CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;        //CAN设置为正常模式$ o& o6 Z5 m7 r6 P5 g2 I
  18.         CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;                 //重新同步跳跃宽度1个时间单位
    3 ^3 e- Y2 L! e
  19.         CAN_InitStructure.CAN_BS1=CAN_BS1_3tq;                 //时间段1为3个时间单位( E7 f! o5 |7 w9 b4 Z& Z5 G
  20.         CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;                 //时间段2为2个时间单位
    8 @" c) u9 A3 V5 p1 v" P. D
  21.         CAN_InitStructure.CAN_Prescaler=24;                  //时间单位长度为24           250k1 l, k# M" d# x: y% I/ @# e! g8 ?- w
  22.         CAN_Init(CAN1,&CAN_InitStructure);% s9 H2 ?, p+ i1 n, T" J
  23.                                                       //波特率为:36M/24(1+3+2)=0.25 即250K
    1 Y* N! o3 `6 v4 \
  24. : e! T) K& X$ T2 C$ e6 a
  25.         /* CAN filter init */% }4 {; z1 r, x% u
  26.         CAN_FilterInitStructure.CAN_FilterNumber=1;//指定过滤器为1% ?" q9 F5 V  o& e0 G$ u% w
  27.         CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;//指定过滤器为标识符屏蔽位模式
    * n, T4 x9 B8 c: C8 M- x2 j
  28.         CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;//过滤器位宽为32位+ m$ {# a3 w# L+ }1 a2 K3 I
  29.         CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;// 过滤器标识符的高16位值1 ~9 N, r) j+ J# w( m
  30.         CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;//         过滤器标识符的低16位值4 f$ s! i, O" C4 U: i0 x
  31.         CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//过滤器屏蔽标识符的高16位值1 l5 [# ~* P' z9 I' M0 r
  32.         CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;//        过滤器屏蔽标识符的低16位值; b7 A, n/ ~# i) r# D
  33.         CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;// 设定了指向过滤器的FIFO为0% K" ~% y: V( j; r2 D
  34.         CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;// 使能过滤器3 {% ]; W% E# l$ U- l0 p
  35.         CAN_FilterInit(&CAN_FilterInitStructure);//        按上面的参数初始化过滤器$ G2 o0 y2 G. g9 C0 L7 a% Q
  36. 2 Y8 E: t% I  @3 V5 P4 u! t: q
  37.         /* CAN FIFO0 message pending interrupt enable */
    4 m0 h8 S4 K# n, Q
  38.         CAN_ITConfig(CAN1,CAN_IT_FMP0, ENABLE); //使能FIFO0消息挂号中断$ |& V( A( K; v& L
  39. }  
复制代码
" w, u; Z! n7 B6 R& G( }
二、CAN总线通信——波特率计算
' S, D, w9 j4 \. c6 h7 X1. CAN总线时间特性5 j& B( K$ I. h# ~" ^' t
同步段(SYNC_SEG):通常期望位的变化发生在该时间段内。其值固定为1个时间单元(1 x tCAN)。- V; _- Z% C* N* |8 I
时间段1(BS1):定义采样点的位置。它包含CAN标准里的PROP_SEG和PHASE_SEG1。其值可以编程为1到16个时间单元,但也可以被自动延长,以补偿因为网络中不同节点的频率差异所造成的相位的正向漂移。7 l9 y5 e1 ?$ R# Q7 l
时间段2(BS2):定义发送点的位置。它代表CAN标准里的PHASE_SEG2。其值可以编程为1到8个时间单元,但也可以被自动缩短以补偿相位的负向漂移。5 \# f' O# i1 s- q  N7 Y

- o7 T; |; L) q' ~1 w# Q GMOO5VVLO[FLC9U6]W{ZH.png
+ c7 N9 {- a/ ], g; h3 f/ N+ x2 h/ h* a; t* @; p
2. 波特率计算公式
% ]7 C' ^8 b) A0 ^* ECAN波特率=APB1时钟频率/BRP分频器/(1+tBS1+tBS2)
& E' w2 `; S' d0 q) C! l# X) k" T% n: V9 I' I3 V/ B
一般APB1时钟频率为36Mhz。如下图常见CAN总线的波特率设置。+ l* t' z: w4 E( V2 X

' Z, s$ G2 a( @$ B- s( O2 q KPILTGAY5}$UF_PKKT5NJLU.png + W! C% [0 M6 `; X1 m, k2 Z
Z[5DG6T[ZC]06389K9H3}QI.png
" n1 G$ U- Z* h% C1 U& O+ h4 }" R7 c) o) `
3. CAN波特率有关的寄存器" S! ^% z- t8 X3 r* ]

! A" _2 \5 Z# `4 n: l, f+ \! k( Z; Z %JE[TE(VB2MHP0~NY)O$QUG.png
& L' M5 h9 _& R2 y# e" x& A" r# y) J% ]- i  n+ [( {9 R
C2JRU3{U}`BHN)[4D(KIZN1.png
+ o: n# |$ C" k3 s3 ~
+ U  b0 y* q) s- c* \
* V* ^3 E/ X! k& v  ]
9 k/ f. f4 T* R1 @8 }# y
收藏 评论0 发布时间:2022-5-4 22:00

举报

0个回答

所属标签

相似分享

官网相关资源

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