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

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

[复制链接]
STMCU小助手 发布时间:2021-12-1 22:18
STM32F2-CAN通信-发送任意长度,调试好的,与大家分享4 V$ \1 u* R; v* \0 a" w
* R% D5 f' \" R
  1. #include "include.h"
    3 Q8 I% c0 ?# m0 E
  2. //************************************************************************************************************************************************
    + g4 I5 h$ X4 Y  D; E
  3. //20190611调试完成
    , u8 u- M" _) D* G* D
  4. //By Wang" Y, ~, y$ W6 ^2 V( f
  5. //************************************************************************************************************************************************
    3 G& |  F( Z( O6 x2 u. |/ x7 i
  6. % c) I5 u/ e3 A, Y% N  i
  7. CanRxMsg RxMessage;
    & A, L+ G3 _0 @% _5 w) k4 P
  8. CanTxMsg TxMessage;
    ! E4 s7 u9 ?  s# e! J, `1 Y1 y) o
  9. //************************************************************************************************************************************************
    4 _: n4 ]! d5 Q3 W
  10. //函数名:void NVIC_Config(void)0 \4 Z) m+ y* f( F& D( Y8 `% D
  11. //功  能:  CAN通信接收RX0中断配置' c8 e7 C; x7 l
  12. //参  数:无
    2 x5 `2 R+ D7 {: s: A. H2 Z
  13. //返回值:无
    ! |; ]+ i; S0 s3 b9 B
  14. //************************************************************************************************************************************************( |9 k7 x1 I- u% D# s) }! p. f: X

  15. 1 v+ R/ F) }2 V. N
  16. void NVIC_Config(void)) L$ U8 h# ?5 i4 n: E
  17. {, _& ^0 l1 w  H/ ~; P
  18.   NVIC_InitTypeDef  NVIC_InitStructure;) M% N* o  h8 ]' p7 j' w

  19. / U$ p% s' x4 Y+ m% x5 ^
  20. //#ifdef  USE_CAN1 * O% K+ m( _9 p7 k/ ~
  21. 7 q1 w3 T* ^% c3 c3 z* ]
  22.   NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;//与CAN1_RX1_IRQn;区别0 n5 y" [, z2 D% W( g$ H. T
  23.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//不同的中断优先级一样会怎样" L: h) H3 t, j% j6 _) }, e
  24.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;* p3 I- Y5 O* a, N+ K7 K; K
  25. , [2 @4 R' L7 O
  26.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;9 T! s8 b/ [# }+ g" E# G5 f
  27.   NVIC_Init(&NVIC_InitStructure);2 M; u' }8 q" F( w

  28. ) H8 A) @6 f# n6 l# q/ r1 ~
  29. }
    9 L2 f8 V" a/ F6 R8 Y8 ~7 m9 H5 X
  30. & t2 Z) v: T! T3 L* L
  31. //************************************************************************************************************************************************- C; m: |" f' ^
  32. //函数名:void CAN_Config(void)
    ) K. Y5 O& @& K1 ~& r! a- r
  33. //功  能:  CAN1配置 PD0-RX;PD1-TX
    5 `5 G5 d  e" z1 [# V- E
  34. //参  数:无
    - a* N0 O! a. V: G' `9 l' N) W
  35. //返回值;无
    & q8 ~5 ^+ }& N+ y
  36. //************************************************************************************************************************************************
    # o" z/ ^  W- w2 i
  37. void CAN_Config(void): n& u# b0 n1 n+ S9 H
  38. {
    6 A) E: V- g& H
  39.   GPIO_InitTypeDef GPIO_InitStructure;
    0 a8 n3 u( d( W4 w8 t' F
  40.   CAN_InitTypeDef CAN_InitStructure;  b/ P7 b- d; b# o6 C" y+ a% B
  41.   CAN_FilterInitTypeDef CAN_FilterInitStructure;
    ! {; I; x6 E" o: A( B- |
  42. , K7 E. I1 ?* l1 q+ w
  43.   /* CAN GPIOs configuration ***********************************/" y* B' c4 e7 i
  44.   /* Enable GPIOD clock */1 S2 U% e& T1 S- _* j! l! {
  45.   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
    / |: F! k* F/ T: O. {
  46. - [9 z; c3 z: E. e5 ], x  }, u
  47.   /* Connect PD1 to CAN1_Tx pin */
    # ]( x+ }6 M; E, n
  48.   GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1);# h1 Y3 c# Y5 o: s. H
  49.   /* Connect PD0 to CAN1_Rx pin */- R+ W3 [3 F5 ]3 O: h
  50.   GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1);6 r) [; R4 \, Q. _, e; g4 K/ Q

  51. , z% d% e$ [! j$ ~. }- ~/ f
  52.   /* Configure CAN1_Rx(PD0) and CAN1_Tx(PD1) pins */9 g5 e) A' N% q. ]) L* s, _* K# X
  53.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;5 Y* o8 q* b# K8 W2 A$ x" u3 `
  54.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    ! t* N" q. l. W! l5 Z) f- N! h
  55.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    ; E1 s, g! u0 |4 }+ K8 R! c
  56.   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;' |+ `( M6 f2 S' \# g
  57.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    7 v' Y  U6 Z; W; h) x2 T
  58.   GPIO_Init(GPIOD, &GPIO_InitStructure);
    5 m* i- \' m3 p

  59. , v- m2 W! d! ?: s- O/ a  ?
  60.    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//Rx要单独初始化,否则进入不了中断,不能按照ST官方库来设定  h  n0 A1 z6 U2 f
  61.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    6 b( T* F2 ^7 P2 Y' e: r8 T
  62.    GPIO_Init(GPIOD, &GPIO_InitStructure);9 _% @) Q* t+ O5 @: k0 X: F% i/ O
  63.   /* CAN configuration *****************************************/# P$ I- O: E& a4 V. ^
  64.     /* Enable CAN1 clock */2 _. ~/ x2 n  @3 W6 c6 g& d
  65.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
    2 O8 t$ O( z4 T0 x+ [

  66. . Z2 }* L2 m' ?) I- ?
  67.   /* CAN register init */
    2 }% J* D3 `1 g1 ^
  68.   CAN_DeInit(CAN1);6 B! B7 W$ F! M/ m% e
  69.   /* CAN cell init */
    $ T1 b5 E( z5 L1 y' z
  70.   CAN_InitStructure.CAN_TTCM = DISABLE;' q) s8 e7 k3 u. ?3 b
  71.   CAN_InitStructure.CAN_ABOM = DISABLE;
    , m" H4 K# ^- T, P5 T9 L
  72.   CAN_InitStructure.CAN_AWUM = DISABLE;2 w7 a. A* N2 F. Q; B: V. P4 o
  73.   CAN_InitStructure.CAN_NART = DISABLE;0 o8 ?. D9 T4 L3 R! N$ y
  74.   CAN_InitStructure.CAN_RFLM = DISABLE;
    1 B% z3 l! a8 r  U
  75.   CAN_InitStructure.CAN_TXFP = DISABLE;% @; x5 E8 V0 d6 F; ^1 q5 O- F; S
  76.   CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
    2 F+ B3 q9 |0 S5 q" R4 E. z# {
  77.   CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
    # j1 E! k3 H% x  ?% O" \
  78.   /* CAN Baudrate = 1MBps (CAN clocked at 30 MHz) */ //30/(1+6+8)/4=500k
    4 T7 C3 ]  W& o3 Z
  79.   CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
    9 p. d2 `4 p& V2 K1 E2 T
  80.   CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
    7 B, i& l% V( A5 I
  81.   CAN_InitStructure.CAN_Prescaler = 4;
    " V+ e# f7 Z! `
  82.   CAN_Init(CAN1, &CAN_InitStructure);
    . l  \& v9 I: v. X0 _$ T' a

  83. ( V& ]% W+ l) L" H
  84.   /* CAN filter init */
    4 \8 m% c6 }/ y
  85.   CAN_FilterInitStructure.CAN_FilterNumber = 0;% q& g7 \2 s( K
  86.   CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;0 ^+ F+ R9 A) i2 C% G% w* r3 z
  87.   CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
    % o6 Z# L5 j; ^
  88.   CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
    * I% q8 |( e! N- o) s
  89.   CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;! H! u$ ~1 ?9 O7 Z
  90.   CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
    . _* s7 H4 M; F; t
  91.   CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;2 c# T+ l  k4 x, L( @" q4 U
  92.   CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
    , B& ~0 V1 A- \- V* R
  93.   CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;, J; v1 u* S0 b$ B! k
  94.   CAN_FilterInit(&CAN_FilterInitStructure);3 H, w/ N( e1 X1 h

  95. 6 }7 c: {. A+ J2 K3 _, |' x
  96.   /* Enable FIFO 0 message pending Interrupt */  
    ' {: J2 o* N3 c3 N1 b' o% A8 x
  97.   Init_TxMes();//发送结构体参数初始化
    9 m' A) ~8 y4 z
  98.   Init_RxMes();//接收结构体参数初始化& v5 l% R  D' b2 o# |" `( t5 o
  99.   NVIC_Config();//中断向量配置8 c) Z: ?. J( c* m9 p; y
  100.   CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
    : t/ S( C, R2 N' ~1 S2 A' g6 q
  101. 7 ~, d3 q  P; R! e! J
  102. }) h2 d- w; Z4 ~' _
  103. //************************************************************************************************************************************************
    4 ^0 m: W; [& \8 p/ t, v" \. e
  104. //函数名:void Init_TxMes(CanRxMsg *RxMessage)3 ]+ N8 i* W1 c( I5 a
  105. //功  能:  Initializes the Tx Message
    0 m4 S" S, X1 e% L, n" o8 K
  106. //参  数:无
    1 k1 h% P3 \/ U* v$ m3 B6 t( P
  107. //返回值:无6 N8 T# U: @, E& t4 S0 ^  e$ [
  108. //************************************************************************************************************************************************3 G' g7 M2 x$ q3 U2 P! i
  109. void Init_TxMes()
    , ~/ p1 L/ `6 ?5 ?1 ^
  110. {
    2 L- e9 j4 X9 m; G4 e' E! [
  111.     /* Transmit Structure preparation */7 P* v; g7 d# v
  112.   TxMessage.StdId = 0x123;//标准标识符,必须在( TxMessage.IDE = CAN_ID_STD;//标准帧)情况下才有效' R. C9 B' X$ u" ]! ?. {7 \6 e- K) W
  113.   TxMessage.ExtId = 0x00;//设置拓展标识符(29位),必须在( TxMessage.IDE = CAN_ID_EXT;//标准帧)情况下才有效6 G" G8 P; }; ]9 Y* l
  114.   TxMessage.RTR = CAN_RTR_DATA;//数据帧: J4 n9 G2 s9 H2 y! I$ E
  115.   TxMessage.IDE = CAN_ID_STD;//标准帧 * x; U) Q* H9 v9 Z; o1 ?: g4 ^4 G
  116.   TxMessage.DLC = 8;//发送数据长度  DLC=0-8
    5 Q+ n: y: @( m
  117. }1 S* \* f" O7 Q! r( {
  118. //************************************************************************************************************************************************" W0 e; h7 A# ?0 s8 _. l8 L) ~
  119. //函数名:void Init_RxMes(CanRxMsg *RxMessage)
    " h6 ~% L* @; l$ d! q- i
  120. //功  能:  Initializes the Rx Message4 A% w1 p' h3 ^$ a: x8 X
  121. //参  数:无
    8 m7 j" e/ g$ n+ \
  122. //返回值:无
    , Q0 l' l) l% \. M
  123. //************************************************************************************************************************************************3 G0 T" k2 L# Y+ s) M2 T
  124. void Init_RxMes()+ ^* N1 R* E/ o* J4 d
  125. {
    + _. u: f2 P( B& J3 k$ e! N
  126.   u8 i = 0;% {7 L% m% k9 A* m' r/ G* E
  127.   RxMessage.StdId = 0x00;//这个可以在接收中断中判断 如果RxMessage->StdId = TxMessage.StdId 接收正确
      E+ [$ m. ^+ i6 U- d/ U1 V
  128.   RxMessage.ExtId = 0x00;//这个可以在接收中断中判断 如果RxMessage->ExtId = TxMessage.ExtId 接收正确
    * T% q: E" B8 t
  129.   RxMessage.IDE = CAN_ID_STD;//这个可以在接收中断中判断 如果RxMessage->IDE = TxMessage.IDE 接收正确 # m% P" \/ U8 m6 Y+ U4 ^5 g
  130.   RxMessage.DLC = 8;//接收数据长度" Q/ G* B7 U1 ~& d" l
  131.   RxMessage.FMI =16;//????????????????! B2 j7 n7 u  r
  132. % w* e1 Y- b- Z9 f+ ]
  133.   for (i = 0;i < 8;i++)
    2 p4 C' d6 W$ w3 d2 j  T5 B
  134.   {9 F- y. R& C/ g1 T6 J
  135.     RxMessage.Data<i> = 0x00;</i>
    8 j& |& c, N! h6 O  w8 `
  136.   }2 W- V' g0 c+ G
  137. }
    0 n; ]5 @! A4 j: H+ J9 `
  138. //************************************************************************************************************************************************6 [& ], I3 S/ z1 t  A* J5 l
  139. //函数名:void CAN1_RX0_IRQHandler()* h6 n- a% V' X2 l+ ^8 y. |
  140. //功  能:  CAN1-RX0接收中断服务函数2 p- ^% J6 r7 o, m5 m
  141. //参  数:无6 P# o* `6 D4 `6 T" e
  142. //返回值:无: F) x- d, \) ]; [) g
  143. //************************************************************************************************************************************************
    + t( g" j4 }7 r6 X- N. z& a$ ]+ J
  144. void CAN1_RX0_IRQHandler()  //与CAN1_RX1_IRQHandler()区别
    & H% W+ g. n/ ^) ~. W. d' b
  145. {& {3 k& a0 c; a) B* p( v; u
  146.   if(CAN_GetITStatus(CAN1,CAN_IT_FMP0)!= RESET)//判断是否发生CAN-R0中断
    2 g, z1 i5 P# m1 {2 X: r( l
  147.   {  p& `8 K& Y3 S- i* `: n
  148.     CAN_ClearITPendingBit(CAN1,CAN_IT_FMP0);//清除中断标志) z; r* ]' d; ~' C: }+ d
  149.     if(CAN_MessagePending(CAN1,CAN_FIFO0)!=0)//接收到数据6 {# h  o! `. o4 n% ~0 l+ f; K; o3 e
  150.        CAN_Receive(CAN1,CAN_Filter_FIFO0,&RxMessage);//接收数据最大只能8字节
      n5 F" ?* q  n# B- |! O
  151.   }
    , e6 }8 k# j8 ~. e* c* D
  152.   Usart_Send_Buff(RxMessage.Data,8);//发送数据RS232通信    " X  C; Y; O9 E$ E
  153. }# I. _% Y# M- u5 q
  154. //************************************************************************************************************************************************
    + R/ p# ?% [+ I
  155. //函数名:u8 CAN_SendData()' k5 ]0 O, D5 ]; B- s" {3 L- @& a
  156. //功  能:  CAN发送数据  发送第二步
    1 z  V1 z$ G: h& Y2 p
  157. //参  数:Msg数据指针;Length数据长度4 h! L- V1 y' h0 s8 c
  158. //返回值:返回成功/失败标志4 q# R* x  T; }) p2 Q8 O5 E
  159. //************************************************************************************************************************************************
    ) B% t- z! C% s$ T& _) J) y8 `
  160. u8 CAN_SendData(u8* Msg,u8 Length)
    # s7 h0 {) z1 \- b- [+ R% I
  161. {: a" Z: I) q! e0 t: p
  162.   u16 i=0;7 r2 P; ]7 |; T. L8 k9 t; n- @
  163.   u8 mbox=0x00; $ c) k& i$ K$ X
  164.   TxMessage.DLC = Length;//发送数据长度  DLC=0-8
      f- J# f1 G7 @" [, M
  165.   for(i=0;i<Length;i++)9 r& ^8 }7 G. A
  166.   {" [1 `/ U5 Y: W/ q% u
  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;">;
    - s4 x8 W# W6 N( n3 a$ L
  168.   }
    7 N8 a+ M  H" v. Z8 {' Q! K
  169.   mbox=CAN_Transmit(CAN1,&TxMessage);//发送数据  返回邮箱使用数量
    " D3 K( S+ Z0 o$ V# f
  170. 5 ~" F3 i& F# K4 W0 B8 ?
  171. //  while((CAN_TransmitStatus(CAN1,mbox)!=CAN_TxStatus_Ok)&&(i<0xfff))
    + x& [0 ~/ P" |  H
  172. //  {
    - R) |: r! [' S, U6 f
  173. //    i++;1 X! ]. e0 q6 z
  174. //  }- D# s: \9 o' d( g
  175. //  if(i>=0xfff)
    / @% H7 C: G3 ~% m7 f! k1 v
  176. //  {0 z$ C* K. a; d
  177. //    return 0;//发送数据失败
    . O2 F) L" r1 e+ X1 h, n' |
  178. //  }
    3 B4 H7 C! v) p1 C! t+ W
  179. //  return 1;//发送数据成功6 P+ _: w2 E3 J
  180. }" a9 j0 p+ j5 q$ a; ^
  181. //************************************************************************************************************************************************, r! }. _) x' n- K# D/ A
  182. //函数名:void CAN_SendDataProces(u8* data,u8 Num)
    ' Q) G; h9 b8 }" Q, z
  183. //功  能:CAN发送数据前期处理   发送第一步
    8 _) u; S0 T( X
  184. //参  数:data数据指针;Num数据长度
    ' M* E) |! |( a' D4 |2 {
  185. //返回值:无
    " B$ V( r, M0 r' i$ l
  186. //************************************************************************************************************************************************4 F* ]. z1 B7 x
  187. void CAN_SendDataProces(u8* data,u8 Num)' g% {& U" u! g- A- ~9 g1 V/ A
  188. {
    ! h4 P9 J5 x0 Y" G; }# f, @
  189.   u8 flag=0x00,i=0;
    % p' }; W. Q! M4 I1 I' @
  190.   u8 Count=0x00,Left=0x00;* d3 v: K# X2 k2 U! c& B

  191. 9 Z  f. S. }/ l; b
  192.   Count=Num/8;//求多少个8字节倍数: z+ K5 m3 d+ L. E0 x& V8 c$ |; u8 R
  193.   Left=Num%8;//剩余小于8字节的数量: V; `6 y0 Q8 G& E- e! K
  194.   for(i=0;i<Count;i++)
    , x, z. g  d& z; a' u: ], V" [
  195.   {, Y* P  f/ E6 T% w* B) i9 x( C
  196.     flag=CAN_SendData((data+i*8),8);//发送整8字节的数据: S9 \* G# q( \
  197.   } # Y5 }( F! v! Y. e+ @
  198.   if(Left>0)//有余数才单独再发送一次
    4 `! K1 l$ u  |- M# \; q
  199.   {
    & i2 g) x# k  Q/ d. t  e1 x4 S7 a
  200.     flag=CAN_SendData((data+8*Count),Left);//发送剩余字节% d; A" f. `3 g: @$ v
  201.   }3 x/ Z* K, Y( P, m/ |1 P
  202. }
    1 \* K' N# i8 G) C7 ~. K
  203. //************************************************************************************************************************************************) x# ~# [% Z% D  y- K* ~7 B1 `
  204. </span>
    2 B. D' t: ^9 I( N; ^" c- Q
  205. </span></span>
复制代码

, T1 ~$ V6 r9 _% K7 f+ u
收藏 评论0 发布时间:2021-12-1 22:18

举报

0个回答

所属标签

相似技术帖

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