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

【经验分享】STM32F103:CAN总线通信——发送和接收

[复制链接]
STMCU小助手 发布时间:2022-5-4 22:00
一、CAN总线通信 发送# R# I/ D. I0 Z# i/ J$ `, h- Z. s
1. CAN总线通信发送配置流程+ i) X- z" ^. q6 V$ @! c+ T- {
1.写入标识符" Q; O9 {* ^& u$ w) a6 q$ h
2.写入标识符类型(标准帧/扩展帧)" r8 J4 S! n$ U/ u
3.写入帧类型(远程帧/数据帧)0 L( s9 b: g7 O5 l! [% L3 ]
4.写入数据长度
* t7 k+ r7 C8 J  V5.写入数据9 C/ \- c, o% |7 ?* R2 z
6.发送数据- s' v& v" }) e- {/ x
2. CAN总线通信发送相关库函数! L1 b& N% K# D& S4 N
发送数据结构体:
3 N. F' O. _, R3 n: U9 U& F: H& ]0 ]# R+ @
  1. typedef struct) e) P' o. A/ c. Q! A& I( |4 u8 W  W
  2. {4 U3 n% e" n: F' D, k
  3.   uint32_t StdId;  /*!<指定标准标识符6 ~% S* F: T9 n9 Q  B! f6 x
  4.                        该参数可以是0到0x7FF之间的值,11位数据 */
    ) E  z4 Q) a5 j8 ]" R3 ~

  5. / R6 j# n# m3 _: ]  j# l
  6.   uint32_t ExtId;  /*!< 指定扩展标识符
    " p7 r; d" g: J) v
  7.                         该参数可以是0到0x1FFFFFFF之间的值,29位数据 */' _: e# A3 d+ o% _
  8. ' J! z4 _/ z: |
  9.   uint8_t IDE;     /*!< 指定要传输的消息的标识符类型
    / _% q" i7 A: N9 l; w
  10.                         标准帧:CAN_ID_STD, i/ |" P( `" q' B$ S% y
  11.                         扩展帧:CAN_ID_EXT        */
    ' u$ B% P+ W/ G) h& |% s+ J

  12. 4 S$ R" ^$ z  l1 Z$ m
  13.   uint8_t RTR;     /*!< 指定要传输的消息的帧类型3 ^/ ], U. W1 E. H2 s( @- a: U
  14.                          数据帧:CAN_RTR_DATA/ ]) G7 H- e" ^1 B8 v
  15.                          远程帧:CAN_RTR_REMOTE         */
    % ^6 @* {; L6 Z* V  C2 e: s
  16. & A  W6 o3 i& P, O! `
  17.   uint8_t DLC;     /*!< 指定将要传输的帧的长度。0 U3 a/ s( u& i! B
  18.                                                 取值范围为0 ~ 8        */3 v. Q9 l% F& ?! `' z! d5 X
  19. , q; i: j; W% U+ K) @1 }$ \
  20.   uint8_t Data[8]; /*!<        包含要传输的数据。
    + ?9 i8 ?% _" I- ?9 c& Z  n1 t4 r
  21.                                                 取值范围是0 ~ 0xFF        */* j+ V- J# l1 y: ~9 ]' m: [
  22. } CanTxMsg;
复制代码
8 q9 j- Z$ h% b. I6 j/ |7 J$ e* H4 }
发送库函数:
0 f1 d# }9 M! D. w% \+ _
2 R: g% w7 r3 C8 q
  1. /**
    2 p+ C4 D' |$ M* E
  2.   * @brief  Initiates the transmission of a message.+ A# k1 ]. {9 r
  3.   * @param  CANx:      where x can be 1 or 2 to to select the CAN peripheral.
    & w1 ?# N* o: |7 u  @+ P
  4.   * @param  TxMessage: pointer to a structure which contains CAN Id, CAN2 U/ E& K5 H, O
  5.   *                    DLC and CAN data." K1 b# U: C- t7 B$ u
  6.   * @retval The number of the mailbox that is used for transmission
    5 Z; Y+ ~$ R# N. g  A
  7.   *                    or CAN_TxStatus_NoMailBox if there is no empty mailbox.% j  R) z% Z; g" b
  8.   */
    ) }# b' Y+ ^; R$ S6 x

  9. 6 ]/ ~7 T  p- e1 k& W  v& I
  10. uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage);
