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

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

[复制链接]
STMCU小助手 发布时间:2021-12-1 22:18
STM32F2-CAN通信-发送任意长度,调试好的,与大家分享
% X; s. l: z; w5 i
" L6 L1 E2 u& v
  1. #include "include.h"& X" p3 L; n* e2 d3 E1 X, k
  2. //************************************************************************************************************************************************
    ; u+ A7 d$ ?4 X
  3. //20190611调试完成) O. W- [# ^! p( W0 U$ H# Y
  4. //By Wang
    0 u  Z/ u  n7 o. y
  5. //************************************************************************************************************************************************' {: u" C4 X2 \  ?$ ^8 @9 j! ^

  6. 3 s8 N$ Z6 E) _9 O
  7. CanRxMsg RxMessage;
    ! o8 w$ s$ l7 v
  8. CanTxMsg TxMessage;' V) r3 _- I4 e
  9. //************************************************************************************************************************************************- W1 ^4 g, \! g
  10. //函数名:void NVIC_Config(void)
    . f& U" ]2 G- |- {& @  R  L: E
  11. //功  能:  CAN通信接收RX0中断配置3 t9 a1 F; y+ Y/ F( D
  12. //参  数:无
    6 t; n) j8 ^; Q+ \" b
  13. //返回值:无
    ) m: f! ?- g. q* {
  14. //************************************************************************************************************************************************9 O1 n# `, \" x) o

  15. $ `9 L  g. _% v- l, M: f
  16. void NVIC_Config(void)
    % b" T9 D1 z( Q. S7 I
  17. {' n2 u! J% D: w; j" q: A
  18.   NVIC_InitTypeDef  NVIC_InitStructure;  S7 U- L; z3 i$ K6 \) h8 W
  19. & E) e5 N3 a1 N7 K9 ~0 `8 L- Y
  20. //#ifdef  USE_CAN1 & ^1 ]# I# W+ l' u: {1 q

  21. * ?0 z  N3 ?! w9 G
  22.   NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;//与CAN1_RX1_IRQn;区别5 I0 U( s9 p4 e
  23.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//不同的中断优先级一样会怎样( p& G* @6 U1 ^3 ?5 R/ V( @7 B! {2 \
  24.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
    & x( j1 ?8 `$ I4 o8 C
  25. + I, C& c: ^0 D6 I6 w* m% d3 ]
  26.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    3 q9 c, [( @  Z: o& Z
  27.   NVIC_Init(&NVIC_InitStructure);( N- e/ x0 m" u* p3 {

  28. ) D* v9 f3 ]0 c/ g- A. t
  29. }+ s* T1 Q# k8 O6 b8 ~

  30. * d1 ^( f! K- r+ k1 g
  31. //************************************************************************************************************************************************
    ) W# v0 O" m9 b. M5 N- P: G+ w0 {' J
  32. //函数名:void CAN_Config(void)3 f4 ~6 E# T0 p  w* e
  33. //功  能:  CAN1配置 PD0-RX;PD1-TX( w; F* R2 t6 }: ~) `" a) g6 q: P
  34. //参  数:无8 a; ?1 o# L, x
  35. //返回值;无
    ( N. L+ }* X( r. C2 U$ I
  36. //************************************************************************************************************************************************/ Z3 s$ K) u* G6 {8 T" [6 Z4 @
  37. void CAN_Config(void). P$ U( G+ {4 u6 m) O& f$ i/ m8 P
  38. {
    3 D) c- b+ ~  Q9 q6 n7 ?
  39.   GPIO_InitTypeDef GPIO_InitStructure;! i+ j1 Y) A* m% O! I" A
  40.   CAN_InitTypeDef CAN_InitStructure;
    , u8 ]! L8 ~7 M! y% X  P# f0 F
  41.   CAN_FilterInitTypeDef CAN_FilterInitStructure;
    ( l' z& u4 {% a7 r. N$ T

  42. 8 M# V) k- F/ ~: B4 }5 G
  43.   /* CAN GPIOs configuration ***********************************/
    - a* Z% U! U: h' v
  44.   /* Enable GPIOD clock */
    : V+ E) M. {3 V9 l$ p# l1 q
  45.   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);# h1 B, I: Z) B+ X- F- J( K3 L

  46. ( i# C% B+ D  {
  47.   /* Connect PD1 to CAN1_Tx pin */# F6 A- f, Z* J7 C
  48.   GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1);
    1 ^; Y7 _$ u9 h! z( a
  49.   /* Connect PD0 to CAN1_Rx pin */
    0 l* C9 Q# x+ x8 Z- z: a2 z
  50.   GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1);
    5 b4 ?! W! w+ N' J

  51. 4 g" ~/ b9 u. O
  52.   /* Configure CAN1_Rx(PD0) and CAN1_Tx(PD1) pins */
    6 {$ }  g, P  e9 m/ s- p7 D, _6 b
  53.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    & Q& W  P: h" t( @- Y
  54.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;) z# `  L8 R& M; _' I
  55.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;, o) I+ P: Q9 t1 l* H" E
  56.   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    9 `- U  s5 X6 |0 a" R
  57.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    + y3 o8 i/ h! [; A1 T
  58.   GPIO_Init(GPIOD, &GPIO_InitStructure);4 {) p# m% J* Z* D+ [1 L  i+ E

  59. 7 r" S2 f1 J9 ?6 H, `( l
  60.    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//Rx要单独初始化,否则进入不了中断,不能按照ST官方库来设定& @& W0 K5 P5 ^$ U5 J, V6 y% u$ p
  61.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;% C( `/ R- G" S( Z6 b9 k# U
  62.    GPIO_Init(GPIOD, &GPIO_InitStructure);
    - l$ ~1 y8 Z! a
  63.   /* CAN configuration *****************************************/( p8 l6 |2 d) ?
  64.     /* Enable CAN1 clock */
    % L$ `$ a. l6 z- ~% ~
  65.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);6 [* O" g& g0 O2 M/ B

  66. 4 P* S. C+ q) {. R& Z( j, s
  67.   /* CAN register init */
    1 f; i* e; U1 V3 k0 M% T
  68.   CAN_DeInit(CAN1);
    " R! |' B; v' x, J9 Q
  69.   /* CAN cell init */- w' S7 E0 p8 {
  70.   CAN_InitStructure.CAN_TTCM = DISABLE;5 |6 g) E; m0 x5 Q. R6 z% Z$ z( T
  71.   CAN_InitStructure.CAN_ABOM = DISABLE;6 m9 S1 {) Y; |, D1 ~0 @
  72.   CAN_InitStructure.CAN_AWUM = DISABLE;4 [$ |. s' k. W
  73.   CAN_InitStructure.CAN_NART = DISABLE;
    0 G( T: M  o8 M9 l$ @; ?- ^# I0 {& B
  74.   CAN_InitStructure.CAN_RFLM = DISABLE;
    " a/ `/ G' l" Z* t. g0 _
  75.   CAN_InitStructure.CAN_TXFP = DISABLE;
    ' A; |( h+ p2 O* v) {
  76.   CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
    7 c2 I  F- E3 t7 S  h) G" X7 U
  77.   CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
    : B+ E: j3 C. A( y# R- S- G3 Z3 Y
  78.   /* CAN Baudrate = 1MBps (CAN clocked at 30 MHz) */ //30/(1+6+8)/4=500k
    4 Y$ [8 \; l  a  \8 r& ?
  79.   CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;) C% c% E- N# l9 R4 T4 j. a) U
  80.   CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
      d' ^/ y, M- \3 N
  81.   CAN_InitStructure.CAN_Prescaler = 4;
    0 z  {# e& N7 \7 e/ {+ D0 ^' Q# p# [! H
  82.   CAN_Init(CAN1, &CAN_InitStructure);
    # l) ]( v8 n4 X6 q+ r( C
  83. 5 ?6 ?2 \# d! W. J% y
  84.   /* CAN filter init */
    4 M. j& n- i8 x) @- G8 B* t1 s1 v  a% F
  85.   CAN_FilterInitStructure.CAN_FilterNumber = 0;
    : B; _% c: ~- ]4 d% g
  86.   CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
    9 L& q5 T) F4 s$ ^
  87.   CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
    7 J8 Y: s5 J4 C
  88.   CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
      r; o( z4 V: e7 t7 L
  89.   CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;$ c2 i/ _6 z7 r8 _; s
  90.   CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
    % Z" Z3 u8 R( `% t# q3 E! B
  91.   CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
    * ~  G/ |- Q- Z5 I' c
  92.   CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
    5 F6 M3 Z8 `% ?. C9 S) \5 g8 o9 e
  93.   CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;* O, n1 r3 B. ^1 f9 ]
  94.   CAN_FilterInit(&CAN_FilterInitStructure);
    2 g3 r7 i, |# ?; V; b
  95. , h9 I) g& b* w  ^. W% i
  96.   /* Enable FIFO 0 message pending Interrupt */  
    8 a) T6 A. ^: Q
  97.   Init_TxMes();//发送结构体参数初始化
    % I$ Z7 t' G* F- h( x9 m
  98.   Init_RxMes();//接收结构体参数初始化( k8 |$ y( D6 Z/ L: |2 z5 d
  99.   NVIC_Config();//中断向量配置0 b& o; X) h3 {
  100.   CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
    0 `2 ?  F$ V9 D3 e) Q8 C! @1 u& e. B, c

  101. & r% [4 H. |6 |
  102. }
    7 g( h# D4 I) x0 t% ^/ ?5 c! Z
  103. //************************************************************************************************************************************************
    2 \1 u( A  D$ ~' C& o
  104. //函数名:void Init_TxMes(CanRxMsg *RxMessage)
    , }# v$ F; |, J- K: i' G$ W
  105. //功  能:  Initializes the Tx Message
    2 k+ O9 c8 V) e* U5 q
  106. //参  数:无
    4 q2 L/ p  O/ y' Z7 V8 P+ v
  107. //返回值:无
    / \' j3 S! y( V; X, I8 z5 U
  108. //************************************************************************************************************************************************
    5 J( J& `! A$ R! c! L0 J
  109. void Init_TxMes()
    & |# j# ^' o) x
  110. {+ p$ _$ H7 b) [0 i) L: B
  111.     /* Transmit Structure preparation */
    : u+ c  Y! d6 t3 C- `, C7 R
  112.   TxMessage.StdId = 0x123;//标准标识符,必须在( TxMessage.IDE = CAN_ID_STD;//标准帧)情况下才有效
    9 h* M/ F" S0 |% M6 p( Z- y0 F
  113.   TxMessage.ExtId = 0x00;//设置拓展标识符(29位),必须在( TxMessage.IDE = CAN_ID_EXT;//标准帧)情况下才有效" i# M' E5 V& @, \" B3 [  R4 i& o
  114.   TxMessage.RTR = CAN_RTR_DATA;//数据帧0 T$ E$ x% z+ u' s7 \7 T) A
  115.   TxMessage.IDE = CAN_ID_STD;//标准帧 ) t: }5 J$ }5 R1 Q
  116.   TxMessage.DLC = 8;//发送数据长度  DLC=0-8
    1 K, ]8 r2 w/ S% F$ L# p3 s
  117. }
    / B1 Y0 ~8 s5 Z( l+ m) T
  118. //************************************************************************************************************************************************8 b( h9 p% y) `* I3 K8 _
  119. //函数名:void Init_RxMes(CanRxMsg *RxMessage)+ I8 G$ s3 u( a1 s
  120. //功  能:  Initializes the Rx Message
    * o' r9 S) e  Z' X4 k+ F8 M1 S
  121. //参  数:无
      _- }5 H. g5 j
  122. //返回值:无
    # F1 p% j5 }6 v1 @3 l
  123. //************************************************************************************************************************************************
    / P$ O/ i3 s% s! Y
  124. void Init_RxMes()
    ; R# Z1 |) U, W, c+ ~7 A% V% i6 m
  125. {
      T3 r) b) t# r- u/ s
  126.   u8 i = 0;- R9 F1 a  I; f' s( g* n
  127.   RxMessage.StdId = 0x00;//这个可以在接收中断中判断 如果RxMessage->StdId = TxMessage.StdId 接收正确   x* P4 ]; H# G) K
  128.   RxMessage.ExtId = 0x00;//这个可以在接收中断中判断 如果RxMessage->ExtId = TxMessage.ExtId 接收正确
    4 I  J3 l' M3 `6 Y
  129.   RxMessage.IDE = CAN_ID_STD;//这个可以在接收中断中判断 如果RxMessage->IDE = TxMessage.IDE 接收正确 & W7 x$ _4 S9 X3 E5 O6 W# E
  130.   RxMessage.DLC = 8;//接收数据长度
    ! b. P8 |! M" [, j+ Z
  131.   RxMessage.FMI =16;//????????????????
    & [; ^4 \; j8 I' V# O. x  K
  132. 9 k$ p! s8 [8 C0 \
  133.   for (i = 0;i < 8;i++)
    / R" ~$ l8 ]  ]) v8 b
  134.   {
    - X% V: b0 T5 ~9 b
  135.     RxMessage.Data<i> = 0x00;</i>
    2 F0 Z' ]2 b6 W) K' B6 Z
  136.   }
    - W8 W6 N5 O" U
  137. }
    4 N9 j3 l# k5 a
  138. //************************************************************************************************************************************************
    ! I7 s$ W+ h$ n$ V) ?7 O
  139. //函数名:void CAN1_RX0_IRQHandler()
    # u" |5 }! A) V) T% ^
  140. //功  能:  CAN1-RX0接收中断服务函数- {8 l. a! `- q; F% [! m) }
  141. //参  数:无
    & ~9 _( @, F' t6 g7 L+ h
  142. //返回值:无5 P8 g) p" C; k
  143. //************************************************************************************************************************************************
    ' Z- q9 v% h; m/ k" J/ Y
  144. void CAN1_RX0_IRQHandler()  //与CAN1_RX1_IRQHandler()区别
    & E2 _. Z: p2 ~; D  p
  145. {, f+ s2 h' I- m9 m, d
  146.   if(CAN_GetITStatus(CAN1,CAN_IT_FMP0)!= RESET)//判断是否发生CAN-R0中断- ^' }! ^5 L, ?* K* u9 C; }
  147.   {: w* z9 m1 G5 i; n9 O: e
  148.     CAN_ClearITPendingBit(CAN1,CAN_IT_FMP0);//清除中断标志
    ' q( z) a8 {( c. |, T" S% \+ x, o
  149.     if(CAN_MessagePending(CAN1,CAN_FIFO0)!=0)//接收到数据) z& p, b$ S2 Y! d0 T1 N
  150.        CAN_Receive(CAN1,CAN_Filter_FIFO0,&RxMessage);//接收数据最大只能8字节
    4 p. d& F* o3 G
  151.   }
    9 L, }' f5 W# v* @( q1 f2 ]6 ^
  152.   Usart_Send_Buff(RxMessage.Data,8);//发送数据RS232通信    6 z+ s$ |: J& S6 s
  153. }
    . Y4 C/ @+ q* L+ [: E
  154. //************************************************************************************************************************************************7 I( u# r1 }5 w. I7 N1 U
  155. //函数名:u8 CAN_SendData()
    $ |* d% F$ F' R. X' g) x
  156. //功  能:  CAN发送数据  发送第二步: F9 X7 J: K% D- s# d: T
  157. //参  数:Msg数据指针;Length数据长度) R$ I6 n: ~5 @( z; E3 c! [
  158. //返回值:返回成功/失败标志
    . X: i' l) I  T* |8 N% W
  159. //************************************************************************************************************************************************
      c6 O3 T& J; G# F3 @- d
  160. u8 CAN_SendData(u8* Msg,u8 Length)
    8 R' V9 r" X/ _8 y
  161. {
    " R* }( t3 Q) V. U3 K* k9 d
  162.   u16 i=0;
    ' V$ U( |  B& c% d& q4 N5 m& [+ |
  163.   u8 mbox=0x00; , v# E! M4 n+ M! u
  164.   TxMessage.DLC = Length;//发送数据长度  DLC=0-8
    7 ~5 V7 y9 h5 }0 w4 h. Q. e
  165.   for(i=0;i<Length;i++)
    8 k$ U: q' e- H6 G7 Y! x
  166.   {1 K2 r: W3 N' J! R( A" I
  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;">;$ B  z, q8 Z4 ]. G6 y! Z( t% `( L
  168.   }
    $ z; ^4 j. F; R4 w
  169.   mbox=CAN_Transmit(CAN1,&TxMessage);//发送数据  返回邮箱使用数量
    ; [% J6 D: ^" ^3 g

  170. " O6 M; a5 R. ]4 Z0 o0 F5 L4 ]  G: Y
  171. //  while((CAN_TransmitStatus(CAN1,mbox)!=CAN_TxStatus_Ok)&&(i<0xfff))+ l9 [- \2 M  B$ g/ @4 s& k
  172. //  {
    # u* t& D; h! X. D, u& `
  173. //    i++;! G) N5 _( G7 e
  174. //  }; h& B0 T6 e- N1 U
  175. //  if(i>=0xfff)
    0 A: h& }1 Z. Z+ t  h5 y
  176. //  {
    8 d# }0 @: j2 |# D
  177. //    return 0;//发送数据失败9 R+ g/ O4 [9 W+ J' e5 S( B4 M6 C+ [! S* ]
  178. //  }
    ( U/ q' j8 e3 r/ C# o
  179. //  return 1;//发送数据成功
    0 C8 [2 C2 c7 E2 x
  180. }  O" y: d* b' h
  181. //************************************************************************************************************************************************
    / `1 _8 _6 U( L5 A5 f: K
  182. //函数名:void CAN_SendDataProces(u8* data,u8 Num)$ b+ o) _! o9 s
  183. //功  能:CAN发送数据前期处理   发送第一步
    . M# l2 i7 o4 o
  184. //参  数:data数据指针;Num数据长度' T0 n+ \  [0 T$ U% X$ J5 I- n" Z
  185. //返回值:无
    $ y& i  a8 i% E5 P  s, }  E) X% K1 r
  186. //************************************************************************************************************************************************
    # h, g8 m2 S0 x( z4 l
  187. void CAN_SendDataProces(u8* data,u8 Num)6 d! ~  T$ |! v3 K4 @) K4 v
  188. {  Y; L/ [3 Y- g  f' g. m
  189.   u8 flag=0x00,i=0;* j4 `$ L, b6 {) I& H" P0 H
  190.   u8 Count=0x00,Left=0x00;9 w- z( z# h9 ^  I; I

  191. - [+ u% A6 A: I9 O" B& U; ^" N1 [
  192.   Count=Num/8;//求多少个8字节倍数5 w5 W: S* t  k1 `# F# s: }
  193.   Left=Num%8;//剩余小于8字节的数量
    3 M- x9 u3 g" @! ~# i$ o
  194.   for(i=0;i<Count;i++)
    4 K8 q8 A# o. S7 {3 E! C
  195.   {
    / Y, A7 U! q3 E+ _1 c  C4 j6 S8 W6 b
  196.     flag=CAN_SendData((data+i*8),8);//发送整8字节的数据
    ' ?9 v' A6 f; Y' M, W6 U2 j4 B
  197.   } % Z7 y8 W. t, s2 W8 a
  198.   if(Left>0)//有余数才单独再发送一次$ X# X4 S  s  l- C; H
  199.   {
    ' v7 Q6 Z# `1 `* w+ b5 m& i& a) `
  200.     flag=CAN_SendData((data+8*Count),Left);//发送剩余字节
    * ?# f/ A8 K+ G7 i( F6 j( D. q
  201.   }% T4 p& I/ c7 I/ g9 L7 S# n' P1 k
  202. }
    7 Z3 E, Q0 J' h$ N0 V
  203. //************************************************************************************************************************************************! }9 O1 w+ h' b3 P: Q- [9 R; D7 g& T. B
  204. </span>
    3 X. ]: ]9 Q9 ?1 s$ |
  205. </span></span>
复制代码
) T- O. f" `1 F' k
收藏 评论0 发布时间:2021-12-1 22:18

举报

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