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

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

[复制链接]
STMCU小助手 发布时间:2021-12-1 22:18
STM32F2-CAN通信-发送任意长度,调试好的,与大家分享. z9 c* p! ^5 J% a

+ |+ U: J7 ?9 ~4 z7 W
  1. #include "include.h") ^6 H  h' r0 I) e9 ]
  2. //************************************************************************************************************************************************) [$ A, C! A# y# B; }7 I
  3. //20190611调试完成
    8 f7 I9 D# v: H
  4. //By Wang7 r: o. R' M7 s  p: P4 b
  5. //************************************************************************************************************************************************* J+ I# }( |2 a; c, S2 D
  6. ! o1 \) A& L4 r0 ?' o5 \
  7. CanRxMsg RxMessage;2 \0 p; e, ]( {5 E% c
  8. CanTxMsg TxMessage;
    # X' S3 |. _6 z& K, i5 U/ g
  9. //************************************************************************************************************************************************
    # E% X% Z/ e/ M. h
  10. //函数名:void NVIC_Config(void)  V7 g- z/ K: b+ B5 Y
  11. //功  能:  CAN通信接收RX0中断配置/ k9 @: p  T- Z0 U1 i8 M) e
  12. //参  数:无# k+ N) X# H* u  H/ P7 d
  13. //返回值:无
    " p* g; _. ~7 Y. o, z8 r3 ~, H9 s
  14. //************************************************************************************************************************************************
    - g) J- t$ i5 A7 R3 Q8 K9 w

  15.   E2 v7 |- X# W1 L6 T  f4 i0 x
  16. void NVIC_Config(void)
    9 v4 G/ o5 j0 ~4 M* L
  17. {
    " K  i1 R' A% Y0 I
  18.   NVIC_InitTypeDef  NVIC_InitStructure;9 D+ S+ m3 D& F+ v0 p8 v; y
  19. . g4 x" c! l, v
  20. //#ifdef  USE_CAN1 + a- O4 g4 E* Z7 t0 X# V

  21. , F0 P1 L4 e, |" k8 D; O3 \# Y
  22.   NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;//与CAN1_RX1_IRQn;区别  E# o; V* |: E3 U4 f& V
  23.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//不同的中断优先级一样会怎样$ v+ [' |. J  M( p! [0 ~
  24.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
    ( S( V5 A' h2 L$ }
  25. : S6 ^8 N8 y2 z/ f( A2 g
  26.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;7 E6 }( L3 y8 {5 g1 a  T) r+ F9 s
  27.   NVIC_Init(&NVIC_InitStructure);
    # V$ ^; c) A- ^# r) R# @4 ~
  28. 7 _! c) _& p& K3 X* e
  29. }
    # m% Z1 h3 a8 F, z3 l

  30. ! _  E2 L6 t! w/ V# d
  31. //************************************************************************************************************************************************
    ; B& _( E  H, [( N
  32. //函数名:void CAN_Config(void)
    6 T* ^% F* G4 K2 p7 z4 |
  33. //功  能:  CAN1配置 PD0-RX;PD1-TX3 J3 f5 u1 G# O+ p: g
  34. //参  数:无) W& K: }# O  S
  35. //返回值;无
    - M/ u9 y9 c/ F1 @% w) m
  36. //************************************************************************************************************************************************9 o+ m5 [, @1 ?' W) o# J+ P4 C
  37. void CAN_Config(void)
    " e! q4 Z# n; k. V
  38. {" S' q7 {: U: f4 C3 E# H+ I
  39.   GPIO_InitTypeDef GPIO_InitStructure;  K% V+ u& @* o( Y3 ?
  40.   CAN_InitTypeDef CAN_InitStructure;2 l* b& T$ {. ~- E1 l
  41.   CAN_FilterInitTypeDef CAN_FilterInitStructure;  C0 t: x( k+ K. l& W" ?) t0 W
  42. 0 {* ]. l2 C( Z" P5 z' j/ T
  43.   /* CAN GPIOs configuration ***********************************/4 G2 {' I$ D5 |  N' H$ s
  44.   /* Enable GPIOD clock */
    2 F5 |: ]- X) {/ o
  45.   RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
    # D1 X0 Y; i3 x. N' p5 X' j( o. n

  46. , V# q& X. ?+ h5 C
  47.   /* Connect PD1 to CAN1_Tx pin */' c9 B( P7 X: j4 s% O# [' Q
  48.   GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1);/ _/ d; r3 r% f8 G
  49.   /* Connect PD0 to CAN1_Rx pin */* G! c$ W/ ]5 t  ]6 N4 _' s* l/ x; O
  50.   GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1);* T1 _  `+ n/ F5 g: T

  51. ! S7 p/ }' m' g8 a" A8 ^
  52.   /* Configure CAN1_Rx(PD0) and CAN1_Tx(PD1) pins */
      E. I% v! E  u; T
  53.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    / D7 c) ]% V' H  o9 z9 _
  54.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;. o: f2 k. a$ `" T
  55.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;+ W  }3 K% D- n2 W
  56.   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;% T% N* z4 T+ A+ M6 o% ]# i
  57.   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    8 Y1 x( }& p0 i+ `- N
  58.   GPIO_Init(GPIOD, &GPIO_InitStructure);# g+ u6 R! H9 [+ @
  59. # x- n! i* j0 u4 f
  60.    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//Rx要单独初始化,否则进入不了中断,不能按照ST官方库来设定
    7 p3 v8 r9 ]& b. }% `" Y
  61.    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;, {+ W6 K; a6 \2 X. G, Z+ `" @
  62.    GPIO_Init(GPIOD, &GPIO_InitStructure);1 g9 Q$ t. S- z% B$ r% g
  63.   /* CAN configuration *****************************************/' P& F! y& q* z" @
  64.     /* Enable CAN1 clock */
    : M% {9 z2 ?9 o% i( E9 d5 t
  65.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);% l; h6 H* h. z9 w4 P# Q

  66. - X2 S$ R; ?+ B# c
  67.   /* CAN register init */& f7 f; I7 @- @: Q7 A# G4 Y" K+ n
  68.   CAN_DeInit(CAN1);
    . H( r: j. G( ~0 z  I
  69.   /* CAN cell init */% f" d9 V( o3 Q
  70.   CAN_InitStructure.CAN_TTCM = DISABLE;
    5 P6 ?- y1 b# F: a( \3 D
  71.   CAN_InitStructure.CAN_ABOM = DISABLE;+ f7 L% J( \6 N8 r
  72.   CAN_InitStructure.CAN_AWUM = DISABLE;8 L. W: d( X7 F9 x
  73.   CAN_InitStructure.CAN_NART = DISABLE;
    4 F3 Q( k) t* [
  74.   CAN_InitStructure.CAN_RFLM = DISABLE;
    0 m) ]1 B+ M4 t4 f
  75.   CAN_InitStructure.CAN_TXFP = DISABLE;
    - t$ B- u, q% ?% E% K
  76.   CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;7 a% [% o) H5 x
  77.   CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
    + \- U$ y& w7 g& ?# N! ]+ P
  78.   /* CAN Baudrate = 1MBps (CAN clocked at 30 MHz) */ //30/(1+6+8)/4=500k  b8 x- t3 ?6 V) f  Q. T, N
  79.   CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
    & j2 Q9 {# W4 ?( H! U! A
  80.   CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
    6 o4 t0 Z8 ^0 H
  81.   CAN_InitStructure.CAN_Prescaler = 4;) G! Y' V) ^5 {* j  u% w
  82.   CAN_Init(CAN1, &CAN_InitStructure);% F& o" I; n0 i- |; T

  83. - |' h  S4 V; S4 y+ p
  84.   /* CAN filter init */
    6 E& f2 }& y6 a! m& U
  85.   CAN_FilterInitStructure.CAN_FilterNumber = 0;$ s9 P' e' v: @1 N. j  ]  Y& q
  86.   CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;6 W. Z9 d) z6 B* J; x! ?/ A) w- |3 N
  87.   CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
    $ f: i5 u6 y; p* D- W5 Y1 o. [
  88.   CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
    1 S8 }$ M! h* C' n" e- P/ R
  89.   CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
    $ s0 C1 T0 A/ Z2 ^! F% F
  90.   CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
    ! S  t1 }3 c* w" q( A$ a. n" m
  91.   CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;1 x1 s/ @! z( j2 i& U
  92.   CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;3 ^8 D" j& a" N. ^6 V8 t3 d; e8 Y+ X
  93.   CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;! I& C& y: R8 i* Q
  94.   CAN_FilterInit(&CAN_FilterInitStructure);
    ' ]0 T4 m+ `5 m3 G3 I. z

  95. + F+ R0 \8 t" S6 l8 \" W  o
  96.   /* Enable FIFO 0 message pending Interrupt */  7 o# u  v- N9 i1 V+ Z* r; W
  97.   Init_TxMes();//发送结构体参数初始化  M0 }( F2 d' Z7 d( R8 {: M
  98.   Init_RxMes();//接收结构体参数初始化
    6 Y8 Z4 S2 T/ P5 n- `6 `/ l6 {
  99.   NVIC_Config();//中断向量配置& v7 O/ G/ w# J/ ?
  100.   CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
    . b" e0 b$ H% b9 K2 a5 K& e% J7 [" |

  101. $ i" T( R" D# J# N; }, M) {& m' Y
  102. }) o1 R' {' t4 z. H& x. s# e! y
  103. //************************************************************************************************************************************************
    ) J$ }+ k$ `9 j, J0 _$ j' s* G
  104. //函数名:void Init_TxMes(CanRxMsg *RxMessage)7 R0 R/ B9 D# X7 E$ F! t, h! T
  105. //功  能:  Initializes the Tx Message
    , @- M- _: S: J( c4 s
  106. //参  数:无
    # X$ y1 I& e6 C- b+ \$ }7 A% }
  107. //返回值:无
    + i( G/ C: {/ P) Q2 e9 e
  108. //************************************************************************************************************************************************2 Z# b# f. _# i( y" [
  109. void Init_TxMes()
    8 A+ c. \4 D; p
  110. {% D9 ~  S3 s) X) S/ r
  111.     /* Transmit Structure preparation */9 J& N4 i  T/ [
  112.   TxMessage.StdId = 0x123;//标准标识符,必须在( TxMessage.IDE = CAN_ID_STD;//标准帧)情况下才有效) r8 D) m' U1 d; X* y# T9 h9 P
  113.   TxMessage.ExtId = 0x00;//设置拓展标识符(29位),必须在( TxMessage.IDE = CAN_ID_EXT;//标准帧)情况下才有效
    9 Y  T4 l. q4 B: Z, q# l5 K
  114.   TxMessage.RTR = CAN_RTR_DATA;//数据帧+ _! A* {. S* C4 l
  115.   TxMessage.IDE = CAN_ID_STD;//标准帧
    2 a+ Y' x# z9 B5 n. K% Z, O& U
  116.   TxMessage.DLC = 8;//发送数据长度  DLC=0-8
    - t2 v2 P1 i* S% U
  117. }$ C0 ^" s7 _; S5 P  Q. r
  118. //************************************************************************************************************************************************+ M" P/ Z# ^4 L! l# t( z* k6 t5 a
  119. //函数名:void Init_RxMes(CanRxMsg *RxMessage)( ]; V5 u% O! X' [# K4 L
  120. //功  能:  Initializes the Rx Message
    5 s: `+ H4 |, s8 t& N; G
  121. //参  数:无
    + m/ X3 |: t. s- w( @
  122. //返回值:无: E5 Y6 z) S( v' v( I* x8 ?
  123. //************************************************************************************************************************************************* V5 ^% N" B$ A6 P- k
  124. void Init_RxMes()
    1 H6 f( f* s4 a6 w0 M9 c+ V
  125. {7 y5 m+ [; j8 p  a- Q
  126.   u8 i = 0;' b9 C+ e4 c! X* Y+ C# x4 m5 ^; S; s
  127.   RxMessage.StdId = 0x00;//这个可以在接收中断中判断 如果RxMessage->StdId = TxMessage.StdId 接收正确
    $ J7 {' T" ]: q% P
  128.   RxMessage.ExtId = 0x00;//这个可以在接收中断中判断 如果RxMessage->ExtId = TxMessage.ExtId 接收正确 / `5 j% W% @" R9 ?
  129.   RxMessage.IDE = CAN_ID_STD;//这个可以在接收中断中判断 如果RxMessage->IDE = TxMessage.IDE 接收正确
    7 w9 Q$ k$ T+ x) V. ?+ i4 {
  130.   RxMessage.DLC = 8;//接收数据长度
    2 G4 C& \* A4 K" l: B
  131.   RxMessage.FMI =16;//????????????????; W! f) W3 s5 X# p8 L
  132. ' H4 P+ t; g" E6 z4 p4 Z* z2 M
  133.   for (i = 0;i < 8;i++)' K- U! z1 _) a6 [
  134.   {
    5 f( B1 E2 ~( D4 _9 h' ^
  135.     RxMessage.Data<i> = 0x00;</i>/ K" y% e& ~' `5 i8 j) J
  136.   }
    & ?+ G! i, ~5 Y! f3 I
  137. }3 H1 W$ w1 a* P4 F( b
  138. //************************************************************************************************************************************************
    ! u0 K" O0 T+ T" I
  139. //函数名:void CAN1_RX0_IRQHandler()% q* E8 S8 |6 }
  140. //功  能:  CAN1-RX0接收中断服务函数
    ! o. B/ `+ w0 u; x1 b
  141. //参  数:无
    2 R- j, Q3 f' R
  142. //返回值:无
    , l% u- @9 v) o
  143. //************************************************************************************************************************************************
    1 [1 w9 N  @' r
  144. void CAN1_RX0_IRQHandler()  //与CAN1_RX1_IRQHandler()区别
    3 J5 [2 O5 M9 e3 G
  145. {
    $ l' @" [5 C- j* [
  146.   if(CAN_GetITStatus(CAN1,CAN_IT_FMP0)!= RESET)//判断是否发生CAN-R0中断
    & |4 V0 F) [7 B$ y' J# O
  147.   {! \0 X: x5 K9 Y7 {
  148.     CAN_ClearITPendingBit(CAN1,CAN_IT_FMP0);//清除中断标志
    7 ], `8 x& \  r* z0 x! G
  149.     if(CAN_MessagePending(CAN1,CAN_FIFO0)!=0)//接收到数据; S: N1 T2 L6 u' r
  150.        CAN_Receive(CAN1,CAN_Filter_FIFO0,&RxMessage);//接收数据最大只能8字节( \7 d% d% s; ?  V- V& w% N
  151.   }
    % @) K; l6 {$ g, m+ P" x
  152.   Usart_Send_Buff(RxMessage.Data,8);//发送数据RS232通信   
    8 x  A9 |4 U, D8 g, g
  153. }6 ^. @2 Q+ o! k: i3 h
  154. //************************************************************************************************************************************************0 J7 M# F6 c% m* B- o2 @8 Q
  155. //函数名:u8 CAN_SendData()
    * e( G9 o8 d+ q; q$ h9 h: g2 c# M
  156. //功  能:  CAN发送数据  发送第二步
    6 m" v( Y; o6 L/ d1 x1 n
  157. //参  数:Msg数据指针;Length数据长度% |  F+ n" g" k- [8 I( t! y& y  s
  158. //返回值:返回成功/失败标志- _8 y( v! E  N6 x6 g8 ^
  159. //************************************************************************************************************************************************7 H$ D3 D5 T7 g0 D# S+ Z
  160. u8 CAN_SendData(u8* Msg,u8 Length)
      l: B1 E4 S, H) P( ^3 l
  161. {
    7 u' h6 m: J. p$ U3 Z; F
  162.   u16 i=0;
    8 F/ l% q( f& v% F
  163.   u8 mbox=0x00;
    7 i' |& ^+ e$ v3 }  n2 n9 i4 J
  164.   TxMessage.DLC = Length;//发送数据长度  DLC=0-8
    # e' w8 \6 u$ [: u9 b6 u3 S8 ~5 Q+ h
  165.   for(i=0;i<Length;i++)
    * N( Z9 ^6 i4 _. m
  166.   {) A# }1 \" E# ~$ ]2 Z
  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;">;# |; V3 b; T1 Y0 L9 Y
  168.   }
    % o7 p1 S: H/ e" b
  169.   mbox=CAN_Transmit(CAN1,&TxMessage);//发送数据  返回邮箱使用数量
    % `- U9 s' `  j9 W8 u  m4 }

  170.   i  V$ D4 w% A/ \5 \
  171. //  while((CAN_TransmitStatus(CAN1,mbox)!=CAN_TxStatus_Ok)&&(i<0xfff))
    3 F$ h" }2 _" \3 a' G
  172. //  {$ N, b' {9 o$ j5 `" c
  173. //    i++;; b& p. ~$ ?5 s8 m" h
  174. //  }: Z8 k- F- b8 m
  175. //  if(i>=0xfff) $ S  k, S( T' F7 a- G6 m# D
  176. //  {7 n* Q- {# C7 }/ J0 G5 [$ w
  177. //    return 0;//发送数据失败2 C4 G& V! C: m( A
  178. //  }
    ; R9 N/ X( e# f) U
  179. //  return 1;//发送数据成功3 i: R! F1 A/ Z$ h4 G$ \
  180. }
    & t2 i1 w" P0 z3 U% Z8 h; j7 a
  181. //************************************************************************************************************************************************
    : H/ }0 ?8 }& }! A0 ^3 }! T3 U' y7 q, ^
  182. //函数名:void CAN_SendDataProces(u8* data,u8 Num)
    5 |0 ~+ g+ _- J' e% j" _
  183. //功  能:CAN发送数据前期处理   发送第一步
      Y$ `% g% o  t+ ]1 o
  184. //参  数:data数据指针;Num数据长度3 X5 M" y- M9 s0 D) W. k7 X1 Y% H
  185. //返回值:无/ k' Y  V' o1 J, \3 Y5 T
  186. //************************************************************************************************************************************************1 p( b4 e' M+ i8 @8 \7 f) b" ?8 I
  187. void CAN_SendDataProces(u8* data,u8 Num)
    ( q2 f7 Y0 A5 t2 ^2 g7 N
  188. {" j: s" ]1 i, v8 ~
  189.   u8 flag=0x00,i=0;
    : j" @; B( Q  t" u) v$ `
  190.   u8 Count=0x00,Left=0x00;9 D6 Z% b! d0 l/ Q# d
  191. : z' _  }" g9 Z1 @) `8 Q
  192.   Count=Num/8;//求多少个8字节倍数
    / Z; V' c) s+ V2 M) _+ U6 L
  193.   Left=Num%8;//剩余小于8字节的数量
    4 K* f+ L5 w( z0 t0 _2 G
  194.   for(i=0;i<Count;i++)* l4 S# q: ]" t0 Z' b$ E1 w
  195.   {
    " N! d! G/ o/ o/ E- \2 F
  196.     flag=CAN_SendData((data+i*8),8);//发送整8字节的数据
    6 F& [: `" U" P/ I; v* e
  197.   } " @2 P* Q. n. A0 B
  198.   if(Left>0)//有余数才单独再发送一次
    ' Z% p! F+ D; p8 T/ D# E2 H
  199.   {! M* Y0 ~; G8 T0 i: M% R6 R" r
  200.     flag=CAN_SendData((data+8*Count),Left);//发送剩余字节
    # K2 l9 r3 D+ l1 G/ z
  201.   }, D9 g" I0 f* [# n8 u  n1 f
  202. }6 }  [1 V6 z5 z0 m
  203. //************************************************************************************************************************************************
    3 B4 F3 k0 L  ~, l0 z* P3 c# K
  204. </span>
    + t/ a8 T, f! E. e! N
  205. </span></span>
复制代码

  T% j. \0 C' I4 V
收藏 评论0 发布时间:2021-12-1 22:18

举报

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