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

【经验分享】STM32F1(CAN)

[复制链接]
STMCU小助手 发布时间:2021-11-26 17:00
1,开发环境
; T; F' N8 ~- h
; |% Z) x& J7 h8 n1,固件库:STM32F10x_StdPeriph_Lib_V3.5.0
  v$ S5 Y" N, ^7 h% h) G6 a4 i2 O7 P  i  T. G/ Y
2,编译器:ARMCC V5.06
' |! p+ G3 T1 {: ?2 m
7 _0 P/ T" b9 }+ \8 O. O, |3,IDE:Keil uVision5
$ K. X' v) r8 I5 k( Z. E6 t: Y3 X2 k/ k' _) O* ^! B
4,操作系统:Windows 10 专业版
$ F; v2 X/ s" ?6 g# f7 q7 f
; b: m& V) p( S3 O+ s6 @# V
" `9 }2 `* X6 w% }# C- X8 `2,程序源码
7 }, h' U5 c9 Z  h/ O, Z9 P
6 ~4 t: D) |- Z  Y7 h8 t: `RingBuffer.h 文件2 j# \9 Q' H! H7 {2 D
  1. /**# p" z+ @# ^4 ]. o" H- p
  2.   ******************************************************************************
    5 Y9 N8 A% u1 G8 V+ K+ c, i# [# A
  3.   * @file    RingBuffer.h
    : \0 n) ^# G, }4 E; ?; g0 b7 P
  4.   * @author  XinLi5 E* _9 I4 T: i% e
  5.   * @version v1.1
    ; `- `0 p/ N7 Q4 W$ v6 [- z* _/ ]
  6.   * @date    15-January-2018
    0 O3 ?& w& M; i
  7.   * @brief   Header file for RingBuffer.c module.
    & z& Z/ D. p3 z8 q: S; h
  8.   ******************************************************************************
    7 R( ^5 N1 S' y+ B# n! e
  9.   * @attention
    $ f! Y" _1 ]8 _, G( n# V, n  k
  10.   *
    1 z8 s- o0 U* L, O$ {2 F$ N
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>$ E1 O2 {* r/ h8 x/ l
  12.   *4 C  V8 U0 Q. a. [# {
  13.   * This program is free software: you can redistribute it and/or modify) b: J3 ]3 T3 E1 H# Z
  14.   * it under the terms of the GNU General Public License as published by
    7 R# T% y$ a8 O5 K
  15.   * the Free Software Foundation, either version 3 of the License, or
    : f1 b0 t/ Y6 ?4 L: Y+ }6 d0 P( F
  16.   * (at your option) any later version.. y% m! f2 ]* |! _
  17.   *
    " Q4 `0 O9 C" G- u4 ]
  18.   * This program is distributed in the hope that it will be useful,
    " v) x. K7 H& b9 A1 O. U
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    6 G- \0 ]( f0 s/ m* d
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  A6 A( e- Q0 N, Q) O0 O; {* W  ~
  21.   * GNU General Public License for more details./ g( ~! s, I5 i
  22.   *) w) O$ |& O) h* |3 e1 E. N- y
  23.   * You should have received a copy of the GNU General Public License
    2 y/ t. Z6 a+ Z3 @7 J
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    , t/ C/ ~- w% w) G& T
  25.   *
    " I# f. Q8 I/ W" ^* {9 {
  26.   ******************************************************************************3 L9 U7 v- Y" a' q* ]3 I' t5 _
  27.   */9 |3 d' X; y! q+ I' k$ h
  28. ) U1 C7 I9 n9 ]1 y
  29. #ifndef __RINGBUFFER_H
    7 ]) L3 c7 ?9 i4 f: t
  30. #define __RINGBUFFER_H) T" x& {. f/ F9 Z
  31. 7 C9 b5 @1 u9 X. N  n5 t/ e& h6 g5 f
  32. #ifdef __cplusplus
    7 F. U9 P3 ]4 M0 p" `
  33. extern "C" {
    9 c! Y( r2 q8 |4 J
  34. #endif
    4 ?" c8 C; y/ f- B, b

  35. $ F( K8 h" F" ~
  36. /* Header includes -----------------------------------------------------------*/
    7 y4 q; x" O, }' A1 |' N
  37. #include <stdint.h>' R1 e- y$ ]' s
  38. #include <stdbool.h>
    / Y/ _+ O& R4 |2 e' }; U1 k
  39. #include <stdlib.h>
    , d7 u1 M0 `4 F/ t$ ^, R
  40. 6 _4 l4 u3 m* `0 Y
  41. /* Macro definitions ---------------------------------------------------------*/; {1 j3 p# J9 @8 U8 i
  42. #define RING_BUFFER_MALLOC(size)  malloc(size)
    2 f4 p  l5 K5 m* q& t9 d$ e" O$ K! O  `
  43. #define RING_BUFFER_FREE(block)   free(block)
    : {! E# N, v8 U$ h3 H6 b# }
  44. 6 ^# k  |! h3 k2 T  ^- s5 b7 ?
  45. /* Type definitions ----------------------------------------------------------*/
    7 y4 C6 z8 I* q: e! l8 R2 Q
  46. typedef struct
    ' [, [% M# @9 c+ W8 k1 m) U
  47. {& R' v2 W/ P8 m3 k0 w) F8 z
  48.   uint8_t *buffer;( ^2 }# x9 n) X
  49.   uint32_t size;
    ) ?9 H7 m- H8 d! @/ n4 I3 Z7 \+ A5 j
  50.   uint32_t in;
    ) l: Y) i* }' R5 d5 a7 G7 F
  51.   uint32_t out;
    6 ~% T) l5 S: E. x" W: t$ i
  52. }RingBuffer;6 f  b2 c% c. H: j; P4 w7 [

  53. # k" r: W2 u7 f
  54. /* Variable declarations -----------------------------------------------------*/
    - o1 r+ ?, [) f3 g# N& j! G
  55. /* Variable definitions ------------------------------------------------------*/
    9 {' e6 w; {- V* ^; C2 {
  56. /* Function declarations -----------------------------------------------------*/
    % V3 a$ G! X+ q5 [7 L
  57. RingBuffer *RingBuffer_Malloc(uint32_t size);8 J6 G$ g+ B0 y, {+ i2 ^/ G
  58. void RingBuffer_Free(RingBuffer *fifo);3 |3 I. `2 [' ]% X( P; e
  59. ( w$ w+ R" i  z* F
  60. uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len);
    $ [* x0 A) d* Q$ U7 r. d' N, a! A
  61. uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len);
      x: e" R$ N% {; D* g8 N
  62. # }1 t8 ~4 Z) u$ G% [' m
  63. /* Function definitions ------------------------------------------------------*/
    # P/ j2 E" a$ o
  64. 0 d8 K2 E- `9 e6 c* Z
  65. /**, S* @+ Q9 T' c9 A7 }
  66.   * @brief  Removes the entire FIFO contents.
    ' M3 u! s/ S' i" H/ K* S: g, E
  67.   * @param  [in] fifo: The fifo to be emptied.  v2 [6 o+ c. p! f0 |1 \
  68.   * @return None.( l1 [* G; B, k8 \5 D$ l
  69.   */
    $ i$ G& Y" s- s% H6 T- [/ ]
  70. static inline void RingBuffer_Reset(RingBuffer *fifo)
    . `' K+ p3 I. L! R0 W" H* _! u
  71. {. J: c- s$ V% q( ?: N
  72.   fifo->in = fifo->out = 0;
    ( u0 a1 k9 z- [# ~1 p$ [
  73. }
    1 g% ~# H' W, `) A# G
  74. 8 W, `9 z: O3 U- B
  75. /**
      a5 {+ z* @/ D) E* w8 n
  76.   * @brief  Returns the size of the FIFO in bytes.1 I7 V. p$ `6 ^+ E; Y: N2 o$ Y
  77.   * @param  [in] fifo: The fifo to be used.( D% i3 r8 N8 F
  78.   * @return The size of the FIFO.2 z; `* r+ B( U7 m- y0 [
  79.   */
    & e" z1 T" S1 g
  80. static inline uint32_t RingBuffer_Size(RingBuffer *fifo)6 r6 H! E5 A( o: n/ L% Q9 o: \
  81. {% i3 f/ m" ?. e! t5 P
  82.   return fifo->size;0 C" A' y; V' ?) ^3 C# `9 p( e& ?
  83. }
    ) B$ y+ u, b$ k

  84. - B& r! A# o- i; |* V
  85. /**1 j/ Y8 H+ b* E3 P
  86.   * @brief  Returns the number of used bytes in the FIFO.& w9 m  l8 f9 ~4 g) p
  87.   * @param  [in] fifo: The fifo to be used.5 b& s% V4 y# L( c! P+ S8 q
  88.   * @return The number of used bytes.$ V7 R+ \# y; K4 `
  89.   */
    " {5 z: e  @+ S  n. ~. X
  90. static inline uint32_t RingBuffer_Len(RingBuffer *fifo)7 E3 D. B1 U; ?4 U. ?  U; k( l9 r
  91. {/ @7 L: ]; r+ h# e1 [
  92.   return fifo->in - fifo->out;' k# ~' L7 O" A( n1 t: U
  93. }" v' l* L5 y* c7 v. m$ L
  94. # Q6 o7 ]! }- x$ N2 b
  95. /**
    ; h4 u' V  T, P: d! J
  96.   * @brief  Returns the number of bytes available in the FIFO." l  C% A& |, i8 e* P' L6 e+ f
  97.   * @param  [in] fifo: The fifo to be used.
    " a5 Z" W0 H& V& W$ S9 M0 F/ `
  98.   * @return The number of bytes available.
      z$ x/ F& A8 A6 T1 e
  99.   */
    . r0 O; m9 Z/ D: y! I8 V( x5 m) ?# k
  100. static inline uint32_t RingBuffer_Avail(RingBuffer *fifo)
    / J( ]! B  O- C
  101. {& P0 L  V1 i8 b' }2 R+ s5 r
  102.   return RingBuffer_Size(fifo) - RingBuffer_Len(fifo);1 Z' j. R2 V0 B" Z$ C5 H8 Y/ t9 x( b
  103. }: a7 Z$ ^0 b. F$ Y$ _
  104. 7 w  K+ l( _/ G. m
  105. /**5 F0 _& L$ n# [
  106.   * @brief  Is the FIFO empty?1 w0 h8 s. \0 J8 o: q
  107.   * @param  [in] fifo: The fifo to be used.
    ; U' G$ p) [% k
  108.   * @retval true:      Yes.9 I. H+ \& F4 {; m4 D5 u
  109.   * @retval false:     No.8 E3 G: t# U' L0 e
  110.   */
    $ z7 f, k  j+ `1 i
  111. static inline bool RingBuffer_IsEmpty(RingBuffer *fifo)' \5 l6 l2 [7 g& m; R* Z$ p7 G
  112. {
    6 z5 T. \* k/ r
  113.   return RingBuffer_Len(fifo) == 0;
    & ]8 N! m! ?$ I
  114. }' _& c  D) }/ `) Y6 `: N: N7 P

  115. 1 U8 Q* o# V4 [* h: C
  116. /**0 J* N1 B- y3 e+ |7 [9 o
  117.   * @brief  Is the FIFO full?% `; t7 {/ k1 Z7 C. T6 V5 P# l
  118.   * @param  [in] fifo: The fifo to be used.
    ( N) T, Q. ?4 h& K$ X5 r
  119.   * @retval true:      Yes.' a2 [$ t7 A0 Y
  120.   * @retval false:     No.
    - @/ c( C$ V- V: ~5 A% E9 n& ]
  121.   */
    1 R( ^7 M( e/ P
  122. static inline bool RingBuffer_IsFull(RingBuffer *fifo)$ k  r( A; N- {' X% \% ~% m
  123. {
    6 U3 a% y: ?. m
  124.   return RingBuffer_Avail(fifo) == 0;
    6 A1 m4 b8 E" W1 x$ B
  125. }
    / d9 g' i- _; L1 c4 [; T5 y

  126. ( r- P2 p! @3 H2 y9 T
  127. #ifdef __cplusplus9 F: d9 G9 Q; w5 Y9 ^, A, [8 o- X  Q
  128. }8 w# h9 ]3 D; `& ~, v& z9 a; g2 H" {
  129. #endif
      L! u( Y/ d# L% U6 J5 t
  130. ( Y* w( w8 e8 N  ?& x
  131. #endif /* __RINGBUFFER_H */* M1 B: }3 w; P& Z: y6 W) B
复制代码
. x7 _: _) ]( a3 o, R6 }/ K8 p, T

$ ~1 K9 G, K* {! CRingBuffer.c 文件9 R6 n3 `* e9 o  h
  1. <div>/**
    7 R  k* [) q5 d2 R7 q
  2.   ******************************************************************************
    5 }# H2 ^# F* Y; J* ]3 s
  3.   * @file    RingBuffer.c. n$ s2 @4 Y  q0 `5 K$ C
  4.   * @author  XinLi
    ; T; S& e- i  a/ j0 N
  5.   * @version v1.1. i8 u' N. n! K' M
  6.   * @date    15-January-2018) l; L2 Y6 a! H. x. Y6 }+ U6 O
  7.   * @brief   Ring buffer module source file.6 T% q, o& b! k# S9 s  E1 y8 v6 f( V1 j) f
  8.   ******************************************************************************
      d3 e6 ~# o& ^, f9 ^
  9.   * @attention6 K# \! |; B6 E2 j( ^/ `% e
  10.   *: x2 _" u! \- r* ?7 T
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    ) i8 W6 k7 |# x- i9 O
  12.   *; }- ~+ }8 z& z" W5 L4 T
  13.   * This program is free software: you can redistribute it and/or modify: V1 C. L5 @1 p/ \0 Q1 y4 |4 z+ x
  14.   * it under the terms of the GNU General Public License as published by
      r6 r# ]& }  f2 [) G
  15.   * the Free Software Foundation, either version 3 of the License, or& u3 {! n* y5 Q6 _- g$ r
  16.   * (at your option) any later version.$ H1 C) q' H% P& h# L% s
  17.   *
    * N; k/ C( O" _9 v2 d' [2 C6 V
  18.   * This program is distributed in the hope that it will be useful,  B; W, A4 j0 X3 y( R' p
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of- ~& F% i/ Z% u! M8 S6 r
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    : L3 T! _- z0 f
  21.   * GNU General Public License for more details./ ~/ l% @; S( v! g
  22.   *
    , r3 Y! q- B& Q4 O+ A
  23.   * You should have received a copy of the GNU General Public License
    & A. j( A( b8 m2 m$ d) r( r
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    % Q+ w8 K! q1 q2 `9 P; T6 H% \7 k
  25.   *: N7 Q) K7 O" _6 Z4 y3 l  F. T
  26.   ******************************************************************************
    7 i9 E4 f7 ?5 i( B7 o, K$ O9 p
  27.   */5 `/ v1 ~( i! }% L& [# P5 G. h/ ~

  28.   k0 ^' O. G7 T, ~1 [2 ~
  29. /* Header includes -----------------------------------------------------------*/% {$ D# I( X7 c2 A& B0 ^
  30. #include "RingBuffer.h"
    ' U7 y" J' Q0 P0 m5 e/ X4 `% n
  31. #include <string.h>
    1 [" M) t* Y0 M/ d4 k/ Z- I1 G
  32. 4 a: X7 F/ y8 }' q' H# t
  33. /* Macro definitions ---------------------------------------------------------*/0 c6 ~& K7 z, m4 Z: h: l
  34. #define min(a, b)  (((a) < (b)) ? (a) : (b))7 w& p& L$ e6 c- c* e* [- M  T
  35. 3 ^+ t4 w" h: M! |: \
  36. /* Type definitions ----------------------------------------------------------*/$ I7 i# ~2 ~6 t7 r4 R: v
  37. /* Variable declarations -----------------------------------------------------*/9 p% `! W' b# @  t8 w" e
  38. /* Variable definitions ------------------------------------------------------*/6 R2 L) r$ p5 ^; O" G( j
  39. /* Function declarations -----------------------------------------------------*/5 t, r3 o# X, H
  40. static bool is_power_of_2(uint32_t x);
    % C, Q! J6 `$ Y) ~
  41. static uint32_t roundup_pow_of_two(uint32_t x);. k6 D3 J: Y1 V9 i5 \5 u! |! z
  42. . K! K, e7 n( z2 U9 ], Z3 P* L
  43. /* Function definitions ------------------------------------------------------*/
    6 o. I, X7 X; w8 p0 \* O" R  G& m1 f

  44. 4 a$ M6 q7 w! i+ P3 v+ h% E! S
  45. /**1 }  H! W6 M7 v* }/ C# a' z4 E
  46.   * @brief  Allocates a new FIFO and its internal buffer.
    % o, M8 i/ ]) h" @' D  b
  47.   * @param  [in] size: The size of the internal buffer to be allocated.) V9 T. m" E  ~9 _! B
  48.   * @note   The size will be rounded-up to a power of 2.
    . X6 T% i- N# t- j5 {& A& z+ u
  49.   * @return RingBuffer pointer.1 D  ?* {  f6 S
  50.   */
    8 `& k# _& v5 ^, w4 F2 b& V* G
  51. RingBuffer *RingBuffer_Malloc(uint32_t size)
    4 f$ D. g' N- A& N+ z& `% [3 a
  52. {
    " |. X5 U  ~7 i
  53.   RingBuffer *fifo = RING_BUFFER_MALLOC(sizeof(RingBuffer));
    7 H; \0 M* a9 I

  54. 2 m  P$ N6 V( Z$ p; a, o# h7 B7 J
  55.   if(fifo != NULL)6 Z1 ?/ B* m7 n) T, s' O
  56.   {
    : I4 n6 E8 Y- O5 z* E1 I  s
  57.     if(is_power_of_2(size) != true): T* e* t0 s. Y9 M( `3 l' X
  58.     {
    6 \% b; Y2 Q9 ]- G% w5 t% t
  59.       if(size > 0x80000000UL)
    / Z# U2 s: t& Y3 Y: z3 d
  60.       {: F: f2 P  x& H8 t; S
  61.         RING_BUFFER_FREE(fifo);
      A# C" }! m: d/ s! ?1 v% b) Y
  62.         return NULL;
    + u9 z  M3 X3 d( U! F( V% Y
  63.       }& I/ `% q1 z: [2 `' V1 @

  64. ( r& E  j( V$ R
  65.       size = roundup_pow_of_two(size);4 D1 m8 p, F  [" b2 K) ?) `
  66.     }
    7 r9 Z( `2 n3 @- D/ j. q
  67. # O2 ?( c  Y% a! E- g  A
  68.     fifo->buffer = RING_BUFFER_MALLOC(size);
    . f6 i' W  W$ F# B8 N

  69. * [* O9 B% d" s- ?
  70.     if(fifo->buffer == NULL)
    8 e$ t" U- A' `/ o( R; ^1 ?+ W  H
  71.     {) I% V, b9 [" o& o
  72.       RING_BUFFER_FREE(fifo);1 U& Q, M' C$ s7 N4 }" T
  73.       return NULL;
    4 I, t# Z  e# S, I3 x
  74.     }5 K5 E3 j% ~- L6 P7 Q1 J  F
  75.   u3 G2 o3 a8 V/ n/ B: j2 f
  76.     fifo->size = size;
    6 }! j6 |6 S8 [! D
  77.     fifo->in = fifo->out = 0;% J0 r# g+ N: X9 \
  78.   }
    0 ^+ J6 j8 g* S& r# ^, W$ w
  79. ' m* S6 a( i: r, q0 T: \
  80.   return fifo;- O1 p3 D6 ?7 z0 C. ^; X' ?
  81. }# x: \0 q. O, q" p! K

  82. , ]: n+ ]/ v: Z$ X& d8 H
  83. /**
    ) S# B2 x# J" _! m
  84.   * @brief  Frees the FIFO.+ b9 ?# `7 {! ?: @
  85.   * @param  [in] fifo: The fifo to be freed.
      @" K+ J1 x* r
  86.   * @return None.9 U9 d& m0 y1 L  G
  87.   */
    / @7 @# w1 j$ G# H" }) ]
  88. void RingBuffer_Free(RingBuffer *fifo)- r* V5 i( W& h& u" T! D
  89. {
    6 Q% N: x& R8 S5 C
  90.   RING_BUFFER_FREE(fifo->buffer);
    7 A# `$ g  [* n4 X" s" q. Z
  91.   RING_BUFFER_FREE(fifo);3 E' ~% d; _! m) H1 P
  92. }
    $ X+ |6 ?! V6 U% ~4 V9 n- Y4 ~

  93. ; x7 {6 \' C$ N: b) {
  94. /**
    ' ^) h; w9 ~$ s. [  |* G
  95.   * @brief  Puts some data into the FIFO.: s. u5 p5 S3 ~
  96.   * @param  [in] fifo: The fifo to be used.' q! [( u/ Y% r0 o9 g& I" _7 \
  97.   * @param  [in] in:   The data to be added.  p, W* X2 G/ x2 z9 W( L5 A. l2 T+ j
  98.   * @param  [in] len:  The length of the data to be added.
    7 g$ L3 {: p4 t& P( c
  99.   * @return The number of bytes copied." w9 |8 x1 Z$ b( t
  100.   * @note   This function copies at most @len bytes from the @in into) v: g. V2 d$ b7 E
  101.   *         the FIFO depending on the free space, and returns the number' N4 [9 j# a+ Z4 l0 a" n3 _+ P6 Z4 m
  102.   *         of bytes copied.1 Y2 V, r& k. o" Z( F0 u2 F. C
  103.   */
    $ a$ U1 n+ v/ d# e
  104. uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len). m' k3 ]; k, Q5 O; w7 N4 O
  105. {
    , d( z# x: e( [( ?$ ^& Z
  106.   len = min(len, RingBuffer_Avail(fifo));1 e1 O% l( x2 @5 ]- u# V, d
  107. , H' F7 R3 C! B
  108.   /* First put the data starting from fifo->in to buffer end. */6 R+ b; g9 F+ }$ p- G
  109.   uint32_t l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));" h. u& |- |2 g
  110.   memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), in, l);4 ~7 Q" ?8 e! w1 ?" y' \

  111. $ B8 a0 J1 ~8 v$ |
  112.   /* Then put the rest (if any) at the beginning of the buffer. */
    " i; Y9 x5 @' E! ^/ Q+ U. C7 h
  113.   memcpy(fifo->buffer, (uint8_t *)in + l, len - l);
    - [( @& l" m- ?5 s; P9 K
  114. 1 l% V6 u3 Y( m$ y$ q
  115.   fifo->in += len;
    3 G: O3 q" h$ ^0 W2 ^- a

  116. 7 |" `/ f( x- r$ B
  117.   return len;
    : a; r7 u* {2 |5 d$ h8 Q# V
  118. }
    . ^; H: z/ g' F$ k% ]/ E

  119. : E* _) ^2 |: ~5 l3 Q* T) R( e
  120. /**0 r7 |  Z, x- h' O; Z! i
  121.   * @brief  Gets some data from the FIFO.; A! U2 K" F9 c& f
  122.   * @param  [in] fifo: The fifo to be used.0 V: w6 r( n3 v3 y5 Y9 c
  123.   * @param  [in] out:  Where the data must be copied.
    5 \* q! c: m% ?8 Y6 c
  124.   * @param  [in] len:  The size of the destination buffer.
    9 Y3 p- D4 v/ d- d1 I7 L
  125.   * @return The number of copied bytes.
    ( E) J5 V/ }3 i/ N/ t" L/ c4 l
  126.   * @note   This function copies at most @len bytes from the FIFO into
    0 Z0 w, b: ^3 `9 o4 ~
  127.   *         the @out and returns the number of copied bytes.1 I6 l* Z6 g& m! s  t- p
  128.   *// R1 e/ A* @5 c* m" Z3 g
  129. uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len)
    3 O. t& O1 M& G: Q3 S) `
  130. {% L' C$ A5 J/ z( w
  131.   len = min(len, RingBuffer_Len(fifo));- p: D: t8 l- \, N- M# e
  132. / G+ \, N: S" i
  133.   /* First get the data from fifo->out until the end of the buffer. */
    2 g$ r; G; @5 J! A+ E8 n: }
  134.   uint32_t l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));, Y8 h% x9 B  @$ x, A
  135.   memcpy(out, fifo->buffer + (fifo->out & (fifo->size - 1)), l);
    8 {1 @' A. Z9 |$ u) g0 f
  136. ) ~- V* e, T* {
  137.   /* Then get the rest (if any) from the beginning of the buffer. */
    9 J' x& x0 n9 i) \0 T
  138.   memcpy((uint8_t *)out + l, fifo->buffer, len - l);
    3 C& J- U( A. B) L1 Y* V
  139. / n7 X. @# N- |
  140.   fifo->out += len;
    - x( B! o3 [, [8 ]# y' j3 l* U$ e
  141. & h2 D+ _' R& s- l# m7 [- r7 h
  142.   return len;
    + G" Q  Z& d' A) d1 U* I. [; t
  143. }
    0 {2 F1 H! M. m, B( ^2 c

  144. ; u0 U. W* F0 J$ }! M9 W: D* F$ Q
  145. /**% t! x8 k. a# O. Q
  146.   * @brief  Determine whether some value is a power of two.3 G+ c" p$ |5 f4 v+ _5 V. U
  147.   * @param  [in] x: The number to be confirmed.
    6 w4 X) \7 _, o
  148.   * @retval true:   Yes.
    & U1 O9 l& O& k- t
  149.   * @retval false:  No.
    ( t0 d. T  X% J9 I
  150.   * @note   Where zero is not considered a power of two.
    6 v% W" h- R7 Z& ^! k
  151.   */# k/ D" V+ B3 N$ I9 F
  152. static bool is_power_of_2(uint32_t x)
    , v9 J) X0 p4 d
  153. {& k4 g. Y/ ?  [6 f
  154.   return (x != 0) && ((x & (x - 1)) == 0);& B- J4 U& O2 @5 b0 Z9 k! Z
  155. }( Y2 Q7 R: D( _% ]7 O
  156. 4 j/ ~' o' N' T
  157. /**" H1 Y8 s% l2 ~* r) K9 U
  158.   * @brief  Round the given value up to nearest power of two.' e+ ^) a8 K9 L% L9 ?) ]
  159.   * @param  [in] x: The number to be converted.
    & A4 P1 n. E. n/ [6 [1 i
  160.   * @return The power of two.
    * Y" _) c! M" Y; d# a$ R6 Q* _
  161.   *// p% K! k- z" u7 @
  162. static uint32_t roundup_pow_of_two(uint32_t x)
    + E' ?2 }6 M: B$ e* ^7 I
  163. {( [% C; `( ]- y" o. m1 S
  164.   uint32_t b = 0;6 B/ D4 x  d+ H. v- Z6 N; s4 l% ]

  165. , E6 [6 l+ A4 {" `
  166.   for(int i = 0; i < 32; i++)6 ~, \( U7 q# f1 N! c0 D9 a9 q! }% O
  167.   {
    1 v5 N: n4 L4 n& G2 Q) ^. u' ^
  168.     b = 1UL << i;
    ; {- X$ w0 S/ D1 b: \1 e

  169. 1 {0 d, g2 c; f) m9 r  U% r2 P4 `3 @
  170.     if(x <= b)4 g2 a& |9 s7 o2 R: L9 h* O( k" p6 }
  171.     {% A. f9 P7 M) n4 |) v- i
  172.       break;6 {: d( |: d* B. B- s
  173.     }4 s. U2 m& s4 c4 e9 b) a
  174.   }
    . [% }/ A+ \$ e3 B8 r: E3 ?

  175. # I: ]/ i& \  m4 u& z
  176.   return b;% R+ D' a! J& d+ t/ ~
  177. }</div><div></div>
复制代码

: P8 [0 H4 h5 d8 P! e3 m! p+ |" V' n
CAN.h 文件* x3 u/ [1 I0 A
  1. /**
    " R2 l  U$ [. G7 Z  K
  2.   ******************************************************************************
    ( t, X2 ~. C3 D" Q; _
  3.   * @file    CAN.h5 I, @) m: K! N8 c, B. V! F
  4.   * @author  XinLi, y5 e! a/ e$ ^: r% u+ m
  5.   * @version v1.0. I4 u% G; W2 i
  6.   * @date    24-June-2018
    * k- B' _, {8 y. M4 `& h
  7.   * @brief   Header file for CAN.c module.1 B& N" n$ T. |4 t1 k" b% X1 j
  8.   ******************************************************************************
    # o7 b& _3 Y. m
  9.   * @attention. V6 [8 z' D7 I* F3 e, s
  10.   *
      D5 E1 g) s- y3 _4 B( P
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    : [9 H. L$ n7 U4 D9 F
  12.   *. d; |' u4 M$ P0 C* M6 F
  13.   * This program is free software: you can redistribute it and/or modify
    5 w+ X0 P% ^* h+ f% ~. N
  14.   * it under the terms of the GNU General Public License as published by! L/ ^3 M2 ~# K
  15.   * the Free Software Foundation, either version 3 of the License, or0 W% Q, E; {, Y
  16.   * (at your option) any later version.
    6 Z" c  X  t6 z" s" x
  17.   *
    " S+ c% Y3 [1 h4 U) T
  18.   * This program is distributed in the hope that it will be useful,
    7 [& g& N9 J+ P! o' y
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    1 e1 K8 f+ R6 S2 t  ?) G
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the" o" U6 R+ s0 ?" T' R/ O7 B. W
  21.   * GNU General Public License for more details.
    + g( _3 h( r! ]
  22.   *
    9 W! I- e' S/ W( e: \# q# S2 c
  23.   * You should have received a copy of the GNU General Public License
    . A3 p/ H# c( V( n9 N+ I: N% p; m
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>2 C( Y3 @9 M  a% R2 `
  25.   *
    , ?+ M8 W1 F, |8 I( R: F, z
  26.   ******************************************************************************
    & v6 h& Z( v7 V9 K$ C7 G, l
  27.   */- H* B/ W1 q4 U+ z" a% W6 x! J

  28. ) s6 R& G9 H/ X4 k7 B: ?1 L
  29. #ifndef __CAN_H
    ' G4 _1 N7 u0 o( _: {+ I
  30. #define __CAN_H
    7 B9 e. F8 _1 [' q* a7 k! X
  31. 8 P! k" g+ I3 j! ]9 T. n
  32. #ifdef __cplusplus% Z/ r( ~, M  _! d* ?! W! S' }% z
  33. extern "C" {
    6 L  Z0 g$ I$ l
  34. #endif  |1 B5 @+ C9 w5 ~$ E& T
  35. " O  d# k$ f# P% Y! g
  36. /* Header includes -----------------------------------------------------------*/& Y* O  K1 y% s! ?: r7 u- T, p* E# A
  37. #include "stm32f10x.h"5 j8 l1 I2 Y0 q/ Z2 ?! s# P9 F
  38. #include <stdbool.h>
    : t$ _/ T( n3 Q. m
  39. 1 }7 `3 I+ _' j) i6 L
  40. /* Macro definitions ---------------------------------------------------------*/. i6 i+ A, k& Y& \/ y9 u
  41. ( [, y: Q. A. `
  42. /******************************* CAN1 Configure *******************************/7 P7 P/ d; e; r
  43. #define CAN1_TX_BUFFER_SIZE        (16)
    , T8 g6 W: ^9 t6 c$ j& S) S
  44. #define CAN1_RX_BUFFER_SIZE        (16)0 C- T2 V3 p  X+ {
  45. & T( B- l  F: w
  46. #define CAN1_TX_GPIO_CLOCK         RCC_APB2Periph_GPIOB
    - T5 C! F1 |, J  V  N# A% {: F! \
  47. #define CAN1_RX_GPIO_CLOCK         RCC_APB2Periph_GPIOB
    ! ?& y2 }2 n4 q( q/ I
  48. 8 B7 Q. b7 U# {5 x; e/ H
  49. #define CAN1_TX_GPIO_PORT          GPIOB4 E& U) J2 U" v/ H3 Y9 ^
  50. #define CAN1_RX_GPIO_PORT          GPIOB+ b* ~  @2 s/ b. h' E( l8 W0 g

  51. * @& N) c# I, w! A! o
  52. #define CAN1_TX_GPIO_PIN           GPIO_Pin_9
    , b0 E! g6 U2 w/ n$ W+ D
  53. #define CAN1_RX_GPIO_PIN           GPIO_Pin_83 T0 `$ t; z" ]0 T3 J+ k- O
  54. + o" }' e$ E9 v1 d3 P8 n
  55. #define CAN1_IRQ_PREEMPT_PRIORITY  (0)4 m( V8 N# D  r/ F
  56. #define CAN1_IRQ_SUB_PRIORITY      (0)
    ! z0 h4 R$ A& r
  57. 4 e3 b* J& N$ Z1 `5 Q7 A. I
  58. #define CAN1_PORT_REMAP()          GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE)
    & O" y+ `& Y6 o9 O
  59. /******************************************************************************/$ G$ z' _- C8 U1 H% p

  60. ! `. z! j. N+ @
  61. #ifdef STM32F10X_CL
    1 |1 c! e( q  }2 N$ v! V. `
  62. /******************************* CAN2 Configure *******************************/2 ]6 h, R) O9 P* S! w& ?2 ?+ P
  63. #define CAN2_TX_BUFFER_SIZE        (16)
    ( U* Z! |) f5 Z* S
  64. #define CAN2_RX_BUFFER_SIZE        (16)  n  S7 N9 ~2 O* y
  65. 9 X6 O6 y. h) o, @1 h
  66. #define CAN2_TX_GPIO_CLOCK         RCC_APB2Periph_GPIOB
    8 p- ]3 p2 H7 Z, S1 |1 }0 K7 \
  67. #define CAN2_RX_GPIO_CLOCK         RCC_APB2Periph_GPIOB
    ) i- t7 P+ ?2 N( k! J

  68. / s6 c7 A/ x( p' ?5 K+ O9 u7 [* j
  69. #define CAN2_TX_GPIO_PORT          GPIOB
    3 P- E1 g8 o9 n3 n: ~- ^8 h
  70. #define CAN2_RX_GPIO_PORT          GPIOB1 h+ n  ?2 j' \2 J

  71. * R8 y) i/ Z5 Q+ m- V4 @6 m4 m
  72. #define CAN2_TX_GPIO_PIN           GPIO_Pin_13+ H- p# b6 \' R4 Y
  73. #define CAN2_RX_GPIO_PIN           GPIO_Pin_12
    % k7 Q1 M  B: P2 v& k4 H0 O2 [

  74. : o9 L( h1 R! f$ B0 L
  75. #define CAN2_IRQ_PREEMPT_PRIORITY  (0)
    8 b$ b* E  ^$ G
  76. #define CAN2_IRQ_SUB_PRIORITY      (0)' y$ E6 }) B' o* m/ W# P2 j8 R

  77. ; w# ?/ l' B; q9 y  j
  78. #define CAN2_PORT_REMAP()          GPIO_PinRemapConfig(GPIO_Remap_CAN2 , DISABLE)
    5 N! F4 i  a( _" z5 D* q" r' E1 T
  79. /******************************************************************************/# }" U% }( U* \2 T- N
  80. #endif /* STM32F10X_CL */- W4 H, w, z- n4 M7 ]8 c( j
  81. ) `1 M+ x  D7 c2 p+ f( k
  82. /* Type definitions ----------------------------------------------------------*/. c2 I7 N! ]! I' e
  83. typedef enum
    6 L, j8 {& T2 K# V2 i  f* V7 k
  84. {
    8 h+ U# n  p9 s. [
  85.   CAN_WorkModeNormal   = CAN_Mode_Normal,, x$ H: L$ k: i, b( g: v
  86.   CAN_WorkModeLoopBack = CAN_Mode_LoopBack1 C& b6 Y3 o- R( j" o7 P% h( J! F
  87. }CAN_WorkMode;) g% o: U+ p1 t& r' a! k+ P

  88. ! v2 k9 c7 x4 [" w- f9 [
  89. typedef enum
    : m5 |: x( A+ u6 r* ?% i' p
  90. {
    2 x) e7 P6 ]; F7 j- V- S! N" \
  91.   CAN_BaudRate1000K = 6,' X' L: Q& M( D" ]
  92.   CAN_BaudRate500K  = 12," q! A1 F. B/ Y: q- I- L9 [( T
  93.   CAN_BaudRate250K  = 24,
    ; V* l8 _/ B; v
  94.   CAN_BaudRate125K  = 48,/ L$ ?3 y) f+ j0 L. r
  95.   CAN_BaudRate100K  = 60,
    * H5 E7 K+ Z6 k, W+ a, V* ?
  96.   CAN_BaudRate50K   = 120,
    9 o& @6 i: F; Y& ]6 l
  97.   CAN_BaudRate20K   = 300,+ s  e) Y- T! `& N! p
  98.   CAN_BaudRate10K   = 600
    9 M5 M& S& q+ u  p- \- n& i$ }! i
  99. }CAN_BaudRate;4 ?: u3 q& y+ V( t+ z
  100. 5 T; \- e0 X+ O0 @5 F) F0 k5 X
  101. /* Variable declarations -----------------------------------------------------*/
    7 i. S) N1 M9 D) b
  102. /* Variable definitions ------------------------------------------------------*/* s1 W0 e' w- |# h. Z$ \
  103. /* Function declarations -----------------------------------------------------*/
    4 v# S& r1 |2 e6 O! I
  104. void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId);
    1 [5 ]( z+ }. H; l# T( l
  105. void CAN_Unconfigure(CAN_TypeDef *CANx);' G6 R0 y  ~+ E' |7 o: W
  106. , j) i& ?9 w3 c7 L" v& B
  107. void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));4 O7 v( b  {1 a4 u! _! C  C* }
  108. void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));
    9 ~* d9 C& }) \
  109. 8 Y5 |) S( F3 s" T& E
  110. uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number);( Z5 h3 q5 N6 j! l  x/ `
  111. uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number);
    # G8 G8 ^, I/ n- p) ~  H

  112. , \5 f4 H' T9 h! [, i5 \
  113. uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx);/ Y. S& y" R# [; N* U3 L+ K$ W& v" ^
  114. uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx);
    3 U! @$ P% K* p6 P; ?. m
  115. uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx);
    " ?3 K' e! J% U2 O& \  l/ o
  116. uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx);2 N8 a( ]# t' p6 C

  117.   y& q, X0 o  j! [
  118. bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx);1 ?) J! o3 O3 Z
  119. bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx);
    ( W/ g$ {  `! J. `& r- {. N& c4 C* p
  120. bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx);
    5 [! A* l$ r! H" U' I, B
  121. bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx);
    " `2 l7 @) M+ V

  122. + H1 K; b. ~  n
  123. void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx);
    ' ~# T8 d7 |' @& W8 [
  124. void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx);
    , k) p/ o6 n0 F. I
  125. . c, J, S4 M) b$ T  y0 D0 `
  126. bool CAN_IsTransmitMessage(CAN_TypeDef *CANx);
    1 d9 H1 q7 \1 A) D% s
  127. + Q9 g$ G2 p- L. j% F# r) _) W
  128. /* Function definitions ------------------------------------------------------*/
    * e) q9 `: [# T
  129. 9 t& H' F9 ]' J6 @3 J  {6 ]
  130. #ifdef __cplusplus
    5 {# K3 n- v6 O& s5 e8 e
  131. }
    * M5 Z7 ?4 |3 p. l% {& {
  132. #endif
    8 A; _8 g  x. A, A9 a4 ~

  133. + a- y: g; w8 s0 E, \: B' \
  134. #endif /* __CAN_H */( m/ J- X5 p. H9 P2 X$ x) f) t4 L& f
复制代码
, c9 \$ ~1 d8 l+ S9 ]
1 E, I  f, W7 B8 m- F  f% N

' u& h  }, l- U: u) Q0 a% B% ECAN.c 文件
8 \% |" U6 Y0 A! `* t+ {/ ~7 L# |8 E3 `2 @) r5 Q
  1. /**' M  \( @) q  i3 S& R. K* Y
  2.   ******************************************************************************/ U0 s  {# a0 }: d. @; m/ j
  3.   * @file    CAN.c/ a" C* w9 Z( R
  4.   * @author  XinLi
    ! v7 n* p. E' F2 m- d
  5.   * @version v1.0
    9 p8 B  o) E& X6 z. X
  6.   * @date    24-June-2018
    " o9 j! o. `% F9 E7 w! J1 W
  7.   * @brief   CAN module driver.
    4 @) j: j6 N$ |$ }3 ^
  8.   ******************************************************************************
    + s4 g( b, J* H4 x3 q5 @$ L% k
  9.   * @attention
    ( a0 |8 K* N9 ?/ F$ s
  10.   *$ r4 d+ l. `/ W
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    / E+ q2 E3 h: g
  12.   *. M* x( q; l) P# d+ m8 r
  13.   * This program is free software: you can redistribute it and/or modify5 W, h) |4 `. G- r7 d2 R
  14.   * it under the terms of the GNU General Public License as published by3 k5 ?. `' t$ p# P/ o, b( }
  15.   * the Free Software Foundation, either version 3 of the License, or3 {% g9 q) l# z
  16.   * (at your option) any later version.2 H- m" ]! a" d5 Q- }
  17.   *+ v: Y* G% P! o1 M
  18.   * This program is distributed in the hope that it will be useful,
    / W5 q$ k* O* n5 I
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of7 D9 B! c/ j- d0 l% k. F
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the6 Z2 w+ A- `" Q( e& S; _7 u* ?& H
  21.   * GNU General Public License for more details.4 D5 v+ l- \6 J. ^
  22.   *7 y& U' N6 r. D* Y; S" }) F
  23.   * You should have received a copy of the GNU General Public License
    4 }9 R+ K) g0 T3 s9 g  r7 m, [. n% X
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    , w0 r7 c! X9 p2 @
  25.   *
    + j* l8 k, H' O6 l  ?
  26.   ******************************************************************************" a4 y9 ~- a' C: U
  27.   */
    $ u9 ]! O( W! a- L& N6 [9 v
  28. 0 _- o7 _+ b0 F' w
  29. /* Header includes -----------------------------------------------------------*// y5 \7 G! D) g' @
  30. #include "CAN.h"& Y8 e- u7 L) A* ]7 [2 e& ]" T
  31. #include "RingBuffer.h"
    ' T) E, w% Y3 G
  32. 6 ^! }: t4 m! X# r
  33. /* Macro definitions ---------------------------------------------------------*/
    : F! C& ]6 e* b! F6 c
  34. /* Type definitions ----------------------------------------------------------*/
    6 F. c  e$ S* \' y# W# u
  35. /* Variable declarations -----------------------------------------------------*/
    ! N2 w7 T2 P6 s
  36. static volatile bool can1InitFlag     = false;5 n5 d( l- m) V; R4 U4 t: c$ h5 Z
  37. static volatile bool can1TransmitFlag = false;
    - m2 L% V0 k4 d, M8 K! m$ Q/ b
  38.   Y9 ~. @: D4 ]7 t! n; T2 e; H$ m
  39. static volatile void (*can1TransmitFinishCallback)(void) = 0;# j# G, [" Z. T( A2 T6 h2 d- m5 J
  40. static volatile void (*can1ReceiveFinishCallback)(void)  = 0;" w# {) ^- ]) B: B$ m0 W
  41. 3 k$ A3 u& Y  r4 Q
  42. static RingBuffer *can1TxBuffer = 0;
    . l, A3 U/ z6 a  j% M
  43. static RingBuffer *can1RxBuffer = 0;! y/ j& C! e+ L  G! I1 q& H  a/ C
  44. , P* O" M0 B+ o& F4 S3 T
  45. #ifdef STM32F10X_CL; ]2 O. r3 p( l- W# Z) y
  46. static volatile bool can2InitFlag     = false;
    . u$ Q* W3 G4 x* B0 W( q
  47. static volatile bool can2TransmitFlag = false;
    / l* X/ s% i; U' Y9 j$ C

  48. % c2 s" b! v/ L& \& ?
  49. static volatile void (*can2TransmitFinishCallback)(void) = 0;! @$ e8 i$ Y/ y+ W
  50. static volatile void (*can2ReceiveFinishCallback)(void)  = 0;* e" ^! F" u3 s$ W/ D& ^  K
  51. ' v: n9 U1 V) u( j/ w' g: ]# r
  52. static RingBuffer *can2TxBuffer = 0;
    , U- a' @$ e& F  ?
  53. static RingBuffer *can2RxBuffer = 0;
    9 o4 E/ |9 ?1 e$ O3 ^2 Q
  54. #endif /* STM32F10X_CL */& p% e" j" u$ r
  55. # J- |# m" m6 t: N
  56. /* Variable definitions ------------------------------------------------------*/3 @) O7 u6 b) Y/ M) B! d2 ^
  57. /* Function declarations -----------------------------------------------------*/
    + V( t/ g" R, {! R7 `
  58. /* Function definitions ------------------------------------------------------*/
      J3 t" G) E* C* `& A/ C0 r
  59. " d: f4 M, {" I" d. \6 c0 i) D
  60. /**
    - H! t7 z  T( A0 J
  61.   * @brief  CAN configure./ q* X  O% w! C( i
  62.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.1 G1 [2 y5 L# `% V8 r& ~$ i) c
  63.   * @param  [in] WorkMode: Work mode.
    ; a+ h& q2 w* V0 R& C
  64.   * @param  [in] BaudRate: Communication baud rate.
    . S2 ^1 a$ @' f7 K& m* O" \
  65.   * @param  [in] StdId:    Filter standard frame ID.3 _* x" ?0 Y3 t( p; J6 e. j4 Q) v
  66.   * @param  [in] ExtId:    Filter extended frame ID.
    ' U: X; p) K3 `# L; x! F4 J) V
  67.   * @return None./ W. N. K) m6 v2 l) O8 G
  68.   */  F7 {$ P' R" i. f
  69. void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId)
    , a7 U5 J6 V; _1 J
  70. {% |5 r6 V/ z7 n- A& ], Q
  71.   GPIO_InitTypeDef      GPIO_InitStructure      = {0};
    * T2 L5 v4 w1 |! n2 r
  72.   CAN_InitTypeDef       CAN_InitStructure       = {0};# |/ A# P: q) ?# w; d& t: w
  73.   CAN_FilterInitTypeDef CAN_FilterInitStructure = {0};. d: ?/ A( T1 P+ c8 [
  74.   NVIC_InitTypeDef      NVIC_InitStructure      = {0};
    5 h% m# g0 k' Z2 b
  75. * t+ q2 Z+ _  Z! t3 ?2 X6 x
  76.   if(CANx == CAN1)
    ; k! I6 o; }0 G; @" J
  77.   {( Q5 c, S$ V, o8 M7 R
  78.     if(can1InitFlag == false)5 m! C( I! s3 a- m) k1 i
  79.     {! v) ~# O' i  s4 T% e! E
  80.       can1InitFlag = true;: L( u1 r- e* c" s
  81. 0 u; a- f% z7 ?
  82.       can1TransmitFlag = false;0 {" e& }3 X: Q/ A9 a6 D4 k& K* ]" c

  83. ( d8 i* R2 K7 A! z* H4 S
  84.       can1TransmitFinishCallback = 0;& F7 Y. w5 v  s) |4 C
  85.       can1ReceiveFinishCallback  = 0;
    - M& [) D0 L* f$ w
  86. ! K1 Z" O1 O/ \# k* F- M2 p. b
  87.       can1TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN1_TX_BUFFER_SIZE);
    6 `' Z) A1 L" Z1 l3 B/ o, u# o9 N
  88.       can1RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN1_RX_BUFFER_SIZE);
    , k. G, T! l6 x1 g$ |  X) a' k8 j3 f

  89. ; s5 I8 ^& r$ `; Y8 C
  90. #ifdef STM32F10X_CL- B( J& z  |9 h* {  u2 p, w( \
  91.       if(can2InitFlag == false)
    6 p& G2 X: _1 C0 U6 e
  92. #endif /* STM32F10X_CL */
    9 u% W9 }: b" V
  93.       {3 ?) s. R* t: Q
  94.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);$ [; D, P) n, \; L
  95.       }
      G+ A: N1 o$ C3 W- E! \

  96. " W! e1 ~% y1 L% W& j* p
  97.       RCC_APB2PeriphClockCmd(CAN1_TX_GPIO_CLOCK | CAN1_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);
    ! A. N) k; U% r0 {% m

  98. $ d* b  b3 ]) W- `2 F6 Y
  99.       GPIO_InitStructure.GPIO_Pin   = CAN1_TX_GPIO_PIN;. C1 Q) b$ t5 F* O) c" ]0 d
  100.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
      M# J7 S- C' X
  101.       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;! T9 {: ]: p0 Z  f
  102.       GPIO_Init(CAN1_TX_GPIO_PORT, &GPIO_InitStructure);
    - V1 N3 R) C9 J/ D  G8 |- O+ G# y
  103. ; n* D% f! s' I3 E2 |
  104.       GPIO_InitStructure.GPIO_Pin   = CAN1_RX_GPIO_PIN;
    ' V% [/ c+ d; i8 }! v, i. G
  105.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
      G# b7 D$ [% |5 l2 c" x8 k1 y
  106.       GPIO_Init(CAN1_RX_GPIO_PORT, &GPIO_InitStructure);
    , E$ h( l+ {# g; z1 r3 x- F

  107. $ |8 W/ C- A4 T3 n5 Z
  108.       CAN1_PORT_REMAP();
    4 j& `5 q6 J9 V. ^" W( b
  109. ) n: Y9 @  c# Q$ p8 g  O
  110.       CAN_InitStructure.CAN_Prescaler = BaudRate;2 y% X8 H, l+ R5 q, k! ^. Y
  111.       CAN_InitStructure.CAN_Mode      = WorkMode;
    ) V  a. A: u- J3 Y
  112.       CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;
    2 Y6 o: U1 n( k7 f2 A
  113.       CAN_InitStructure.CAN_BS1       = CAN_BS1_3tq;
    " L2 A$ t* L  @
  114.       CAN_InitStructure.CAN_BS2       = CAN_BS2_2tq;& @7 o- A0 i  s" C& l4 M  d! ~, n7 h
  115.       CAN_InitStructure.CAN_TTCM      = DISABLE;) {4 @# l, y0 N' A
  116.       CAN_InitStructure.CAN_ABOM      = ENABLE;" E8 Q1 _3 ^; @/ ?0 h) \
  117.       CAN_InitStructure.CAN_AWUM      = DISABLE;
    1 M) V8 Z6 S' o- }4 p. b& |- y
  118.       CAN_InitStructure.CAN_NART      = ENABLE;
    ) N& q, H7 B) l4 n- X- p
  119.       CAN_InitStructure.CAN_RFLM      = DISABLE;; b8 x* `: {# A% w
  120.       CAN_InitStructure.CAN_TXFP      = ENABLE;
    # ^3 b7 d. m* R
  121. 6 q! l/ X/ {/ B% N! C/ H
  122.       CAN_DeInit(CAN1);
    $ c+ y" `3 {  W8 v/ v# c
  123.       CAN_Init(CAN1, &CAN_InitStructure);0 R" g0 m6 Y; m# @
  124. * z0 P/ R6 z4 p4 \0 \- Q4 j. c+ |8 P
  125.       CAN_FilterInitStructure.CAN_FilterIdHigh         = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);8 M/ K" x; z+ M/ }' G: E2 O8 y3 w
  126.       CAN_FilterInitStructure.CAN_FilterIdLow          = (uint16_t)(((StdId<<18)|ExtId)<<3);
    * ^, R" `% O# {
  127.       CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;
    " E" i* a& e2 K# D
  128.       CAN_FilterInitStructure.CAN_FilterMaskIdLow      = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;( W" V% E  [3 s: y+ ?) d
  129.       CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
    * Z( V& [) n4 J
  130.       CAN_FilterInitStructure.CAN_FilterNumber         = 0;  a1 s  z3 I. ^$ a8 \
  131.       CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask;
    + A/ ]9 G, ]: F3 k5 ]
  132.       CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit;
    ( {4 W0 s- \+ @/ Z/ K- e! A7 u
  133.       CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;
    5 L0 f4 |( i, g( S
  134.       CAN_FilterInit(&CAN_FilterInitStructure);
    3 W& t. Q. x- a( n1 y6 h2 o& j

  135. 0 [- G# b8 P( w0 K% Y+ _
  136.       CAN_ITConfig(CAN1, CAN_IT_TME | CAN_IT_FMP0 |CAN_IT_FF0 | CAN_IT_FOV0 | CAN_IT_FMP1 | CAN_IT_FF1 | CAN_IT_FOV1 |
    5 X6 X. z! P. ^* k0 T  n5 y! K
  137.                          CAN_IT_WKU | CAN_IT_SLK  |CAN_IT_EWG | CAN_IT_EPV  | CAN_IT_BOF  | CAN_IT_LEC | CAN_IT_ERR, DISABLE);
    2 m9 L  f- ~3 \
  138.       CAN_ITConfig(CAN1, CAN_IT_TME | CAN_IT_FMP0, ENABLE);
    9 ~! _6 u# ~+ @- J8 J6 h" V- V  G2 l
  139. , X3 l) k- d; T3 e: k1 L. G' ^
  140. #ifdef STM32F10X_CL$ U8 _& U. Q1 {, v; Y) {( F9 |
  141.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_TX_IRQn;" e$ Y# P" Y$ c8 f8 e. r
  142. #else
    8 i+ Q% n) u6 o% B; p
  143.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_HP_CAN1_TX_IRQn;
    , h( f( ?6 @% g6 _6 y
  144. #endif /* STM32F10X_CL */$ |+ U+ P, `. G% v9 @
  145. # M) |/ w& T6 _. R3 N) B
  146.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;. ?2 M* Z& n  h7 X7 K4 f( F2 E
  147.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN1_IRQ_SUB_PRIORITY;
    $ r7 ]% b+ w8 g: y& }, j
  148.       NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;# |( Q; [+ b, ^7 b8 E
  149.       NVIC_Init(&NVIC_InitStructure);% O; J8 r' Z- M( R8 C1 g
  150. 3 }, Z' v1 B, b$ M5 Q
  151. #ifdef STM32F10X_CL- Y) f/ {- D, |" e
  152.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_RX0_IRQn;4 a0 j* V* l8 Y: o; J# `- Z
  153. #else
    ) ?% w$ r( Y: N, \- E; Q
  154.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_LP_CAN1_RX0_IRQn;
    1 G7 U- `! J, P' g; |1 e
  155. #endif /* STM32F10X_CL */( ^6 g+ W, C. ]! ]- o; G
  156. ) z, r1 e4 K2 p) U' C( q
  157.       NVIC_Init(&NVIC_InitStructure);
    5 I1 q6 Z4 C; ^( i
  158.     }* j! T1 ?$ P2 T2 a" J! s7 F
  159.   }
    . o' O( L9 G# {9 {! B
  160. 0 q) a6 \# ^6 B' j* s1 d# {
  161. #ifdef STM32F10X_CL2 k' [' }; t1 r! N
  162.   if(CANx == CAN2)" |% p- k0 j* N+ g
  163.   {
    5 S/ d: {; e7 w. J" L# H' n* n
  164.     if(can2InitFlag == false)$ \3 F: y3 M; y
  165.     {
    # C; Y# G2 r/ @8 b
  166.       can2InitFlag = true;
    : t& v) E( |# z# o

  167. & x9 Y/ b8 Y- S6 D3 |1 |5 x) E
  168.       can2TransmitFlag = false;+ ]. O# U& M, X* @  a' D! u

  169. * z; s$ m' [  C1 U% H% s! R
  170.       can2TransmitFinishCallback = 0;1 q& ~0 N. x0 M2 \
  171.       can2ReceiveFinishCallback  = 0;
    1 P7 P6 z! X1 z# N2 Y! n

  172. 2 \1 ?* A2 r- s$ q, j
  173.       can2TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN2_TX_BUFFER_SIZE);
    1 R7 J3 G7 Q1 |/ {0 j
  174.       can2RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN2_RX_BUFFER_SIZE);4 H; v) u( @: `6 {, W

  175.   U: C: |8 j. W: D
  176.       if(can1InitFlag == false)
    3 I! t/ k* l0 W( t
  177.       {
    8 s, Y7 h" n6 I+ D' y; h/ |
  178.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
    6 n/ E* z3 h2 c, L/ B
  179.       }+ r8 T( C2 Q% U9 y  n6 X0 s% u7 m
  180. , n' o! }* ?5 P$ I
  181.       RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);9 M- S- x; E! o- X/ P
  182.       RCC_APB2PeriphClockCmd(CAN2_TX_GPIO_CLOCK | CAN2_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);
    6 P8 R  e1 _5 M  V4 b" Z

  183. ! ^- @, ^; j7 c  i! I
  184.       GPIO_InitStructure.GPIO_Pin   = CAN2_TX_GPIO_PIN;5 y! D- U3 h9 J2 H! J
  185.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;/ m. q" n7 s* F2 R
  186.       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    / b. z. g8 `! |
  187.       GPIO_Init(CAN2_TX_GPIO_PORT, &GPIO_InitStructure);9 x. O: L( p) E: y5 W

  188. , ?: v/ S! c( {) w! ~; }7 a' X7 {* f
  189.       GPIO_InitStructure.GPIO_Pin   = CAN2_RX_GPIO_PIN;
    $ @* w" _& F1 f6 q
  190.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;5 X$ ], m$ r- C
  191.       GPIO_Init(CAN2_RX_GPIO_PORT, &GPIO_InitStructure);5 V2 W& E1 z3 t* T8 |; ]* r
  192. 0 C- e% i) o# L5 X) R
  193.       CAN2_PORT_REMAP();
    # Y) }& C2 }% B& [, v+ E! K9 ~
  194. 4 Z6 q; `& d! B/ R9 d, G, F) M
  195.       CAN_InitStructure.CAN_Prescaler = BaudRate;
    # B$ N3 A1 }3 Z0 @" I
  196.       CAN_InitStructure.CAN_Mode      = WorkMode;* U+ `! P0 }/ {* s& J( b2 t
  197.       CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;3 I& k/ s( r' b$ O, M
  198.       CAN_InitStructure.CAN_BS1       = CAN_BS1_3tq;" I5 |* \4 b/ j* r- z3 K
  199.       CAN_InitStructure.CAN_BS2       = CAN_BS2_2tq;& E9 W9 p" S+ I# ?
  200.       CAN_InitStructure.CAN_TTCM      = DISABLE;
    6 v0 d) ]* {" e4 X* p( a: ^/ s5 O; d
  201.       CAN_InitStructure.CAN_ABOM      = ENABLE;# t% _# D3 m0 l2 O: U
  202.       CAN_InitStructure.CAN_AWUM      = DISABLE;
      R1 b1 T. \  r$ o+ x0 b
  203.       CAN_InitStructure.CAN_NART      = ENABLE;  I% Z, t9 Y+ H! w2 L* o/ A
  204.       CAN_InitStructure.CAN_RFLM      = DISABLE;! {  T5 K, }( Y9 ?
  205.       CAN_InitStructure.CAN_TXFP      = ENABLE;
    - ^9 [) L/ c( m3 m

  206.   X) z! }, G6 |7 c
  207.       CAN_DeInit(CAN2);( D! b5 n' [+ V. v5 L1 P4 f+ m
  208.       CAN_Init(CAN2, &CAN_InitStructure);5 c! h1 s- O1 |& N! F% S! O7 U

  209. ! f" m* x% Y! z: x
  210.       CAN_FilterInitStructure.CAN_FilterIdHigh         = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);* l% C4 I3 I3 N: L4 b
  211.       CAN_FilterInitStructure.CAN_FilterIdLow          = (uint16_t)(((StdId<<18)|ExtId)<<3);
    & K# l' x% g8 G7 ?3 T8 s9 `
  212.       CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;1 X# u8 X+ C5 a5 I" `
  213.       CAN_FilterInitStructure.CAN_FilterMaskIdLow      = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;
    ) ^1 B4 ^0 ?0 h7 Y) b
  214.       CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
    , P5 f7 S! j! U+ h, x% p
  215.       CAN_FilterInitStructure.CAN_FilterNumber         = 14;
    9 ^* a6 s" c1 c3 O3 `/ q# [+ ?
  216.       CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask;: N: X  e) n" K, s6 D; W5 {
  217.       CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit;4 c  }' F9 V- g8 w5 @
  218.       CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;% c) @% I' c, R1 {1 j
  219.       CAN_FilterInit(&CAN_FilterInitStructure);
    * G+ A  K! H3 ?6 }
  220. 6 H* L0 }" V% L* E5 l+ A+ b
  221.       CAN_ITConfig(CAN2, CAN_IT_TME | CAN_IT_FMP0 |CAN_IT_FF0 | CAN_IT_FOV0 | CAN_IT_FMP1 | CAN_IT_FF1 | CAN_IT_FOV1 |" }% z3 B! r3 u8 v4 L& t
  222.                          CAN_IT_WKU | CAN_IT_SLK  |CAN_IT_EWG | CAN_IT_EPV  | CAN_IT_BOF  | CAN_IT_LEC | CAN_IT_ERR, DISABLE);' G, N. m% M2 E) J$ p
  223.       CAN_ITConfig(CAN2, CAN_IT_TME | CAN_IT_FMP0, ENABLE);; g1 q7 j3 e6 `4 x& C" W

  224. , c7 a* E7 c5 O, a
  225.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_TX_IRQn;
    7 P6 S- b0 C) \" W
  226.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;
    0 j* p# A1 |5 \3 |3 b0 r
  227.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN2_IRQ_SUB_PRIORITY;
    6 P$ r9 s( D0 c2 r' k# u
  228.       NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;8 E; U" F6 M0 N8 J  U9 m
  229.       NVIC_Init(&NVIC_InitStructure);' y- Z' a4 i5 ^8 q1 W: i9 r5 P/ x$ q

  230. ' g7 M1 V  y  u, b
  231.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_RX0_IRQn;( M$ T$ N* m5 e/ y2 a  ]  K4 `' c
  232.       NVIC_Init(&NVIC_InitStructure);; h  @6 T) d" t+ g
  233.     }8 G* t/ }9 f- G
  234.   }( I! P+ i, y9 x# c- t0 V( ?6 }
  235. #endif /* STM32F10X_CL */+ x; W" [7 Q% z' J) [
  236. }
    5 y/ n1 W. y& |6 W( p, I) o
  237. # O0 e, ^9 N8 m. o/ s* D
  238. /**
    7 n2 \! B/ g4 z/ h- p- Q
  239.   * @brief  CAN unconfigure.+ O2 b! H" L7 F; C# l5 K: {
  240.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.7 M; O3 N8 m% A7 R% @/ M
  241.   * @return None.
    9 _3 ~& `6 _0 }" M& ]+ y) M2 Z
  242.   */
    - r7 x% o, E7 y# m" \
  243. void CAN_Unconfigure(CAN_TypeDef *CANx)
    4 v( _; e  A9 N. Z
  244. {
    " \! Z- W- l5 j+ W4 I
  245.   NVIC_InitTypeDef NVIC_InitStructure = {0};4 _' @9 u0 F9 W# I! c* B7 @# X
  246. 3 G0 k" p4 t4 z! L. H
  247.   if(CANx == CAN1)
    # [9 r- z. D+ L1 i, G& R" l
  248.   {
    0 O- d% @8 A! ^# P* E3 x/ p' V, R  v
  249.     if(can1InitFlag == true)  H6 z' P' T1 {' J" F
  250.     {
      s, W6 G7 E5 L* \! h& t
  251.       can1InitFlag = false;
    - D0 T5 {4 w  k

  252. 1 P; S( G4 [/ o
  253. #ifdef STM32F10X_CL
      y% r/ q# m- W7 M) B
  254.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_TX_IRQn;
    7 x8 c1 A! l/ E5 P) _) l2 o# M
  255. #else
    # b4 H8 W( @4 f- c* }" q
  256.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_HP_CAN1_TX_IRQn;) |/ ~+ U" s: g
  257. #endif /* STM32F10X_CL */
    9 @5 E& f7 z0 e2 n9 p

  258. 6 k% n( }4 T$ B. S; T
  259.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;
    4 f! U/ i9 u$ f
  260.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN1_IRQ_SUB_PRIORITY;: Y+ |# p7 T* ?
  261.       NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;6 {9 Z( s+ n' \
  262.       NVIC_Init(&NVIC_InitStructure);1 I/ g8 h7 K8 m- `0 F( v) t

  263. 3 I3 L& o0 k. `- H
  264. #ifdef STM32F10X_CL
    7 B/ u) v. J" Q: S
  265.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_RX0_IRQn;" k& Q, r/ J. o+ j6 `* V4 l- Z
  266. #else
    4 r) P- ^& ]: ?& y% S6 Y/ X8 n
  267.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_LP_CAN1_RX0_IRQn;
    ; ~' j4 [" m6 ?$ {% Q% Q
  268. #endif /* STM32F10X_CL */
    : x, c) e* ^! P3 T. Z5 W$ D2 |

  269. 9 x, H2 Q0 E! @$ s- z; J, f
  270.       NVIC_Init(&NVIC_InitStructure);- R, i" R. o( ]' R! n( P# ^% z

  271. 6 {2 g. x  d" B3 O3 U: F
  272.       CAN_DeInit(CAN1);* F: @2 J+ V1 H
  273. ! Y* ~3 r" C& K
  274. #ifdef STM32F10X_CL! V5 |$ O! I# m8 x5 [' Y3 C
  275.       if(can2InitFlag == false)
    : Y- `+ c' P- q; v- `2 L1 N" ^3 L
  276. #endif /* STM32F10X_CL */
    + C# g& X$ c+ f) I7 A9 e. l
  277.       {
    / J( _) R! k- ~  n/ l: x
  278.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);+ q$ F0 i- N% N/ D, }5 c& k
  279.       }7 t8 _2 J% @1 G6 R* \7 i" V
  280. 1 Z8 ?( Q. Y! u' `
  281.       can1TransmitFlag = false;
    5 [5 g* N. X) `+ F4 z* K
  282. 9 a2 L; @* X' e6 t; i; T
  283.       can1TransmitFinishCallback = 0;
    / y" q4 k5 r" r" N1 q6 U
  284.       can1ReceiveFinishCallback  = 0;# P/ Y. Z! W+ `8 p

  285. + i" t* U  @  l7 n6 O  U
  286.       RingBuffer_Free(can1TxBuffer);! V  c; F( f  g, T7 a
  287.       RingBuffer_Free(can1RxBuffer);$ b6 Q* }. L& u- v  y+ k( s& N
  288.     }
    2 D8 P3 x( O* W; G, M9 n6 r% I  y; `
  289.   }0 l' E! U- h  n+ ?& j5 w

  290. 1 E* p1 Y; i2 W2 |; C+ E
  291. #ifdef STM32F10X_CL
    ' P+ @$ L7 K5 u' D
  292.   if(CANx == CAN2)0 j0 ]/ B9 }0 A8 g- q
  293.   {) d1 {3 Q7 C9 l# i9 M
  294.     if(can2InitFlag == true)
    & E1 ]) E. F9 m, N+ H) y( ]* J$ a
  295.     {
    1 @  P0 b- }- Q, H, a
  296.       can2InitFlag = false;
    # }9 ^/ D* V0 x0 {6 s  n, x0 K
  297. & o  J+ b# n- }. P
  298.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_TX_IRQn;
    & ]$ ?3 C( }! p: L! s& E) V
  299.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;! N+ p" O% D( U! y% G3 i! J
  300.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN2_IRQ_SUB_PRIORITY;0 w0 i  [# \" D
  301.       NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;3 e! Q  _# r% C) M3 f& `8 m
  302.       NVIC_Init(&NVIC_InitStructure);6 R- k6 w! q- u) S" d) |

  303. ( M1 T1 d' r% a- k! h& I/ O
  304.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_RX0_IRQn;$ o* N! i* z2 M9 c! B% O( A
  305.       NVIC_Init(&NVIC_InitStructure);' X; @/ R( G2 q- B0 x0 T+ z

  306. - s% r6 \: ~7 z' ^
  307.       CAN_DeInit(CAN2);
    % `5 ~2 i1 M  t; B- L
  308. 9 R' ]7 q# \/ m2 C3 ^& L) ~
  309.       if(can1InitFlag == false)' {2 l- q9 C6 {+ G; a5 c+ C6 v" m
  310.       {$ @* U+ e, Q4 \! p% \5 q- {
  311.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);, Z# a, m9 V: W  V6 O' [
  312.       }+ G" r7 W7 T' d- k# `

  313. + N4 K5 e- _$ ]; F5 I) l1 ]! {  t
  314.       RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, DISABLE);- a+ A1 x! I7 }' U' N. @9 C5 P

  315. ' c- @' [, q% S( b  {) y
  316.       can2TransmitFlag = false;" y" A1 p7 A( m. x% s/ a: _

  317.   P" q$ w9 {# @# N/ W: }6 Y, E8 |
  318.       can2TransmitFinishCallback = 0;
    ) `! j. h" p5 J7 z1 u2 r, G+ p8 u, S
  319.       can2ReceiveFinishCallback  = 0;
    ( l2 L4 g. H, p; M

  320. $ L* B8 P3 x3 A
  321.       RingBuffer_Free(can2TxBuffer);
    . F+ J8 m( ^" b9 d
  322.       RingBuffer_Free(can2RxBuffer);
    3 ?/ @5 i' ?9 }7 W
  323.     }
    % Q9 i/ v, h" [9 Z
  324.   }+ x! d! W  ^$ \$ h3 I& d1 G$ a6 U
  325. #endif /* STM32F10X_CL */1 L5 ]) O5 `; |. @0 D
  326. }
    " z6 c# J; G% K; f. r6 S% q
  327. 4 O6 ^& R: F( {% D4 N2 a" u7 y' w
  328. /**8 }! m- }5 M; l2 }% Q
  329.   * @brief  CAN set transmit finish callback.
    2 U- @" s  O" v6 Y
  330.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.
    ; R% L, b$ A. R8 H' f& w
  331.   * @param  [in] Callback: Callback.
    7 E( E2 e( G& C1 O
  332.   * @return None.
    2 y& V$ d8 R( r
  333.   */) z" E1 c* T. W$ T' v
  334. void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void))- F/ A$ u+ O9 s+ o
  335. {- ?- Y$ ^' [) r/ Z
  336.   if(CANx == CAN1)/ c2 S( I# {1 R# n
  337.   {
    : b. \9 x8 m. j: G" p
  338.     if(can1InitFlag == true)
    + @4 f  L3 I% L; L% L: J/ H( W/ C; l
  339.     {0 u& z+ u. g* l! e1 ]8 ~
  340.       can1TransmitFinishCallback = (volatile void (*)(void))Callback;
    . D% w) W2 G: l- e- P, \3 a% n% g
  341.     }
    3 n  Y/ \9 X! N. m2 Z
  342.   }/ y7 p/ h: d! X' v$ K1 {
  343. , x  q$ ^3 G  j& z" L0 S' b
  344. #ifdef STM32F10X_CL! d0 @4 R9 R  a9 \0 i0 R& K
  345.   if(CANx == CAN2)
    ! j! Q' ]: B4 ?
  346.   {. }" P! m7 Y4 a1 e9 J: j
  347.     if(can2InitFlag == true)
    ; M* r9 {% Q+ S1 }
  348.     {
    , i& p, w) i. t
  349.       can2TransmitFinishCallback = (volatile void (*)(void))Callback;9 t* `9 @8 Y0 u
  350.     }
    2 r. k  U- q( J" H7 u1 @
  351.   }
    , P; e$ p$ M. N8 C# ]
  352. #endif /* STM32F10X_CL */
    9 B  g; ?4 [+ j
  353. }* A  r; b; F( w# v  E9 y! o

  354. 5 v$ j  _. ], V# Z9 o
  355. /**
    6 `( I1 b6 f/ m; m3 z4 R- I
  356.   * @brief  CAN set receive finish callback.
    / }2 V! R8 r0 f4 ^: d. v6 \+ M
  357.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.% T: R- B/ Q0 D
  358.   * @param  [in] Callback: Callback.3 m5 N$ V% W0 h9 u
  359.   * @return None.
    # g- a% I: O: m; r# K5 w3 s9 t. l
  360.   */
    $ t, l2 K. v2 n; N+ B; L
  361. void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void))% B/ C% R: o. E3 z6 `
  362. {
    / [% ~" R" s9 g7 O0 e
  363.   if(CANx == CAN1)
    3 N, O! j, c' l, Y
  364.   {
    + e6 o! i! ?, O. |4 n
  365.     if(can1InitFlag == true)
    % c/ r2 M4 o6 ]5 T
  366.     {$ X4 v, Q1 e5 k: H
  367.       can1ReceiveFinishCallback = (volatile void (*)(void))Callback;
    1 o  |0 G% |0 e0 e) |0 |; k
  368.     }
    3 Z7 t) j! x7 J9 m* o
  369.   }
    0 z' l( S) @% X/ N" n
  370. 9 C) }/ n# c. M! w/ ?
  371. #ifdef STM32F10X_CL
    0 b* b% L2 k4 {
  372.   if(CANx == CAN2)
    ( p0 y3 S; Y9 B/ m8 b. l
  373.   {
    6 q- ~+ B7 G  u. }5 b( C
  374.     if(can2InitFlag == true)
    $ p/ v0 y; d5 U& U6 p5 j
  375.     {* T0 L) H- Q  Q$ o. H
  376.       can2ReceiveFinishCallback = (volatile void (*)(void))Callback;
    * f( H0 f3 y) n( w' T/ T, m  {
  377.     }7 T6 C* g- X- {* N5 Q* F: g+ n
  378.   }
    " n' C6 m9 z- _8 `
  379. #endif /* STM32F10X_CL */! S8 J! M2 t" G: l( Z& ?; n, [
  380. }
    ) Q& A6 @% U" j5 x/ Y- G+ \5 R

  381. ( S/ X5 a7 z/ D& ~$ g
  382. /**
    $ A% y1 E" a- U8 w4 C+ F6 _% F
  383.   * @brief  CAN set transmit message.
      h! f" C: |. w2 Y9 `
  384.   * @param  [in] CANx:    Where x can be 1 or 2 to select the CAN peripheral.
    ' Q+ K0 Y1 m9 L4 @0 G
  385.   * @param  [in] Message: The address of the message to be transmit.+ @( `3 _2 H. W: Y  u" U
  386.   * @param  [in] Number:  The number of the message to be transmit.6 S: w. B  w7 {7 [8 F  k
  387.   * @return The number of message transmit.
    3 t5 i5 s0 H* S* B
  388.   */
    & x2 V: K5 B4 T. K2 k# J9 X
  389. uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number)
    . c, c" H* j7 {1 ]) \; u* `, v
  390. {4 ?  u3 o1 S- d2 A" i3 Q1 v8 C4 z
  391.   if(CANx == CAN1)& U+ n: A3 u4 s. r) y4 Z
  392.   {
    ; c! N/ C8 B& H% b
  393.     if(can1InitFlag == true)
    * F: f) r4 _* f4 @4 c7 l1 V
  394.     {& d$ V3 p7 p6 `. v: ^6 t
  395.       uint32_t available = RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);
    . ~& C  z+ P1 a( }* [- g: |4 N

  396. ' w+ s5 v4 g: d  P' u; u
  397.       if(available > Number)
    6 F0 W- n, N( D, b3 z1 {
  398.       {
    0 ?& b. L1 K- [
  399.         Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);
    % `0 o  _7 k& K, |1 }8 C, o
  400.       }. ~2 i* B* B* V* r  m5 _
  401.       else
    0 p) w7 A) T% c: Y. [$ o! X4 n
  402.       {
    . t! Q$ p/ F! k  D! B7 v
  403.         Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);
    ; v2 R% D3 g$ K; X. [1 U
  404.       }$ y3 V( r; |3 l

  405. & P' H) q' t7 j
  406.       if(Number > 0)
    / c8 w4 N" {6 N" H  t5 }
  407.       {
    ! z2 R: J4 e4 N
  408.         if(can1TransmitFlag == false)
    & V1 U. r* o( J( Z3 V
  409.         {( x1 k/ T5 x; e' Z( Z
  410.           can1TransmitFlag = true;5 ?5 i, v" K6 X
  411. ! g2 l* f/ m1 r! q
  412.           CanTxMsg canTxMsg = {0};
    - F: [( A7 g+ U  N# J9 W
  413.           RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg));
    9 S- @# E; A, p. i
  414.           CAN_Transmit(CAN1, &canTxMsg);
    ' D! R& V  Y. ~' P- o4 ^+ w  m
  415.         }
    , G) L. _  F$ ~0 ~/ r0 g2 k
  416.       }5 |: V4 ?0 `9 O& y: e: v, x
  417. $ c# h( B: \+ _! E/ A8 H6 R: {
  418.       return Number;) L3 I: t2 y5 O( d
  419.     }
    # ~3 W: d' _# s, ^
  420.   }* E1 m9 U  ?3 ]% h
  421. ; M) h( O6 e; v, x  B
  422. #ifdef STM32F10X_CL
    # _/ L1 m+ o- b
  423.   if(CANx == CAN2)" V5 T9 f$ w* G2 d4 p$ G. z  k* B: R
  424.   {
    + T% B$ `! _! _$ B# L: u
  425.     if(can2InitFlag == true)( c' a- e: g/ E
  426.     {
    % M$ ?* w' P) ^' P' L( ?" t- `
  427.       uint32_t available = RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);
    # V3 R; ?! {+ H' d, N- N5 b+ `2 ]
  428. ( F! c8 G5 `1 m7 k0 m
  429.       if(available > Number)# \) l7 _; i& j# v$ Y* {2 F. ~
  430.       {
    / L7 e6 f3 ]4 ^* M( q
  431.         Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);
    3 W6 q8 z! S0 ^# E
  432.       }- x* Q. i  G& a4 C3 m9 C  A, P
  433.       else
    / W4 g( m; l% C7 Q" i# Y
  434.       {
    6 Z& A' ~" i$ |* B: w% D  t2 q
  435.         Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);
    , B. J+ C2 u7 K1 |) ~8 _1 B
  436.       }. C' [" W2 g  F' W2 @
  437. - l& w2 m& V' z& @
  438.       if(Number > 0)
    4 I; U$ ^) O& W0 f2 h
  439.       {6 ?* _4 Y; F( r; c! m: \! ~; s) ~
  440.         if(can2TransmitFlag == false)
    - J9 y5 m: Z' K9 G4 W' Q0 r# R
  441.         {! V8 ~5 b5 \) ?* T* w6 [
  442.           can2TransmitFlag = true;
    + d; C( _  m, O; R, m
  443. 2 j+ b0 {7 u5 c( k, y* C% Z. E  g
  444.           CanTxMsg canTxMsg = {0};
    ' e5 ^3 D6 S  x! |! [. M# x
  445.           RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg));
    " h! M! e9 H  n. S4 h
  446.           CAN_Transmit(CAN2, &canTxMsg);
    * z6 J8 X5 y: y
  447.         }% S9 ~* H. K9 i5 q  U% @
  448.       }
    2 R4 V9 b& p" X& V% i1 G8 V* L" V1 ]

  449. : [* {. L# g# X. Z$ i+ {
  450.       return Number;: h4 j7 W5 M5 O( n" |) {
  451.     }' _* b0 h( {: Q  s* v  x
  452.   }5 x3 L8 {& M* j- _- w! Z
  453. #endif /* STM32F10X_CL */
    ( L4 L; Z! s# h6 G
  454. 4 r7 |" [% L2 ]
  455.   return 0;0 x5 a7 p) R7 O4 [& y1 ?
  456. }
    3 f9 i' S* B# b( R' z

  457. . p' P( f" ^# I
  458. /**
    6 U, C5 K9 s, p9 i/ a
  459.   * @brief  CAN get receive message.
    4 p1 d2 ~+ v- l& a$ {
  460.   * @param  [in] CANx:    Where x can be 1 or 2 to select the CAN peripheral.* @/ r$ q/ z# U7 e1 j
  461.   * @param  [in] Message: To store the address of the receive message., q2 Q5 f3 l# }- x& C
  462.   * @param  [in] Number:  To read the number of the received message.7 d) E  g! ^9 ?
  463.   * @return The number of message obtained.
    % V' U. m+ g* b# f  I
  464.   */
    " Z; H# C; [2 @  X  Q% s6 y) |
  465. uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number)
    7 c1 h2 l+ [  \& d' T
  466. {
    ! b% f# K+ d4 _' B: d
  467.   if(CANx == CAN1). s# D9 I% G* [" ]6 t" j2 s
  468.   {
    7 _1 b6 e. ~' f- z) a& L+ l
  469.     if(can1InitFlag == true)
    . h0 W% }# X( {5 E, n' ~: b
  470.     {8 S8 ]6 @0 X* E( k5 b! ^
  471.       return RingBuffer_Out(can1RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);
    ( E3 `# Z& C: d( M/ f
  472.     }
    , t  H. |5 X7 k- `8 l+ {: m4 P
  473.   }3 e& o1 x' X( |1 v' X' S! _

  474. 7 z5 r' ^' V# E
  475. #ifdef STM32F10X_CL
    3 o. k4 S5 x* _
  476.   if(CANx == CAN2)
    . z" C4 f, m& K( D$ @
  477.   {9 |4 b% \0 ^1 _3 v7 v& P2 I) _
  478.     if(can2InitFlag == true)* U; ?6 P& D/ [( x* i1 M- p
  479.     {/ z$ a* C% L# o0 o4 o
  480.       return RingBuffer_Out(can2RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);! k" @5 u' J9 [3 o, r
  481.     }
    * G8 ]; n" \* o. I; l5 Q
  482.   }
    2 O* ~9 r8 r, ~! l6 j0 N( h, {" R; z
  483. #endif /* STM32F10X_CL */
    ) ^! e) X0 X' D2 k. M9 Y3 x+ X" L
  484. - Y$ \; U% y) }2 \: Y
  485.   return 0;
    , w. y8 ]6 L1 s. p# {- I. V* Q1 z
  486. }
    % D7 J9 C, h2 L9 M; F

  487. 2 K2 o0 e) ~- }7 z  [
  488. /**
    - M9 |8 L% X7 ^2 ~
  489.   * @brief  Get the size of the CAN transmit buffer used.
    ; v: s8 ]6 h/ j$ Y9 F  P
  490.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral." f0 l  d; v" f7 |
  491.   * @return Used the size of the transmit buffer.1 ]5 ?/ q+ r, e) L- J, \
  492.   */$ a8 W* C- \: W) l0 D) Z) ]" l
  493. uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx)
    * N" J. S7 j& ?
  494. {1 @  o1 o1 g) M& A0 Y+ M
  495.   if(CANx == CAN1)3 K* K  C1 ]+ k. n7 Y% C  ~! }
  496.   {
    + x0 g, a/ D* N1 v9 r+ E
  497.     if(can1InitFlag == true)' o1 `$ b  }9 o7 |+ p* n; _
  498.     {% |# j* E8 F& A: W' f
  499.       return RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg);# B* f! s. D  n" Z& \1 L
  500.     }4 ]8 y$ j9 w$ j- ~" f% R
  501.   }
    7 R; ]  B) M2 [! O
  502. ) Z) ^" T2 c3 _* C' z) N8 C  I9 v
  503. #ifdef STM32F10X_CL# H" q/ W$ v$ f; R# K
  504.   if(CANx == CAN2)
    0 [% N) O* h# t2 n) a
  505.   {
    . J1 X) q8 Z6 [# z
  506.     if(can2InitFlag == true)
    % t% c$ [2 J3 o/ I' W
  507.     {
    ( Q& d7 C3 o; R# q
  508.       return RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg);
    0 T+ q) C& C: G( p6 Y. ?4 ~
  509.     }
    5 F# y$ c+ n* ?$ m% p
  510.   }3 j1 O  i" Y+ {$ @  C+ u: }! [# f
  511. #endif /* STM32F10X_CL */
    " k3 }' j# C# R9 N4 @

  512. 1 O; r& s" g/ M/ x& e1 `2 x( f
  513.   return 0;3 F6 i" c# O! n0 h% M+ q
  514. }2 \8 k( ?5 r4 L& x/ n
  515. 1 ?7 Y7 d4 b! [
  516. /**! y9 R, h/ ^. W9 f8 a, p
  517.   * @brief  Get the size of the CAN receive buffer used.
    $ ^. [8 o6 B# S; l2 a
  518.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    4 f9 d# z9 ~: ~7 W( o
  519.   * @return Used the size of the receive buffer.
    7 k. {4 R1 _9 ^& E/ ~7 o' B' r
  520.   */
    7 n' `' r; K2 }8 P7 c) w3 p( _
  521. uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx)% ~. f2 {5 y: P$ r- k
  522. {
    & Z' V' U* U2 S7 `+ Z
  523.   if(CANx == CAN1)
    . i! A8 `+ _9 `- `" a+ |
  524.   {
    + J3 H. M1 O1 r9 U+ o
  525.     if(can1InitFlag == true)5 ]' `) t3 C9 g
  526.     {" @) K' }, n3 p* t
  527.       return RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg);
    $ }8 }6 E/ H# [- m4 C2 F5 F" F
  528.     }
    # b, x" Y7 T6 ~8 O4 H8 ]
  529.   }. \# L# s) q1 P% c
  530. . }- I5 e0 {7 R5 G; U' Z
  531. #ifdef STM32F10X_CL' v( b6 E) U; ^- L% S/ E. p: @' y- v+ F0 d
  532.   if(CANx == CAN2)$ E3 {5 G$ {6 K7 S. G! l0 m% \
  533.   {6 W: [9 H0 ~2 I' o) {1 |
  534.     if(can2InitFlag == true)
    " _7 A2 ~2 _6 e7 o
  535.     {' ?! j) z1 @9 B$ c& j! }7 C
  536.       return RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg);
    * f8 f+ k$ D/ E7 \! ?0 X
  537.     }- V5 H1 u/ S' W& |+ y
  538.   }
    * i! `4 t! c. \+ A/ V7 N
  539. #endif /* STM32F10X_CL */
    " H8 E. ]1 s! S& e9 w; S

  540. 2 l: Z* n% d" U0 i5 C8 Z* I1 `* M2 P
  541.   return 0;* H) J$ [6 ^6 z- p
  542. }( @) `) A& a9 S8 U
  543. 2 u7 w: c! N. F  {* [7 v
  544. /**3 g4 O# [  S- V
  545.   * @brief  Get the size of the CAN transmit buffer unused.) {0 m4 E- k. V) P$ E
  546.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
      y6 y! n# B7 x6 C$ b1 p. Q( I
  547.   * @return Unused the size of the transmit buffer.
    , Z1 n* U/ v2 U" |6 C: H
  548.   */) S% q; L; `5 k  p! w6 M0 Y+ q5 a. o
  549. uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx)  q8 [7 g6 o3 Z7 q$ h% h" d
  550. {4 D) D+ O1 Z9 N0 G# F1 ?7 N7 U% X/ m
  551.   if(CANx == CAN1)# h! y7 }3 x( @1 D
  552.   {3 Z4 Z1 H0 I1 k
  553.     if(can1InitFlag == true)+ l8 K' k3 W1 ?- A4 }' ?6 [' r
  554.     {+ A& n: T/ Z; p" b
  555.       return RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);: V3 m% e0 s/ X! l
  556.     }* ?7 ^! a& Q4 u: P. |, @" R
  557.   }
    ) @9 h$ b7 ~  j, m6 S
  558. 5 u/ v/ ]7 B' Q7 {# G
  559. #ifdef STM32F10X_CL
    7 t" ?1 h3 n. T  {6 |- z* X
  560.   if(CANx == CAN2)' ^+ w9 p! U+ i$ |" h( d3 d
  561.   {
    3 o8 Q; L) @  q1 J" v) N  i3 f. {3 J
  562.     if(can2InitFlag == true)# l, V0 P: d0 O3 H- C6 |
  563.     {/ K" i# `& n+ i4 H
  564.       return RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);
      X6 i+ \4 Y) q& J2 n7 P
  565.     }& [5 R* G% a$ D! U: Z
  566.   }" Q) g& s" j: f& u2 d) o2 O( S
  567. #endif /* STM32F10X_CL */7 e0 {% q6 n3 g/ ^* _# K1 C; E3 B
  568. ! a% U0 ^3 u( A. x$ b" h0 w4 x
  569.   return 0;
    * T9 R2 k& M! V3 y$ j! F2 V
  570. }4 D- g+ P( q) `8 P8 Q; D+ Q; ?
  571. 0 O2 c" J5 E9 s/ h0 L
  572. /**4 i4 o% i( e- |1 ?7 s! u/ [" Z
  573.   * @brief  Get the size of the CAN receive buffer unused.# a! }2 t7 H- K3 u  k0 N0 j
  574.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.- z, Y- Z) C: ]0 B% G! h. V5 ]( x
  575.   * @return Unused the size of the receive buffer.
    8 {* ]$ b+ G/ a6 [, `: H  D
  576.   */
    9 b/ t8 }& p! O5 C+ d8 X+ p* v8 d
  577. uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx)
    + S$ u* Q8 N& L$ I0 N  v/ D1 I5 U
  578. {
    , v# m7 S1 o  x$ e
  579.   if(CANx == CAN1)
    % x, A/ G4 H; C1 t' V6 C+ H
  580.   {
    $ T2 R! W' W( M8 V6 ^
  581.     if(can1InitFlag == true)
    * q1 l, g$ o; n  P* T5 ]; V
  582.     {
    ' a* s0 m' n& D- C+ c$ ?
  583.       return RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg);' t' }5 a. F9 {- i0 J
  584.     }
    * w# E! d/ F% {# L" d0 [
  585.   }
    2 i: ^8 k2 i  m& [  v9 B

  586. ) ]3 ?5 O/ T- Y! B! Q
  587. #ifdef STM32F10X_CL$ s' I  H( m! ~+ O
  588.   if(CANx == CAN2)( ~$ I# a! ]4 s+ z. }
  589.   {
      g* ]; G4 v6 I: a" N
  590.     if(can2InitFlag == true)# _+ ]& R6 j& }" z
  591.     {
    & j' J- |( p: O$ u0 t: @/ o: b
  592.       return RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg);' j2 @( U/ F) v- L2 \4 e7 L% @
  593.     }9 z& ^5 e$ X" Z9 Y4 O5 y
  594.   }- [  G" S% N3 S4 l1 w! W
  595. #endif /* STM32F10X_CL */; {$ G) {0 B* h/ N9 {1 z9 M0 {

  596. . f  M, s3 a* l- V) k3 S8 H
  597.   return 0;! p& a( e# J1 S: E
  598. }: x6 ?% M% ^* z9 R# e, _! g) K
  599. 2 c% q/ q1 y; v( k( S9 W& J
  600. /**
    & X3 z) ~9 V0 B$ z9 U9 D' k
  601.   * @brief  Is the CAN transmit buffer empty?/ D. \4 j4 i1 g5 Z; p/ c" s. O
  602.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.% r  e1 H6 P, ^0 _/ f
  603.   * @retval true:      The transmit buffer is empty.6 ^/ P& R- g+ h) T4 M
  604.   * @retval false:     The transmit buffer is not empty.% P% s: K9 W* P# B/ U3 a3 ^" U  P
  605.   */$ \& {- J+ n' {/ w$ p1 G
  606. bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx)
    . w* S; Q: b+ y6 Y& u0 [' J; `. Q
  607. {( \1 ^$ \) a( r% R& O" A8 b# t
  608.   if(CANx == CAN1)
    , L3 w3 w4 `5 [4 m- S% ~
  609.   {
    ) X9 j% @8 j, l  y. l+ [
  610.     if(can1InitFlag == true)
    . k4 z4 o' j. P$ t; @8 }
  611.     {4 r" V" b9 I1 V# \" V! a1 H
  612.       return !(RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg));
    7 v7 _" a" R  s) [6 Z0 T* h6 r/ I
  613.     }7 x: l. W- k" |2 A* P; D! o+ g/ D& s
  614.   }
    ! k3 M# N9 r% u" p4 j
  615. : R; X6 \! ~6 H$ k! v
  616. #ifdef STM32F10X_CL* q, [: P  H0 `+ _# H8 G
  617.   if(CANx == CAN2)
    % j8 _9 D# Y# R" V2 U/ Q$ i
  618.   {( a. L$ p6 c3 x+ R& a6 j9 `9 c7 m! r
  619.     if(can2InitFlag == true)
    % h! c9 A& L" J: c  n
  620.     {
    % o0 T; [; U9 k2 V
  621.       return !(RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg));
    & h0 H0 |4 F% J! H- L
  622.     }1 V: N* E1 l) t) i
  623.   }
    ( V3 @2 ^8 J# x  M; [/ I
  624. #endif /* STM32F10X_CL */
    8 y0 d1 B$ I7 b% w5 ~7 t+ j

  625. , G# n6 V7 O* b3 b
  626.   return false;0 _% G1 g% o" I- B% G
  627. }
    7 h2 b  k! E, S3 I( f: i
  628. * B1 Z! D3 R$ |9 F: _  K
  629. /**& T$ i( h+ {+ Z+ z
  630.   * @brief  Is the CAN receive buffer empty?
    ; Q2 d/ ~" {4 |0 p8 A
  631.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.3 r0 Y5 z- s8 @8 j/ Y1 D  }. Y3 U
  632.   * @retval true:      The receive buffer is empty.0 M% C% S0 M* ^0 [% [
  633.   * @retval false:     The receive buffer is not empty.
    ( W1 K, @; K" I7 y. E5 b
  634.   */
    * ~) v- N% u5 N; U
  635. bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx), e2 g# m/ Y' ?2 k
  636. {1 Q1 M$ w$ r+ R! Y4 \% F; T2 l5 K
  637.   if(CANx == CAN1)
    ( Y# m6 Y" O3 l% ~* s
  638.   {
    8 i" q7 u0 r$ [5 a6 y& w
  639.     if(can1InitFlag == true)
    3 D4 i" A9 _0 e' y+ W7 d
  640.     {! G" w+ q: i8 Z$ c
  641.       return !(RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg));
    8 l2 ^9 u: u, K$ q
  642.     }1 g" J& F! n* I( t5 {0 O8 h1 C3 U$ N
  643.   }$ @8 X1 u5 A- u9 v
  644. ' k3 T$ G, [1 Q# {, E
  645. #ifdef STM32F10X_CL
    # x- J& V. I" z. T0 C. z. u  Y- c9 U0 N
  646.   if(CANx == CAN2)3 q1 G" Y3 W  ^  I2 `
  647.   {
    2 Y! @# ^7 u8 T3 D+ d
  648.     if(can2InitFlag == true)  }& ]% X  h, M/ @) e; x2 L
  649.     {2 J" [3 A/ @' F$ j5 e% y8 t" n
  650.       return !(RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg));
    & s: W' B, q' L, Z' x1 i
  651.     }
    . L  z+ o1 }$ C0 ?7 V+ q' L
  652.   }
    2 Q7 U8 H5 X7 p6 O, ?
  653. #endif /* STM32F10X_CL */
    & u8 k' Z) ~+ R
  654. * p+ a. o# b' Y  d) @' A- d5 {
  655.   return false;
    / {6 u* c1 R& R7 l9 d$ g
  656. }* S  {% r. C$ F

  657. . J4 ^$ ?1 t; D- @
  658. /*** {) f6 @, z% `1 e% Z5 m* b
  659.   * @brief  Is the CAN transmit buffer full?
    / d, Q$ b3 H+ }4 i- |9 {
  660.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    ! E4 j5 \+ ^) n+ g  m6 {1 ]5 [
  661.   * @retval true:      The transmit buffer is full.
    2 R4 d! G' D/ X9 _9 F. \! v
  662.   * @retval false:     The transmit buffer is not full.
    7 F/ J" ?+ i1 d* {! V0 l, Q- ?/ r
  663.   */
    + ?1 ~* ~/ m$ M. h3 ~7 f
  664. bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx)
    & y( X1 z4 v, [
  665. {1 ~1 V1 n$ b' Q, _- X- C
  666.   if(CANx == CAN1)
    3 S1 c/ t0 O8 }% t% F7 p
  667.   {
    5 [! c8 y/ R4 x( z' g8 C
  668.     if(can1InitFlag == true)$ d! c7 z) `, m- E% x- W
  669.     {
    # l9 A2 {& K5 L# E/ o
  670.       return !(RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg));
      z4 R. Z/ K3 c9 y
  671.     }1 R/ l6 n% q! ^9 L( u8 I4 ]
  672.   }
    + L) C  J7 R) h
  673. 6 f4 |( c: h. {! W$ P+ g1 @0 o
  674. #ifdef STM32F10X_CL
    ; P# G# S- M5 ?) s, ^# n. \7 l
  675.   if(CANx == CAN2)# K, I) z% G- w& M5 T- P
  676.   {# N# Z( J; `/ c7 d! `4 V$ H
  677.     if(can2InitFlag == true)
    : Y* I8 F0 N, n% H& @
  678.     {2 n- z9 t: D5 D4 O
  679.       return !(RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg));
      I6 W& X2 w/ S# I- B6 I
  680.     }
    , }  f4 w3 U: ^: C
  681.   }
    2 b+ \0 p0 g5 x2 v2 \* M
  682. #endif /* STM32F10X_CL */
    - ~' C( r( [/ U) n
  683. ' `# s  M6 ^- h; L
  684.   return false;
    2 o& D9 F  h( O$ o& u
  685. }
    ! }' v( C8 n0 y" E# r

  686. + r  Q4 W  X) B/ i2 e
  687. /**  S# n. Z- S: a9 ]! T
  688.   * @brief  Is the CAN receive buffer full?
    0 r1 `; O9 z+ V; A5 H# @0 c
  689.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.4 n6 w6 A! ]9 [: A
  690.   * @retval true:      The receive buffer is full.  @( N& A. r3 R3 ^
  691.   * @retval false:     The receive buffer is not full.0 ~8 t0 y1 H- I2 _: r
  692.   */
    2 Z6 p+ b  p" w% {* F. D, y
  693. bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx)
    1 y9 d6 j! _7 W9 J; T1 ^
  694. {
    , w$ z& d6 J, e' T$ t1 X
  695.   if(CANx == CAN1)# o3 d! s: V+ f% O: O1 C
  696.   {
    6 K9 |6 w9 A. q9 J
  697.     if(can1InitFlag == true). f, {3 T" Q+ o2 Y4 U
  698.     {  T& V- i* m- N6 K+ v( n
  699.       return !(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg));
    . {3 B, j. q; s! t: v6 [' E- P/ T
  700.     }
    " D6 ~2 O5 [+ k! x
  701.   }' c' `* @. L8 L9 ^) r
  702. ( J4 N. y. ]! p5 w! u2 f: `- ?7 g
  703. #ifdef STM32F10X_CL
    3 Z1 I# k7 F; J7 M( J
  704.   if(CANx == CAN2)
    " [1 U0 \' \* j3 Y/ F% \
  705.   {6 ^, d2 F% \  A; Q. m$ n$ o9 H
  706.     if(can2InitFlag == true)
    3 s- k" \! h( r4 R- Y0 M
  707.     {
    5 D1 z) q2 s- Y( H; g3 ^& J' M4 b8 k
  708.       return !(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg));. A0 w( O" q3 Z+ u- V
  709.     }
    1 z: x/ c5 F6 s
  710.   }- x9 W# H1 ~) A$ N7 O
  711. #endif /* STM32F10X_CL */
    ! N  o5 n4 R4 j; v" N5 R  q- w
  712. * h8 X( {. b3 d* u8 m- Y6 w
  713.   return false;
    1 o8 |, _" _5 _2 F% F# U
  714. }
    7 ~6 m0 n, {' {# c
  715. % _/ B8 y+ x$ D9 n/ O( n
  716. /**, T, _+ [" W2 v$ y8 P& @
  717.   * @brief  Clear the CAN transmit buffer.7 u! J* {/ D/ D1 @" d* r' _/ R# T
  718.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    - K' x; |. S# A9 K6 h
  719.   * @return None., D! A# x9 [1 [2 q; Q' i
  720.   */
    ) ~- D7 Y, m1 ~" w, L
  721. void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx)
    5 A3 ?, }, A$ q3 d, N, m0 A
  722. {4 [! _( L1 d' h! ^0 c
  723.   if(CANx == CAN1)  a8 d) s$ T+ G' Q  u
  724.   {3 P- ]  R" C; X4 h
  725.     if(can1InitFlag == true)) s) h1 g7 _) W+ \1 F* s
  726.     {
    7 X$ f' X1 C4 }1 q( Y. q& r
  727.       RingBuffer_Reset(can1TxBuffer);
    1 R( c% j4 j# A
  728.     }. k9 r$ h0 e) d& G
  729.   }4 ^) F. k) H$ P4 m7 b& p7 W% x

  730. 4 S9 n; y+ d* m% @4 x. _
  731. #ifdef STM32F10X_CL4 W$ O/ |& R$ G+ K9 J# A3 R( t
  732.   if(CANx == CAN2)
    $ ]8 f& E  J! Y8 v  @) h+ F# i4 P
  733.   {
    ! V3 C( n* Y! u. c
  734.     if(can2InitFlag == true)4 x6 V, b1 W* L) r' N
  735.     {
    4 s) q+ l7 m% V; ?" C! x
  736.       RingBuffer_Reset(can2TxBuffer);
    8 Y" a# W3 V5 l. q7 {3 `* c" E3 @! w% A
  737.     }
      l  T* O! v. ?
  738.   }
    # |+ U; U/ k  {
  739. #endif /* STM32F10X_CL */% q' l6 S. W  K$ W  D& O5 x
  740. }/ b7 r8 M$ |6 E* P

  741. ( f  f- Z% G$ \* V  U
  742. /**
    8 B9 @5 y, M) P9 v' v* M
  743.   * @brief  Clear the CAN receive buffer./ x' K7 T) E7 K: ?, x8 ^) d
  744.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.+ t: k6 k0 ]6 W/ n" g
  745.   * @return None.$ p) W, ?/ [4 K9 x/ i
  746.   */
    2 }- S7 w7 q7 S
  747. void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx)- Y- \5 a) u4 ?- `
  748. {
    . v; U! j( y4 B; M
  749.   if(CANx == CAN1)
    - E/ m1 ?6 M) w6 h$ J
  750.   {
    + q- }) z3 f5 e& d7 l4 U9 l
  751.     if(can1InitFlag == true)
      r) X4 h; T) k- t
  752.     {$ x9 C- s" C* }
  753.       RingBuffer_Reset(can1RxBuffer);4 ^! f4 ?& l. o6 Z5 t. ~  H8 k0 [
  754.     }: F) G" \0 w0 x7 T& U6 ?4 S# b
  755.   }
    7 z5 S) U$ t9 z+ R8 O) K
  756. 3 X. V7 u1 O# u
  757. #ifdef STM32F10X_CL
    . L+ y( S; G5 a$ z1 A- R; T- N
  758.   if(CANx == CAN2)
    $ D! Y+ _/ F" R) d; R
  759.   {
    + X9 A8 ]8 K2 i+ K1 H
  760.     if(can2InitFlag == true)
    / i* K0 [$ g) s
  761.     {4 f4 u. r$ u- b1 q, [5 P
  762.       RingBuffer_Reset(can2RxBuffer);
    . k. t8 F7 e2 W% Z
  763.     }
    $ l! P+ ]+ H& N* L( E! a
  764.   }. m5 S7 u1 ^! j6 ^( h( ^- B
  765. #endif /* STM32F10X_CL */( ^2 ]  J  \) x
  766. }
    0 y6 D/ |4 s+ a; \  V

  767. & K3 |( K" l  e9 d/ i, ]
  768. /**7 }3 x* J& ?) w( g
  769.   * @brief  Is the CAN transmit a message?
    ) B9 n7 e, c8 l8 c! S5 J( ~4 u1 Y
  770.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.6 j% \- M# v" s* U1 n# v. t2 [
  771.   * @retval true:      Is transmit a message.
    ! A3 f; e! u0 @- ]
  772.   * @retval false:     Not transmit a message.
    / W  a2 B; C: o) Q1 N+ d
  773.   */" K- S3 Z/ [, l0 {/ u, b
  774. bool CAN_IsTransmitMessage(CAN_TypeDef *CANx)' G6 V& a: P6 u# J( i
  775. {
    - a2 ^3 R' n3 H4 a- ~) L+ Q
  776.   if(CANx == CAN1)2 u5 j' u+ S5 b- C
  777.   {
    $ |: o( n7 t4 A1 E6 @
  778.     if(can1InitFlag == true)9 @  r! J4 y/ m% b3 y
  779.     {
    - I: t( a/ a6 i6 ]# F+ o. z& ]1 H. V6 x
  780.       return can1TransmitFlag;
    6 C) w2 E  l/ l3 ?4 \' t
  781.     }: S7 P1 M! q. x6 k1 J: N
  782.   }
    7 }+ r; M  L# ]# i* m4 n1 |& _
  783.   b, h5 J9 Q! c: h
  784. #ifdef STM32F10X_CL+ W( t  q1 _% d) q
  785.   if(CANx == CAN2)% Y: j1 ?$ j9 P/ b# f; T! b- Y: X
  786.   {
    - `+ \+ w1 X8 E, ~0 j
  787.     if(can2InitFlag == true)! G: k: N0 Y* V. R) H: u
  788.     {
    * H& t6 B9 y2 L( d% {- K
  789.       return can2TransmitFlag;
    + ?' o/ y& |3 t7 g/ L4 e; A; Q
  790.     }
    : w7 j  f* l/ ]' t, Q" n3 L6 F' \
  791.   }
    ' O7 q: ?. b9 }8 y- Y6 K) a
  792. #endif /* STM32F10X_CL */+ i( C0 I6 i$ a3 f

  793. * v  p6 I# F& t; c8 S
  794.   return false;
    0 F0 P) |6 }' ^$ _, x
  795. }1 i( S6 ~" |) Z: l

  796. 1 k& n# H) _3 X. R/ [( i
  797. /**
    - n& m# {! B) R) g1 B
  798.   * @brief  This function handles CAN1 TX Handler." ]5 R' ?" e7 M, f/ S+ W
  799.   * @param  None.
    ' E5 E, ^& _  |0 e0 j
  800.   * @return None.
    $ X. y1 R, x$ `" d3 |% J: c  ~  O4 |
  801.   */
    $ b; n3 f, i4 G) v4 `  y
  802. #ifdef STM32F10X_CL9 j# X. w4 X+ @
  803. void CAN1_TX_IRQHandler(void)
    ) W) V; m9 `8 a) e' H5 C3 C! r
  804. #else6 C+ t% Q; ]. B. N9 ^! y
  805. void USB_HP_CAN1_TX_IRQHandler(void)( v9 G! N( ~! J
  806. #endif /* STM32F10X_CL */; Z" ^/ j, n' |# ~7 d# z
  807. {
    " T. c# H- U2 V% g
  808.   if(CAN_GetITStatus(CAN1, CAN_IT_TME) != RESET)( v' x- N1 w6 Q7 R) L" S; d0 z
  809.   {
    4 x8 _/ b, \* j! Y8 M5 V* w
  810.     CAN_ClearITPendingBit(CAN1, CAN_IT_TME);
    - t7 _4 W' H$ c2 \( n
  811. ; K" b& f+ J% Y' F$ W
  812.     CanTxMsg canTxMsg = {0};& U' h7 Z( O# O$ E; a* j8 y
  813.     uint8_t  number   = RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);6 x& n( w" Y+ z! Q# F9 m; {. u

  814. ! D8 d( S1 m* k" Z
  815.     if(number > 0)) X7 \( H; {) [* \* ?# _" H
  816.     {
    6 f7 x& ?+ d* h, r4 C5 g% i
  817.       CAN_Transmit(CAN1, &canTxMsg);
    & N! l0 K: H; B% Z) N  n5 {
  818.     }- ^/ s3 g  }* n# C8 }
  819.     else" N# P! ~1 O* r1 f6 [
  820.     {$ U! G  {2 G) `- v! S0 Q) }" }
  821.       can1TransmitFlag = false;& n  a# v' \  c  W0 v" w1 J
  822. 0 m, P5 i! Y. e1 a+ r- ~
  823.       if(can1TransmitFinishCallback != 0)6 [; M& {, J, s/ d0 P+ H1 l
  824.       {( e% V/ Z. _* B) \1 y
  825.         can1TransmitFinishCallback();) y! ~" T  f2 q2 m! k5 C$ |
  826.       }5 ~' m( Y! g0 ~- Y2 T1 }" v' p: i
  827.     }
    # Q) k8 F! \$ ?1 n8 Z$ I# c
  828.   }( @+ `1 T. _1 q- z5 Q1 e! b; N
  829. }$ x) w. J! z4 ]( l/ h+ T$ m2 x( ?& @  H
  830. / b, k, ]& }) `
  831. /**  F# z9 O9 g! i* z
  832.   * @brief  This function handles CAN1 RX0 Handler.4 G7 p0 t- v1 H& F
  833.   * @param  None.
    9 r( q" {0 Q% R# E# m0 t
  834.   * @return None.6 n' I( W3 q- X4 _0 S6 t/ \( r
  835.   *// i  f& Y1 |* t# k- x. b$ d$ J8 A
  836. #ifdef STM32F10X_CL/ p2 L; ~; x4 ]+ s! R' L8 S4 L' ^
  837. void CAN1_RX0_IRQHandler(void)2 X; J9 j; \4 v; w. Y
  838. #else
      a; i- _5 T% D- w. F& R- }8 V
  839. void USB_LP_CAN1_RX0_IRQHandler(void): v# i) F( P7 U3 b+ h3 E1 ?
  840. #endif /* STM32F10X_CL */
    7 _0 w: m# s/ D, G3 |" c# L1 u
  841. {
    : O8 x& O2 H8 y
  842.   if(CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET)7 Q# B$ {  C8 E8 d& g
  843.   {2 N, ^3 |) W' `4 ^: X1 U' F
  844.     CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0);' o4 [0 V: M) e# j/ k. z% Q% n0 y

  845. 5 ?9 S+ U) {* p' @% G4 T
  846.     CanRxMsg canRxMsg = {0};
    6 ~4 E6 c0 \/ Q3 x! d0 ^7 p7 L
  847.     CAN_Receive(CAN1, CAN_FIFO0, &canRxMsg);
    4 I& m3 l0 ], q

  848. + O/ n2 |6 H5 u
  849.     if(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg) > 0)
    $ ~+ e4 l( v; w7 @4 e% |
  850.     {
    ' {" A) B& T) u5 P2 W
  851.       RingBuffer_In(can1RxBuffer, &canRxMsg, sizeof(canRxMsg));% [- {$ Q$ z; W8 S0 u& Z
  852.     }
    2 J3 ~$ [9 Q0 m; l: g1 o

  853. + Q& v  x9 T; k& `( z. v. h
  854.     if(can1ReceiveFinishCallback != 0)
    # Y9 o- C' \  ?. V
  855.     {
    / W  t. z9 x* N: J* o. R. z8 z
  856.       can1ReceiveFinishCallback();
    * e; n9 X% z. h
  857.     }" [/ t/ s9 }/ ~5 z4 f
  858.   }
    . m4 q9 b! Y5 s0 I5 C( n
  859. }9 |- `1 J  }# @" Z. o% w0 P, l
  860.   C8 L  i, D2 [8 L
  861. #ifdef STM32F10X_CL/ w- c, o+ J- @3 m' `4 R
  862. /**
    / V: Q: Z1 f/ U& \7 ^; y' z
  863.   * @brief  This function handles CAN2 TX Handler.. j, V# k3 p2 [+ h6 H
  864.   * @param  None.
    ) p$ Y9 x1 g3 c5 B3 m7 H) O
  865.   * @return None.
    $ k3 Y) t' Z7 A) v; o; p
  866.   */4 r2 A! n7 t5 c9 K' c0 L
  867. void CAN2_TX_IRQHandler(void)
    , J6 A# `1 \% Y& t7 A
  868. {
    7 I0 a- O9 _+ V" B/ Z3 G4 B' D6 o4 A
  869.   if(CAN_GetITStatus(CAN2, CAN_IT_TME) != RESET)2 f) {( L% g% l* d3 D% y* J2 ^
  870.   {
    - A3 `! b# t3 v( f$ f' O& W& ]
  871.     CAN_ClearITPendingBit(CAN2, CAN_IT_TME);
    ) o; F" V% r: n0 r" w; _# z) M$ _% X
  872. 3 S* K4 _+ Z/ Y6 I( ^: m
  873.     CanTxMsg canTxMsg = {0};1 S' B+ W, k9 O$ n9 B  `7 E; Z
  874.     uint8_t  number   = RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);
    1 Q# Z8 K+ S5 h% w
  875. 4 B' W& U+ b( `) W; ^- D
  876.     if(number > 0)
    4 l: p, j* o8 }
  877.     {$ K& d  U: j7 E& }* _  Z8 |3 i
  878.       CAN_Transmit(CAN2, &canTxMsg);4 M8 K6 K& F$ j) ~" d. P" }
  879.     }
    / ?0 }& Y1 k5 e
  880.     else
    % L% o) c$ e' i
  881.     {
    # D) {. L8 l1 R1 {# u
  882.       can2TransmitFlag = false;
    - Z8 S& H5 h% S7 F/ u
  883. 8 K3 j6 u) z; m: S- `5 E
  884.       if(can2TransmitFinishCallback != 0)' d* k; G, T: t
  885.       {
    4 ^0 c: T- p4 _' N
  886.         can2TransmitFinishCallback();
    6 n, R6 j; x' y
  887.       }
    - P' G( x  Q7 U  X2 ?; e" k2 N$ V
  888.     }' ]3 D8 v) T4 e) T1 [
  889.   }; I4 |# O1 Z' `& w9 J( O
  890. }7 \2 n7 c- e$ D; U  {

  891. % I. J) ~& `  l) U  A  X$ T. V  t
  892. /**8 v4 }0 p4 g% l: X5 m
  893.   * @brief  This function handles CAN2 RX0 Handler.
      ~- d. u( p5 F
  894.   * @param  None.& _% G# e% `  K+ x6 n8 L3 b+ V
  895.   * @return None.9 x. \, D- R: L/ ~
  896.   */
    . \7 G1 s" p/ l9 e5 A
  897. void CAN2_RX0_IRQHandler(void)
    1 n: P7 J5 {/ O% \: I
  898. {
    ) x" l  [( P. u
  899.   if(CAN_GetITStatus(CAN2, CAN_IT_FMP0) != RESET)1 ]. |6 A3 J! ^1 A; w
  900.   {
    4 u: Z% b* q. q! n8 R& r
  901.     CAN_ClearITPendingBit(CAN2, CAN_IT_FMP0);# q' y8 l7 D2 f, k8 e

  902. 4 K( @$ Y& {* o$ A, T8 `
  903.     CanRxMsg canRxMsg = {0};9 V- A2 d+ I$ `. t2 u0 P1 V' b
  904.     CAN_Receive(CAN2, CAN_FIFO0, &canRxMsg);
    2 ?- E- T/ {0 }; F% A) t$ k

  905. ) f; `7 y( B5 s! h- G
  906.     if(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg) > 0)* q" [2 P: a6 W0 F* p7 V
  907.     {2 ?' f0 o( M8 O) g5 M. ^+ r
  908.       RingBuffer_In(can2RxBuffer, &canRxMsg, sizeof(canRxMsg));2 E' l, X( Q% g& J7 k8 ~! j4 x, i
  909.     }
    0 D" O+ ?7 |: D6 l5 C* g4 z

  910. - Y7 b# h+ P2 t0 m5 X( r
  911.     if(can2ReceiveFinishCallback != 0)
    7 l6 Z8 |7 {4 a
  912.     {
    * e- E0 v+ s+ j9 K& o+ _9 F( v
  913.       can2ReceiveFinishCallback();$ Y  S" |# i& K, G$ E" Z7 R
  914.     }
    7 s+ J0 ]8 D7 g# K$ v
  915.   }
    * B, {) s6 n* q9 m
  916. }
    " P+ ?+ q7 t( r. u1 P6 m
  917. #endif /* STM32F10X_CL */: J) x# t" `% `( H
复制代码
( h: _* g7 E. M3 g" Q# q( Z! y

# W9 F8 z4 y7 {4 O  lmain.h 文件& X. V5 H3 @* W. Q
  1. /**
    : O  E. c2 g8 l9 z6 K5 D
  2.   ******************************************************************************1 \* Q. Q$ u  R3 x
  3.   * @file    main.h
    6 D0 `2 Y4 ^6 p' C1 @% ~% H
  4.   * @author  XinLi
    ; _: ^) t, L$ G% i1 G7 [
  5.   * @version v1.0) a# h7 X: o# ~( S# M5 v
  6.   * @date    24-June-2018
    . e( F) U; q" T0 ?
  7.   * @brief   Header file for main.c module.
    4 |- d3 z8 B8 p; a  h- P
  8.   ******************************************************************************. P, M7 T8 o" j5 a. \
  9.   * @attention/ Y5 D/ N( s3 u8 i( F+ C3 [9 A9 W
  10.   *
    4 G* L2 j2 S. i; U
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    9 ?6 w3 x: e/ F0 b4 U. i) ]
  12.   *7 B. c* b  @- m1 e, ~
  13.   * This program is free software: you can redistribute it and/or modify, Y/ B/ o. J4 G6 r9 e1 {+ ~- {# v
  14.   * it under the terms of the GNU General Public License as published by
    1 Q- M' v( a7 F/ E0 ~1 M" {  M
  15.   * the Free Software Foundation, either version 3 of the License, or
    5 y- W+ e9 y, r/ Z" D: t' I
  16.   * (at your option) any later version.
    ; H! G- y0 `8 X6 |! o# q& i
  17.   *" [1 t9 K0 f6 J
  18.   * This program is distributed in the hope that it will be useful,
      n: ], r& V1 }2 l) H/ F  ~' q
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of# `7 W. r: m- h) B1 T1 y" r
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  z% n6 ?2 ~/ G2 V( i, k8 j+ I) p
  21.   * GNU General Public License for more details.
    ; t2 v7 P$ x4 l
  22.   *
    # S/ V5 O0 ?8 K
  23.   * You should have received a copy of the GNU General Public License0 `; h: j! y7 \8 `# P6 M
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>* M4 k7 q. d. a( ^" `4 ?1 `  g- W5 D
  25.   *
    % D5 ^; U) P0 Q
  26.   ******************************************************************************
    7 [2 \' Q6 q. A! O. f
  27.   */+ }5 V; q4 |; C6 d2 D" j

  28. " `' V4 W7 _  \
  29. #ifndef __MAIN_H
    ) j9 f/ v$ J+ v( h3 s$ A6 ^% @
  30. #define __MAIN_H
    ' B2 d+ ^( [* z8 M

  31. 2 i! l9 ~0 r' E0 x
  32. #ifdef __cplusplus
    1 G7 D: x+ @, z8 l+ h$ V7 N
  33. extern "C" {
    + h2 i! O/ G: H" ~
  34. #endif
    $ Z: P. L" C/ W& ?/ k  e9 [, z

  35.   s  l; F. ^" I/ X* Q
  36. /* Header includes -----------------------------------------------------------*/
    9 F# [! U: O6 }/ K. P' @8 u% @
  37. #include "stm32f10x.h"; H% S; a; g* j

  38. & k' m6 X" H6 ]  ~$ I4 r
  39. /* Macro definitions ---------------------------------------------------------*/) ]3 x2 ]  w: i+ }. H; m& V) f
  40. /* Type definitions ----------------------------------------------------------*/2 F; T- @. @9 X( g" N/ U! O  Y! ~
  41. /* Variable declarations -----------------------------------------------------*/' |; s$ H! o; P1 _
  42. /* Variable definitions ------------------------------------------------------*/
    / j% f6 R$ f  R! I" O1 U: E6 X
  43. /* Function declarations -----------------------------------------------------*// Q6 r% l* A  W
  44. /* Function definitions ------------------------------------------------------*/( G% q& h) B% p1 m+ N
  45. + \! K, A; B' K* D- O2 i1 f
  46. #ifdef __cplusplus
    ( }* T* W5 l$ \, K: [& S; d
  47. }
    5 Y7 ?8 D1 ]  T. Z9 p- g# u
  48. #endif5 [; K# U( F/ K7 N6 ?! V5 O
  49. $ J* ^' X% V4 Z9 `; }" @* j
  50. #endif /* __MAIN_H */