复制代码
4 M- c4 Z  i' E  J
3.CAN总线通信发送程序8 \5 I9 D7 B' e' v! x& d, p
标准帧具体代码如下:) [- D6 X, f# V) m4 f3 v. A! n
) f5 j; F" c, e! w2 v8 D* Q! n
  1. CanTxMsg TxMessage;        //定义结构体变量1 N- n/ {6 |, e6 Z  b3 R$ x( U# e
  2. /* 发送数据*/* I: b9 u+ M) ^  R: B2 W0 F
  3. void CAN_TX(void)# N0 {4 A; W' T5 i" x
  4. { : y* u; w- ?8 R8 F! ?
  5.   TxMessage.StdId=0x01;                                //标准标识符为0x01
    / @* w/ f" w/ m9 ]( f, L: t( ^: M6 m
  6.   TxMessage.IDE=CAN_ID_STD;                        //使用标准标识符 CAN_ID_STD
    ; \3 F" P: O$ t. h% m- i" i8 _0 A
  7.   TxMessage.RTR=CAN_RTR_DATA;                //为数据帧
    6 h5 ^3 l# Z+ |! g# {; O. i
  8.   TxMessage.DLC=0x08;                                //消息的数据长度为8个字节
    # j) P. Z3 S. R, E# e
  9.   TxMessage.Data[0]=0x01;                         //第1个字节数据  
    ' F; p9 G- c, ~* A$ ?3 _7 h" n
  10.   TxMessage.Data[1]=0x02;                         //第2个字节数据  
    8 I. R9 Y( B- ^6 i" ?( t5 Y' n2 _8 U
  11.   TxMessage.Data[2]=0x03;                         //第3个字节数据  
    ( T1 q8 ?! ^2 I2 \; {/ _. N
  12.   TxMessage.Data[3]=0x04;                         //第4个字节数据    n: O  ?( ?! A" U- o& u, l
  13.   TxMessage.Data[4]=0x05;                         //第5个字节数据  
    1 g7 Z9 a: I& V2 B& z& ~8 c4 s3 Y
  14.   TxMessage.Data[5]=0x06;                         //第6个字节数据  
    5 T% B- @2 V! J- j2 E" P/ P) z
  15.   TxMessage.Data[6]=0x07;                         //第7个字节数据  
    7 }5 q) R1 K; {- E* f
  16.   TxMessage.Data[7]=0x08;                         //第8个字节数据  
    0 d7 h( E6 f. E6 A* @
  17.   CAN_Transmit(CAN1, &TxMessage);         //发送数据
    6 ]6 ^3 t% V2 X9 Q3 w
  18. }
复制代码

4 u9 x2 ^  ~% L. Z- v' Y扩展帧具体代码如下:' d- r' Z1 W* u  n. g$ o9 s9 W
0 ]( \. ~1 A3 \2 }3 B
  1. CanTxMsg TxMessage;        //定义结构体变量- Z) |2 M9 |5 \' N
  2. /* 发送两个字节的数据*/  X% j7 @* v3 ~; ]
  3. void CAN_TX(void)7 I( E# W0 Z6 W6 N, g
  4. { / S6 P! o# D* M- Q9 H& k

  5. $ C" O5 q/ `; T9 F8 [) D
  6.   TxMessage.ExtId=0x1FFFFFFF;                 //扩展标识符 0x1FFFFFFF
    5 x, N/ u9 r& Q4 s
  7.   TxMessage.IDE=CAN_ID_EXT;                        //使用标准标识符 CAN_ID_EXT ! @% c- w6 H$ |- U) E
  8.   TxMessage.RTR=CAN_RTR_DATA;                //为数据帧
    + U8 p: ]7 X5 X) _
  9.   TxMessage.DLC=0x08;                                //消息的数据长度为8个字节5 L- M1 _2 L# y
  10.   TxMessage.Data[0]=0x01;                         //第1个字节数据  2 `4 r: V  E* D. Y* o0 c# w
  11.   TxMessage.Data[1]=0x02;                         //第2个字节数据    w) [' A6 u: [
  12.   TxMessage.Data[2]=0x03;                         //第3个字节数据  % P  u9 Q0 L0 E+ x  {# F, m
  13.   TxMessage.Data[3]=0x04;                         //第4个字节数据  ; W* n0 d3 U0 |- O) G
  14.   TxMessage.Data[4]=0x05;                         //第5个字节数据  
    0 e" j# r1 p, r7 r" F7 l
  15.   TxMessage.Data[5]=0x06;                         //第6个字节数据  + ^( u- U# y* y
  16.   TxMessage.Data[6]=0x07;                         //第7个字节数据  
    & S( M, \% c4 z) u* B, m* B
  17.   TxMessage.Data[7]=0x08;                         //第8个字节数据  
    0 t, ?' y' ~& P' }! q7 V
  18.   CAN_Transmit(CAN1, &TxMessage);         //发送数据
    - G' k2 m$ J: `
  19. }
