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

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

[复制链接]
STMCU小助手 发布时间:2022-5-4 22:00
一、CAN总线通信初始化配置
9 [% F% M7 P* R1. CAN总线通信初始化配置流程

! F) X, p8 y! r: `CAN总线GPIO和时钟配置- {8 p; s# @% r  F& t7 F
CAN总线接收中断优先级配置' D+ P0 f" V' z) J# D% n8 j
CAN总线初始化配置. E6 `) o  u9 @2 t' `
2. CAN总线GPIO和时钟配置1 n( J8 i3 |$ C' T9 ^
CAN引脚配置
& U( h* z7 M0 g1 a. u  f) ?7 v: t4 R& U- }; f4 k! y
${BDSWRF4[GB%I%MZOLXC@3.png
- |* B( O5 w; f# N, O+ H P10HG5ZV(V(V~N6$YL1(]ES.png
& i' n; m6 E3 ~$ D( p
0 N/ a4 \1 Y# T& p" q0 s& d: k5 \
/ P# Z. ~8 ^' ^CAN时钟配置:
7 }7 T5 \. P' f# D: F& U4 p6 Q# Z

& q( P& J! Y6 m* W9 E; a NO5_I7]74%~`$QQWH_NT{EA.png 2 R# ?8 p3 i0 {5 R7 W! `$ t3 n

* C6 k' v; p( Z  P" G$ G W3B$Z~7_)%U47070WW%_AUY.png
" ]% g' h- B" i' x; M+ a3 q
0 ~& _1 F. w  R3 B3 c  v1 B) r% w4 m$ S& Y/ L9 {, R  I: a
PA11和PA12引脚,CAN GPIO初始化,具体代码如下:
+ Q3 w/ `* X5 V# N5 o0 O3 }
& X- h. E3 ^; N) o, _5 F
  1. /*CAN GPIO 和时钟配置 */2 E( F; f) Y8 P& _* O- v& T0 p
  2. void CAN_GPIO_Config(void)# i' h* a: v# R9 I  s  f* J% D! a
  3. {: m7 d( D* h6 g+ O) c. Y8 ?
  4.         GPIO_InitTypeDef GPIO_InitStructure; 8 n+ U0 B0 d+ f7 T
  5.         /*GPIOA端口时钟使能*/         
    ' z5 L* X1 X  v$ v  T4 H  L
  6.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);                                                                                                                         ; s( l; a+ c. S. u
  7.         /* CAN1 模块时钟使能 */
    : [' Z. H6 b. I1 t, w% i
  8.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); ( o% {# I/ B6 `9 p. I' }5 Q' w
  9. + ^; |) E6 a4 A  |* U
  10.         /* Configure CAN pin: RX */         // PA119 v& D3 N* Z! n1 [9 n7 u! h# p& Y
  11.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;  M+ Q6 b. E) C$ E1 F1 f; {
  12.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;         // 上拉输入1 v5 ?" W+ E7 \3 B  v( v
  13.         GPIO_Init(GPIOA, &GPIO_InitStructure);3 j" ^( ^& G- v; `
  14. # T, x$ K/ m8 h2 N: ^% T5 Q
  15.         /* Configure CAN pin: TX */   // PA12
    ) d. S3 W; l4 N' d
  16.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
    ! C& t9 T* Y/ Z2 F) G) c2 j
  17.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
    ; ?! w% U/ V* F. @9 C
  18.         GPIO_Init(GPIOA, &GPIO_InitStructure);
    ' X& b$ ?" a& Q) [% _7 m; L7 |$ [
  19. }
复制代码

, L: m7 J+ W/ g/ GPB8和PB9引脚,CAN GPIO初始化,具体代码如下:" O5 t" F* Q2 \# v9 V: S( }
0 @1 {. k  q8 S1 f* X
  1. /*CAN GPIO 和时钟配置 */% N3 e/ {. b# r- c: f. s
  2. void CAN_GPIO_Config(void)
    8 d- E$ u/ |9 o' U5 \7 \6 k
  3. {
    / z: X' r- @9 f% ~7 x3 h; y
  4.         GPIO_InitTypeDef GPIO_InitStructure;
    : x- R3 s9 c8 m5 j" D
  5.         /* 复用功能和GPIOB端口时钟使能*/         * {5 x/ u$ F+ i  J
  6.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE);                                                                                                                        
    4 J# Q3 Y5 h4 d" P% ]5 u
  7. 6 R) p8 M! M7 Q9 |- U
  8.         /* CAN1 模块时钟使能 */- i, I8 x9 ~# e9 N* a3 \
  9.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
    3 y, M7 F5 L/ k

  10. # Y- |+ M; p% {
  11.         /* Configure CAN pin: RX */         // PB8- R- {" j' i9 _
  12.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;) y2 k8 e3 l* t7 T4 A5 y0 E
  13.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;         // 上拉输入) y0 }! W% h' K* i5 k# B/ c7 C8 \
  14.         GPIO_Init(GPIOB, &GPIO_InitStructure);" P) Z# q+ j5 ?* A! Z$ ~1 m
  15. ! Q' H$ q; U  j! r- n- {; I
  16.         /* Configure CAN pin: TX */   // PB92 ?& y! }% J! ^: t& ^* @
  17.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  l3 m1 B2 ^5 W: j7 ~0 x' U
  18.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出: T- d6 W( y1 P1 o) Q
  19.         GPIO_Init(GPIOB, &GPIO_InitStructure);- P$ m7 v3 \) n. t% I7 X

  20. 9 x4 D" u9 M. y4 n2 z2 h3 H, o
  21.         //#define GPIO_Remap_CAN    GPIO_Remap1_CAN1
    " v: E9 w3 ~8 T8 |7 u& K  @
  22.         GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);  0 |% K/ a3 O# L5 x# D
  23. }
