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

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

[复制链接]
STMCU小助手 发布时间:2021-12-1 22:18
STM32F2-CAN通信-发送任意长度,调试好的,与大家分享
+ t- _: ]+ U8 P% A
% q( g( ~' C) x. M% \+ U
  1. #include "include.h"+ _* z7 m1 U8 n
  2. //************************************************************************************************************************************************
    4 P* G" D6 K! U% e. k9 j/ j( i
  3. //20190611调试完成
    3 t6 o! V; \. ~& v) e- h2 R
  4. //By Wang# j8 r" R+ J8 e" d0 g
  5. //************************************************************************************************************************************************
    9 `0 X0 j& Y! ~8 }9 Y+ o$ X
  6. # S/ U- J# A! l
  7. CanRxMsg RxMessage;
    . w& ?1 E+ ]4 T8 P) y. H9 S
  8. CanTxMsg TxMessage;
    9 r" Y3 x5 X6 m$ M0 v
  9. //************************************************************************************************************************************************2 f# [5 n& N* p
  10. //函数名:void NVIC_Config(void)
    1 }% f0 K3 \5 r5 L
  11. //功  能:  CAN通信接收RX0中断配置
    ! C4 X8 a+ W* G8 T" H+ U. i
  12. //参  数:无
    ( s' g( h# O4 q7 L$ r
  13. //返回值:无
    / \) S0 @; [0 L4 e5 @
  14. //************************************************************************************************************************************************
    0 G3 s4 w! @; F; t1 m  U

  15. 6 P( `% z7 G1 E- r) @
  16. void NVIC_Config(void)
    / ?3 L1 [& |( J5 O4 m) [6 d
  17. {. C; R$ I1 r' g, |! h# G
  18.   NVIC_InitTypeDef  NVIC_InitStructure;
    , g  |6 [2 H. e5 N9 ]  }

  19. " n6 r# ?0 J% z7 m, N" N
  20. //#ifdef  USE_CAN1
    3 N! c' {0 t+ q2 M

  21. : G2 o$ {! {! d9 ]! l3 |
  22.   NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;//与CAN1_RX1_IRQn;区别
    # z" F( c7 w2 I4 }
  23.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//不同的中断优先级一样会怎样
    ' U3 g& Y! M3 X# I! {( O
  24.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;( n: S3 ?2 |4 s

  25. + ^7 L; U( S) S
  26.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;0 ^- d4 g+ I. U% e
  27.   NVIC_Init(&NVIC_InitStructure);
    * u$ s( B, f" t8 d& o) K
  28. , h$ C2 w! `, C) Y+ m( \0 N2 y/ ^' M
  29. }
      v$ f: v6 P5 A2 m# M) _9 ~8 f; |3 @
  30. 5 x; d6 W: _/ }& o* g
  31. //************************************************************************************************************************************************. H# ^" F. V6 @. _/ I
  32. //函数名:void CAN_Config(void)! k7 Z7 E8 q# W
  33. //功  能:  CAN1配置 PD0-RX;PD1-TX
    ) p/ M" G* _6 E: _7 n; }" w2 o
  34. //参  数:无) U. ^: o1 {) r/ Q: M
  35. //返回值;无9 |3 z9 M6 S5 t& T8 J
  36. //************************************************************************************************************************************************  k& v4 B  J' X% |3 K8 z1 U2 d
  37. void CAN_Config(void)  ?4 t( w6 q) _$ y- ?
  38. {
    , h6 S( H! t* Q  s3 H
  39.   GPIO_InitTypeDef GPIO_InitStructure;
    . n9 D+ {: M& j
  40.   CAN_InitTypeDef CAN_InitStructure;' x0 h* j' [+ i( Z; [0 c
  41.   CAN_FilterInitTypeDef CAN_FilterInitStructure;( k% b2 l5 [$ F
  42. $ L+ j" W) t1 o  y: B+ j& u8 j+ T
  43.   /* CAN GPIOs configuration ***********************************/, X  D3 K8 o6 l
  44.   /* Enable GPIOD clock */
    4 F8 Y; R4 W6 k8 D* x, {
  45.   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);7 L) l* M4 a* P6 Q; N+ y2 L3 U

  46. / |0 t# b4 `4 `  {( |
  47.   /* Connect PD1 to CAN1_Tx pin */
    ; U; X5 h$ \  L" {
  48.   GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1);
    9 O3 k+ Q* \7 |) W) A7 q
  49.   /* Connect PD0 to CAN1_Rx pin */
    6 {1 F8 F0 w' f" i
  50.   GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1);
    1 S2 M4 I3 A/ y: i

  51. 5 i0 w8 i6 S; y7 A- C  e( ?, V
  52.   /* Configure CAN1_Rx(PD0) and CAN1_Tx(PD1) pins */* j2 I1 _. b+ T( E6 m
  53.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;, o! [6 q4 N3 q) `
  54.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;# W( ?+ I0 V2 r( m7 _5 u
  55.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    # b0 O. L4 }+ G. @
  56.   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    0 \! |- K( X3 s& g* s: C
  57.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    3 i! u4 B0 E) Y2 i! D6 _
  58.   GPIO_Init(GPIOD, &GPIO_InitStructure);
    7 G/ p& R2 z) f% p; S1 ?" T
  59. + c; s1 O2 m# w% m% k: u3 T# g8 a
  60.    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//Rx要单独初始化,否则进入不了中断,不能按照ST官方库来设定
    ( D2 ^' K, P) Z. X9 s
  61.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;& j, y) ^' G/ I2 Z
  62.    GPIO_Init(GPIOD, &GPIO_InitStructure);" e& G7 R, n' o1 n2 d. o
  63.   /* CAN configuration *****************************************/
    % `1 w5 x3 n" o) d2 F
  64.     /* Enable CAN1 clock */$ j! q! Q9 e! j' ~6 ]
  65.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
    ( X8 L' b+ t  a8 A

  66. 6 y0 [# h5 F3 b* l. E0 c
  67.   /* CAN register init */
    3 R" ~+ [9 z8 G! Y, G
  68.   CAN_DeInit(CAN1);1 a  A0 J; N) F8 C% x" A! x
  69.   /* CAN cell init */
    + f: e3 l+ |6 Y3 U! D. w
  70.   CAN_InitStructure.CAN_TTCM = DISABLE;, u1 U! L3 F, ]( T" h8 w/ n- R* s
  71.   CAN_InitStructure.CAN_ABOM = DISABLE;+ n. I3 Y* h- N5 |( G, E& Y" X1 Y4 \
  72.   CAN_InitStructure.CAN_AWUM = DISABLE;8 R( d" {% U! K& ]4 {# K
  73.   CAN_InitStructure.CAN_NART = DISABLE;, m4 X7 z5 J2 D+ G2 Y( ^- u
  74.   CAN_InitStructure.CAN_RFLM = DISABLE;
    7 z6 Y( X; u6 m' J
  75.   CAN_InitStructure.CAN_TXFP = DISABLE;! }3 p' x/ a4 ]
  76.   CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;9 O4 {3 R0 ~$ D4 r+ ~
  77.   CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;: O: S6 t+ B$ k0 n- M5 }! W
  78.   /* CAN Baudrate = 1MBps (CAN clocked at 30 MHz) */ //30/(1+6+8)/4=500k2 H2 u2 Y  G# B% a6 X5 G! C5 W
  79.   CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
      _0 m% W  v8 G- T3 L) l2 V7 K6 m5 ^$ }
  80.   CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
    & N  n, E: M/ o* F3 q/ o
  81.   CAN_InitStructure.CAN_Prescaler = 4;
    4 o+ X5 U& f+ J- k; m* {
  82.   CAN_Init(CAN1, &CAN_InitStructure);; c$ e& M/ P" W7 a! c0 `
  83. 0 i" Q- _6 V6 j' K  X5 N0 \) J6 e% x
  84.   /* CAN filter init */
    " {0 L6 j7 g2 d$ C& W
  85.   CAN_FilterInitStructure.CAN_FilterNumber = 0;3 \5 m( r% n2 D/ L' j
  86.   CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
    ! R7 I% S* {: z9 k9 I) C
  87.   CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;& f  q" `' h2 a( z
  88.   CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;( H* @- ], t' V* f% p$ Y4 R* ~! k
  89.   CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
    / \! _  ~9 a; W9 x  ]( f
  90.   CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
    ) w* r  _! u; }  l9 s
  91.   CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
    " f1 |# `! u6 E& [; D5 L
  92.   CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;  P, m) k, B8 k  |. i# F
  93.   CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;7 k+ V8 B& W/ v* ^, p, W( U
  94.   CAN_FilterInit(&CAN_FilterInitStructure);
    7 r- W0 K& O% t8 R2 F
  95. 0 J0 |! f. V5 @; L7 {0 {
  96.   /* Enable FIFO 0 message pending Interrupt */  2 w) c( X% f. w; W7 Y) `3 A. {
  97.   Init_TxMes();//发送结构体参数初始化- c3 u# J" t8 m3 r8 [, N0 s( T
  98.   Init_RxMes();//接收结构体参数初始化; s6 r- F% J) r/ _1 o8 |$ g
  99.   NVIC_Config();//中断向量配置  p0 h+ a4 {6 a$ U/ A" e
  100.   CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);' X. V  X4 S0 y! Q4 h- g

  101. 4 h& F1 c7 {( R& |3 r
  102. }; ^- t5 K" T. G) K( Q
  103. //************************************************************************************************************************************************
    , ]4 J" z, i. h5 P$ E% A
  104. //函数名:void Init_TxMes(CanRxMsg *RxMessage)1 B0 |4 k& e# L  y* L9 C3 C
  105. //功  能:  Initializes the Tx Message  D& _% k) W5 s8 o8 _
  106. //参  数:无7 O, D. \$ J! _# J2 F1 d7 x
  107. //返回值:无+ R3 w4 D) J" h6 S
  108. //************************************************************************************************************************************************( t, G' d" M+ q8 x& G1 O8 l
  109. void Init_TxMes()
    ' d% o0 v- v5 Q6 x. Z
  110. {
    3 C5 r* r- Z' _0 _* P
  111.     /* Transmit Structure preparation */
    & n+ }# V7 j, [* t3 m$ F
  112.   TxMessage.StdId = 0x123;//标准标识符,必须在( TxMessage.IDE = CAN_ID_STD;//标准帧)情况下才有效
    1 W% u7 R% I7 j! B% p
  113.   TxMessage.ExtId = 0x00;//设置拓展标识符(29位),必须在( TxMessage.IDE = CAN_ID_EXT;//标准帧)情况下才有效
    & u4 w* w8 {& t$ N+ P7 u
  114.   TxMessage.RTR = CAN_RTR_DATA;//数据帧) |0 a* n% `* t  v- \
  115.   TxMessage.IDE = CAN_ID_STD;//标准帧
    5 J9 w. g% S: \% ^+ v/ F
  116.   TxMessage.DLC = 8;//发送数据长度  DLC=0-8% _4 [% m, |+ g: ^( ?  X8 c
  117. }7 M/ Z1 p  u" r8 ^
  118. //************************************************************************************************************************************************
    ! \9 I3 T3 x4 }& U2 {" u% [+ O* Q! c
  119. //函数名:void Init_RxMes(CanRxMsg *RxMessage)
    2 H- t# J; F# n+ s2 U
  120. //功  能:  Initializes the Rx Message; r' C: `: k  p( g; _5 h! t: F
  121. //参  数:无
    0 L( r$ A5 ~0 K1 \" V4 c" m
  122. //返回值:无
    % d( l$ c, h( n9 C
  123. //************************************************************************************************************************************************6 Q% \% r2 N+ V# k
  124. void Init_RxMes()) |- C0 e% ^: H, F& n
  125. {
    9 \! I6 [. Z9 J! M/ ~
  126.   u8 i = 0;
    8 O: m, j5 p" G* O2 s
  127.   RxMessage.StdId = 0x00;//这个可以在接收中断中判断 如果RxMessage->StdId = TxMessage.StdId 接收正确 & I% U. Y% [5 Z& }3 j! ]/ T
  128.   RxMessage.ExtId = 0x00;//这个可以在接收中断中判断 如果RxMessage->ExtId = TxMessage.ExtId 接收正确 : V) i$ n$ |+ |/ W1 c3 c8 z0 a0 b
  129.   RxMessage.IDE = CAN_ID_STD;//这个可以在接收中断中判断 如果RxMessage->IDE = TxMessage.IDE 接收正确
    . ^* W( ?9 |( C0 Z! o0 [) A; U6 q
  130.   RxMessage.DLC = 8;//接收数据长度
    1 o0 a, r4 G; l' j
  131.   RxMessage.FMI =16;//????????????????
    ; E! Y: V# o/ h! y1 |( S+ P
  132. 1 n* ]5 G+ G3 H
  133.   for (i = 0;i < 8;i++). l5 l8 Z; x0 Z: U" l
  134.   {( F5 a" U3 s7 W
  135.     RxMessage.Data<i> = 0x00;</i>  m- K1 p5 r# C1 D" Z
  136.   }, a1 u: W" v, c7 ]+ B
  137. }
    0 @, {2 h; P/ ?5 L8 |+ Y+ v/ d
  138. //************************************************************************************************************************************************
    $ h* X4 ]$ h+ H9 J
  139. //函数名:void CAN1_RX0_IRQHandler()
    2 n4 R2 }0 |% q0 j6 n
  140. //功  能:  CAN1-RX0接收中断服务函数
    5 o. k6 u/ F  B- ?$ e
  141. //参  数:无0 e# ~1 j- N# `) I" ~6 W8 e
  142. //返回值:无" a  H. Z  {8 _$ Y+ B) F, l
  143. //************************************************************************************************************************************************9 B0 K- \% V5 H
  144. void CAN1_RX0_IRQHandler()  //与CAN1_RX1_IRQHandler()区别
    ) E1 H; |! d' w6 f* u
  145. {1 J# X, g3 ^* p
  146.   if(CAN_GetITStatus(CAN1,CAN_IT_FMP0)!= RESET)//判断是否发生CAN-R0中断( L) w' T# r/ I3 I# R( l
  147.   {
    9 P& u3 m3 _' q  r8 k# N
  148.     CAN_ClearITPendingBit(CAN1,CAN_IT_FMP0);//清除中断标志; ?. k* M3 f* r: m3 n
  149.     if(CAN_MessagePending(CAN1,CAN_FIFO0)!=0)//接收到数据' w3 k0 Y/ v) a" T
  150.        CAN_Receive(CAN1,CAN_Filter_FIFO0,&RxMessage);//接收数据最大只能8字节4 R/ D  o7 U9 _0 G" G, }8 a
  151.   }' W. K  o# {& F+ w
  152.   Usart_Send_Buff(RxMessage.Data,8);//发送数据RS232通信    # R" r: P6 ^, y% f) a1 P
  153. }4 j  M" i- E9 q3 G/ ~/ w
  154. //************************************************************************************************************************************************
    ( G, l: b, O% W$ r
  155. //函数名:u8 CAN_SendData()
      M% E& M7 P: L4 `. Y8 a! t
  156. //功  能:  CAN发送数据  发送第二步
    ! M3 g# ?4 w4 `
  157. //参  数:Msg数据指针;Length数据长度8 ^" N  O$ u0 {
  158. //返回值:返回成功/失败标志1 r! m. p3 u  `# g
  159. //************************************************************************************************************************************************$ R% m, a0 D4 j" ^
  160. u8 CAN_SendData(u8* Msg,u8 Length)- H/ t7 H8 s7 F( q" W) b
  161. {
    5 F% y$ \1 I& S4 t" _( O4 h! s$ ?
  162.   u16 i=0;
    ; A8 X5 s/ @. F. n- }+ r* `6 |
  163.   u8 mbox=0x00;
    ! P" i9 \0 I+ @& T& G
  164.   TxMessage.DLC = Length;//发送数据长度  DLC=0-89 W$ Z- Z% m0 H0 h' x0 Q# K
  165.   for(i=0;i<Length;i++)
    + E. X0 {( N% c
  166.   {, m0 c+ a. q0 `+ \0 N+ y& `* q3 |9 e
  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;">;7 ^* `1 C$ p% M8 c
  168.   }' |  ]( l7 ]$ ^; M
  169.   mbox=CAN_Transmit(CAN1,&TxMessage);//发送数据  返回邮箱使用数量
    - }" ]/ T: M! j" f" G' r% F

  170. 7 Z: {+ f7 Y; P) Y# Z, w
  171. //  while((CAN_TransmitStatus(CAN1,mbox)!=CAN_TxStatus_Ok)&&(i<0xfff))) r1 f( A# S: g/ u9 C* m
  172. //  {" J4 D" F( x- [
  173. //    i++;( D" s* v3 O* `( T- d% B
  174. //  }
    , q$ b) K$ j3 m( ^0 ^4 E$ `
  175. //  if(i>=0xfff)
    6 w& Y* S: y, s4 ]( i
  176. //  {3 \. M. Y/ u, z& g5 o  a1 V
  177. //    return 0;//发送数据失败! e& f$ H' x- A, n. @
  178. //  }) p; @. n' @$ w! n; M0 d: H
  179. //  return 1;//发送数据成功
    8 }# ?* d/ R' V9 W7 i- ]
  180. }2 K9 r; x8 l7 z3 @% s
  181. //************************************************************************************************************************************************+ C. q& T5 K- ~  s6 |
  182. //函数名:void CAN_SendDataProces(u8* data,u8 Num)
    9 U; s8 e4 a7 m) B4 s2 l+ c
  183. //功  能:CAN发送数据前期处理   发送第一步
    & g$ z! p' `8 C+ M
  184. //参  数:data数据指针;Num数据长度
    ; Q% M- \7 P2 R9 G( x
  185. //返回值:无  U: ^% y0 t3 ~: _7 b( Z6 f9 Y/ {
  186. //************************************************************************************************************************************************  q- j. ]) W- I4 E2 W
  187. void CAN_SendDataProces(u8* data,u8 Num)
    2 i* i* o3 {$ S) W
  188. {2 g1 c+ }6 b8 F. ]/ n6 i
  189.   u8 flag=0x00,i=0;
    - E7 T- H9 N' L
  190.   u8 Count=0x00,Left=0x00;( Y. D' a" M) q: @- ^# R
  191. % R' V; h) q# u+ R+ X7 L
  192.   Count=Num/8;//求多少个8字节倍数3 c2 E5 x# M! a4 ~* @
  193.   Left=Num%8;//剩余小于8字节的数量
    6 R: c1 ?8 ?: _3 v) r
  194.   for(i=0;i<Count;i++)2 c6 V2 v$ ~1 f  F5 V2 V
  195.   {
    2 k7 E$ G) Y# h5 }. n1 I
  196.     flag=CAN_SendData((data+i*8),8);//发送整8字节的数据# d( t+ K% M" I6 y5 M: J
  197.   } ( |, U0 T- F& c9 v' I# ]
  198.   if(Left>0)//有余数才单独再发送一次
    & T8 {0 G4 T2 L- n& U8 G! J8 s
  199.   {
    6 I; d4 r( s; t1 h: M2 L% `
  200.     flag=CAN_SendData((data+8*Count),Left);//发送剩余字节
    3 c# q& `. o- k) H7 i3 }
  201.   }
    ' I8 m' Q" F0 j1 c* \, V$ h
  202. }
    ) X: [5 E/ q4 X% h8 W% d# d0 m
  203. //************************************************************************************************************************************************; z8 V0 [$ d& a6 d
  204. </span>
    : \1 X4 `( S# C7 t
  205. </span></span>
复制代码

; T. R5 [7 v# j9 t6 k: T0 T
收藏 评论0 发布时间:2021-12-1 22:18

举报

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