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

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

[复制链接]
STMCU小助手 发布时间:2021-12-1 22:18
STM32F2-CAN通信-发送任意长度,调试好的,与大家分享- {. a$ \& X4 k9 v& y9 S- Q
/ C/ ]( e% X8 x( h; M8 o
  1. #include "include.h"7 W! `; W& }" P  x" }
  2. //************************************************************************************************************************************************1 P7 f# a( a+ f" w5 m
  3. //20190611调试完成
    + V8 L  W5 _, X: S. M
  4. //By Wang
    % E( Y8 [" O% r$ A& [& @: j
  5. //************************************************************************************************************************************************, d- V; x& w( R3 A

  6. ' Z) B! {5 C$ G. `$ e: _' O  B
  7. CanRxMsg RxMessage;# N' w6 i2 G# Q3 t
  8. CanTxMsg TxMessage;
    ! V4 O2 G: t* E, }0 ~& L
  9. //************************************************************************************************************************************************
    8 l; c; o6 F! n. j4 r! h
  10. //函数名:void NVIC_Config(void)
    . W4 g& B! }7 g1 Q: Y
  11. //功  能:  CAN通信接收RX0中断配置/ M7 D0 Q; @- ^% M  p$ \/ ?3 e3 a
  12. //参  数:无
    2 w! b+ O# f0 W% \" i- D) U
  13. //返回值:无& b* r* g6 T3 v1 r; V
  14. //************************************************************************************************************************************************
      J$ U: Z' G9 o
  15. 6 [0 x0 e6 `# F% h/ @
  16. void NVIC_Config(void)
    % k$ f  L2 b9 Y3 e/ ^6 L. H( l
  17. {! M. b" Y6 ]7 }1 X6 X/ ^3 F( d
  18.   NVIC_InitTypeDef  NVIC_InitStructure;
    0 a  R% f  I' P3 C$ Y
  19. + K4 [) O8 }$ f3 O
  20. //#ifdef  USE_CAN1
    0 r% ?' m) y9 n

  21. 5 T8 V1 _$ g8 d6 R5 K: j$ `
  22.   NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;//与CAN1_RX1_IRQn;区别
    3 P$ T6 a- {: p( n1 P0 J
  23.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//不同的中断优先级一样会怎样0 O8 ^  k& C( G0 G) }6 T( f, v
  24.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
    * B+ A& Q% A! \; l4 X
  25. 2 g! \# r. n( D) y$ r; {8 N
  26.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    ( S$ Q# H) ?, o; g9 H1 ~
  27.   NVIC_Init(&NVIC_InitStructure);3 i9 X0 R, [& k/ z4 p, v

  28. : \( v/ I# \$ \
  29. }
      t- b$ l/ F/ _% t& w: x

  30. . q" R# y8 a/ A# t1 [
  31. //************************************************************************************************************************************************
      w! O4 z4 R4 U# k4 p2 o
  32. //函数名:void CAN_Config(void), x5 r5 r& Y( ~  n# {
  33. //功  能:  CAN1配置 PD0-RX;PD1-TX
    7 p% P) L1 y4 X+ }, |1 _
  34. //参  数:无% }2 Q+ [4 E) b4 I
  35. //返回值;无
    + Q' L  z" U5 V1 h2 T, Q
  36. //************************************************************************************************************************************************
    & }. ^: u3 D9 Z& j/ Z; t& n& z* k/ A
  37. void CAN_Config(void): s/ G' f4 ]# f0 Y1 U1 q: _( h1 X
  38. {4 i. Q4 `: B9 R# x7 ?
  39.   GPIO_InitTypeDef GPIO_InitStructure;; s( V( F3 M$ @) Q5 z
  40.   CAN_InitTypeDef CAN_InitStructure;6 ?4 v/ I" |/ Z( j
  41.   CAN_FilterInitTypeDef CAN_FilterInitStructure;
    . `4 c+ A- f) @. H& D

  42. 1 M% m; Y+ n+ p  l. R
  43.   /* CAN GPIOs configuration ***********************************/
    & s, |! G3 S: A; D: V
  44.   /* Enable GPIOD clock */" M+ [: U$ u- x1 o) w8 P
  45.   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
    . b: u1 K: s3 R) J9 h
  46. - p* V5 \( k' |/ O
  47.   /* Connect PD1 to CAN1_Tx pin */1 c$ P- T/ [* e- g6 H
  48.   GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1);4 H0 |1 n; U$ B, G4 G- f0 i
  49.   /* Connect PD0 to CAN1_Rx pin *// M2 r! H2 ]/ B$ I, F2 X9 e& `! ]
  50.   GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1);6 I) D/ g. j4 e/ o

  51. ; Z8 m' q4 J% A% g; Q6 p+ E
  52.   /* Configure CAN1_Rx(PD0) and CAN1_Tx(PD1) pins */  u( Y, H, D. I+ Y
  53.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    ) D- g6 \% V! j0 I# O' `5 ?
  54.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    ' A5 b# M! \/ A1 y1 H: b$ M" S- l# w
  55.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    $ |" S( X  y: e( s+ d8 K* e
  56.   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;- z, F1 m! y- H: u) w9 q
  57.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;: V) Y* O/ m! u6 _, P
  58.   GPIO_Init(GPIOD, &GPIO_InitStructure);
    " ^5 P* |) I- U7 b
  59. 6 ~. ]% @" a  I  M! }8 J% ?
  60.    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//Rx要单独初始化,否则进入不了中断,不能按照ST官方库来设定; [$ ~. d6 q# C4 D& v3 _) n
  61.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    . I* Y0 T& J) U! ^- a
  62.    GPIO_Init(GPIOD, &GPIO_InitStructure);/ O( V8 B/ N- q, f8 \
  63.   /* CAN configuration *****************************************/8 j# i; [; h/ ]; z# l0 y* F
  64.     /* Enable CAN1 clock */
    ( {! y9 j( {" F" E$ K9 l! P7 W) I
  65.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);$ g5 O$ c$ A) {% _% w. m5 Y6 p" v& x
  66. : n+ K( {: Z; S( Q+ L* @$ _
  67.   /* CAN register init */
    - u8 R4 P% @& f: P5 T
  68.   CAN_DeInit(CAN1);* k5 R/ O* u% p! _
  69.   /* CAN cell init */0 Q7 J* e8 y4 m2 P; D' G0 Z& P  _1 o
  70.   CAN_InitStructure.CAN_TTCM = DISABLE;
    . h) G" y5 U: f2 z
  71.   CAN_InitStructure.CAN_ABOM = DISABLE;1 ^2 m; A7 ^0 V+ G8 B" f
  72.   CAN_InitStructure.CAN_AWUM = DISABLE;
    - P* B$ W7 ~8 h/ ~% D
  73.   CAN_InitStructure.CAN_NART = DISABLE;+ F) @! B5 U5 f3 i; m5 e
  74.   CAN_InitStructure.CAN_RFLM = DISABLE;
    % d, y+ H1 N% i+ \) B
  75.   CAN_InitStructure.CAN_TXFP = DISABLE;
      R: j, Z* s( `
  76.   CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
    3 N; U9 E6 m5 S+ W" P
  77.   CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
    $ Y& ?+ Z# I: b
  78.   /* CAN Baudrate = 1MBps (CAN clocked at 30 MHz) */ //30/(1+6+8)/4=500k
    5 e8 o: x0 j, |9 M" m) p+ {8 r% K3 a" h
  79.   CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
    - Y9 u  o$ @) E
  80.   CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
    - P7 B" L( O/ f, ~) q  D; R# i* o; H% l
  81.   CAN_InitStructure.CAN_Prescaler = 4;" \2 I* f: b$ m) E% p
  82.   CAN_Init(CAN1, &CAN_InitStructure);
      s! ^5 q* h, c; Y
  83. 7 [" [& o2 V2 A" z% m2 Q
  84.   /* CAN filter init */7 r6 g2 f& |  B
  85.   CAN_FilterInitStructure.CAN_FilterNumber = 0;; l( }. X& Z3 P
  86.   CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
    4 u+ w8 {  t4 X5 L$ |% R5 u
  87.   CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;2 ^, r! F; }+ S4 s! x7 v. r& |
  88.   CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;2 u! {# \/ P2 n1 m
  89.   CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;6 z: X6 z; W% {5 T& {8 ?+ V
  90.   CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
    # G% U6 K% k8 f
  91.   CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;% n9 Q/ a0 `4 y3 G' t" q
  92.   CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;" D% y# O6 D6 m' s
  93.   CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
    6 U& o* |' n3 G9 L& ^
  94.   CAN_FilterInit(&CAN_FilterInitStructure);
    7 ?4 k, @6 X! f( y0 |. L- A7 g; ]# Q' G

  95. , h+ s7 N% V# h: m
  96.   /* Enable FIFO 0 message pending Interrupt */  - q9 g8 C9 F1 G! r
  97.   Init_TxMes();//发送结构体参数初始化
    0 ~1 q* F' ?3 L) g
  98.   Init_RxMes();//接收结构体参数初始化/ k& O9 i; v( g2 K3 C
  99.   NVIC_Config();//中断向量配置# z2 ^. P* V+ U3 y$ n; O9 d0 z
  100.   CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);& [6 H* o; ]7 H) B
  101. ( l+ `! r9 @. E& f" Q) W
  102. }
    4 i6 d  u9 Y' c  m
  103. //************************************************************************************************************************************************
    1 F+ M* f) q) K  N  c
  104. //函数名:void Init_TxMes(CanRxMsg *RxMessage)8 ^3 d3 ~# z0 o* ^, R4 E8 c
  105. //功  能:  Initializes the Tx Message$ e7 H+ G, k8 I- T4 @6 l# _. K
  106. //参  数:无
    - y( y& n, w" D. N
  107. //返回值:无+ y# `$ n6 Q) x* K4 u
  108. //************************************************************************************************************************************************
    , R) j! @' y. h. \  _/ p
  109. void Init_TxMes()
    4 x! L0 A$ c/ ?4 t0 b1 `6 s; H' W8 r
  110. {/ d4 u* _& J$ v: {4 I2 v
  111.     /* Transmit Structure preparation */$ L% w, L) s6 G4 x1 k
  112.   TxMessage.StdId = 0x123;//标准标识符,必须在( TxMessage.IDE = CAN_ID_STD;//标准帧)情况下才有效6 _/ r- Q7 E' I
  113.   TxMessage.ExtId = 0x00;//设置拓展标识符(29位),必须在( TxMessage.IDE = CAN_ID_EXT;//标准帧)情况下才有效* }0 T1 y3 d9 Z# S7 d. q' V3 e
  114.   TxMessage.RTR = CAN_RTR_DATA;//数据帧
      [( j( w0 w4 T1 N7 n
  115.   TxMessage.IDE = CAN_ID_STD;//标准帧 $ P) ?) U( G2 v7 Q8 v
  116.   TxMessage.DLC = 8;//发送数据长度  DLC=0-8
      X% Y+ h7 q( v4 O! }" E) S! q
  117. }
      v, k3 H( ?  r$ k1 Q0 F2 U
  118. //************************************************************************************************************************************************
    ) x% W7 f& h. q5 V' v
  119. //函数名:void Init_RxMes(CanRxMsg *RxMessage)6 P; d# U' U4 U7 _' c3 b
  120. //功  能:  Initializes the Rx Message$ q, e9 M# r" b$ G. }4 H6 J* m2 {
  121. //参  数:无
    $ P* X8 o: D) P3 o
  122. //返回值:无
    1 \# ~1 |1 o- X, [/ E
  123. //************************************************************************************************************************************************, P, A) F+ k  l. b; A
  124. void Init_RxMes()% D6 o, i  h8 `; N, X
  125. {
    2 J. N' \% b# P/ z7 Z0 [2 T
  126.   u8 i = 0;
    ; r, @/ k; s) n) H6 G
  127.   RxMessage.StdId = 0x00;//这个可以在接收中断中判断 如果RxMessage->StdId = TxMessage.StdId 接收正确
    5 N3 [$ U% C0 o- [9 G. d
  128.   RxMessage.ExtId = 0x00;//这个可以在接收中断中判断 如果RxMessage->ExtId = TxMessage.ExtId 接收正确 3 k; |, x% L& y+ n$ p6 k
  129.   RxMessage.IDE = CAN_ID_STD;//这个可以在接收中断中判断 如果RxMessage->IDE = TxMessage.IDE 接收正确 0 H( r# ^  e- c2 B3 D
  130.   RxMessage.DLC = 8;//接收数据长度4 A, J  Y; l3 r, Y" g
  131.   RxMessage.FMI =16;//????????????????
    2 m" k) [8 a, Q7 a. d
  132. 4 j2 ]1 C2 |+ E- Q( z& G( n/ c: \
  133.   for (i = 0;i < 8;i++)
    ( O' {* L# X* N8 R2 ^, Q
  134.   {
    4 J1 F. P& o, I. S, b8 x0 V
  135.     RxMessage.Data<i> = 0x00;</i>, `. ~; B' e, {: ?. ^0 c' f
  136.   }
    5 [! Z4 d$ f; X
  137. }
    9 Q7 b- V0 J* C0 [. Z$ G, Z
  138. //************************************************************************************************************************************************/ E" E( k/ O+ h
  139. //函数名:void CAN1_RX0_IRQHandler(): t0 C5 ^  w. M& h* b
  140. //功  能:  CAN1-RX0接收中断服务函数8 ]- o* J+ y3 ^2 R. w/ c% }
  141. //参  数:无1 b$ N( P( K! ]8 `$ p6 B" `/ ~
  142. //返回值:无+ q5 A  `% C1 j0 r2 i% }& U; g
  143. //************************************************************************************************************************************************3 }+ s- A; \: ]6 \' q2 n
  144. void CAN1_RX0_IRQHandler()  //与CAN1_RX1_IRQHandler()区别
    & A! g* H% ]2 p4 `& x' q! C" L
  145. {
    ' B3 R) h$ L( [/ V
  146.   if(CAN_GetITStatus(CAN1,CAN_IT_FMP0)!= RESET)//判断是否发生CAN-R0中断
    4 h; X; I4 ]( E  Q9 v7 b, W) z
  147.   {* z  B9 T0 O+ K5 L
  148.     CAN_ClearITPendingBit(CAN1,CAN_IT_FMP0);//清除中断标志0 _9 Q& q$ C: i0 @8 f: x
  149.     if(CAN_MessagePending(CAN1,CAN_FIFO0)!=0)//接收到数据
    , D( Q" \/ P# s( J3 A( I) ~' ?
  150.        CAN_Receive(CAN1,CAN_Filter_FIFO0,&RxMessage);//接收数据最大只能8字节8 _( k/ l  W" p
  151.   }
    6 m) j9 K+ L7 F, G% j2 t
  152.   Usart_Send_Buff(RxMessage.Data,8);//发送数据RS232通信    * F/ I. @. v2 F  B5 |( Y2 h% s, R9 B
  153. }
    : E6 N! |; e& x+ P
  154. //************************************************************************************************************************************************
    " w6 h5 Q7 `. u' K4 K* M0 s+ C8 C! E6 x
  155. //函数名:u8 CAN_SendData()9 N. T$ }8 U* t' j+ w9 C9 T
  156. //功  能:  CAN发送数据  发送第二步
    ) W$ W! V+ p1 |/ A$ w7 e$ |1 a& g5 ^# v
  157. //参  数:Msg数据指针;Length数据长度
    8 H* Z$ V1 t2 k. r. s, [
  158. //返回值:返回成功/失败标志
    ' F' B: J2 C9 n& h( F: \1 R/ n
  159. //************************************************************************************************************************************************
    ( ^% u. O( f7 Z1 e
  160. u8 CAN_SendData(u8* Msg,u8 Length)
    : }" ?, n' H3 V0 {0 [8 J" j
  161. {
      r* }. \; |$ O2 E3 U
  162.   u16 i=0;* _( V; _3 H. I9 N7 c/ v
  163.   u8 mbox=0x00; # `. z. w3 q+ F9 {; L, s$ S
  164.   TxMessage.DLC = Length;//发送数据长度  DLC=0-8
    , F+ i5 G% C, X$ ]9 q2 F
  165.   for(i=0;i<Length;i++)
    3 S- g9 U. o" q6 f' Q! O
  166.   {
    5 w* ~9 M" Z/ _% m6 j+ \4 B) X) G
  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;">;! w4 ^( o, u2 \( Q' T3 ?
  168.   }! |4 {3 x% B; \& K+ K. h1 _  u4 y* m
  169.   mbox=CAN_Transmit(CAN1,&TxMessage);//发送数据  返回邮箱使用数量) Q, x3 T/ F+ A* E! d

  170. ( c' g. g4 D/ q4 M3 M! p
  171. //  while((CAN_TransmitStatus(CAN1,mbox)!=CAN_TxStatus_Ok)&&(i<0xfff))
    6 m6 X/ G/ k8 w
  172. //  {! |& x- p# \, G' g
  173. //    i++;  K% }/ D% ]. H# m
  174. //  }7 z7 C; h1 J  ~* a% ]
  175. //  if(i>=0xfff)
    3 z; c& B2 M: m- {. v4 b# P
  176. //  {4 j* G1 x' N7 S+ p9 o: g
  177. //    return 0;//发送数据失败6 o3 u1 i8 @! d5 v  o% h7 a$ b
  178. //  }% D7 |. o' Q! O0 k8 W( X% I( R
  179. //  return 1;//发送数据成功
    : l7 @8 m0 m2 J( f$ Z: r
  180. }
    " ~& L7 U) n2 G9 y& f* ?
  181. //************************************************************************************************************************************************
    8 B- ^  p9 j  X& O3 T
  182. //函数名:void CAN_SendDataProces(u8* data,u8 Num)# [& c" x9 e! V0 j0 ?4 M
  183. //功  能:CAN发送数据前期处理   发送第一步
      v4 j, r! z6 k; M% q& F1 _, v
  184. //参  数:data数据指针;Num数据长度
    : a% r' K: L! w" `' Z! ^
  185. //返回值:无
    " F9 [1 g' a, w# }3 ~6 x
  186. //************************************************************************************************************************************************! P& V7 k. [  e* p
  187. void CAN_SendDataProces(u8* data,u8 Num)
    , v1 [: Y- X+ S" v2 L4 }% M
  188. {- h6 b2 \+ c) @! Z
  189.   u8 flag=0x00,i=0;
    8 l1 q( R/ V) z" b/ j* L
  190.   u8 Count=0x00,Left=0x00;3 Q# M7 d9 A; {8 E

  191. 1 D+ `6 K9 _3 p- K
  192.   Count=Num/8;//求多少个8字节倍数
    2 u, p. u: s0 C
  193.   Left=Num%8;//剩余小于8字节的数量  \, I0 q9 Z2 Q- H; U
  194.   for(i=0;i<Count;i++)" F9 \' Y) j5 [. K
  195.   {8 O4 Q# T7 e3 j% l4 [$ T+ F) {* k
  196.     flag=CAN_SendData((data+i*8),8);//发送整8字节的数据! \$ S6 i$ c) X0 P
  197.   }
    + h2 O9 ]0 b5 p' w' r; n
  198.   if(Left>0)//有余数才单独再发送一次
    ! A  Z5 w: a* Y& I$ ?$ X! E
  199.   {2 l. y; Y2 Q  t
  200.     flag=CAN_SendData((data+8*Count),Left);//发送剩余字节& t+ b* J7 v3 ^0 T# k! B( E' B
  201.   }! U9 G9 u  u* P: V
  202. }0 u; j+ {2 a4 C1 y9 j5 M
  203. //************************************************************************************************************************************************
    3 \7 e& I. q% K0 S# B6 z1 c# v
  204. </span>" G% S3 O1 P) x  G, \2 Z- x# I
  205. </span></span>
复制代码
  D+ ^! g0 A/ `( W" P' L$ K
赞 收藏 评论0 发布时间:2021-12-1 22:18

举报

0个回答

所属标签

相似技术帖

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