复制代码

& T2 r; L! x! M4 G, L* g3. CAN总线接收中断优先级配置
* s' V7 A9 m0 S2 S+ w具体代码如下:$ `+ G2 U0 ]1 m& [

. ^5 ~$ l5 Z% g% j1 U5 Q8 o
  1. /*CAN RX0 中断优先级配置  */
      X5 w) W& |4 A5 x+ Y
  2. void CAN_NVIC_Configuration(void)
    ; j9 K( M3 \: e5 o5 O/ E4 O0 L
  3. {! F  q) K2 c* P: ~& c# F. F
  4.     NVIC_InitTypeDef NVIC_InitStructure;
    ) H- l/ a; w3 }1 o7 V3 B/ S/ Z/ O/ O
  5.           /* Configure the NVIC Preemption Priority Bits */  ; Q' V2 g) a" E% ]9 r7 m
  6.           NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
    # A5 c" K5 o5 g! [! _7 L

  7. , B' Q) _& g+ B6 d; z, X
  8.         /* enabling interrupt */
    7 l, ~6 N1 A! M; Y/ i! U' G& r' {5 y
  9.           NVIC_InitStructure.NVIC_IRQChannel=USB_LP_CAN1_RX0_IRQn;;" ?0 I' X* R& b# i$ b, c& s* k
  10.           NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;. `( s" ]( k4 g" F
  11.           NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;3 D# j' O3 _0 `% r" f
  12.           NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;4 N1 Q4 n1 ^( S% K2 p8 T+ a
  13.           NVIC_Init(&NVIC_InitStructure);
    0 x9 _, X: \1 j1 T+ {
  14. }
复制代码

: T& W/ a, Y2 Q8 R0 ?4 ^; n4. CAN总线初始化配置
6 H6 z2 J4 ?/ p6 ]1 `$ Q# j$ b
具体代码如下:9 [: |* c4 j( H
7 j( i+ i6 A. |4 O
  1. void CAN_INIT(void)
    ; ?& l' _! A) h; L# f
  2. {
    $ g; s* A+ c8 O/ @/ V8 H# I) q" W
  3.         CAN_InitTypeDef        CAN_InitStructure;
    1 Y! {% S) {6 J  m
  4.         CAN_FilterInitTypeDef  CAN_FilterInitStructure;
    ( ]6 \1 ~! x& |7 V; A

  5. 4 G" B+ f" _9 I( z: k6 f
  6.         /* CAN register init */
    - l8 B7 |' @: k4 N. J
  7.         CAN_DeInit(CAN1);        //将外设CAN的全部寄存器重设为缺省值
    ; {' E# j: g' O
  8.         CAN_StructInit(&CAN_InitStructure);//把CAN_InitStruct中的每一个参数按缺省值填入
    ! r, y+ X5 u" x9 ~  {
  9. , Q' S" _8 R/ G; I$ i
  10.         /* CAN cell init */
    . }7 h1 v% t& @8 [; @/ I) \  k; x
  11.         CAN_InitStructure.CAN_TTCM=DISABLE;//没有使能时间触发模式
    / t1 }$ i9 P' \# E) c. e9 \
  12.         CAN_InitStructure.CAN_ABOM=DISABLE;//没有使能自动离线管理
    ' C& ~8 D+ _$ p( Z+ Z/ d
  13.         CAN_InitStructure.CAN_AWUM=DISABLE;//没有使能自动唤醒模式2 J- {( I2 t; c; L7 I3 W4 \
  14.         CAN_InitStructure.CAN_NART=DISABLE;//没有使能非自动重传模式& ]5 [7 t  I7 d! [7 w: J# L. C& @
  15.         CAN_InitStructure.CAN_RFLM=DISABLE;//没有使能接收FIFO锁定模式
    % S3 K7 k' z/ ~$ P
  16.         CAN_InitStructure.CAN_TXFP=DISABLE;//没有使能发送FIFO优先级8 o, o2 X# [7 Q
  17.         CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;        //CAN设置为正常模式4 i5 B4 k5 |/ D! `$ k& U8 A
  18.         CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;                 //重新同步跳跃宽度1个时间单位
    * Q7 `8 {: Y1 m" L
  19.         CAN_InitStructure.CAN_BS1=CAN_BS1_3tq;                 //时间段1为3个时间单位$ f) L3 N# N* J3 I# P( l& \
  20.         CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;                 //时间段2为2个时间单位; m3 v9 [/ S5 N' B
  21.         CAN_InitStructure.CAN_Prescaler=24;                  //时间单位长度为24           250k5 p2 n4 A" S' y" K4 k
  22.         CAN_Init(CAN1,&CAN_InitStructure);& _8 l* G' ^% x0 s( ?1 }
  23.                                                       //波特率为:36M/24(1+3+2)=0.25 即250K
    $ {$ i6 C5 k. @
  24. $ T: @+ e7 I# k
  25.         /* CAN filter init */
    ! C3 D9 \% a8 r3 P
  26.         CAN_FilterInitStructure.CAN_FilterNumber=1;//指定过滤器为1: g' B6 j) D' T$ M: f( I5 m
  27.         CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;//指定过滤器为标识符屏蔽位模式, w! r( G+ e+ W- f. Y
  28.         CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;//过滤器位宽为32位
    ; B/ y" w4 ~$ p# B/ T% }9 ~1 G0 h' X
  29.         CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;// 过滤器标识符的高16位值
    " h) P  A( q1 O/ K5 T
  30.         CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;//         过滤器标识符的低16位值
    ; r3 Y4 g( H% X. W1 J
  31.         CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//过滤器屏蔽标识符的高16位值: }+ U1 ^: y: @  \5 X
  32.         CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;//        过滤器屏蔽标识符的低16位值0 a6 j* e) }# A: J- Z7 Z3 n
  33.         CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;// 设定了指向过滤器的FIFO为0
    " Z( e: x! F6 u7 |; Z2 q
  34.         CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;// 使能过滤器+ N1 @3 U% X2 S, |  ^8 U( U
  35.         CAN_FilterInit(&CAN_FilterInitStructure);//        按上面的参数初始化过滤器: v* [0 M6 U- E* r

  36. 9 }$ }$ a. a) u$ m7 j
  37.         /* CAN FIFO0 message pending interrupt enable */ ; a6 \% _' ~, }' o
  38.         CAN_ITConfig(CAN1,CAN_IT_FMP0, ENABLE); //使能FIFO0消息挂号中断
    + {/ b% L' l5 n# ~
  39. }  
复制代码
; p+ p/ e4 g- O) S6 }: B/ D& x
二、CAN总线通信——波特率计算
& h% G6 |+ h5 ]- K0 A; v. y1. CAN总线时间特性- q- ]5 E4 X* u: [2 b
同步段(SYNC_SEG):通常期望位的变化发生在该时间段内。其值固定为1个时间单元(1 x tCAN)。
1 L6 H) ^* q3 `$ X时间段1(BS1):定义采样点的位置。它包含CAN标准里的PROP_SEG和PHASE_SEG1。其值可以编程为1到16个时间单元,但也可以被自动延长,以补偿因为网络中不同节点的频率差异所造成的相位的正向漂移。
$ i" X( l7 O6 j- F% C5 s: |1 n  ^, l/ w) W时间段2(BS2):定义发送点的位置。它代表CAN标准里的PHASE_SEG2。其值可以编程为1到8个时间单元,但也可以被自动缩短以补偿相位的负向漂移。
+ h' u* |& [" u0 x( k# G4 o4 C* y) E: O* _* ?5 d
GMOO5VVLO[FLC9U6]W{ZH.png
6 H! H( W5 [8 i" M. [# Y# m' u- X% }/ k4 f3 L3 a6 G/ v+ ^" y
2. 波特率计算公式
$ t* E0 y3 ~5 }8 SCAN波特率=APB1时钟频率/BRP分频器/(1+tBS1+tBS2)% s1 Y8 N$ K( p4 _. v7 D

# ]( i+ G/ N9 d- w; ?' w. W一般APB1时钟频率为36Mhz。如下图常见CAN总线的波特率设置。% _' a1 D/ }9 w( f3 D

& a8 ?& W4 P. }3 g0 L! S KPILTGAY5}$UF_PKKT5NJLU.png
4 M6 ]4 ?3 G' \' [+ G3 k* P# c3 I Z[5DG6T[ZC]06389K9H3}QI.png % a  t: m) g) Y5 {* ^1 B
& p5 O* ?  A  O. b0 W6 [
3. CAN波特率有关的寄存器
; C. y" ~1 [  _' F7 I5 b/ i8 c
% L0 ]  @% r- d7 a
%JE[TE(VB2MHP0~NY)O$QUG.png
% s4 E5 [4 g1 T# k# E6 ~; `3 z$ H& W' A' [( |, @% {0 P
C2JRU3{U}`BHN)[4D(KIZN1.png
4 I2 v! e1 O: R$ @
1 w2 X8 W& d+ |% q1 k9 m% t' i, S. y

8 i1 }, r0 O! S. z. x  A
收藏 评论0 发布时间:2022-5-4 22:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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