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

【经验分享】can总线-stm32

[复制链接]
STMCU小助手 发布时间:2022-1-17 20:39
一、什么是can总线?
can总线因为使用电压差表示逻辑1和0,所以抗干扰性强,传播距离远(500kbps 时130M),比特率越小越远
1.can有几根线?
  2根,can_H ,can_L
2.can怎么表示1,0?
  can_H - can_L > 0.9V ,为逻辑 0,也称为显性电平。
  can_H - can_L < 0.5v ,为逻辑1,也称为隐性电平。
一般can_H为3.5V , 2.5V
一般can_L为2.5V ,1.5V
二、stm32 怎么使用can总线
1.can接口在哪?
  

, M6 d2 A& j. s- Y
1247024-20190905145414413-588054644.png

' c, C6 k, ]0 u) J8 r+ ~  C" c
  stm32有can总线控制器,以及有库函数stm32f10x_can.c可以驱动该控制器
  但stm32只是有can总线控制器,要真正连接can总线,她还要外接can总线收发器,才能分出来can_H ,can_L,例如如下芯片:
  这个芯片的主要作用是发送时根据TXD的电平来决定can_H 和can_L的电平,以及接收时根据can_H 和 can_L的电平差来决定RXD的电平。
" R7 S- A: J3 y" a: w6 P: r

