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

【经验分享】STM32F2-CAN通信-发送任意长度

[复制链接]
STMCU小助手 发布时间:2021-12-1 22:18
STM32F2-CAN通信-发送任意长度,调试好的,与大家分享
; h1 V1 c' B" e: j" u( P5 J2 V- |6 L
+ j. {, \' u& O4 c0 I5 d7 j, }3 d
  1. #include "include.h"  {' Y  _7 l; O
  2. //************************************************************************************************************************************************
    , Q0 Y1 n/ e* a2 d4 ~- P/ X
  3. //20190611调试完成- f+ l, ]6 |: @; A: K
  4. //By Wang
    9 @' v9 \; {; Z9 v' U
  5. //************************************************************************************************************************************************% r5 m4 W$ s& |5 l
  6. / k5 j; [; x7 D5 t+ h# g9 }- |
  7. CanRxMsg RxMessage;4 Q. I3 `9 x5 K) B% |
  8. CanTxMsg TxMessage;
    , c& l6 u& j  E9 d  K
  9. //************************************************************************************************************************************************2 t# G& h$ T$ j# w, a
  10. //函数名:void NVIC_Config(void)7 z: o/ A. E( E  y7 I( J
  11. //功  能:  CAN通信接收RX0中断配置
    * ]  j5 A7 }8 M4 `1 U
  12. //参  数:无5 L1 u9 c' f' i3 U6 E! ?
  13. //返回值:无
    9 R# k- e  F$ u0 b2 [
  14. //************************************************************************************************************************************************
    ' v) y# W; |7 _6 ^8 m) c

  15. 6 Q1 P6 m9 Q. h8 f& y
  16. void NVIC_Config(void)
    3 @6 {% _/ C; q4 ^: n# r% E/ W
  17. {3 h3 c- Z0 Z: N8 H& l; C
  18.   NVIC_InitTypeDef  NVIC_InitStructure;: u. A+ W% u& M: z8 s
  19. : x3 [3 y& m2 f# ?6 k8 _
  20. //#ifdef  USE_CAN1
    9 a. j0 U# k% {1 D

  21. # l5 t  a, d8 B5 e
  22.   NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;//与CAN1_RX1_IRQn;区别% Q! L  l" ]8 }3 y% [
  23.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//不同的中断优先级一样会怎样" U' c8 l: s8 N2 W) d
  24.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;+ s5 s7 @0 c$ z* e: e2 l& J
  25. 6 R- j* w6 ~! ~" B+ P' Q
  26.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;- y3 _1 S, |3 E  E, Y% r$ b7 l
  27.   NVIC_Init(&NVIC_InitStructure);( y0 m( r/ @, d6 K) _% J. Z7 J

  28. 5 E* ~# m% k8 w7 V+ k8 g
  29. }" C9 T( O, D$ ~
  30. 2 t, V" A) b4 V
  31. //************************************************************************************************************************************************
    $ Q3 K" y* d# a1 V. V
  32. //函数名:void CAN_Config(void)
    : v/ D, G) K% p2 P! q; y% M! X
  33. //功  能:  CAN1配置 PD0-RX;PD1-TX2 h' O" J: L4 R; n0 w& X
  34. //参  数:无
    / s. W  x8 e! B; V" F4 f
  35. //返回值;无
    7 t7 D4 D2 A5 S* y, T
  36. //************************************************************************************************************************************************
    # b( O; @" _, `: e# e, K; J, r+ C
  37. void CAN_Config(void)
    # T' ?) Y& d- u* O" R" b# q
  38. {
    3 p. U# H: \; p. c( I4 [9 t
  39.   GPIO_InitTypeDef GPIO_InitStructure;/ w/ w* w! G' y1 Z* ^. Z5 \+ ?  \. V8 R7 N
  40.   CAN_InitTypeDef CAN_InitStructure;
    ; [5 a1 Y: l8 F5 z3 X& N/ c! S8 e
  41.   CAN_FilterInitTypeDef CAN_FilterInitStructure;
    ) l  C# g$ z3 ?5 e" [# z
  42. # f: Q- M$ e# f( B* [! [5 V1 \# W
  43.   /* CAN GPIOs configuration ***********************************/
    2 x% P. D* Q& {" A
  44.   /* Enable GPIOD clock */
    ( a/ D9 N" ]) d+ A& [- B: B$ J
  45.   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);% G# B1 H4 \9 [5 ?
  46. 9 F. j- P/ ~" Y0 w" l  f: m
  47.   /* Connect PD1 to CAN1_Tx pin */
    % k  z7 X0 }$ J8 j
  48.   GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1);
    . \( d' p9 q5 A9 V
  49.   /* Connect PD0 to CAN1_Rx pin */, R5 h- _  z6 E- \% ^
  50.   GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1);
    8 R+ X% l5 R* d8 Q& v
  51.   E, O, G" [' t6 L
  52.   /* Configure CAN1_Rx(PD0) and CAN1_Tx(PD1) pins */  Y: Y- I7 e) M- u1 m/ d/ R
  53.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    " y* q, V& ?1 H+ V' G/ T
  54.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    $ u4 s4 _! R7 Q. F( R8 ~$ D
  55.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;1 m- x5 D& @" @3 R
  56.   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;" N1 D  a" A& [
  57.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    - m" y1 U9 b* V8 u0 k/ K: J
  58.   GPIO_Init(GPIOD, &GPIO_InitStructure);
    6 {3 o+ Q/ r. |" ^* _0 x
  59. * ~6 P1 N4 z4 `" P: e4 Z* V$ D' C
  60.    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//Rx要单独初始化,否则进入不了中断,不能按照ST官方库来设定
    2 k1 p, l, y3 x- ?. J- ~, s2 \
  61.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    7 z* i7 \0 z, ^0 q
  62.    GPIO_Init(GPIOD, &GPIO_InitStructure);8 I0 Z! o" f7 H7 ~( U
  63.   /* CAN configuration *****************************************/
    ! P9 A6 \3 W' p9 T. l$ {. O7 C1 L
  64.     /* Enable CAN1 clock */
    ! |$ u! b0 G( }: }4 x: f
  65.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);( i0 u' l" f9 m( ^( T+ C! n+ x: H! R6 G
  66. ( D9 u& t% b4 n) S3 E$ h
  67.   /* CAN register init */2 _  Z3 v5 L1 Q5 Z& Z3 ~+ I+ D
  68.   CAN_DeInit(CAN1);# o3 m. Z/ Z: W, u( D
  69.   /* CAN cell init */
    + q' d4 o7 U' S, ~+ B7 c8 B' `2 j/ |0 Z
  70.   CAN_InitStructure.CAN_TTCM = DISABLE;
    6 \! ~9 e* e& A& j
  71.   CAN_InitStructure.CAN_ABOM = DISABLE;& I) M# \6 ]' G: ?0 J9 u3 V5 D
  72.   CAN_InitStructure.CAN_AWUM = DISABLE;
    7 h. Q# M2 A! |; @" n# Z  @
  73.   CAN_InitStructure.CAN_NART = DISABLE;( M2 d" i4 }+ h* Y6 v
  74.   CAN_InitStructure.CAN_RFLM = DISABLE;. n& k9 e- N+ W( @! Y
  75.   CAN_InitStructure.CAN_TXFP = DISABLE;; s& N. B. P. c* a! H$ o
  76.   CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;- K/ H7 o0 Z5 x6 D7 Z6 e
  77.   CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
    $ j4 c, z+ v8 M! v( A% E/ d
  78.   /* CAN Baudrate = 1MBps (CAN clocked at 30 MHz) */ //30/(1+6+8)/4=500k
      `3 H& n  L1 j3 O2 ]# f0 P
  79.   CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
    ' Z) ^' G1 o% x3 M
  80.   CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
    1 t# J; z& B8 n1 k* e9 e
  81.   CAN_InitStructure.CAN_Prescaler = 4;; L$ |$ V$ Y. `) g  v
  82.   CAN_Init(CAN1, &CAN_InitStructure);; Z9 U; }: E9 r+ C/ j% f! J* ~

  83. ( G0 f% V, t1 [4 I: g2 n
  84.   /* CAN filter init */+ o$ h  C. _' O
  85.   CAN_FilterInitStructure.CAN_FilterNumber = 0;
    - S2 C3 o- U- `. R
  86.   CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
    ! n1 q4 o. o* o% y; E
  87.   CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;9 N& n3 T5 @, k
  88.   CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;5 K# D0 Y; h" S+ W1 I
  89.   CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;4 Q1 _* a- \/ j% Z5 c$ G3 Q
  90.   CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
    5 u, X% V  V& k2 G! T, P7 S; K
  91.   CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;' K  ~9 Q+ [) Y
  92.   CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;5 C  H4 E5 {/ R" v& K
  93.   CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
    / C% b5 n2 v; k% B7 Z
  94.   CAN_FilterInit(&CAN_FilterInitStructure);
    7 T) p6 z7 m/ O! y
  95. 3 I3 O- z. ^. Q, |- `
  96.   /* Enable FIFO 0 message pending Interrupt */  
    6 _% P/ S& v  n! R" [: Q: B' x8 h/ ~
  97.   Init_TxMes();//发送结构体参数初始化- p2 S& w! }# `/ N- D/ M  f
  98.   Init_RxMes();//接收结构体参数初始化1 h0 ^" @$ s' k, S0 T6 @# V
  99.   NVIC_Config();//中断向量配置
    8 C0 G( L( t' ~. H  B( n" ^* a; |0 r  Y
  100.   CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
    1 x' F0 x' V+ ]

  101.   z8 h4 g7 z& Y7 L) H% S
  102. }
      {& w6 v1 c/ d! N4 c* A
  103. //************************************************************************************************************************************************5 S( h* G0 g# k' x+ D9 u# ^
  104. //函数名:void Init_TxMes(CanRxMsg *RxMessage), X" A! \" N+ w# |& ?3 N; a
  105. //功  能:  Initializes the Tx Message- U4 }- H3 E/ \4 t6 }3 U: X% A; d/ u
  106. //参  数:无
    6 O; d; O; B# p) l* M
  107. //返回值:无
    0 ~! }1 y1 N* B+ z1 X* z
  108. //************************************************************************************************************************************************/ d2 l# R) V% @+ n. h: y
  109. void Init_TxMes()
    . g! i3 v% y' B) e6 Q
  110. {0 G; P9 J' H8 {  ~+ |4 F
  111.     /* Transmit Structure preparation */8 I- P, t+ w4 V* O7 U- e( t$ x
  112.   TxMessage.StdId = 0x123;//标准标识符,必须在( TxMessage.IDE = CAN_ID_STD;//标准帧)情况下才有效' d! G* x+ e( _. k3 o  x% M/ Q- t
  113.   TxMessage.ExtId = 0x00;//设置拓展标识符(29位),必须在( TxMessage.IDE = CAN_ID_EXT;//标准帧)情况下才有效
    6 S' d/ F, O6 s6 K, q4 e& K
  114.   TxMessage.RTR = CAN_RTR_DATA;//数据帧
    # |& s9 t& w# n& O/ T6 w
  115.   TxMessage.IDE = CAN_ID_STD;//标准帧 0 s, F( o8 }: q  _" k, \
  116.   TxMessage.DLC = 8;//发送数据长度  DLC=0-8
    4 @# |' ^* S$ Z; v/ k6 P
  117. }4 E& {' N2 O! q  [( v& I
  118. //************************************************************************************************************************************************2 {: {# j& |& Q6 s5 Z
  119. //函数名:void Init_RxMes(CanRxMsg *RxMessage)
    9 \0 Q1 ]+ k3 L5 o" y
  120. //功  能:  Initializes the Rx Message
    7 |3 S# n2 ?; O3 d/ j. I
  121. //参  数:无( b" A4 h- f+ t0 K) V1 b
  122. //返回值:无
    . _5 E  `( Y7 p- }, O9 y# U2 L
  123. //************************************************************************************************************************************************
    ! `! b- p- `8 x" Z, b
  124. void Init_RxMes(). |- ?1 {4 i  x# x& ^$ ?4 n% A
  125. {# Z/ h/ b: }8 F6 [+ L0 j/ T/ O
  126.   u8 i = 0;# j+ I" }+ n. u- K
  127.   RxMessage.StdId = 0x00;//这个可以在接收中断中判断 如果RxMessage->StdId = TxMessage.StdId 接收正确 # q' u; S4 @. Y$ G; `6 o
  128.   RxMessage.ExtId = 0x00;//这个可以在接收中断中判断 如果RxMessage->ExtId = TxMessage.ExtId 接收正确 7 }/ g, y: B  ?) ]8 B
  129.   RxMessage.IDE = CAN_ID_STD;//这个可以在接收中断中判断 如果RxMessage->IDE = TxMessage.IDE 接收正确 8 `' T7 V3 I* t* G$ H5 |6 U) ~7 d
  130.   RxMessage.DLC = 8;//接收数据长度
    $ I6 U* g7 a# R7 K  {6 l$ q; g
  131.   RxMessage.FMI =16;//????????????????; H4 U) N: d! a
  132. $ t6 i+ C3 b; Y1 ^
  133.   for (i = 0;i < 8;i++)
    ; k5 i, `9 R4 c" E" {, i: [
  134.   {1 I- N0 k" D  t+ H" l# o
  135.     RxMessage.Data<i> = 0x00;</i>. u. w8 b6 o: U) Z1 \% q! c3 {
  136.   }$ p: g) x% c5 i$ Z3 y
  137. }' R  ^! v& x2 t! U2 A
  138. //************************************************************************************************************************************************
    ; W9 ?: y. N% \
  139. //函数名:void CAN1_RX0_IRQHandler()
    # b' A7 I2 j, z) U. ]2 w
  140. //功  能:  CAN1-RX0接收中断服务函数$ b) A( M2 a# l9 m# x% R. v9 B# V
  141. //参  数:无
      j: L, H! i. K: D
  142. //返回值:无8 }" K! \5 d' ^1 x8 ]$ S4 ~( W. u
  143. //************************************************************************************************************************************************
    3 j( a- E; n- d7 R* N" b5 ?8 r, J
  144. void CAN1_RX0_IRQHandler()  //与CAN1_RX1_IRQHandler()区别* h( p1 {: }/ [+ w& ^, y5 ^
  145. {
    " u9 H  f/ |3 M- n0 P2 B; z
  146.   if(CAN_GetITStatus(CAN1,CAN_IT_FMP0)!= RESET)//判断是否发生CAN-R0中断9 a$ u* j3 B4 U8 |; A% G4 i
  147.   {9 o6 ~5 W$ ~6 R2 W
  148.     CAN_ClearITPendingBit(CAN1,CAN_IT_FMP0);//清除中断标志7 c( F2 j& ?3 M( @
  149.     if(CAN_MessagePending(CAN1,CAN_FIFO0)!=0)//接收到数据
    6 i7 [7 W9 P' W4 I) ]4 H
  150.        CAN_Receive(CAN1,CAN_Filter_FIFO0,&RxMessage);//接收数据最大只能8字节7 X, @0 u$ t/ l% O
  151.   }; o* p( q! R2 K6 @. `/ d& V, Q. U
  152.   Usart_Send_Buff(RxMessage.Data,8);//发送数据RS232通信   
    " K1 o; g; R& J! q% I9 L( c) }
  153. }
    2 q  g0 O# w' l5 n
  154. //************************************************************************************************************************************************
    1 Z3 M1 ?* d+ Y% m; X+ s
  155. //函数名:u8 CAN_SendData()% v4 I1 j' ?" _+ b+ G. O. Y/ _
  156. //功  能:  CAN发送数据  发送第二步
    5 x  i8 x3 g$ M" I: f  L2 o
  157. //参  数:Msg数据指针;Length数据长度& g0 \% H9 K9 |. I6 |/ m
  158. //返回值:返回成功/失败标志2 Y5 I# d8 F; C; x) ]* r( x6 w
  159. //************************************************************************************************************************************************
      F' P( F9 `' u1 l9 s
  160. u8 CAN_SendData(u8* Msg,u8 Length); M3 p, _$ u3 L( U* e' O
  161. {
    1 }# F4 u: X  `9 I2 ]% {- g! I
  162.   u16 i=0;9 V' \& ~3 R  a
  163.   u8 mbox=0x00;
    ! m! t' p7 ^- V& W5 Z* S( ?( [
  164.   TxMessage.DLC = Length;//发送数据长度  DLC=0-8' n1 ~; c- C# j+ W5 ?
  165.   for(i=0;i<Length;i++)
    1 ?# e6 I' q4 G8 t7 e
  166.   {+ h! i2 N9 Z  |8 Z+ S/ B
  167. <span style="font-style: italic;"><span style="font-style: normal;">     TxMessage.Data=Msg</span><span style="font-style: italic;"><span style="font-style: normal;">;
    8 E" n$ m. f0 `6 {
  168.   }
    9 s" P: @7 E8 l0 I* j+ I' ^
  169.   mbox=CAN_Transmit(CAN1,&TxMessage);//发送数据  返回邮箱使用数量
    # D7 o, [4 z& e7 l

  170. 6 L2 i8 i- u( s& T3 m7 Z: R
  171. //  while((CAN_TransmitStatus(CAN1,mbox)!=CAN_TxStatus_Ok)&&(i<0xfff))! E2 W) c! b/ b2 |
  172. //  {
    ' G- h- y' C/ {$ j  w+ \
  173. //    i++;
    ' }& m, y5 V5 U6 t) S
  174. //  }
    5 l( {& j8 V3 C5 r5 R
  175. //  if(i>=0xfff)
    ( r* E  J( v! }8 s3 k
  176. //  {
    4 P. S& A6 d* U
  177. //    return 0;//发送数据失败- o/ \4 g6 q4 H; B$ |
  178. //  }( E6 Y" L( X) e  H
  179. //  return 1;//发送数据成功
    4 w, u0 ?  Q7 m6 x
  180. }
    % a3 \$ k8 ?9 G4 V! d2 u
  181. //************************************************************************************************************************************************( O  o% |, Z0 G8 ^
  182. //函数名:void CAN_SendDataProces(u8* data,u8 Num)
    - h: @* |3 V8 L5 Y7 n, Z" \
  183. //功  能:CAN发送数据前期处理   发送第一步
    $ n% q( _0 P' ~( v! Q5 F2 l5 v
  184. //参  数:data数据指针;Num数据长度3 Z- y: O7 g6 ~# `
  185. //返回值:无
      @' O3 h; Q6 v1 Y, b% r
  186. //************************************************************************************************************************************************' ^6 c" G/ I9 W1 x$ ?! Z' k
  187. void CAN_SendDataProces(u8* data,u8 Num)
    2 ?0 A: {# [0 P; U- M  M2 [' J& n
  188. {
    ( v- Z6 |! p: M, o
  189.   u8 flag=0x00,i=0;3 S2 m# w, L. P5 w; v9 \! w: ~/ y9 F0 `
  190.   u8 Count=0x00,Left=0x00;
    8 R0 C) U. }2 S6 x

  191. 0 s  R& q' e0 P
  192.   Count=Num/8;//求多少个8字节倍数8 m  F! B# Q' c/ ]
  193.   Left=Num%8;//剩余小于8字节的数量' |/ i4 B/ ~" S
  194.   for(i=0;i<Count;i++)
    % [- X5 l7 Y5 t3 [' C
  195.   {
    3 y" f1 }, |& }5 `* J  s; d
  196.     flag=CAN_SendData((data+i*8),8);//发送整8字节的数据0 O$ g) ]: f6 e  M
  197.   }   d$ q7 N* P9 ]8 d
  198.   if(Left>0)//有余数才单独再发送一次3 R$ r; S: k& i$ q) u8 G( w
  199.   {" O" s/ W) [/ O$ ?
  200.     flag=CAN_SendData((data+8*Count),Left);//发送剩余字节  _0 O$ o) ]5 k, i, l
  201.   }
    0 _( M# {6 S1 {. D1 b2 T1 r0 X, b
  202. }/ M3 X6 Y/ n0 d
  203. //************************************************************************************************************************************************& r* {" F( @4 e8 ?
  204. </span>
    / F# W. i' S, M
  205. </span></span>
复制代码
/ a& _6 U  Z+ r% f. m
收藏 评论0 发布时间:2021-12-1 22:18

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版