复制代码

) k+ V* S0 _+ C$ \) \( x/ a. m$ n& r二、CAN总线通信 接收) I- B8 R" D1 m! \. b! }! a
1. CAN总线通信接收配置流程. X0 H% Q$ Z9 B; ^2 }7 e: r
进入CAN总线接收中断/ k8 j( g. o! p
CAN总线接收库函数接收数据' ?, A8 W' @2 X& |" o. P2 J2 w
解析接收数据
  ^# g8 A- H7 o. A实现对应功能
* @5 F  @+ h" g+ e. W: I
& P) `1 v; E% \  }3 L9 x2. CAN总线通信接收相关库函数0 |- I8 H1 F( g# y( |; N
接收数据结构体:
, i: A% P/ R3 V& \. W
3 f3 X, J2 s' @& i6 x3 E9 Q
  1. typedef struct
    " i$ Y' l/ m" p2 d4 P' _# ?5 y3 Y
  2. {
    3 C- x) Z. U0 [$ O% ]9 r; V; ^- P
  3.   uint32_t StdId;  /*!<指定标准标识符
    - R) l+ M6 K! R* @9 I1 ^' f
  4.                        该参数可以是0到0x7FF之间的值 */
    ' t5 k( ^4 a0 T3 ~0 ]6 E3 {

  5. , L3 `0 i, M  S  U& W0 R% B2 v
  6.   uint32_t ExtId;  /*!< 指定扩展标识符
    4 I: B3 _/ T% j* Z
  7.                         该参数可以是0到0x1FFFFFFF之间的值 */
    4 s' s! [& j$ w* j8 g. `! Q- P

  8. 1 W4 R7 h6 h, J1 o0 c
  9.   uint8_t IDE;     /*!< 指定要传输的消息的标识符类型# ]( a8 K2 x8 k4 b' g
  10.                         标准帧:CAN_ID_STD
    ( T: O- l" b, j% t+ B
  11.                         扩展帧:CAN_ID_EXT        */
      {" {) V, P/ Y) _' `
  12. ' P1 w* g4 W' l, s: K+ r6 M5 @' P: T
  13.   uint8_t RTR;     /*!< 指定要传输的消息的帧类型
    ! Y1 y2 [% R1 l* O! }1 N. |* @
  14.                          数据帧:CAN_RTR_DATA0 W7 S" r4 p1 F
  15.                          远程帧:CAN_RTR_REMOTE         */
    1 k+ f" ?2 Z, T  }9 {8 D

  16. , u, I5 O% [9 t. X
  17.   uint8_t DLC;     /*!< 指定将要传输的帧的长度。
    & z1 k$ v  E2 h  Y" Q- v9 U
  18.                                                 取值范围为0 ~ 8        */
    6 Q# g" G+ u& t# [

  19. / a: E5 B1 E6 M: ]2 x1 }1 `
  20.   uint8_t Data[8]; /*!<        包含要传输的数据。
    2 S8 v# n) C, I0 ?
  21.                                                 取值范围是0 ~ 0xFF        *// w- J2 G% v5 p- f9 Q. o: e
  22.                                 
    & U- o" p  G' ?. ^" u. k" y' e
  23.    uint8_t FMI;     /*!< 指定存储在邮箱中的消息所经过的筛选器的索引
    * w, b' _' n' H: s- N& q1 [% S
  24.                                                     该参数可以是0到0xFF之间的值  */: D4 s, x, f. x2 X
  25. } CanRxMsg;
复制代码

4 L/ B% V/ F$ ?7 k接收库函数:
+ E# s2 `' j2 s3 @3 _
0 M+ D9 r3 J" }. _! D8 d
  1. /**
    . L# D* V# l/ _# R3 e9 T
  2.   * @brief  Receives a message.
    # C( W  \/ x: p. e+ G: R- S
  3.   * @param  CANx:       where x can be 1 or 2 to to select the CAN peripheral.
    % F1 P) S9 K% O4 e% p
  4.   * @param  FIFONumber: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1.' i; @' f: C6 p5 s# w5 l0 B( h
  5.   * @param  RxMessage:  pointer to a structure receive message which contains 8 O! M6 I) B0 r/ [' _
  6.   *                     CAN Id, CAN DLC, CAN datas and FMI number.
    0 a& o& _5 c+ R2 Z
  7.   * @retval None.
    + }) H  |  h; R+ E
  8.   */
    ! n+ O7 B4 w0 n0 F# i
  9. void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage);
