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

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

[复制链接]
STMCU小助手 发布时间:2021-12-1 22:18
STM32F2-CAN通信-发送任意长度,调试好的,与大家分享
8 z9 V9 C# V9 B# d
/ {' }/ q9 F: D3 ?2 d3 N/ a
  1. #include "include.h", [$ T, M$ |$ X  a8 S: L
  2. //************************************************************************************************************************************************& V; Q5 \2 _2 n
  3. //20190611调试完成
      A: g$ U- D4 y: o. V* T* P
  4. //By Wang* y' P. t& l. f( J. U( ]
  5. //************************************************************************************************************************************************
    % {4 s8 T8 }, b

  6. % Z, U. o; e& E6 }
  7. CanRxMsg RxMessage;
    : J$ L  e1 Y4 }& p
  8. CanTxMsg TxMessage;
    1 d8 j# `8 S9 |( Q5 @! X/ G
  9. //************************************************************************************************************************************************
    1 O) d3 f' m' ~9 [3 ^
  10. //函数名:void NVIC_Config(void)
    2 X  ]# ?+ n" {6 v
  11. //功  能:  CAN通信接收RX0中断配置
    / y2 m& X4 p! Q7 k8 Q
  12. //参  数:无0 P6 d% f/ n; v( d$ b  E
  13. //返回值:无# ?, M  Z" ?- f* [
  14. //************************************************************************************************************************************************4 F# @5 E$ b7 h2 _! K$ n
  15. 5 w! v7 U+ @% F. P0 e5 h8 m
  16. void NVIC_Config(void)+ F7 {6 `# B& d% y
  17. {+ [$ Z1 u* S8 n4 c' ^
  18.   NVIC_InitTypeDef  NVIC_InitStructure;0 T& \$ j+ Q: N1 ]- j6 j8 y+ |
  19. " K" ]5 ~/ N# q' D3 P
  20. //#ifdef  USE_CAN1 3 s) I! {8 Y9 l# L

  21. " ~) L# M/ ?# k" B
  22.   NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;//与CAN1_RX1_IRQn;区别
    " N# M* _. ]& T# q0 ~) K
  23.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//不同的中断优先级一样会怎样1 O5 B) i! y8 P2 `
  24.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
    8 b/ T* o- A0 S! E

  25. / i+ i( ?- J- Z2 e! [
  26.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    - F+ X& s" p! ]9 x
  27.   NVIC_Init(&NVIC_InitStructure);3 T. C; A; P9 z/ W

  28. " x- n! x4 K9 u7 Z( a
  29. }
      A3 A, P# t' h

  30. 6 e* Z  X  f, j" j& L( R1 a+ m
  31. //************************************************************************************************************************************************
    1 d, T9 I. d( Y
  32. //函数名:void CAN_Config(void)
    + p7 S: n) z1 y( s
  33. //功  能:  CAN1配置 PD0-RX;PD1-TX
    2 h6 a- S. F2 ~  s' D
  34. //参  数:无
    4 Y# e0 ]) c; V* V* p2 \
  35. //返回值;无
    6 C6 o0 @2 N' d' e4 {2 X# ~
  36. //************************************************************************************************************************************************
    ) T  H1 [0 B6 `5 b7 t6 l1 j
  37. void CAN_Config(void)  [, B9 |5 F5 b. E) J
  38. {
    ! t1 `; M1 \- w- e9 ]
  39.   GPIO_InitTypeDef GPIO_InitStructure;6 e- h4 x; Z+ H
  40.   CAN_InitTypeDef CAN_InitStructure;
    & x% q% K( K6 v7 }' u9 {
  41.   CAN_FilterInitTypeDef CAN_FilterInitStructure;
    / L8 W2 E7 ~& ~# B: ~8 }  H7 \4 g
  42. / d9 g* ~' J0 S. c- m" ?/ u
  43.   /* CAN GPIOs configuration ***********************************/
    8 ?- a2 u- d7 P" F$ {" M
  44.   /* Enable GPIOD clock */  s: A0 e6 e5 D9 _. Z0 N2 Y9 v
  45.   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
    0 @' u. b4 v( q( Q3 V

  46. , X% j" `  G1 f" q* l. d% j
  47.   /* Connect PD1 to CAN1_Tx pin */
    # d+ f4 m. X8 Y
  48.   GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1);1 P- Z; p5 w7 i" T, ^. P
  49.   /* Connect PD0 to CAN1_Rx pin */
    8 }8 T9 C5 ~% i# c- T
  50.   GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1);4 j- e3 Y+ i( R/ q

  51. * ^& \1 b" f2 f% \4 _2 M
  52.   /* Configure CAN1_Rx(PD0) and CAN1_Tx(PD1) pins */" |5 s( N# {5 }: y, J6 |! z- Q8 h
  53.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    : b2 |; {) `9 K1 n( q
  54.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;! V, C' B- ~' Q; @8 Q+ n& W6 q
  55.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;2 R9 @4 r2 I+ a) [' h! ~
  56.   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;5 q" O1 t0 P0 q6 J% K6 i' u/ x+ @; F
  57.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    # P; G$ `, g: y8 a! o
  58.   GPIO_Init(GPIOD, &GPIO_InitStructure);
    5 T) Q( o" e6 q  @5 ~* _
  59. " H" ~. P- t0 l* j: O
  60.    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//Rx要单独初始化,否则进入不了中断,不能按照ST官方库来设定
    $ r8 Y) G* l# v) n& X3 ?  w
  61.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;" t: g  N6 }, B, \' {. J/ ^
  62.    GPIO_Init(GPIOD, &GPIO_InitStructure);
    1 h& P" i& p, x: s
  63.   /* CAN configuration *****************************************/
    , w5 h8 f9 {8 ]
  64.     /* Enable CAN1 clock */
    " e8 [- A, }" ]
  65.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);# P+ f& K( D+ L9 `# o) }7 i
  66. # k- ~) H0 C. r: {% X
  67.   /* CAN register init */5 y$ A# B1 d8 v6 l$ D0 E
  68.   CAN_DeInit(CAN1);3 J9 k' N2 z, G/ O* b8 l: u
  69.   /* CAN cell init */" x1 ^2 J" b9 x3 y. V
  70.   CAN_InitStructure.CAN_TTCM = DISABLE;
    / Z: ]$ Y. i' X& |9 O
  71.   CAN_InitStructure.CAN_ABOM = DISABLE;2 ?! [9 L+ l* i. C) d6 ^' [' Z
  72.   CAN_InitStructure.CAN_AWUM = DISABLE;
    , B& y; i- D) s
  73.   CAN_InitStructure.CAN_NART = DISABLE;' n$ o' o  n5 g. P' V+ B, N: q/ t
  74.   CAN_InitStructure.CAN_RFLM = DISABLE;* E  c/ n0 ?2 f# c4 y2 l3 W
  75.   CAN_InitStructure.CAN_TXFP = DISABLE;
    ( y4 k% O: V6 @1 X
  76.   CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
    ' r6 t* j1 L5 G. g$ |! a. p
  77.   CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;9 Y( e( h& Q+ q& @
  78.   /* CAN Baudrate = 1MBps (CAN clocked at 30 MHz) */ //30/(1+6+8)/4=500k" `) y0 u  V  m5 b- u
  79.   CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;, H7 u4 H0 v, f
  80.   CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
    0 ~; I# A" {1 S/ G7 _. r8 f
  81.   CAN_InitStructure.CAN_Prescaler = 4;* S$ X8 d( {4 C
  82.   CAN_Init(CAN1, &CAN_InitStructure);
    * b; g' S4 f3 x( K0 }
  83. 3 s1 U6 F+ L; ?4 B9 P0 r+ v
  84.   /* CAN filter init */
    5 ~' s) w* z% T1 e  i; n5 s
  85.   CAN_FilterInitStructure.CAN_FilterNumber = 0;
    & x  P6 l% o- T. c! P4 @
  86.   CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
    ) |+ z6 l3 L: o) L7 j6 a
  87.   CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
      u5 N, k2 z. p7 p1 p. N7 P. e
  88.   CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
    ! p( A/ t. F+ e
  89.   CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;9 d" J9 M2 f2 x, \- |# G+ |
  90.   CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;) e, H9 N. R! k" j/ B+ ?7 F
  91.   CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
    6 T$ I/ ~5 I: n" c2 x1 M
  92.   CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
    3 t; `6 M& E% e
  93.   CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
      o& T( D% `9 O, H, f& T
  94.   CAN_FilterInit(&CAN_FilterInitStructure);2 g) V, P) G& R: n. q

  95. / t1 B% [4 {1 J4 ]5 q6 d! M6 n  U
  96.   /* Enable FIFO 0 message pending Interrupt */  
      g- E5 n$ E" a9 M* t
  97.   Init_TxMes();//发送结构体参数初始化+ a& F" |. D3 r# h! D* [9 @. ]
  98.   Init_RxMes();//接收结构体参数初始化, j5 E; u+ r& L' W) {4 i: B
  99.   NVIC_Config();//中断向量配置
    ( ?2 d7 _# G& G# h
  100.   CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);9 l/ _% k+ M' h% O

  101. 2 p0 h6 t- P# W% m9 t
  102. }
    $ S6 W+ T* B5 O
  103. //************************************************************************************************************************************************6 H, ~; P' H$ ]
  104. //函数名:void Init_TxMes(CanRxMsg *RxMessage)
    * H0 h/ k; _5 J: u( Z( }
  105. //功  能:  Initializes the Tx Message
    7 A0 e3 s! E3 c9 ]5 o- U
  106. //参  数:无* m1 m2 Q* x; u- ]" [
  107. //返回值:无
    " k% U0 J3 }5 m
  108. //************************************************************************************************************************************************
    : ^- C  I7 o- g! q" @
  109. void Init_TxMes()9 z8 p% G8 n6 e: P7 _
  110. {! K6 g! z2 [* o/ i' P2 B
  111.     /* Transmit Structure preparation */
    " I4 H/ l% i$ D4 z. @1 ]" p- S
  112.   TxMessage.StdId = 0x123;//标准标识符,必须在( TxMessage.IDE = CAN_ID_STD;//标准帧)情况下才有效
    ! a7 J0 C0 P( C+ v: o7 H4 u1 e) F
  113.   TxMessage.ExtId = 0x00;//设置拓展标识符(29位),必须在( TxMessage.IDE = CAN_ID_EXT;//标准帧)情况下才有效, n2 D1 \; j" `) P$ Z* x; N3 w1 l
  114.   TxMessage.RTR = CAN_RTR_DATA;//数据帧
    ! y" ?- |% M9 X6 m
  115.   TxMessage.IDE = CAN_ID_STD;//标准帧
    & V+ p, y& m( p* v; ?+ b3 ^5 d
  116.   TxMessage.DLC = 8;//发送数据长度  DLC=0-8, m9 q: i- |; K8 D
  117. }- H3 p) ?" i, q* o* g
  118. //************************************************************************************************************************************************
    8 t5 j4 b4 d, Q( p& S  S. Y% O
  119. //函数名:void Init_RxMes(CanRxMsg *RxMessage)' Y+ q& T& G# i8 ^. Y. n0 E
  120. //功  能:  Initializes the Rx Message& a% n! S. c* D# B
  121. //参  数:无
    9 A/ u# Y$ o0 U' z
  122. //返回值:无
    : w6 S/ J0 F* h
  123. //************************************************************************************************************************************************
    1 V+ ^: K% l1 ]& v" B$ _
  124. void Init_RxMes()8 _8 C% x$ p7 `7 w: U
  125. {
    1 T0 z/ E1 `( C5 N2 B
  126.   u8 i = 0;
    : L7 {7 w+ c' S! o
  127.   RxMessage.StdId = 0x00;//这个可以在接收中断中判断 如果RxMessage->StdId = TxMessage.StdId 接收正确
      c+ A7 X" F3 L6 E8 L$ i
  128.   RxMessage.ExtId = 0x00;//这个可以在接收中断中判断 如果RxMessage->ExtId = TxMessage.ExtId 接收正确 3 d" D4 t) {' U" [! u8 B7 }
  129.   RxMessage.IDE = CAN_ID_STD;//这个可以在接收中断中判断 如果RxMessage->IDE = TxMessage.IDE 接收正确
    1 W% e. q7 C( ?
  130.   RxMessage.DLC = 8;//接收数据长度/ e9 E- x, q6 U2 k
  131.   RxMessage.FMI =16;//????????????????# I; C6 U  \- C* x
  132. 4 t& A2 C! i5 r
  133.   for (i = 0;i < 8;i++). f4 q8 }# f3 X
  134.   {% x8 b  N# \, l# W
  135.     RxMessage.Data<i> = 0x00;</i>' b: |# m% U4 A" _; Y; \8 M; v
  136.   }$ y' M, [  C, O  q: B
  137. }! `9 O/ \0 y8 M2 j. a/ U4 H
  138. //************************************************************************************************************************************************
    8 o1 ~& W. n7 G
  139. //函数名:void CAN1_RX0_IRQHandler()( |! |0 @0 Z0 c9 M+ ^( l( [. y
  140. //功  能:  CAN1-RX0接收中断服务函数
    2 Q$ m' u+ _5 T5 A
  141. //参  数:无4 E* g' I# C' Y% ^8 H5 e; b
  142. //返回值:无
    2 L. q  h/ ?7 v4 ?
  143. //************************************************************************************************************************************************
    , m3 x2 O0 z; J, v7 V
  144. void CAN1_RX0_IRQHandler()  //与CAN1_RX1_IRQHandler()区别
    3 O+ J" \5 _  p. R: D; e6 P2 v3 P$ S5 ^
  145. {
    * ?$ a$ U$ V/ v! y# W" t6 S1 o
  146.   if(CAN_GetITStatus(CAN1,CAN_IT_FMP0)!= RESET)//判断是否发生CAN-R0中断& n! ~& p5 W- Z; ?* R$ F
  147.   {
    % x+ I; a7 \: s; O  ]8 g
  148.     CAN_ClearITPendingBit(CAN1,CAN_IT_FMP0);//清除中断标志4 g# ~' y& |" I8 U2 h7 j; [; D
  149.     if(CAN_MessagePending(CAN1,CAN_FIFO0)!=0)//接收到数据# G4 h7 M% u1 c; N9 q
  150.        CAN_Receive(CAN1,CAN_Filter_FIFO0,&RxMessage);//接收数据最大只能8字节
    # o* ~+ j/ y; X9 B- P. X
  151.   }8 k, @" I8 c+ O
  152.   Usart_Send_Buff(RxMessage.Data,8);//发送数据RS232通信    6 G) O$ W2 g0 L( b
  153. }: N4 ^2 o% P/ f4 L3 U
  154. //************************************************************************************************************************************************
    ! I' a- X: W2 ]. _
  155. //函数名:u8 CAN_SendData()
    8 l2 ^4 v, a1 B4 p+ ~
  156. //功  能:  CAN发送数据  发送第二步
    7 F# u3 P$ l7 Z1 x0 X: l
  157. //参  数:Msg数据指针;Length数据长度
    2 C& [% e9 v' R- ?+ k
  158. //返回值:返回成功/失败标志
    6 u) K. l& i, B) x2 p2 p; `
  159. //************************************************************************************************************************************************
    ; b0 \+ E" [- U, Z
  160. u8 CAN_SendData(u8* Msg,u8 Length)
    $ F/ I, ~3 P: K' I( V( X; n
  161. {, M% C; J! V% `; \
  162.   u16 i=0;
    0 k5 p4 ]0 c2 s( }" c
  163.   u8 mbox=0x00;
    1 p! O# h5 ^. a; j  W0 B
  164.   TxMessage.DLC = Length;//发送数据长度  DLC=0-8" z  L0 R7 J5 J; {# n$ D
  165.   for(i=0;i<Length;i++)
    0 R$ J' {$ X& {# _# c% S- Q& b2 t
  166.   {
    ! Q0 [% z- Z) O  J1 b1 j  @$ |
  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;">;1 R2 R; l0 p- o6 ^* ?* Z
  168.   }8 g( S% F6 ~3 G  }0 g4 [+ v
  169.   mbox=CAN_Transmit(CAN1,&TxMessage);//发送数据  返回邮箱使用数量
    / ^1 e* H# E( L2 a8 l& l

  170. ) d0 t8 Q% `' a& g* H( D
  171. //  while((CAN_TransmitStatus(CAN1,mbox)!=CAN_TxStatus_Ok)&&(i<0xfff))) v; `& V$ w3 _+ E! P8 ]; p- |
  172. //  {4 }& x; B1 u! X, o) A, f
  173. //    i++;8 B2 e  P" J) Z, m. Y1 W
  174. //  }3 l$ V6 l: i" x$ W0 q* u
  175. //  if(i>=0xfff) , k' U& Y0 C+ `. n6 S4 ^8 i
  176. //  {
    8 V( [; C4 [- s% ~: H$ s6 ]
  177. //    return 0;//发送数据失败
    ) y' R, c6 w% z) z4 R* @  j+ q
  178. //  }+ D3 ~5 Q9 b5 k, I2 ]9 u/ q
  179. //  return 1;//发送数据成功
    ( _/ q1 t% M! m- ?8 F4 [( k
  180. }" e& ]9 I1 n/ D! N5 d  q0 R
  181. //************************************************************************************************************************************************
    * ]2 W' B$ o' k' i$ N' [
  182. //函数名:void CAN_SendDataProces(u8* data,u8 Num)
    6 g) R- F8 ]$ y9 o& Z% [
  183. //功  能:CAN发送数据前期处理   发送第一步
    5 }$ [9 g5 K  h& i1 b
  184. //参  数:data数据指针;Num数据长度# r, ~! H- v, q3 c$ a
  185. //返回值:无" G. }: p& q( N8 `% l
  186. //************************************************************************************************************************************************: d1 u8 C8 ?$ @
  187. void CAN_SendDataProces(u8* data,u8 Num)
    * o) P, }  T# c: D
  188. {
    0 }- l- W6 u$ t% q3 q3 ?% [" G
  189.   u8 flag=0x00,i=0;) z' \6 ?( k# _+ j' @& b2 v- T
  190.   u8 Count=0x00,Left=0x00;
    8 _) C, J% t1 j5 t* G
  191. 7 t# v1 M- f5 }3 R2 ~: p
  192.   Count=Num/8;//求多少个8字节倍数
    - W/ r. Z8 ]9 H9 w
  193.   Left=Num%8;//剩余小于8字节的数量& A' x* s$ c) p" _
  194.   for(i=0;i<Count;i++)) L2 ]8 [: h9 ?* J5 n. ^3 a2 x
  195.   {& O+ O- E" @( ~+ N' U2 z$ ~
  196.     flag=CAN_SendData((data+i*8),8);//发送整8字节的数据4 Y, K; x$ m  ~9 ]" v9 f
  197.   }
    + S: s* A' H: S: A- o- V
  198.   if(Left>0)//有余数才单独再发送一次8 s/ k" k  f- \: e0 N5 J
  199.   {
    + C4 i! [. X- s
  200.     flag=CAN_SendData((data+8*Count),Left);//发送剩余字节
    2 I1 p( r$ W! L& s; a% ]  z
  201.   }9 O& q* \. H/ [# H) b
  202. }
    " p3 m4 S! o; g
  203. //************************************************************************************************************************************************
    3 C3 h' X. ^. _* y6 j  c; T0 f
  204. </span>8 o9 j- n+ G9 i2 f! R& t
  205. </span></span>
复制代码
3 u- m3 D/ c7 r, }  }2 a
收藏 评论0 发布时间:2021-12-1 22:18

举报

0个回答

所属标签

相似技术帖

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