复制代码
4 e7 \: J1 d. W- H8 b

* z; r1 Y+ f  i. H! |main.c 文件
  D" p+ \; D( I" d# [& v: c
  1. /**
    5 l6 \1 I3 M+ N: i# g  w- R
  2.   ******************************************************************************+ ^4 s  Q* E% g% d0 K) ^/ s! ~
  3.   * @file    main.c
    - u3 i3 g1 W7 E1 k' _' R
  4.   * @author  XinLi# p1 I4 c" T2 k& P. H
  5.   * @version v1.0
    6 L# _% b1 Z+ U  I# q* Y
  6.   * @date    24-June-2018
    * f% M+ v& G  `2 W6 J/ A. q
  7.   * @brief   Main program body.% {! `) c1 Y/ I! u$ e0 @. V
  8.   ******************************************************************************
    ( O2 U/ Q" l# \3 |; f
  9.   * @attention. }0 i' H$ Y' J# A. d; l
  10.   *
    9 R; Y* H; N2 r; z+ n! J
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    . @, |9 e" U! U& A+ n8 t
  12.   *( S( L' \: y7 ^, X! \. K% z
  13.   * This program is free software: you can redistribute it and/or modify
    ! s5 s/ f) ^8 c
  14.   * it under the terms of the GNU General Public License as published by
    # w+ D4 T) F+ U5 z# }0 e
  15.   * the Free Software Foundation, either version 3 of the License, or% ~  W. x5 m1 X- R7 t' M3 R
  16.   * (at your option) any later version.
    - {) U! c1 N' V' j5 y( |! [3 {
  17.   */ B& Y0 I# a$ P+ v
  18.   * This program is distributed in the hope that it will be useful,8 @2 s) A8 q+ I: s2 [9 }5 T* ~
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      S. o% M' E8 o$ w. |0 O& k
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the& B& W5 V5 e& u9 N7 Z! W: |
  21.   * GNU General Public License for more details.
    , L4 ?; F, T- v* q) J
  22.   *
    & S& z4 b; S$ U* t' u
  23.   * You should have received a copy of the GNU General Public License) a4 B+ s/ g  H1 `
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    5 ]5 i9 H8 x4 J) f, k# A$ a: {' N
  25.   *
    % B* b# X% ?7 P0 c% K
  26.   ******************************************************************************
    : J6 b) E6 Q6 c7 Y$ q
  27.   */. a2 M& }, v) j' ^9 ~' F
  28. ; N6 u& q' b& s  X5 _9 r
  29. /* Header includes -----------------------------------------------------------*/8 Q+ Z0 E1 {, t$ M7 B5 h
  30. #include "main.h"
    # x4 U2 o! l( j8 Q( \! m# |
  31. #include "CAN.h"
    8 p' K! F1 T1 a; ^
  32. 1 f3 T; ]. L' W0 V* [) i% I. u& T
  33. #ifdef _RTE_4 Q. Q: F) v; R; K) {
  34. #include "RTE_Components.h"
    * ?0 W% ]: d/ |! G* N' }
  35. #endif
    : w! Z. c' B* F0 E/ h. j! V

  36. : ?0 t* V2 s3 x/ g4 r& S
  37. #ifdef RTE_CMSIS_RTOS2
    * c# @' H5 f: d) k! t
  38. #include "cmsis_os2.h"1 h) ]: j  l. K+ e) w$ j: |
  39. #endif
    - @% S0 I0 D: {( c
  40. # N1 s% [" `8 C5 g: A% {% j  `
  41. /* Macro definitions ---------------------------------------------------------*/
    5 F! O! S! l; ?; N' Z- S  e
  42. /* Type definitions ----------------------------------------------------------*/, Q* Q9 v8 e7 G6 {
  43. /* Variable declarations -----------------------------------------------------*/
    1 k# s, [  T1 n: o
  44. /* Variable definitions ------------------------------------------------------*/
    . g% K! L; I" L3 E
  45. static CanTxMsg canTxMsg = {0};  r- `/ Q  }% b% u1 D2 z
  46. static CanRxMsg canRxMsg = {0};
    $ c5 Y. H1 u2 P6 k7 T

  47. , y, J5 M  b' m% ?3 r
  48. /* Function declarations -----------------------------------------------------*/$ `& A7 e' h" ], C5 s  S0 X* y
  49. static void SystemClock_Config(void);+ f- C# t- P( C
  50. $ H% V0 `& }% M. z  ]' }& Y2 t6 L
  51. /* Function definitions ------------------------------------------------------*/
    4 [; B* L; U" H3 `& J

  52. # m8 g% D; J( r! z! g, w
  53. /**
    2 j) c& \) @: Y; h( W
  54.   * @brief  Main program.% C1 }( M- z& O, N  C& A
  55.   * @param  None.. H0 c' s3 `, r9 r! \
  56.   * @return None.2 y$ m4 V* u7 u& t+ [
  57.   */; z$ k' ~# D" I1 e
  58. int main(void)
    1 t* J8 }0 z2 c: k5 q
  59. {( p3 ?6 E# D2 i& A* y
  60.   /* Configure the system clock to 72 MHz */
    8 T+ U  R' K1 f& e
  61.   SystemClock_Config();
    " }6 W: [" B: k
  62.   SystemCoreClockUpdate();
    0 ~% W  F5 s) S4 P9 ]
  63. 9 |* }  f: \* m5 L# g+ `
  64.   /* Add your application code here */8 [( y# f( a' V# r$ x5 q# S" b
  65.   CAN_Configure(CAN1, CAN_WorkModeLoopBack, CAN_BaudRate250K, 0xAA55, 0x55AA);
    4 T! {! Z7 V* |9 h8 q
  66. ( A* s5 q& H9 D, F7 p5 e& s, I* c
  67. #ifdef RTE_CMSIS_RTOS2
    + |7 e6 S2 G/ J- V+ q
  68.   /* Initialize CMSIS-RTOS2 */* M2 r3 n4 H2 b/ @: j$ `! a
  69.   osKernelInitialize();+ U1 p& c7 f8 f" `0 R8 c( d
  70. + c0 e, d# }% r/ _! `
  71.   /* Create thread functions that start executing,
    1 j' b: E3 Q: L; m. z4 P
  72.   Example: osThreadNew(app_main, NULL, NULL); */5 I3 H0 c0 w" d

  73. , ^  G7 L* R$ s" H
  74.   /* Start thread execution */0 D2 u3 F6 S  L: |  l$ I6 I# Z
  75.   osKernelStart();
    3 {1 N- W) u0 F( W" r  E& n+ j2 v
  76. #endif
    , a$ G/ ~4 i% f: k. M+ O( K" ?
  77. ( x/ A- j7 m0 X3 j. E
  78.   /* Infinite loop */8 F: y5 Q3 x- j
  79.   while(1). D+ b3 U3 d& Q& C+ Y8 D7 j
  80.   {6 D7 {- d' Q. Z  g$ P* O
  81.     canTxMsg.StdId = 0xAA55;/ n" `! T! B) X$ d1 [9 w9 r% o- M
  82.     canTxMsg.ExtId = 0x55AA;  `  a  d3 d: O4 r, K2 s2 b6 Z
  83.     canTxMsg.IDE   = CAN_ID_STD;
    5 T0 c: n4 I+ ?% C/ q
  84.     canTxMsg.RTR   = CAN_RTR_DATA;
    ) l- H. s8 l; ]% K/ b
  85.     canTxMsg.DLC   = 8;+ ^0 j& [+ B+ j+ ~
  86. % \. \4 g' d. J. t/ N
  87.     canTxMsg.Data[0]++;# h0 n( H( T6 ?% u2 q1 V9 ~# i
  88.     canTxMsg.Data[1]++;( R) [+ m  ], k8 @0 h2 N
  89.     canTxMsg.Data[2]++;
    - F( ?& b1 T0 n- x: B
  90.     canTxMsg.Data[3]++;3 S% o/ G. S) z$ ?
  91.     canTxMsg.Data[4]++;0 Z, |/ x, m" q3 m* N
  92.     canTxMsg.Data[5]++;
    . P+ [0 Q2 q$ a2 B- |% L0 c
  93.     canTxMsg.Data[6]++;
    1 b  w/ H3 c. ^! x& c. }
  94.     canTxMsg.Data[7]++;; c4 j' I9 f# N, M) \
  95. % r# j, ^& _8 \8 r3 j. @
  96.     CAN_SetTransmitMessage(CAN1, &canTxMsg, 1);
    - \5 w' b  A# q9 Z9 R0 K
  97. 4 x% }4 Y  g) a' C
  98.     while(CAN_IsReceiveBufferEmpty(CAN1) == true);
    , p  P7 L: O- X# |( F
  99. : `. U. Z' i% e% Y8 H% q
  100.     CAN_GetReceiveMessage(CAN1, &canRxMsg, 1);4 a; @' u/ k1 Z" Q; @# Y
  101.   }+ d# f1 w9 {1 Z$ W! n
  102. }- Y) d( \: {) L/ f; X
  103. ; v: E; a+ j) ~# w- {3 S, d% @0 b
  104. /**+ \1 [! K/ D) i
  105.   * @brief  System Clock Configuration.3 M. P8 Z2 Y: z
  106.   *         The system Clock is configured as follow : 2 c3 z7 o6 B# s7 j
  107.   *            System Clock source            = PLL (HSE)
    - Q% q8 i% Y* |. V, X
  108.   *            SYSCLK(Hz)                     = 72000000
    ; w; t& A# l/ Y3 ~
  109.   *            HCLK(Hz)                       = 72000000
    5 i* k/ y0 f1 ?6 y$ e5 \1 k$ }
  110.   *            AHB Prescaler                  = 1$ O4 |5 k! E5 F9 c0 j
  111.   *            APB1 Prescaler                 = 2. h  \  P- F- L3 N# f! q7 O6 x8 }
  112.   *            APB2 Prescaler                 = 1
      {7 G# J: _2 Q7 a
  113.   *            HSE Frequency(Hz)              = 8000000
    6 ~/ ?% [4 R# _& f# F" i
  114.   *            HSE PREDIV1                    = 1
    # w- R4 T  ]. {2 ?6 l
  115.   *            PLLMUL                         = 95 M2 w6 i' ?+ E- S8 s
  116.   *            Flash Latency(WS)              = 2
    / ^- V- x: V" Y! t: b
  117.   * @param  None.
    ) W' ~+ A# C# k" I! }4 i3 ^
  118.   * @return None.4 ]% |& F0 R4 M) j, f2 W0 Q% t
  119.   */
    + J+ P( ?% Q- ]. S7 x5 u7 a1 x
  120. static void SystemClock_Config(void)
    , o6 x/ w- [. J( w
  121. {. w+ p4 q/ \% e! Q
  122.   /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration */4 |$ I  t( I3 a
  123.   /* RCC system reset */
    . S4 [$ }# N1 b  ]8 V
  124.   RCC_DeInit();
    # j# X$ H8 M1 S7 b4 B0 o, a

  125. + C5 J; V+ L! N: m( D+ p4 \4 d( x
  126.   /* Enable HSE */
    9 `* F' d" [" o% v2 M+ i% n: H
  127.   RCC_HSEConfig(RCC_HSE_ON);3 \' X) ~. J0 r& ^9 p

  128. $ e8 X* b+ m0 ]8 C
  129.   /* Wait till HSE is ready */! c4 T% U. T/ M  e
  130.   ErrorStatus HSEStartUpStatus = RCC_WaitForHSEStartUp();/ f/ [# D! t! W0 r& s
  131. # F4 ?7 M7 N. q: Y) Q
  132.   if(HSEStartUpStatus == SUCCESS)
    % q2 b+ U% `; ^5 z
  133.   {' Y' x, }, ]; {4 ]7 q: L
  134.     /* Enable Prefetch Buffer */
    ! S4 y- Z/ M: i* S' C
  135.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
    % a% @5 f" j  z+ D2 X2 W! ~; m
  136. ; B1 d8 J" R1 E1 f; s
  137.     /* Flash 2 wait state */4 Z) ~, a1 q0 s4 n* u0 d
  138.     FLASH_SetLatency(FLASH_Latency_2);# B  ]; n- c/ l6 h3 b, b% t" l

  139. ! b' F  i4 v% a" b6 Q" u
  140.     /* HCLK = SYSCLK */
    ! }' S" r8 y, A8 R. b. J; N- I
  141.     RCC_HCLKConfig(RCC_SYSCLK_Div1); 7 [0 Q! N* W5 m  e! v- \4 {% u

  142. 8 N2 E3 u" z* D! r9 s, m
  143.     /* PCLK2 = HCLK */
    , |+ R* X% m9 y3 [9 w6 P
  144.     RCC_PCLK2Config(RCC_HCLK_Div1);
    9 _% q/ @; m, O( D. \: @

  145. ! d% N9 D7 C7 o3 U
  146.     /* PCLK1 = HCLK / 2 */. g& Z# P! F  H* i2 e$ s2 Y
  147.     RCC_PCLK1Config(RCC_HCLK_Div2);2 z" `( V- ?+ b
  148. 6 z: D" x5 W1 ^2 U( d/ p
  149.     /* Configure PLLs */3 O" d% T/ A5 z' H
  150. #ifdef STM32F10X_CL2 a. B! k" c# P* i* h4 q; m; K2 |
  151.     /* PLL2 configuration: PLL2CLK = (HSE(8MHz) / 2) * 10 = 40MHz */! l4 k; a4 M- }; o) Y! v( E8 {
  152.     RCC_PREDIV2Config(RCC_PREDIV2_Div2);: W9 I' L: c: x- C3 D# L
  153.     RCC_PLL2Config(RCC_PLL2Mul_10);2 ~/ E- u: Y1 h3 ^0 \4 ?

  154. ( F7 A$ ~1 W7 C/ Q8 X
  155.     /* Enable PLL2 */
    + g  A6 i( g  E+ N# E" N" ]: Y9 |, r
  156.     RCC_PLL2Cmd(ENABLE);; C0 b  A" a& U
  157. 8 e. I6 [$ _' F; f8 |, r
  158.     /* Wait till PLL2 is ready */, M, _3 h5 k* ?3 @
  159.     while(RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET);' `4 O) x) Y6 J- g$ ~9 h9 k  T! k' t+ l
  160. # A5 f& j+ `2 C) _
  161.     /* PLL configuration: PLLCLK = (PLL2(40MHz) / 5) * 9 = 72MHz */( g7 A4 |1 [" ^; h. ?& r8 U
  162.     RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div5);
    $ Z5 a$ R9 E& I9 q
  163.     RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);
    " Y% M( c" ^' N! _
  164. #else; f* z, e+ D$ ~5 [; z4 z
  165.     /* PLLCLK = HSE(8MHz) * 9 = 72MHz */; G+ S: [5 d$ w/ @% U
  166.     RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);6 N$ E+ K9 B! P9 `4 p, A& G- n
  167. #endif
    ' s, _2 D9 z  H% `

  168. 4 g: l7 d$ x0 w0 z2 V. ]' X; b2 e/ K
  169.     /* Enable PLL */# G2 L' k% T- I
  170.     RCC_PLLCmd(ENABLE);' [) W* H. ~2 \1 e, Y7 u
  171. 3 l- D" V: M; _7 k4 r
  172.     /* Wait till PLL is ready */' k6 x  J7 [# J7 G; @
  173.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);. m: Z3 v5 A. M7 U6 q4 _

  174. 5 M( Q5 Q0 A# @
  175.     /* Select PLL as system clock source */# }$ w, q- g& {1 Z% m  @
  176.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    : U1 c! y+ L% G
  177. 2 p* J' C4 R9 k: w! [
  178.     /* Wait till PLL is used as system clock source */
    $ ^- _0 ?  l- I
  179.     while(RCC_GetSYSCLKSource() != 0x08);& h" ~- j6 O. y1 ]
  180.   }9 Y5 P$ h2 }9 p7 m2 _
  181.   else0 ?$ Q) U5 k+ {- h3 u
  182.   {" l) C) _$ q: P2 q8 L0 g
  183.     /* Disable HSE */
    ( [. v! ?% e8 L3 d8 k
  184.     RCC_HSEConfig(RCC_HSE_OFF);" ^' p$ e  I9 e6 l

  185. 5 {8 W" `$ j- n2 c8 K0 q
  186.     /* Enable HSI */& w( S% t8 [* ]- ]! w( e: @$ t4 J
  187.     RCC_HSICmd(ENABLE);: R4 N" k2 p, @- p+ e  o

  188. 2 D" R5 l8 Q% }4 ]
  189.     /* Enable Prefetch Buffer */
    * s9 o+ p# a6 [$ ~
  190.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);& a4 y- L; g/ ]
  191. # u& H) w& c4 u. [
  192.     /* Flash 1 wait state */2 J- d- ?- B- U: g- w
  193.     FLASH_SetLatency(FLASH_Latency_1);
    7 N6 u# e) A( u  n6 ^- U7 M

  194. + i, a' l! _3 c
  195.     /* HCLK = SYSCLK */
    3 |1 T) R7 S4 }4 z2 m& |/ D
  196.     RCC_HCLKConfig(RCC_SYSCLK_Div1);
    4 r8 J' ^7 h* |6 _

  197. ) n9 m* f, t6 G% U2 E: b
  198.     /* PCLK2 = HCLK */- R9 n; l+ P7 R; {$ M
  199.     RCC_PCLK2Config(RCC_HCLK_Div1);
    ; n. |8 v# Y8 O, D/ F/ z% q' ~

  200. $ n$ R( M) Z2 ?4 E
  201.     /* PCLK1 = HCLK */
    6 i3 `  F) v8 F( V' q+ Z- u
  202.     RCC_PCLK1Config(RCC_HCLK_Div1);% W$ u. L( e6 ]7 k3 D
  203. / B% K# u' a% E7 o
  204.     /* Configure PLLs */
    7 C2 r! m+ b! d& R0 o: q: G
  205.     /* PLLCLK = HSI(8MHz) / 2 * 9 = 36MHz */
    9 |8 |% }( m& c
  206.     RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_9);
    " n% D' {5 a! b

  207. $ U. \/ |  T# C) k" I/ l
  208.     /* Enable PLL */9 T! [: |5 m8 ]! z# w5 q! R  j
  209.     RCC_PLLCmd(ENABLE);
    ' j( h+ u+ R9 ~7 ^7 ~6 S, S( G
  210. 9 D" W7 F4 s( i7 B1 @$ e2 _5 A
  211.     /* Wait till PLL is ready */3 y# }- H$ n4 }' _0 I
  212.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
    : a- w1 b  q) V/ h* ?
  213. 6 s2 j( A2 J# U) V9 J* x" D
  214.     /* Select PLL as system clock source */
    4 c+ E  a% }0 M& V
  215.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    3 n. i* y# i! E- I! S% _' I6 }* z' [

  216. ! R( I  s8 d0 P- M, X+ }2 {
  217.     /* Wait till PLL is used as system clock source *// f' ]& T; k6 Z/ J% q
  218.     while(RCC_GetSYSCLKSource() != 0x08);5 A+ H6 V. {, ?( T
  219.   }
    ! W5 e' z' k7 i0 j/ _
  220. }
    : s) B: K6 k4 I
  221. 9 H" _2 j; A3 x2 H' _! I) S7 |
  222. #ifdef USE_FULL_ASSERT3 ?8 u3 G3 p1 |# f& n8 [
  223. /**" \( \7 s8 i& E* `; ?5 [
  224.   * @brief  Reports the name of the source file and the source line number
    + _% _* A5 k0 a8 X
  225.   *         where the assert_param error has occurred.4 n0 ]' B8 i2 f
  226.   * @param  file: pointer to the source file name.
    ) I3 W$ y$ {9 n
  227.   * @param  line: assert_param error line source number.
    : s  j; \  R- j+ d+ r, h
  228.   * @return None.
    # g8 s: k* X" l- b
  229.   */7 a/ l0 N5 X) l) v! G
  230. void assert_failed(uint8_t *file, uint32_t line)
    5 m$ X$ O$ B* O# c- a3 ~
  231. {
    " U4 x9 s$ n8 |2 F* S8 H
  232.   /* User can add his own implementation to report the file name and line number,% q7 ]. x3 [$ F  x/ ~
  233.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */$ [# K+ O: h4 o2 \- U3 m  M

  234. + a% M2 E0 D3 L8 e2 v- [: S
  235.   /* Infinite loop */9 i- o+ `5 `+ G
  236.   while(1)
    ) O! L; g9 P" w! k4 Z5 V/ z+ U
  237.   {( \8 d3 q) h! [* O- g
  238.   }, k& U3 ^: T5 A1 t. `/ n+ i' _: w
  239. }
    # d) k% I( [: E6 N! \3 X* R
  240. #endif
复制代码
$ S) F- a# t" ]4 c7 B  F5 C. N
3,注意  Y' L! U% r8 b, G

& ^8 k6 k4 g8 ]CAN 消息发送缓冲区和接收缓冲区的大小,可以根据应用的需求进行修改,缓冲区使用的是堆内存,需要根据缓冲区大小和应用程序中堆内存使用情况进行配置。! i8 K% v& d( r) i8 ~, f- p' u

2 Q2 |# G9 m  I2 n0 Z- D! ?( p
, o8 J$ q6 G  r+ k; R' \" v0 s' x# q6 u. Y
收藏 评论0 发布时间:2021-11-26 17:00

举报

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