2 b  G6 V& l/ W, \/ T1 L& N 1247024-20190904142132013-1652807192.png
* t$ I: r$ g) B
) C4 `, Y6 r, i
2.can概念入门比较好的文档
https://wenku.baidu.com/view/7701528a6529647d2728520f.html
这个文档比较详细的介绍了can帧的类型,以及各个帧每个字节,每个bit的含义,以及优先级仲裁机制。下面的例程是数据帧。
3.can例程。
! f) a* C( B2 }$ e9 _
  1. #ifndef CAN_H_
    * U* C+ y/ B, w* |4 `
  2. #define CAN_H_1 B7 u% z. ?5 O# u# r
  3. #include "stm32f10x.h"; N2 f# K# F6 a& I
  4. #define RCC_APBxPeriph_CAN_IO RCC_APB2Periph_GPIOA
    & K, l9 H" T) `/ l, J( h" C
  5. #define CAN_RXD GPIO_Pin_11) d5 D' }! q/ l: x: V- ?
  6. #define CAN_TXD GPIO_Pin_12
    ' t# M9 j; f4 j6 c# D' L5 W
  7. #define CAN_IO  GPIOA- h( M, w; v$ y) i3 J

  8. - H: p8 X& ?. @1 {
  9. enum canrate_e  e1 `  ]2 Z- C9 F3 K( d
  10. {* A6 `% j5 ?- K; z3 Y& u" B* z
  11.     CANRATE125K=125,
    # g* w7 ^; g5 t- N. A+ g
  12.     CANRATE250K=250,# J; }3 {. b% B5 F, `# M( G0 H! h
  13.     CANRATE500K=500,* k- D, a+ X. f
  14.     CANNOTLINK,
    ' T' V% J3 T$ B5 A+ }% t+ p$ `
  15. };9 J* I5 z2 P5 O* P0 b1 ^9 e
  16.   |; T& |8 e- j' j' m
  17. enum canStdExt_e
    3 F. `. b( m( U4 K
  18. {
    - x. O7 C% `/ d$ G1 w+ i
  19.     CANSTD=0,
    9 ]2 S% N3 f+ Z! U/ `
  20.     CANEXT=1,5 g. |' ]$ }& z& V
  21. };
    * t% O" |# ^7 [1 K8 [
  22. struct canrxtx_s# X! \3 s2 p2 n  u" b
  23. {; H" O  _% c3 r1 e
  24.     CanRxMsg rxMessage[3];
    5 l, o4 A. C9 f  C  X" R4 Z/ J
  25.     u8 rx_newflag;
    - M3 N! x) l# w; ^
  26.     uint32_t f;* l6 f) q$ X9 o2 a7 [2 @- S
  27.     CanTxMsg txMessage;
    ( O; ~0 J/ N9 c# }3 T+ i- z1 ^

  28. 0 D8 l, e9 F7 d% F
  29. };
    $ V% F$ X4 d: t# u7 }- `
  30. : D0 G  u& i/ t0 m$ v
  31. /*std ID*/
    / |' X- |  E; H' @
  32. #define CAN1_TX_STD_ID 0x7DF //11 Bits ID,Functional
    4 a& L9 \, S* w: v

  33. & o, |' {' x( X. ^* D7 I
  34. #define CAN1_TX_STD_ID_ECM 0x7E0 //11 Bits  ECM ID,physical+ J& J/ |* F+ Q- K: J$ d
  35. #define CAN1_RX_STD_ID_ECM 0x7E8 //11 Bits  ECM ID,physical0 q+ M+ @0 x1 c) K
  36. #define CAN1_RX_STD_Filter 0x7FF //11 bits ECM Filter
    " S! j' L. _9 V8 Q7 I
  37. - J# q. D. w- [+ |' ]7 k$ k
  38. /*extend ID*/
    * o2 @0 |8 B' b" e/ k, h% e
  39. #define CAN1_TX_EXT_ID 0x18DB33F1 //29 Bits  ID,Functional
    . v/ P+ Z2 z4 h, O
  40. #define CAN_Id_Extended_HONDA 0x18DBEFF1 //29 Bits  ID,Functional   HONDA
    2 I2 b; S+ [. v. d& m: v
  41. #endif
复制代码
  1. #include "can.h"
    , j1 l1 \6 p/ \" S1 F: U* x6 B3 Z
  2. #include <string.h>
    5 w2 Z8 v2 ]/ g$ ]( j: U
  3. u8 std_or_ext;
    + c  e6 J6 B. D  j: B5 u& v
  4. struct canrxtx_s canrxtx;
    & C* F, ]  d& _5 N
  5. void CAN1_init(enum canrate_e canrate), A0 ^/ c8 c8 v  b0 U
  6. {% Q0 m! A" q, d* Q3 q# m( O
  7.   B: z% d1 z- ?* g. j
  8.     GPIO_InitTypeDef GPIO_InitStructure;/ ^, J& h4 w2 [: ?# S
  9.     CAN_InitTypeDef  CAN_InitStructure;
    " V$ t5 A) ]) a. {2 E& }- D7 \2 q

  10. : ?4 q  _5 T& H9 G, m* [9 L9 I
  11.     RCC_APB2PeriphClockCmd(RCC_APBxPeriph_CAN_IO | RCC_APB2Periph_AFIO,ENABLE);' g1 J3 O$ v) y/ g7 L: b4 O* |
  12.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE);
      L, S* F! n- p4 `! E! h$ h1 Z9 d
  13.     GPIO_InitStructure.GPIO_Pin = CAN_RXD;
    3 V- A) Q" P/ T+ d8 O! A
  14.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    % y; g8 O9 A. M8 V
  15.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    2 L; A1 y$ R! e: `9 F% d! F# F
  16.     GPIO_Init(CAN_IO, &GPIO_InitStructure);! O, S2 I+ c1 X  C4 W- I# M
  17. 8 N5 v/ D$ V- b+ i& H7 o
  18.     GPIO_InitStructure.GPIO_Pin = CAN_TXD;0 N/ x' x+ f! w' ?
  19.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;4 C- S( c' D& e9 [
  20.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;% K- X& Y6 [3 ^9 A. C* A
  21.     GPIO_Init(CAN_IO, &GPIO_InitStructure);
    ' ?4 j5 R: ~' \/ C3 L
  22. 3 m1 f* I. h) s: E6 ~
  23.     CAN_DeInit(CAN1);
    ; V7 b5 c' ^! Z9 W
  24.     CAN_StructInit(&CAN_InitStructure);
    " v7 {# p9 h- X- E! T( S6 m
  25. " l) w3 Y2 Y) v+ {6 V' v& v) T+ A
  26.     CAN_InitStructure.CAN_TTCM = DISABLE;; x* }$ h1 f5 ^
  27.     CAN_InitStructure.CAN_ABOM = DISABLE;
    1 @2 B  L6 T( n
  28.     CAN_InitStructure.CAN_AWUM = DISABLE;
    , G) V4 u2 y8 z  o9 ]% b7 h" @
  29.     CAN_InitStructure.CAN_NART = DISABLE;
    / l) _! Y4 K5 z6 P9 n' Z
  30.     CAN_InitStructure.CAN_RFLM = DISABLE;
    ! b: V: ^/ k9 y
  31.     CAN_InitStructure.CAN_TXFP = DISABLE;/ W: }% d8 j1 C0 L
  32.     CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;  ^: b0 W: T& T* Z3 y
  33.     CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;# H" z; z3 m+ h* g* Y# z- {
  34.     CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
    5 C0 V' v1 Y  E7 j: c
  35.     CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;: o' j& `* ?7 P& Q$ B7 u
  36.      //CAN BaudRate = 72MHz/(CAN_SJW+CAN_BS1+CAN_BS2)/CAN_Prescaler- a9 h! P# z( I% P1 W
  37.      if(canrate==CANRATE125K) /* 125KBps */. |4 p4 S# f# S/ \, {5 a6 d+ S# U
  38.          CAN_InitStructure.CAN_Prescaler =96;
    - b3 S% f* X) q. B: q
  39.      else if(canrate==CANRATE250K) /* 250KBps */
      G0 z0 ~8 o! Q8 a8 m. j
  40.          CAN_InitStructure.CAN_Prescaler =48;' W( C. |3 _7 [
  41.      else  /* 500KBps */
    ( \$ Z% W& }/ Q4 D1 U3 a
  42.          CAN_InitStructure.CAN_Prescaler = 24;
    ! ?4 J% b4 v, Q: Q0 W

  43. # Q* E* u) e! [- N2 M- T' j
  44.     CAN_Init(CAN1, &CAN_InitStructure);
    $ S& c1 Q& a  ^, [' F6 [
  45. }9 L" H4 X0 Z  @: \# X  `; u0 A( ?
  46. $ W7 C8 m/ T9 M+ \
  47. void CAN1_ConfigFilter(u32 id1, u32 id2, u32 mask1, u32 mask2, u8 std_or_ext)* m2 J5 i2 o5 b2 N
  48. {
    / k" f+ p' u  n8 e! N9 `% x
  49.     CAN_FilterInitTypeDef  CAN_FilterInitStructure;
    2 L6 Q1 b- t, b; G
  50.     NVIC_InitTypeDef  NVIC_InitStructure;
    , ]% i( N3 f$ _/ x

  51. , Q4 _7 N6 Z: a1 t1 C! L" y
  52.     CAN_FilterInitStructure.CAN_FilterNumber=1; //use which filter,0~13
    ) ]  H+ c2 T, z  f* t
  53.     CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;* _1 l  K+ t; j4 t: K' W" V
  54.     if(std_or_ext == CANSTD)
    " y/ J+ A8 q4 D5 u
  55.     {
    , }8 }  b2 Z6 U7 B* N, V
  56.         CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;
    9 b1 X0 [5 g5 d7 T
  57.         CAN_FilterInitStructure.CAN_FilterIdHigh=id1<<5;
    : x; k2 G* j  s9 k+ W8 M' h
  58.         CAN_FilterInitStructure.CAN_FilterIdLow=id2<<5;
    % R$ c1 n/ V2 c. T5 I8 `; h
  59.         CAN_FilterInitStructure.CAN_FilterMaskIdHigh=mask1<<5;
      e; b4 C* e, _$ n
  60.         CAN_FilterInitStructure.CAN_FilterMaskIdLow=mask2<<5;
    8 U1 _  l$ C1 ~9 k
  61. ( c* s0 t. A7 g, b- p
  62.     }' J- S5 m( I6 l& w# U( [
  63.     else2 p' w! d% I, u
  64.     {
    / f8 O' S5 n5 d+ ^0 [8 o" x
  65.         CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
    ( v8 ^5 t% s3 `; M" j) N
  66.         CAN_FilterInitStructure.CAN_FilterIdHigh=(u16) (id1>>13);% Z! y9 e1 \2 E# O- ]$ A- v/ j  _
  67.         CAN_FilterInitStructure.CAN_FilterIdLow=(u16) (((id1&0x00001FFF)<<3)|CAN_Id_Extended|CAN_RTR_DATA);
    * ~* `/ D1 k/ R2 Y, x
  68.         CAN_FilterInitStructure.CAN_FilterMaskIdHigh=(u16) (mask1>>13);
    % B4 t3 a5 ~& L/ p
  69.         CAN_FilterInitStructure.CAN_FilterMaskIdLow=(u16) ((mask1&0x00001FFF)<<3);5 W# E5 J+ a2 N
  70. ; B( b' f5 u/ K: u, J' c8 Q
  71.     }
    - s+ H- t) ^$ ]' Z: V. B/ t" v1 ]- b/ W

  72. 1 `/ }% ~) U' L: S
  73.     CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;" y+ a3 D& O7 Y* F
  74.     CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;2 {- N/ V# a6 s1 T  y4 U% `
  75.     CAN_FilterInit(&CAN_FilterInitStructure);# l& j) W! W7 D- A8 N2 q

  76. ) ~, S6 }) `; j' F( H4 u
  77.     NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX1_IRQn;
    % U7 C0 T8 U+ Z) y1 g

  78. $ b* a6 R5 j; u9 @$ O
  79.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    - J0 ?+ a+ p: D& u; m" L7 Y
  80.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    , i; }: _) Z% W  [
  81.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;% C0 t7 r! o2 W2 {3 D; E$ [5 b& K
  82.     NVIC_Init(&NVIC_InitStructure);
    # ]- n$ M, g+ O8 O" l
  83. & s; V; @5 ]7 N; u
  84.     CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);" G# J5 f! t  U2 P! Y2 P
  85. }
    1 Q: s3 s" f& d8 F6 W5 R1 B
  86. /************************init******************************// t& n1 D4 X& S5 f
  87. void init_demo()
    & T; H5 [( W  _& K
  88. {2 e$ T) L0 |. x
  89.     std_or_ext = CANEXT;' a$ R6 Y4 {& }$ p" |/ y( J/ l
  90.     CAN1_init(CANRATE500K);/ {! A' F9 h/ `3 R
  91.     CAN1_ConfigFilter(0x18DAF110,0x18DAF110,0x1FFFF100,0x1FFFF100,std_or_ext);//extend ID0 z+ b/ v0 O* Y) A
  92. }+ k2 o3 b! P, y! I2 c9 t1 c$ z
  93. /************************tx******************************/1 R6 E" F5 t: g. ~
  94. /*datalen<=8*/
    ' N# Y% e; j7 b' v
  95. int CAN1_TransASerialData(u8* pdata,u8 datalen)
    6 d' y; c! s- {  E
  96. {8 V; e, h) O& l- m/ J
  97.     u8 i=0;
      ?5 N# y& T" {
  98. & q/ G, Q+ O8 J0 Y4 G. C
  99.     Delay_ms(20);6 ?( Z  a4 H' k  m2 x' E5 c( q
  100. 4 r: U  ^( o; Q; l. c/ l: w+ {
  101.     if(std_or_ext == CANEXT)
    ; J. u2 `! j- e  N1 J& U
  102.     {1 Z6 y! S2 @. \- S; y& Y
  103.         canrxtx.txMessage.StdId=0x00;: M, b3 J; D+ s; d9 }
  104.         canrxtx.txMessage.ExtId=CAN_Id_Extended_HONDA;//bentian
    / O5 i0 G* b$ F% z
  105.         canrxtx.txMessage.RTR=CAN_RTR_DATA;! j/ l; k7 B9 S* F
  106.         canrxtx.txMessage.IDE=CAN_Id_Extended;// 29 bits5 H; W5 u' q  ^2 p, J
  107. $ \. j6 p; d( w6 y: C/ L7 g
  108.     }
    % ?2 C2 R: k* q4 O" h/ _& i, u
  109.     if(std_or_ext== CANSTD), |1 }3 ]  o! ~& m
  110.     {; h0 {8 i: Y' Y6 n) n. S  I
  111.         canrxtx.txMessage.StdId=CAN1_TX_STD_ID;6 E( h3 r5 b0 T% l
  112.         canrxtx.txMessage.ExtId=0x00;
    6 ]) n' ?# V( C  R! x
  113.         canrxtx.txMessage.RTR=CAN_RTR_DATA;
    ' L7 n# o' s6 ?
  114.         canrxtx.txMessage.IDE=CAN_Id_Standard;//11 bits
    0 P8 d( m  n3 k: \; ~; h4 _
  115.     }
    ; g8 e  }& [* k# e& u6 U! M

  116.   e; V+ k( i" N7 X+ o% ^
  117.     canrxtx.txMessage.DLC=0x08;
    " E& |* O7 s5 S. E
  118.     canrxtx.txMessage.Data[0]=datalen;, u+ j6 K7 ?# \0 }% h
  119.     memcpy(&(canrxtx.txMessage.Data[1]),pdata,datalen);
    4 Z: Z5 X  k, |. \- @: a/ D

  120. 9 z7 F4 L, K/ T8 ~, R9 J" C

  121. 5 |) E: D" y- R9 ?- I! }5 f
  122.     while(((i++)<3)&&(CAN_TxStatus_NoMailBox==CAN_Transmit( CAN1,&canrxtx.txMessage)))0 T& l3 e! \( W1 V
  123. * y5 W6 E' W7 ]! Q
  124.     if(i>=3)    //timeout' e# U/ @) R& Z- X. v
  125.     {0 n6 s6 d1 M& W; ?( j5 `# N
  126.         return (-1);
    & h& q8 L1 V8 b+ [. J! ]- X
  127.     }
    - m( Y. u9 w" \
  128. 4 l0 v& M+ {. m
  129.     canrxtx.rx_newflag=0;
    * j. E2 `$ i1 a# j+ i
  130.     return (0);2 Y! ?# u9 `% ~3 W+ q" r1 Z

  131. 0 X  V" v8 Q% g; \! I
  132. }) L5 b' c  U1 z( U
  133. /************************rx******************************/" t- {% w& j6 u. ~5 L/ u
  134. void CAN1_RX1_IRQHandler(void)8 g. y# Y, c( Y+ y  ^% ^
  135. {
    ; y) ?! u# M, M0 A1 o- m- S' @
  136.     memset(&canrxtx.rxMessage,0,sizeof(CanRxMsg));
    4 z3 H) W7 x7 n- y* j" X
  137.     if(CAN_MessagePending(CAN1,CAN_FIFO0))
    * u, Y  H( D, G/ K- c* z
  138.         {( F: a' r6 q+ s: F: _% H9 ]
  139.             CAN_Receive(CAN1,CAN_FIFO0,&canrxtx.rxMessage[0]);( h+ G5 B" ^) V
  140.         }/ j6 K2 h7 F* m: i
  141.     canrxtx.rx_newflag=1;
    8 J) `/ C+ {9 h, ^  D) _& K) U
  142. }
复制代码

, B. ~& e6 r" h& j5 _8 D7 T
三、标识符过滤器的解释
过滤器只是用于接收,判断某个报文是否能通过过滤器,过滤器初始化如下:   
  1. CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;      
复制代码
  1. <font face="Tahoma" color="#000000">CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;          </font><div><font face="Tahoma" color="#000000">CAN_FilterInitStructure.CAN_FilterIdHigh=id1<<5;                                                                        CAN_FilterInitStructure.CAN_FilterIdLow=id2<<5;                                                                            CAN_FilterInitStructure.CAN_FilterMaskIdHigh=mask1<<5;                                                                  CAN_FilterInitStructure.CAN_FilterMaskIdLow=mask2<<5;  </font></div>
复制代码
( W0 Y8 f  A9 m+ U$ P
stm32有0~13个过滤器组,每个过滤器组有两个32位的寄存器,通过设置下面两个结构体成员的值可以有四种组合:CAN_FilterMode 和 CAN_FilterScale3 X; r) `2 a. `$ ^% Q% H! B; k  N
1247024-20190905141229352-7031333.png
( l. R, A. ]$ [
5 D8 |3 f) N+ w8 A
四、关于邮箱
如下图,发送3个邮箱,接收每个FIFO 3个邮箱,这是硬件自动管理的,软件不用管,只要判断发送成不成功,中断接收哪个FIFO就行了(要接收过滤器初始化时绑定的那个FIFO)。
每个邮箱都可以存储一个独立的报文,发送调度器(下图红圈)会根据标识符(ID)的优先级来决定先发送哪个报文(比如发送时3个邮箱都有报文,标识符不一样),PS:标识符数值越小,优先级越高,这是由CAN总线仲裁机制决定的(线与,0可以与掉1)。
9 k. u/ k/ x% L- h$ b: h
1247024-20190905145743356-1283941053.png
8 {4 }" p( W8 P$ ~$ t  ?
五、can中容易理解错的概念
1.CAN总线中是没有地址这个概念的,每个报文都是群发。
所有节点都可以发送和接收,先发送的有优先权,此时其它节点处于监听模式,看是否有能通过自己过滤器的报文。
当同时有多个节点需要同时发送时,can总线将实行仲裁,标识符小的优先发送,被仲裁下去想要发送的节点立即转入监听状态,等待下次机会。
标识符是报文的一部分,如下图所示:
2.不管是标准帧或者扩展帧,最多只能携带8字节数据,用户可以根据这8个字节私立协议。
SOF:帧起始信号,显性电平,即can_H和can_L相差很小,小于0.5V,库函数做了赋值,不管。
标识符:11bit或者29bits,代表着本条报文的优先级
RTR:帧类型,是远程帧还是数据帧
IDE:标准帧还是扩展帧
R0:保留位,库函数做了,不管
DLC:数据域长度
数据域:具体携带的数据,最长8字节
CRC:对CRC前所有字节进行校验,得到的结果,库函数进行了这一步,不需要我们自己计算,不管。
CRC分隔符:1个隐性电平,库函数做了,不管
ACK Field:库函数做了,
EOF:帧结束标志,至少连续7位的隐性电平。不管。
$ n7 ^! i0 x8 A8 {; L7 v; [
1247024-20190905145048384-430469517.png
, B4 V0 h1 U1 }" B2 P
3.位填充的概念
在CAN消息帧中,帧起始,仲裁场。控制场,数据场和CRC段,均以位填充方法进行编码。当发送器在发送流中检测到5个极性相同的连续位时,自动插入一个部补位码。
我觉得这个只要了解就行了,实际编程中库函数已经帮我们做了。

: \% K% X' E& O. Q3 Z# B
' H/ P0 J* ~! z/ b$ H
收藏 评论0 发布时间:2022-1-17 20:39

举报

0个回答

所属标签

相似技术帖

官网相关资源

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