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

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

[复制链接]
STMCU小助手 发布时间:2021-12-1 22:18
STM32F2-CAN通信-发送任意长度,调试好的,与大家分享8 S# a3 a5 K0 w) J5 h
. z0 k' S8 c  |  e" d& V4 R( I
  1. #include "include.h"
    7 r1 B" Y9 b. h1 t' h
  2. //************************************************************************************************************************************************
    8 }: |8 p3 {3 D6 _/ M
  3. //20190611调试完成* T- h1 g0 r- ~" ?
  4. //By Wang
    2 Q+ ]) _; q8 T7 a
  5. //************************************************************************************************************************************************
    8 C! Q4 Z5 @* U) l3 \. g. J

  6. " E4 g4 @) G# k* B( p
  7. CanRxMsg RxMessage;4 K$ ~3 J- g/ U# k! l
  8. CanTxMsg TxMessage;
    2 ?# B: M1 z2 j1 U  M
  9. //************************************************************************************************************************************************9 _) J8 f2 Y3 A
  10. //函数名:void NVIC_Config(void)
    - F- [. N1 {' q6 ?) _5 x
  11. //功  能:  CAN通信接收RX0中断配置3 z- S  F& r1 y$ S+ d6 E  d4 b; j2 ]
  12. //参  数:无
    0 d" Q  Q/ U/ h4 m: P8 j' h
  13. //返回值:无
    4 x1 r/ E6 H; q7 Y5 J
  14. //************************************************************************************************************************************************: ~4 z9 T5 ?- ]: d1 e% _

  15. 9 `6 e8 @9 c  R
  16. void NVIC_Config(void)
    ! i; R. t+ _, v, S7 d/ g6 |
  17. {
    ; s# `! m$ X  h
  18.   NVIC_InitTypeDef  NVIC_InitStructure;
    & }% b! k, j' Y

  19. ) x; n' X: r9 T) h7 X
  20. //#ifdef  USE_CAN1 . j7 S; q, [* `
  21.   s2 a7 k0 W8 v6 t- D  }' `
  22.   NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;//与CAN1_RX1_IRQn;区别* b: ~% X6 ]- |& r0 ?9 S5 {, w
  23.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//不同的中断优先级一样会怎样
    7 H$ i% P) t* x9 l
  24.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;8 W- ^# j! W  a, J+ R
  25. 9 u9 L6 H' ?4 s" D7 ]5 ~
  26.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;2 X4 j2 e/ W# T' I
  27.   NVIC_Init(&NVIC_InitStructure);
    * D; D% ^$ G% t# H5 p6 w
  28. $ a5 ]) `1 K! X2 D3 R' }. Q2 `
  29. }' Y& D4 ^# m5 c: D# `5 h
  30. % u: v7 U* X$ O! F9 u8 O
  31. //************************************************************************************************************************************************
    - ?7 ]5 m6 T" A# @/ O
  32. //函数名:void CAN_Config(void)& ^* W- v4 y* d8 R6 [( P7 L- M
  33. //功  能:  CAN1配置 PD0-RX;PD1-TX
    * W+ V  N+ z3 H1 {# V$ C
  34. //参  数:无
    5 T( Y4 E9 a& ?+ M
  35. //返回值;无7 T9 v# l+ d5 W4 y
  36. //************************************************************************************************************************************************$ f% w/ R) e  W2 X; O2 p* u5 M. S
  37. void CAN_Config(void); q9 }7 W. g+ S- W  O2 @
  38. {  j: x2 F6 ~) z, C( \. @% e
  39.   GPIO_InitTypeDef GPIO_InitStructure;
    8 ^/ L$ n5 U: B" Z
  40.   CAN_InitTypeDef CAN_InitStructure;- Q$ Q) h. _0 Q4 z, s% V# |; |( b
  41.   CAN_FilterInitTypeDef CAN_FilterInitStructure;
    : H. j; N& P; V% v/ C5 j
  42. 8 p2 W* Q4 j8 b
  43.   /* CAN GPIOs configuration ***********************************/
    : b# h! B1 L" D  l7 V3 ]
  44.   /* Enable GPIOD clock */
    8 b  ]' d# t4 K6 {$ ]# O+ ~# B4 C
  45.   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
    7 n2 t1 U/ Y8 g5 R( D6 k
  46. 3 N4 O* D6 x" i. {& i
  47.   /* Connect PD1 to CAN1_Tx pin */1 w+ a8 i3 T7 O1 j/ I! M/ Z
  48.   GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1);1 C" u4 C/ D# ~% G% ]0 n
  49.   /* Connect PD0 to CAN1_Rx pin */
    ( T* f) `# ]0 g+ \- ?& x
  50.   GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1);
    * r5 Y7 D( G1 D1 l$ P1 O( J3 z( I* f

  51. & ?, f7 h& w# Z) m
  52.   /* Configure CAN1_Rx(PD0) and CAN1_Tx(PD1) pins */
    2 f3 n" G) g, p+ K, X. l
  53.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;; i" v3 K: {; \, x, m- u
  54.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    8 P$ t; z' j+ s
  55.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    2 z5 x! ^; Y. E: G1 R
  56.   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;# y9 Q  }7 D, s5 v. F, c- J1 V
  57.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    ' j, ^* x4 n1 Z3 P* ?$ S
  58.   GPIO_Init(GPIOD, &GPIO_InitStructure);
    4 i7 z/ G+ |& N8 ~5 T! K
  59. , H* ~: {9 M7 l! T; I
  60.    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//Rx要单独初始化,否则进入不了中断,不能按照ST官方库来设定$ v2 W3 A/ s2 D
  61.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    ' v; n, R1 @) p2 H3 Z
  62.    GPIO_Init(GPIOD, &GPIO_InitStructure);
    6 e2 I' `2 ?9 N- \+ X5 W
  63.   /* CAN configuration *****************************************/
    # j8 I2 y! t( T& J% L% j5 N8 p
  64.     /* Enable CAN1 clock */, i5 v- Y; N, ^5 i( d- Y
  65.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);9 v' I+ ~0 E+ o1 K
  66. " ]. G6 Q7 z7 ]# \, V4 s
  67.   /* CAN register init */
    5 D. t3 F2 t3 U* Z
  68.   CAN_DeInit(CAN1);
    % }2 E; A. {) ]
  69.   /* CAN cell init */9 P4 P7 f; |% H. k5 }0 I4 e
  70.   CAN_InitStructure.CAN_TTCM = DISABLE;+ z7 U% D: w$ N6 j
  71.   CAN_InitStructure.CAN_ABOM = DISABLE;
    5 Z: A: u. R% w9 Y. g2 r
  72.   CAN_InitStructure.CAN_AWUM = DISABLE;8 [6 f# j& \$ u( D1 Z7 k* i" i
  73.   CAN_InitStructure.CAN_NART = DISABLE;( m; _0 f# T0 |) @
  74.   CAN_InitStructure.CAN_RFLM = DISABLE;
    1 o5 _- p, L0 L& }6 W
  75.   CAN_InitStructure.CAN_TXFP = DISABLE;
    4 g+ T2 n2 C- Q/ T/ }0 R
  76.   CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;# d2 d! N, V+ y. w+ M- R, i. J. }( F
  77.   CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
    0 u! B1 r+ n+ c0 v* x
  78.   /* CAN Baudrate = 1MBps (CAN clocked at 30 MHz) */ //30/(1+6+8)/4=500k) q+ }* I: O0 V2 m1 x2 _9 {' l
  79.   CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
    ( ?( F2 F0 l4 [+ |$ h. Q0 @$ R
  80.   CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;5 j: I, s/ D2 y7 ]' p
  81.   CAN_InitStructure.CAN_Prescaler = 4;
    $ s) N3 Z2 F& Y. P; R8 b" ?
  82.   CAN_Init(CAN1, &CAN_InitStructure);2 d/ Z6 `" o& b& G
  83. - e' {/ g4 n) n2 c# m
  84.   /* CAN filter init */) q7 s( P% o( k! Q
  85.   CAN_FilterInitStructure.CAN_FilterNumber = 0;
      W( H. ^( f- z
  86.   CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
    ; s1 l  q5 s1 H7 M2 v) ?
  87.   CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
      p7 O4 K3 N% b7 E
  88.   CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;% r1 Y) R2 B) v5 P# F8 d! u
  89.   CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;/ G2 y  r7 R/ C7 d( R. u% P% f5 I+ w5 J
  90.   CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;1 `* ]/ R) H) O; @9 i
  91.   CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
    - z" P" h! z8 ?9 S0 _0 c% M' K: V) G
  92.   CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
    5 a2 g: C; m- i' Y5 w7 ^1 Z
  93.   CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
    * |/ N6 J  L6 W9 e/ ?* j) n+ O) t
  94.   CAN_FilterInit(&CAN_FilterInitStructure);; A3 |8 X# j3 G  M% t# B- e& V

  95. 5 }5 v# l  T7 S' s+ {
  96.   /* Enable FIFO 0 message pending Interrupt */  7 M( m6 c6 q( c& K# s
  97.   Init_TxMes();//发送结构体参数初始化
    - b% S4 W* @' z% r
  98.   Init_RxMes();//接收结构体参数初始化
    . k; R/ `  Y; s/ J
  99.   NVIC_Config();//中断向量配置
    " {2 P9 m; |) g
  100.   CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);/ ]: X# t  D* Y& k. Z/ j1 V7 \

  101. 1 A( E6 ]# r6 y/ A) C1 ^
  102. }
    ) f# t  }+ |8 N6 z# O$ O* o& J
  103. //************************************************************************************************************************************************; v5 J* v3 ^# T7 [
  104. //函数名:void Init_TxMes(CanRxMsg *RxMessage)- `; m4 Q* ~8 j8 _
  105. //功  能:  Initializes the Tx Message: n+ Q% r. G; E
  106. //参  数:无3 q9 ^+ n  q! ~; M8 u# F
  107. //返回值:无
    0 S2 W( S! n+ [( z* n
  108. //************************************************************************************************************************************************0 @1 J! f6 Y( f3 Q  ]  O
  109. void Init_TxMes()+ l, Z7 M' i; U8 Q
  110. {( p: o9 r# K; u- m. ?' P
  111.     /* Transmit Structure preparation */9 t" f9 a( b. p) X2 y4 l( R
  112.   TxMessage.StdId = 0x123;//标准标识符,必须在( TxMessage.IDE = CAN_ID_STD;//标准帧)情况下才有效. T5 X- [: y* d/ M8 \& A! q
  113.   TxMessage.ExtId = 0x00;//设置拓展标识符(29位),必须在( TxMessage.IDE = CAN_ID_EXT;//标准帧)情况下才有效
    ! G! s* T4 Z6 R% g5 Z7 ]/ V
  114.   TxMessage.RTR = CAN_RTR_DATA;//数据帧$ x' T, q4 G; y, P; y7 S
  115.   TxMessage.IDE = CAN_ID_STD;//标准帧 5 m# t( A/ J" @3 H! A
  116.   TxMessage.DLC = 8;//发送数据长度  DLC=0-8
    9 U% J* Z* k# X9 t0 Y. A
  117. }9 G! ]) v' ^+ E- S
  118. //************************************************************************************************************************************************
    + Y5 s( p5 e# r2 u( ~- ~
  119. //函数名:void Init_RxMes(CanRxMsg *RxMessage)
    % G/ ], s8 T6 f6 l5 w; o7 y
  120. //功  能:  Initializes the Rx Message
    3 f, H2 y, D) p
  121. //参  数:无
    , ]7 D) u  k" u/ d) v5 O
  122. //返回值:无
    5 A# e" i. J4 ^5 Z' C8 `) k* M
  123. //************************************************************************************************************************************************
    - Z* U. c+ ]  u& d  `' U
  124. void Init_RxMes()- W; v& N- m9 b, w* O7 A) l
  125. {: W) z4 E" K1 I% g
  126.   u8 i = 0;
    , q/ p& b/ m5 f# w
  127.   RxMessage.StdId = 0x00;//这个可以在接收中断中判断 如果RxMessage->StdId = TxMessage.StdId 接收正确 ! `* u; H0 k$ g
  128.   RxMessage.ExtId = 0x00;//这个可以在接收中断中判断 如果RxMessage->ExtId = TxMessage.ExtId 接收正确   t5 ~/ t7 y" e- P
  129.   RxMessage.IDE = CAN_ID_STD;//这个可以在接收中断中判断 如果RxMessage->IDE = TxMessage.IDE 接收正确 * I! t( f& y, U2 ]7 W& r5 r! C
  130.   RxMessage.DLC = 8;//接收数据长度
    . u5 Q( U$ z) J$ V: b
  131.   RxMessage.FMI =16;//????????????????7 K4 Y, C* l  g8 Q8 C7 x6 b- K

  132. 6 x1 Y4 S' O$ Y( Y9 l8 g
  133.   for (i = 0;i < 8;i++)( A& ~2 c; v. Z; x
  134.   {3 V- b; p$ ^/ @) U4 Y. e
  135.     RxMessage.Data<i> = 0x00;</i>
    4 d# M+ ^9 ~4 f8 P% {$ Q
  136.   }
    3 s( v+ S6 @+ l' z
  137. }
    % n; Y+ P9 p0 F
  138. //************************************************************************************************************************************************
    & T+ I% y5 Q$ f7 C- z. u& _' L
  139. //函数名:void CAN1_RX0_IRQHandler(), y% ^4 R& T& H# t% S; ~& c
  140. //功  能:  CAN1-RX0接收中断服务函数
    $ Y& T7 Q4 L) e5 A5 I
  141. //参  数:无
    # @$ K. m! h* o: j& \
  142. //返回值:无
    * `; g# I; _9 B0 A5 V
  143. //************************************************************************************************************************************************- a. p- Y# x+ y8 Y2 Q! {
  144. void CAN1_RX0_IRQHandler()  //与CAN1_RX1_IRQHandler()区别( i- v! l- O5 [+ h
  145. {& m) L) r6 |, U- v
  146.   if(CAN_GetITStatus(CAN1,CAN_IT_FMP0)!= RESET)//判断是否发生CAN-R0中断# Y- O* B: p& b  u- X
  147.   {1 K9 l& y& S) i& U% u
  148.     CAN_ClearITPendingBit(CAN1,CAN_IT_FMP0);//清除中断标志
    8 z6 G4 n0 b7 f# x+ S& D) @: {: Y. D7 N
  149.     if(CAN_MessagePending(CAN1,CAN_FIFO0)!=0)//接收到数据
    8 d% y: `; M5 l4 ?( a8 M
  150.        CAN_Receive(CAN1,CAN_Filter_FIFO0,&RxMessage);//接收数据最大只能8字节
    7 ?4 G( i& S% K8 }* G! u" ^
  151.   }  c( z( h% T. a' O# O
  152.   Usart_Send_Buff(RxMessage.Data,8);//发送数据RS232通信    ! ^/ t2 M! V1 @5 h( T- d
  153. }
    7 ^" B+ C9 }: r) A
  154. //************************************************************************************************************************************************
    + u7 g) r: q6 ^
  155. //函数名:u8 CAN_SendData()
    : ]2 }/ P% a  |% S. Z$ n. Q  y
  156. //功  能:  CAN发送数据  发送第二步
    6 x% g: ~( J) K* ~' y+ ~
  157. //参  数:Msg数据指针;Length数据长度* q8 u0 c0 U) }8 P) B
  158. //返回值:返回成功/失败标志& ]  L* A( \; ^  q6 D
  159. //************************************************************************************************************************************************1 c# L5 K$ D0 D0 V  v7 Z/ o: Z
  160. u8 CAN_SendData(u8* Msg,u8 Length)3 G$ m8 \8 Q4 f& A# d* L
  161. {, i! P) W+ D/ J! O
  162.   u16 i=0;! {) [( {4 ^6 ?0 h
  163.   u8 mbox=0x00; & v* \$ d4 Q  r5 c
  164.   TxMessage.DLC = Length;//发送数据长度  DLC=0-86 ~1 C, b' E2 @3 }2 [2 O
  165.   for(i=0;i<Length;i++). O+ b8 x+ B- P5 p  K
  166.   {9 V  c7 I( A3 @$ p2 y
  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;">;
    . J! }6 S1 k" N! P5 ~
  168.   }
    7 ^5 {1 s' ]' x; E: b) z; d
  169.   mbox=CAN_Transmit(CAN1,&TxMessage);//发送数据  返回邮箱使用数量8 J8 U! x! X; S3 v6 A
  170. , M* v/ ]8 |" ?$ L
  171. //  while((CAN_TransmitStatus(CAN1,mbox)!=CAN_TxStatus_Ok)&&(i<0xfff)), t8 ?# ]: @) H
  172. //  {+ n5 p& c, w: \) e8 c
  173. //    i++;
    - C; p* X& B: P' p; |& n4 N( P
  174. //  }( E/ o  W2 ^% {
  175. //  if(i>=0xfff)
    + S7 P- ]. R* t8 K- W" @
  176. //  {
    . s' Z$ x+ g8 ^* D
  177. //    return 0;//发送数据失败
    8 {# S" O- W) [5 T3 v9 A! Z' l" Q) U
  178. //  }
    ( j2 D$ M$ g9 x0 J8 U. d; s
  179. //  return 1;//发送数据成功* N4 X4 B& g: D! Y
  180. }
    9 i0 B7 |& R% J  |
  181. //************************************************************************************************************************************************
    - V/ p' j% o) ]+ F' W. ?
  182. //函数名:void CAN_SendDataProces(u8* data,u8 Num)
    4 r# D4 X( Q0 j& h, v
  183. //功  能:CAN发送数据前期处理   发送第一步
    ; [& w2 u  N8 w; W% P
  184. //参  数:data数据指针;Num数据长度$ ~* _& N5 e- W/ U: {7 {: R: Y) v% C8 m; C
  185. //返回值:无+ @' t9 \9 X% h- T5 X
  186. //************************************************************************************************************************************************5 W1 E" |, z" u4 b7 [3 C3 s7 a
  187. void CAN_SendDataProces(u8* data,u8 Num)  d& Y/ Q3 `# ^% k- h
  188. {: {+ f. j3 w7 s/ k5 P, f5 L' y
  189.   u8 flag=0x00,i=0;" {, Z3 Q* E: d  v+ r
  190.   u8 Count=0x00,Left=0x00;
    ! ^' A  `9 q( X
  191. . O6 V( |$ P1 i6 [! Z3 P1 R
  192.   Count=Num/8;//求多少个8字节倍数
    . n0 i/ ]+ C9 y1 q
  193.   Left=Num%8;//剩余小于8字节的数量3 G, Y4 b- Z+ B) e7 g
  194.   for(i=0;i<Count;i++)8 V- g2 x! @& i/ N; H& x6 m( y4 ]
  195.   {+ V, l- T/ U0 m+ _) e
  196.     flag=CAN_SendData((data+i*8),8);//发送整8字节的数据, H2 q6 q& |5 h$ F8 S
  197.   } 4 _2 g' e- E, b& Y6 u  S
  198.   if(Left>0)//有余数才单独再发送一次" @2 [, l- h9 v! A, C* N
  199.   {
    , e# D+ |, e5 w3 q4 R- f: V# t9 `
  200.     flag=CAN_SendData((data+8*Count),Left);//发送剩余字节
    ' _1 o2 f0 F) w5 s% b
  201.   }
    . T# _0 J+ |4 m$ w% S( L! Y
  202. }2 A. D" M& a- o8 n* V8 N
  203. //************************************************************************************************************************************************
    & P4 U5 N( e" P7 U6 O6 q: X- r
  204. </span>) B& Z& j: G" f& y9 t& Z
  205. </span></span>
复制代码
4 u8 W- {: O" g
收藏 评论0 发布时间:2021-12-1 22:18

举报

0个回答

所属标签

相似技术帖

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