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

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

[复制链接]
STMCU小助手 发布时间:2021-12-1 22:18
STM32F2-CAN通信-发送任意长度,调试好的,与大家分享$ {4 {3 Z, M( ]1 ~6 L$ e# o8 A

. u9 v# d, W' j3 V' P0 @; M1 d& u2 N
  1. #include "include.h"9 c7 G7 ~, ]! F9 r+ I! C
  2. //************************************************************************************************************************************************
    & s' U; I& ^* E! E8 F" Z8 |3 O9 N
  3. //20190611调试完成
    + t# A8 G' u) L9 a6 F2 n) d) S6 p
  4. //By Wang: n3 Q( M; Q+ k+ l
  5. //************************************************************************************************************************************************/ J, @% y" N& E& O' D8 L: D, I

  6. & J- B: G' T" B
  7. CanRxMsg RxMessage;
    $ l% A# q+ v, P: t( g+ u: H
  8. CanTxMsg TxMessage;- a" n% h  b$ L1 |! ^
  9. //************************************************************************************************************************************************
    - c) _' X1 {- p2 I) K, T4 W7 C  k
  10. //函数名:void NVIC_Config(void)! v- U0 |& I  H' E; k8 J7 }# p# x
  11. //功  能:  CAN通信接收RX0中断配置
    7 i; G' d4 D7 H# N& t* n: k
  12. //参  数:无- M. t5 s" o+ v$ [
  13. //返回值:无+ n' |" t# x0 K/ `0 d) r
  14. //************************************************************************************************************************************************( M& p5 ?) f3 ]/ F; S

  15.   k* N8 ^4 _" T) M( g/ s
  16. void NVIC_Config(void)" ?* X+ L& ^" j! s5 ]. c4 w
  17. {# E- l4 E2 u6 ?$ B2 K
  18.   NVIC_InitTypeDef  NVIC_InitStructure;
    3 M. a# @' w2 P- @$ s7 C
  19. 9 i- a, w+ m) j4 ]1 O
  20. //#ifdef  USE_CAN1 & [9 V, E8 U9 d& M, r

  21. ) p* _( C' `# f: K: i' ~( f* t
  22.   NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;//与CAN1_RX1_IRQn;区别- ]6 d& t1 c/ }8 D6 o/ o- ^
  23.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//不同的中断优先级一样会怎样
    5 g0 e! G8 w9 j# X
  24.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
    * g9 j& j$ u: K! u5 I

  25. 6 m8 M8 P& B# C
  26.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;4 w$ w& \+ [" K, a/ Y
  27.   NVIC_Init(&NVIC_InitStructure);
    3 S3 k  H5 f/ Y- }9 h9 z$ ]! ]' n
  28. / ]- `5 q; P* T" V$ R
  29. }1 y3 }+ G& m! i4 m& {
  30. 8 X0 w" t& p' b% W
  31. //************************************************************************************************************************************************
    & F  ^+ j6 S1 v# P5 H' v* O+ d
  32. //函数名:void CAN_Config(void)2 q& P0 P( z7 `# h' s
  33. //功  能:  CAN1配置 PD0-RX;PD1-TX
    / w& ?: {+ f5 n: g5 N
  34. //参  数:无
    * k: i7 d, w6 B% E) D# X, O
  35. //返回值;无* `% j3 i. i& F( \6 Y; T1 {* m
  36. //************************************************************************************************************************************************0 ~8 @/ o9 K( G
  37. void CAN_Config(void). M- \& V/ \7 |8 z- w2 C- R% _
  38. {8 B& A: f, f, a. }* h% L, \& Z
  39.   GPIO_InitTypeDef GPIO_InitStructure;& O& H0 J4 g' \* \% c7 r+ n
  40.   CAN_InitTypeDef CAN_InitStructure;! T# }$ ]1 b- q4 N' x
  41.   CAN_FilterInitTypeDef CAN_FilterInitStructure;; G% z; j3 `- m) j
  42. ; r' R7 k5 B* b+ d: A
  43.   /* CAN GPIOs configuration ***********************************/
    4 \4 r/ \3 \4 H' H7 R
  44.   /* Enable GPIOD clock */
    ( j' V6 H  l; _% E+ `" L6 z# u* P
  45.   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);1 g0 t+ s2 P; _! U5 O+ I: d, `( ~8 z

  46. & |- ?- F! z: @/ {5 Y' ]. [- m
  47.   /* Connect PD1 to CAN1_Tx pin */* F" [) d& P4 j! q+ \
  48.   GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1);
    ! i9 K- j7 o# M: }
  49.   /* Connect PD0 to CAN1_Rx pin */$ _( a0 b2 D& h
  50.   GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1);
    5 `# b+ D% }3 h

  51. : i* |$ O6 K3 ~
  52.   /* Configure CAN1_Rx(PD0) and CAN1_Tx(PD1) pins */( w2 M; b/ v9 O9 B+ E( O8 n
  53.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;" N9 ]  ]+ r3 X
  54.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    4 o" V4 ?, T! J2 i
  55.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    + H$ R0 ], G! |2 \
  56.   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    - g' }# T4 q- |# J' m
  57.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
      x0 \' o+ \4 e
  58.   GPIO_Init(GPIOD, &GPIO_InitStructure);
    2 E9 [7 {. v& ]3 H0 {5 q* V

  59. . e& `& {: j$ M/ J! \  ]$ `6 b
  60.    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//Rx要单独初始化,否则进入不了中断,不能按照ST官方库来设定" X7 @( A4 A+ I3 k5 [
  61.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    . H# `; J' d* E
  62.    GPIO_Init(GPIOD, &GPIO_InitStructure);! d% B1 h; L1 ?
  63.   /* CAN configuration *****************************************// n( h: k2 v' J% B8 [0 w6 M- x
  64.     /* Enable CAN1 clock */3 K. w& X+ K" `! U7 ~
  65.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);1 R6 v$ D. G7 W7 T. Q( Q! e

  66. : g" d: O( d4 O7 s2 X) F
  67.   /* CAN register init */) V0 A! x* ~3 @. J  w, M
  68.   CAN_DeInit(CAN1);2 L3 S$ r( F1 Z, H- _+ k
  69.   /* CAN cell init */( }' G) P3 q# S' d) X
  70.   CAN_InitStructure.CAN_TTCM = DISABLE;
    . }, p' M" g; M7 C
  71.   CAN_InitStructure.CAN_ABOM = DISABLE;
    / n: N7 G! U- A% V$ {
  72.   CAN_InitStructure.CAN_AWUM = DISABLE;
    2 g0 t5 x$ W* g2 W  v. C
  73.   CAN_InitStructure.CAN_NART = DISABLE;
    ! b( I1 c' u/ N
  74.   CAN_InitStructure.CAN_RFLM = DISABLE;
    / f" g) O  v5 z2 B3 [$ V8 H
  75.   CAN_InitStructure.CAN_TXFP = DISABLE;
    ' X" L. b& E$ ~- w% f
  76.   CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;4 I' }: b1 H0 l4 [
  77.   CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;, G; C7 f' ?8 ]" |5 A
  78.   /* CAN Baudrate = 1MBps (CAN clocked at 30 MHz) */ //30/(1+6+8)/4=500k! S: l+ {: k) @; j, S
  79.   CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
    2 q/ Z# g  u) M. J( g
  80.   CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;! L  D: I8 Q: C9 N9 i: K( U
  81.   CAN_InitStructure.CAN_Prescaler = 4;' P5 |' a( J* P) h
  82.   CAN_Init(CAN1, &CAN_InitStructure);' e# S" Z) k& j, [( P

  83. 2 S- B% z+ l9 F8 ^! g
  84.   /* CAN filter init */
    * R& d+ e0 s, a4 N1 s/ q
  85.   CAN_FilterInitStructure.CAN_FilterNumber = 0;
    ! T0 ?0 S6 c  m& @
  86.   CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
    8 {- C* t' R) P; O' W
  87.   CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
    ) U2 z- _- C5 r0 W
  88.   CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
    " U" c6 |& T% q- H
  89.   CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
    5 h( h$ T  m8 ?
  90.   CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
    " P4 U( g# N1 H, K% D7 }; S
  91.   CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
    , V7 O& L, \. J+ j
  92.   CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
    / }" Q9 L% i" g: d
  93.   CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
    & a/ U) y7 k; r
  94.   CAN_FilterInit(&CAN_FilterInitStructure);1 O4 c  y7 I' x: M( `# T
  95. & v/ Z' C7 ~" x' N; K
  96.   /* Enable FIFO 0 message pending Interrupt */  3 r4 H2 D4 H* X$ o* f
  97.   Init_TxMes();//发送结构体参数初始化
    9 A0 @" a5 D/ Y8 M/ ~% R  j
  98.   Init_RxMes();//接收结构体参数初始化
    0 u3 b9 Y( r; K; N1 K" {8 e0 j* ^
  99.   NVIC_Config();//中断向量配置
    6 ~5 D% E0 T  h# f: x. j  o: a  u* [6 P
  100.   CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
    , m! x! b7 p- b  S$ @6 N# Y

  101. + Z6 |; L8 F8 X7 F; ]
  102. }
    , \* X8 i3 z2 \1 k( F: B3 x
  103. //************************************************************************************************************************************************! ~: K* v8 {( _0 m( _
  104. //函数名:void Init_TxMes(CanRxMsg *RxMessage)
    ) P4 v. e3 \; f) v% K
  105. //功  能:  Initializes the Tx Message
    / D) ~- ^( q8 h9 J0 I
  106. //参  数:无% q/ M# A( B* P6 e$ t  ~
  107. //返回值:无+ r3 E5 U9 G) L+ C; H, n
  108. //************************************************************************************************************************************************
    : @  M, h" i1 y# Y
  109. void Init_TxMes()
    ' `8 \/ [/ h/ I% }- `
  110. {$ `; q0 i7 O% K" `2 A
  111.     /* Transmit Structure preparation */
    1 L6 Y- \+ z5 l
  112.   TxMessage.StdId = 0x123;//标准标识符,必须在( TxMessage.IDE = CAN_ID_STD;//标准帧)情况下才有效6 \& y. \( U# J4 e& ^0 I
  113.   TxMessage.ExtId = 0x00;//设置拓展标识符(29位),必须在( TxMessage.IDE = CAN_ID_EXT;//标准帧)情况下才有效  F- M/ a' V9 T+ y6 X5 R
  114.   TxMessage.RTR = CAN_RTR_DATA;//数据帧
    # q/ z1 ~3 J, k" C* C& P
  115.   TxMessage.IDE = CAN_ID_STD;//标准帧 - J  w. r8 y$ O: F, \  T
  116.   TxMessage.DLC = 8;//发送数据长度  DLC=0-8
    0 x$ \5 M0 u. g* j# F
  117. }4 b% w$ t4 Y& z; `4 p# {
  118. //************************************************************************************************************************************************4 J" A6 `' b4 u+ _! L
  119. //函数名:void Init_RxMes(CanRxMsg *RxMessage)
    * P* {4 f+ V+ U& C2 }: i7 l
  120. //功  能:  Initializes the Rx Message" H8 t* V1 ]' E1 u8 n& {
  121. //参  数:无
    4 k! i; h0 B; y/ W9 `% ~
  122. //返回值:无
    3 V2 ]" v6 o! l/ m
  123. //************************************************************************************************************************************************" h$ W4 @! M; Y  T* N: s
  124. void Init_RxMes()
    * U9 q+ P, o6 B0 }$ \4 p/ N% |
  125. {8 g+ b, R5 ]% [/ n! d
  126.   u8 i = 0;
    4 R/ E$ s) f7 B- H; a
  127.   RxMessage.StdId = 0x00;//这个可以在接收中断中判断 如果RxMessage->StdId = TxMessage.StdId 接收正确
    3 n) z* c  |0 ?7 K" p
  128.   RxMessage.ExtId = 0x00;//这个可以在接收中断中判断 如果RxMessage->ExtId = TxMessage.ExtId 接收正确
    6 E( C2 C: u+ f- W. Z
  129.   RxMessage.IDE = CAN_ID_STD;//这个可以在接收中断中判断 如果RxMessage->IDE = TxMessage.IDE 接收正确
    2 M1 W7 e2 p1 B  \. q% N0 w+ G5 v
  130.   RxMessage.DLC = 8;//接收数据长度
    : E) T) }7 z+ z/ ^! M* I3 b
  131.   RxMessage.FMI =16;//????????????????
    , G0 G) V# z4 t# Y2 s  y

  132. & u9 B) D" ]5 I" {  e% i5 D" n2 m/ L; Q
  133.   for (i = 0;i < 8;i++)
    ) `- p4 w1 e' J: ^
  134.   {
    : @: e: Y! l1 ]6 `
  135.     RxMessage.Data<i> = 0x00;</i>" v9 d! D! k0 P% g! @7 O
  136.   }) T6 Q. Q6 _" u/ C. [: }
  137. }  C4 m+ N) A% B' p
  138. //************************************************************************************************************************************************
    2 r$ l2 G$ a  \: i
  139. //函数名:void CAN1_RX0_IRQHandler()
    7 I1 o6 X& c5 F( T' D
  140. //功  能:  CAN1-RX0接收中断服务函数
    6 A* [) |! N  o, A- v
  141. //参  数:无
    % n5 h0 a: f% w
  142. //返回值:无
    8 c- S% \6 y" C3 l% A
  143. //************************************************************************************************************************************************
    " q& j3 S9 d8 ^! b
  144. void CAN1_RX0_IRQHandler()  //与CAN1_RX1_IRQHandler()区别
    2 M. M: [3 Q5 ~6 X5 C8 a9 O
  145. {
    % i4 l5 P, a" G
  146.   if(CAN_GetITStatus(CAN1,CAN_IT_FMP0)!= RESET)//判断是否发生CAN-R0中断
    4 p8 T) r' Z" d+ d2 E& }- K
  147.   {
    5 _" f# G3 _& C0 A
  148.     CAN_ClearITPendingBit(CAN1,CAN_IT_FMP0);//清除中断标志( q) }6 W9 Y! k3 D4 r( }! A
  149.     if(CAN_MessagePending(CAN1,CAN_FIFO0)!=0)//接收到数据
    5 }, u$ f/ O  H; W* [- `
  150.        CAN_Receive(CAN1,CAN_Filter_FIFO0,&RxMessage);//接收数据最大只能8字节' h) H% S' C/ c0 R( z4 R
  151.   }: w6 b, {5 S; ?0 k+ F! q* L9 C
  152.   Usart_Send_Buff(RxMessage.Data,8);//发送数据RS232通信   
    6 p1 L5 V, M/ B0 B+ ]* M% e
  153. }
    6 O* @. z# {: G$ w9 j5 ^& d
  154. //************************************************************************************************************************************************
    # ~; B+ z' L8 \2 Z
  155. //函数名:u8 CAN_SendData()
    - z- u5 |8 m  b! k! R
  156. //功  能:  CAN发送数据  发送第二步
    * _7 A, |3 k; v0 y
  157. //参  数:Msg数据指针;Length数据长度* v/ [' m3 k  L/ _  j' p
  158. //返回值:返回成功/失败标志1 f+ y! o$ ^/ ~& e
  159. //************************************************************************************************************************************************" P& U5 \. Y/ k1 x' S1 b: v
  160. u8 CAN_SendData(u8* Msg,u8 Length)
    4 I) c7 ?9 b" J: p3 D4 b+ T2 K+ m
  161. {
    9 K! ^9 R) e7 z+ G* x% f! C9 a
  162.   u16 i=0;
    2 i4 ~4 S+ P3 w; [
  163.   u8 mbox=0x00; : \6 W" X+ E9 T" L+ d% t5 _
  164.   TxMessage.DLC = Length;//发送数据长度  DLC=0-80 P4 e' o8 j  J+ y! \$ l* J
  165.   for(i=0;i<Length;i++)
    & |* B, g9 J# M" v3 _  l0 y
  166.   {% \5 K7 J- ?& f0 U& b" ]
  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;">;
    + S, A) `. j7 T" j0 l
  168.   }  q5 u% V5 y$ P3 B
  169.   mbox=CAN_Transmit(CAN1,&TxMessage);//发送数据  返回邮箱使用数量/ H$ U6 ?8 o5 ~! f$ T8 B6 I, H
  170. , v7 H% x7 K7 A6 V% B
  171. //  while((CAN_TransmitStatus(CAN1,mbox)!=CAN_TxStatus_Ok)&&(i<0xfff))6 c1 q; H2 y( n4 U0 m7 e) n$ j
  172. //  {
    # S2 g2 s  Z0 t1 ?; G
  173. //    i++;" }) R; h5 P: R' J
  174. //  }9 E' V& ~- w5 Y; e" f
  175. //  if(i>=0xfff)
    & M. c* X7 h0 o: ^( s; B' G
  176. //  {
    6 P% a) B$ g! k; m% M
  177. //    return 0;//发送数据失败* {( v8 W# Q# i* V0 H8 F9 w
  178. //  }
    ' N8 a9 ^* |! E0 {
  179. //  return 1;//发送数据成功
    1 [2 U5 q8 X+ E3 L6 ?
  180. }
    # X) O$ F- [& a$ N* B0 i. K; s
  181. //************************************************************************************************************************************************
    . d9 N% C2 {4 H$ Z
  182. //函数名:void CAN_SendDataProces(u8* data,u8 Num)
    # [$ r% q7 W; y7 D
  183. //功  能:CAN发送数据前期处理   发送第一步6 Z3 g2 S% i! H  \
  184. //参  数:data数据指针;Num数据长度- ~+ h' S+ D6 ?1 I% {5 U
  185. //返回值:无
    - b/ T- ~$ H" M5 {2 ~- H
  186. //************************************************************************************************************************************************9 E  C* z" q& N9 V0 Z- Q
  187. void CAN_SendDataProces(u8* data,u8 Num)
    $ s# k& x- l6 R* K! K% c/ J  ]
  188. {
    " x, O% o+ J6 Q" M4 ]
  189.   u8 flag=0x00,i=0;
    % ]( Q) n. _9 n! G; ?, ?( V  O) i
  190.   u8 Count=0x00,Left=0x00;
    8 \8 k% J, n' K4 I9 L5 v( Q% G

  191. 2 B. W/ G, I% O5 J2 G
  192.   Count=Num/8;//求多少个8字节倍数! Y* k& _% x& a* a8 j
  193.   Left=Num%8;//剩余小于8字节的数量
    # y$ }' c6 n' V0 B% {4 b, S4 q
  194.   for(i=0;i<Count;i++)6 b( V$ [" L) R1 N0 }& ~
  195.   {) l0 P7 v  u! e  A( T% P) }0 I
  196.     flag=CAN_SendData((data+i*8),8);//发送整8字节的数据0 y9 R! u# P! [( q" E
  197.   }
    ; B* ~9 l' |4 k0 r' i6 \& J! ^0 e
  198.   if(Left>0)//有余数才单独再发送一次& F( k, h! N. a+ C  d$ D, V# M2 |
  199.   {! ]/ i+ [# |. I6 H
  200.     flag=CAN_SendData((data+8*Count),Left);//发送剩余字节8 U3 z- m3 K% Z( [3 ^
  201.   }
    * @, o+ R6 O5 A
  202. }
    * \- x! U2 K4 p
  203. //************************************************************************************************************************************************" b0 Z: ]  }2 l0 @
  204. </span>& H' ^) z1 }% h# k' t/ e) C* t; S
  205. </span></span>
复制代码

5 g( P' G4 E0 T7 O8 J$ _
收藏 评论0 发布时间:2021-12-1 22:18

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版