复制代码

8 r3 F% b, d7 w3. CAN总线通信接收程序
0 U7 W& K! v. X' B标准帧:
- H: O% r$ G3 g. Q9 s, ]% ~& h" Q具体代码如下:
" u' f9 |" G; s6 t2 h. h# G8 |7 j- R" S' ]
) k/ H. Q. B" Y. q$ F: x
  1. CanRxMsg RxMessage;//定义结构体变量
      j* V) h2 \- u6 r' I1 Q& _
  2. //接收中断( R# x  N2 X& G- c6 v
  3. void USB_LP_CAN1_RX0_IRQHandler(void)7 ^3 e* H* P( `& t( j( ]7 ~" g
  4. {        
      |. W/ P* P# C; f
  5.         CAN_Receive(CAN1, CAN_FIFO0, &RxMessage); //接收FIFO0中的数据
    4 M% W" `+ ?- Y8 b+ o
  6.         get_data(&RxMessage);        //接收数据处理函数- y8 _% O% h  u( ?  R% Z
  7. } ( e1 t/ A8 L- w! Z' ~" N+ u: m
  8. //接收数据处理函数4 D7 G! s' @2 u' ]* g; x& W8 p
  9. void get_data(CanRxMsg* rxMsg)
    4 k( b0 Y; f( ], i6 K' Y+ Z* u% o
  10. {  F9 \9 f/ v1 k- X& L5 i  @8 z& k
  11.         switch(rxMsg->StdId) //判断标准帧标识符) Z2 _4 s, u" u' }
  12.         {; u1 q7 ?1 t3 Y
  13.                 case 0x001: ! {2 R4 P) m0 G4 T' o
  14.                         //要实现的功能
    5 ]2 U" k' p" A& \( y' k* p# ~* j
  15.                         break;9 E& C& n8 R: u! f' A
  16.                 /*: x9 x" w& K: c% d9 ?/ X6 l
  17.                 *8 }- b* |! k9 X7 [
  18.                 其他标识未列出
    2 ~; `1 I. z* {  k2 l
  19.                 */        
    ( {" O! H5 l8 [, b
  20.                 case 0x7ff:
    ; Q$ S$ L2 x% ?, `% U3 l5 M
  21.                         //要实现的功能
    ( ?/ R8 }* U7 L) b  C
  22.                         break;        & |2 ^. I" Q! d, T: Y( `  F
  23.                 default :
    6 O6 A; N  t5 E4 {
  24.                         break;
    ( e9 K& F3 |  l7 G& }
  25.         }
    ! N3 U/ @+ {' U5 F1 S3 S% u
  26. }        
复制代码
. W  p' ~  q1 K( A5 `! ?" x
扩展帧:
5 E1 P, K8 X6 I# X" T具体代码如下:; ^8 N) U; J2 E& w# {+ u

! Z6 T! E) v' C1 ^) N0 g
  1. CanRxMsg RxMessage;//定义结构体变量1 [5 g: u! Q: }2 q; l
  2. //接收中断1 V7 M$ U% ?# D5 g3 t
  3. void USB_LP_CAN1_RX0_IRQHandler(void)
    1 S/ w7 U3 N6 p5 e' r2 c
  4. {        . |9 r0 h, |5 r! G+ Q2 B6 ~/ O' I
  5.         CAN_Receive(CAN1, CAN_FIFO0, &RxMessage); //接收FIFO0中的数据 5 P" m$ f% A1 q7 O( |
  6.         get_data(&RxMessage);        //接收数据处理函数2 T9 A7 k& U: @* w6 T
  7. } 0 ^  W/ J9 d  L& r* Y! n0 i, N
  8. //接收数据处理函数. r; I  c1 [8 d; \
  9. void get_data(CanRxMsg* rxMsg)
    ( i; c; Z1 x5 H, v2 T# ^
  10. {: T+ m9 b& Z8 f1 ~& m" Q7 F5 Q0 m
  11.         switch(rxMsg->ExtId) //判断扩展帧标识符# O# I) I- A6 g; O2 ]: E. x! R* ~- }
  12.         {
    4 t8 f6 p! ^; h
  13.                 case 0x00000001: # `! ~: y5 L8 t2 R& Z! F" c& Q8 J
  14.                         //要实现的功能
    ) N+ }, ^: v2 u' Z
  15.                         break;( P8 t2 g; W& s) D0 m
  16.                 /*
    $ K: ~8 q, S0 G& g
  17.                 *
    % T' f8 p$ L+ [' Z; y0 x2 v- l7 F
  18.                 其他标识未列出: B6 t5 P. V  E# C& V
  19.                 */        1 f5 u! K& E) y& I5 N, t  O3 B
  20.                 case 0x1FFFFFFF: ' h( n* k5 I( e  K0 G6 N% n3 U+ t5 n
  21.                         //要实现的功能  l7 H1 d* w0 D8 B1 d
  22.                         break;        
    3 r7 h9 c2 g% z5 m) V3 v
  23.                 default :
    2 O; K5 G6 _1 e/ ]3 H( ]
  24.                         break;; s% y. I$ n" M3 V! k" Z! h, u
  25.         }
    0 b: J5 E6 _  H$ \3 @" ?8 n
  26. }        
复制代码

' Y7 ^) S( Z. K' B' Z
3 M' d+ P* p$ V" d8 S0 s0 T5 k+ r& t- q9 g% B( l) U5 A
- U1 }7 Y4 Y, j9 t, L5 d2 g

7 c/ z$ W! z4 `
赞 收藏 1 评论0 发布时间:2022-5-4 22:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

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