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

【经验分享】STM32F1(CAN)

[复制链接]
STMCU小助手 发布时间:2021-11-26 17:00
1,开发环境
5 y. H7 v' U! W, m! g0 ~9 T
/ g( q6 `/ @) H+ i5 O1,固件库:STM32F10x_StdPeriph_Lib_V3.5.03 C: c  C+ e! D, U, j6 l7 B$ h

7 }% ^5 O/ q8 D/ `* V7 _3 Y9 j2,编译器:ARMCC V5.06
9 T* R: D7 t, X# D
+ J; G4 c7 {0 C) K: E0 S3,IDE:Keil uVision5
- t, @7 H6 i5 y  c- U
& x5 e- j. b" q: R4,操作系统:Windows 10 专业版
6 n& Q4 n. g( n! X: v- M, \" |' T

; P# {2 H! C5 `' t2 d4 V# O2,程序源码; _6 u1 v/ {" `8 ~- C  r& [) v8 Q& K

2 D, J. R8 E" `3 X0 hRingBuffer.h 文件% _; p+ C  J/ c3 n5 H/ @
  1. /**7 Z: q/ P. |% V2 o% Z2 j! T: O4 g
  2.   ******************************************************************************% g8 X+ B3 z6 ]* W
  3.   * @file    RingBuffer.h
    : m: C; G5 g% N5 I
  4.   * @author  XinLi
    2 F6 ?) B3 I" }- k8 R' w) X$ u3 y- C
  5.   * @version v1.1
    1 l) s% G! V! z
  6.   * @date    15-January-2018* O5 E& c8 t9 E( K: e8 x# }; J3 Z
  7.   * @brief   Header file for RingBuffer.c module.& M' H, z# g1 `' `5 L
  8.   ******************************************************************************
    ) S2 C# k1 l' M6 S$ g! c
  9.   * @attention
    ( v7 M! ~8 J- ~5 e+ `* f* A& P, I
  10.   *% S: y" S# r1 V3 ~# y- F/ u
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>. ~5 M' f  o  ~1 ~
  12.   *( }7 p: n/ o. i2 }" U" j* t
  13.   * This program is free software: you can redistribute it and/or modify
    9 f$ Q2 @- k+ L
  14.   * it under the terms of the GNU General Public License as published by
    $ Q4 O6 ^  N# K4 V, W+ |1 q! @+ R6 l
  15.   * the Free Software Foundation, either version 3 of the License, or- j8 I7 C4 Y; n0 p# f" J
  16.   * (at your option) any later version.
    4 B+ p. x' L2 V# Y* F
  17.   *
    1 f* V2 b% [0 S8 T# d
  18.   * This program is distributed in the hope that it will be useful,
    + A3 T- k( C! k9 i6 b
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of0 K2 D( g0 p3 _0 P/ e, V% N+ C
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the! ~3 Y  D! o/ l6 l! G/ m; t( S
  21.   * GNU General Public License for more details.- S- ~" o5 `: X7 z1 p( Q+ R
  22.   *; F4 \, l% S) E
  23.   * You should have received a copy of the GNU General Public License& X! P7 E9 l; Q* [& j
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    + D0 K" D( U0 O5 J1 u8 h3 a8 H( o
  25.   *- |8 b- o; X8 p; u
  26.   ******************************************************************************
    + d; G7 y; s% a! E# {% }
  27.   */1 z+ t8 n: ~9 |+ N2 F
  28. + C& D7 v" J9 u2 G: u" P8 @
  29. #ifndef __RINGBUFFER_H. I: V1 q; \. E7 }( d$ O
  30. #define __RINGBUFFER_H# A6 d) j4 z* f/ e. C  t% U0 P: F

  31. 5 p0 |& }/ d! H1 _, E
  32. #ifdef __cplusplus5 y3 |9 z( z; R6 S/ _
  33. extern "C" {
    ' T. \- i% P* W8 b
  34. #endif9 M9 G2 C2 I, ~; @

  35. " ~% q: M: r$ w  W) _
  36. /* Header includes -----------------------------------------------------------*/9 E+ F7 D2 E1 Q: E9 R, A
  37. #include <stdint.h>* ]' t' y& x& N- p
  38. #include <stdbool.h>  J6 V/ r4 K, s3 B9 J% j
  39. #include <stdlib.h>* A6 e! a% F( {9 \0 f

  40. - j- a2 E8 {6 }% r7 T0 O5 j
  41. /* Macro definitions ---------------------------------------------------------*/
    3 `" T- a! E" ~: g- v$ h
  42. #define RING_BUFFER_MALLOC(size)  malloc(size)# [* m7 a4 |. |) Q2 u
  43. #define RING_BUFFER_FREE(block)   free(block)3 W5 u4 S! u1 E# C9 g& c
  44. , I1 U/ `. D( K  h% ]
  45. /* Type definitions ----------------------------------------------------------*/
    * ?# N- b+ C% Y/ e0 U7 |
  46. typedef struct5 q! K. q# M1 S/ I6 b
  47. {
    $ Z" `3 p7 N. U
  48.   uint8_t *buffer;
    7 k4 S1 R' y5 l; F  n
  49.   uint32_t size;
    5 S' g  x8 Q2 z9 c3 Q# E. I
  50.   uint32_t in;0 O% l) w8 X. G. r, s
  51.   uint32_t out;
    ! w- `- Y- k1 N5 ~
  52. }RingBuffer;
    ! h' O! t3 _& l/ b# k

  53. ; S) J% Q8 x' B& N
  54. /* Variable declarations -----------------------------------------------------*/
    0 _+ M9 }* g1 V
  55. /* Variable definitions ------------------------------------------------------*/, z5 W" E# l- `  H6 u) W
  56. /* Function declarations -----------------------------------------------------*/
    ! d+ R7 C# Q- d  @. w
  57. RingBuffer *RingBuffer_Malloc(uint32_t size);& K0 ?1 u+ E5 }- W
  58. void RingBuffer_Free(RingBuffer *fifo);
    . `9 @, U' c2 S( c  Q1 f

  59. + Q2 S6 L1 x: N8 G8 H; N
  60. uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len);% e" w$ D, e& P  }3 P" [/ I
  61. uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len);
    " _: ^& k/ m5 {2 x' S, O( L$ V
  62. ( Q/ S+ Q# [6 T* F% i
  63. /* Function definitions ------------------------------------------------------*/- @+ ~' @9 [, p( ?: O0 |2 a2 w

  64. . [% d" K3 N5 v3 h# N
  65. /**! o& r9 S" t2 h. }5 ~9 w
  66.   * @brief  Removes the entire FIFO contents.: H$ G! ~! c. {" L5 L0 o; j
  67.   * @param  [in] fifo: The fifo to be emptied.
    3 [) [: d/ R2 [3 \2 v
  68.   * @return None.8 F9 ]3 ?$ ]/ [$ Z  u+ |! V* ]' K. \1 \
  69.   */2 b4 U. G$ c( P- l3 l" c% C/ r* [
  70. static inline void RingBuffer_Reset(RingBuffer *fifo)* d5 }9 u6 V, D" r# Z# G
  71. {. C1 w8 m' k3 p3 S- @/ V2 y" c/ N
  72.   fifo->in = fifo->out = 0;8 I- }  |. I! K/ H9 i
  73. }% J0 g* Q8 m7 |$ ]7 x

  74. % k! Y+ M: i; t
  75. /**' m' z$ l2 c2 H, h/ ~
  76.   * @brief  Returns the size of the FIFO in bytes.6 Y) q$ k3 [6 D8 Y3 d
  77.   * @param  [in] fifo: The fifo to be used.9 V6 k* O3 b1 e& c
  78.   * @return The size of the FIFO., s; y* Y& A" ~$ ]% i
  79.   */
    ( J8 o# \# p' b" u
  80. static inline uint32_t RingBuffer_Size(RingBuffer *fifo)! K" |: w% y+ E
  81. {  @7 d- [* t1 z* c
  82.   return fifo->size;0 j  o# V6 t2 y) e/ m/ A( v2 S( B
  83. }
    7 n, Z0 f3 C6 Q! L# z9 h: u9 y

  84.   y1 S; O) F: b+ C/ o2 G* W8 W
  85. /**
    & M0 N: ]3 `$ R2 {
  86.   * @brief  Returns the number of used bytes in the FIFO., s4 ]: u7 g% P, N% {
  87.   * @param  [in] fifo: The fifo to be used.* t+ h) I! H( D4 t2 [8 n
  88.   * @return The number of used bytes.
    * m4 }. X/ a6 C* R. a( `
  89.   */
    + d9 A8 ]) ~: ~" l
  90. static inline uint32_t RingBuffer_Len(RingBuffer *fifo)
    2 o. S" N, O' @/ i2 a
  91. {& v# ?! I/ P1 _
  92.   return fifo->in - fifo->out;% T, f- n+ r7 ~$ X* N. r
  93. }( {+ o# n9 [9 N1 j8 l. Q  |- Z  b

  94. " s- |3 r; _3 R- I
  95. /**& ~. c# G1 Q8 `
  96.   * @brief  Returns the number of bytes available in the FIFO.
    8 w: s& s# }' @5 H( z) C
  97.   * @param  [in] fifo: The fifo to be used.
    - R. S* J0 v! `: ^6 d+ }- C: H
  98.   * @return The number of bytes available.) `, [5 n1 l( ]2 r2 A
  99.   */; `% p( M/ x8 c7 M( ?2 M9 x
  100. static inline uint32_t RingBuffer_Avail(RingBuffer *fifo)
    : @) A) W# R4 |4 W9 g
  101. {
    * U- E0 Q, W( ?) W8 @& _
  102.   return RingBuffer_Size(fifo) - RingBuffer_Len(fifo);
    6 \# s5 y- K0 M4 R" _) P
  103. }
    $ n- t, ^& C3 W' u
  104. & p2 T- E0 A8 R1 z
  105. /**+ p9 s1 N* t0 r
  106.   * @brief  Is the FIFO empty?/ S( Z9 D; c& X( x" }- i- p1 o
  107.   * @param  [in] fifo: The fifo to be used.' h1 B; S( W2 y2 m
  108.   * @retval true:      Yes.
    * Z# h/ w8 j" n8 R
  109.   * @retval false:     No.  Q; u) z+ C( |3 r6 Q# s3 q
  110.   */
    + ^" V. p" L9 }6 h2 y% ?0 R" Q
  111. static inline bool RingBuffer_IsEmpty(RingBuffer *fifo)
    2 U+ Q/ d: ~0 j, Y2 _
  112. {' Z# v  H) f) r& ], O1 ~
  113.   return RingBuffer_Len(fifo) == 0;, l, x8 X/ h" l" e2 v
  114. }; `- s* O' w5 x( ?) {
  115. 2 o1 {. C+ `% H5 y3 q
  116. /**
    1 V0 e0 U; R6 T/ K
  117.   * @brief  Is the FIFO full?
    - w; T6 X1 {( X! W' P: O: p+ W0 E
  118.   * @param  [in] fifo: The fifo to be used.
    ( z# O7 Q( F8 d) q* u
  119.   * @retval true:      Yes.9 l# z2 O; z: X; v3 M. L
  120.   * @retval false:     No.# m7 z4 b2 K  g
  121.   */
    ( Q6 l  E6 y1 C: o
  122. static inline bool RingBuffer_IsFull(RingBuffer *fifo)
    . o9 ~/ O* a1 M' R6 e
  123. {6 }+ s+ j4 a, I' z
  124.   return RingBuffer_Avail(fifo) == 0;5 ~: X: s! x; S! A" l2 r' ^9 w7 i
  125. }
    ' ]# w0 X/ m8 M- N
  126. 7 c, \5 x% q, u) o* }
  127. #ifdef __cplusplus
    1 J  K- Y& W9 a) s
  128. }: W3 E; R" B5 J
  129. #endif
    / ?, f+ N  z7 ?1 `  r

  130. 2 ~- z9 k* w4 p, E5 u
  131. #endif /* __RINGBUFFER_H */
    7 r$ E+ q( F3 p: G' a
复制代码

7 V( [, U% f9 Z# k6 T- }8 T3 W7 P' n, x) N
RingBuffer.c 文件
/ M5 U# s/ Q* f3 D- @
  1. <div>/**2 v' r) j: N* ?  K: [
  2.   ******************************************************************************7 B+ p) W2 |# M6 e3 A
  3.   * @file    RingBuffer.c
    0 x9 U+ H+ I& y; b6 J
  4.   * @author  XinLi
    - B4 G% f- v5 ]
  5.   * @version v1.1
    0 r' p6 K! I% J; ^1 L
  6.   * @date    15-January-2018
    6 u( D6 R/ ]3 `9 o
  7.   * @brief   Ring buffer module source file.
    0 v) P- ]$ d: p0 k
  8.   ******************************************************************************
    ( G. O" q6 ]# h
  9.   * @attention2 u3 s' g( [8 l: D2 i, D5 d8 t
  10.   */ c1 t" F8 k1 Y% ?0 Z: S
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
      d7 r. h3 [; U
  12.   *
    0 ~! U/ ~$ ?" A. r5 a! Y4 [/ }
  13.   * This program is free software: you can redistribute it and/or modify
    / k3 @' ~, e  m$ s4 R2 F
  14.   * it under the terms of the GNU General Public License as published by
    + Q2 X2 }6 _9 a" W
  15.   * the Free Software Foundation, either version 3 of the License, or4 a( _6 k$ L" U& s8 w+ I
  16.   * (at your option) any later version.
    . A0 p! g8 |: V8 {) S* \: o2 e
  17.   *
    ( g" e8 K' _: u$ g
  18.   * This program is distributed in the hope that it will be useful,) l$ Y$ b6 q4 C, K- g9 O' q  j
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    / Z5 i; }$ Z1 g7 t) K- C
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the. w4 r, P- `* K& |' R
  21.   * GNU General Public License for more details.
    % w: ~. O9 q/ [5 ?
  22.   *
    ; x) f% H. Q; \8 `  G
  23.   * You should have received a copy of the GNU General Public License% _% M# j! G( T1 L* S
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>6 l% L3 n  x& e$ }
  25.   *
    8 n6 Y+ @" P3 P& C% J; ~
  26.   ******************************************************************************/ ^, _* p" X# r+ u8 z/ n: M
  27.   */
    6 q" ?! g7 F0 r7 p/ d

  28. ) ?1 `7 M1 i4 S: O5 P
  29. /* Header includes -----------------------------------------------------------*/7 F( c7 p8 N! w$ c
  30. #include "RingBuffer.h": Y) e9 _: M3 u
  31. #include <string.h>, M' ?5 W9 K) ^+ G6 M; u
  32. 8 X" ~( I) E9 q1 |+ h
  33. /* Macro definitions ---------------------------------------------------------*/
    , {' ~4 I  d3 W
  34. #define min(a, b)  (((a) < (b)) ? (a) : (b))7 q5 G7 S% w0 v6 d! Q# X/ z
  35. 2 N3 m# \, a5 a2 d- `6 K8 b
  36. /* Type definitions ----------------------------------------------------------*/+ O/ `+ e0 @+ f) p
  37. /* Variable declarations -----------------------------------------------------*/$ C( [" B0 S$ h7 {* z
  38. /* Variable definitions ------------------------------------------------------*/
    + d5 m, W% S2 U% W. Y. W5 D
  39. /* Function declarations -----------------------------------------------------*/
    1 }5 H& r; f& N) u( l. X# t4 f
  40. static bool is_power_of_2(uint32_t x);
    ) N; Y: s; w: h% a+ U; i
  41. static uint32_t roundup_pow_of_two(uint32_t x);. q8 J0 U. v3 _6 z2 @1 D
  42. + f( E4 h% h( ~) \
  43. /* Function definitions ------------------------------------------------------*/
    : }& v  v& q2 S- A! c

  44. & M- [; e" I5 G# D/ ^: ~. C
  45. /**
    + E8 g) i+ u) f2 Z5 v$ l
  46.   * @brief  Allocates a new FIFO and its internal buffer.6 I$ u4 Q$ ]* [  x( @/ n  f: Z( H
  47.   * @param  [in] size: The size of the internal buffer to be allocated.% J. n: b7 ?/ N8 E  H6 Y6 k+ v
  48.   * @note   The size will be rounded-up to a power of 2.3 U6 y' f# e4 y$ V1 Z( N, ~
  49.   * @return RingBuffer pointer.
    - I& Y/ M) W+ J% x% M
  50.   */
    4 w7 ~: O  \0 S8 ~: P- C1 D# l
  51. RingBuffer *RingBuffer_Malloc(uint32_t size)7 s8 c6 ?* w$ k+ c2 n9 s0 X5 X3 R6 e
  52. {7 _" U7 a" R) `( a+ X' E9 Z
  53.   RingBuffer *fifo = RING_BUFFER_MALLOC(sizeof(RingBuffer));
    ( |- O7 |6 }% A1 Q3 n, Y7 |
  54. , Y4 a! ]$ X7 c/ j* J* K  D
  55.   if(fifo != NULL)9 l- o; r; f" u5 f
  56.   {1 y! k' Y* Q8 g$ L0 M8 K
  57.     if(is_power_of_2(size) != true)' x$ K& c8 F' o; ~! w! _. d
  58.     {
    ! o) |' G) c% q: w
  59.       if(size > 0x80000000UL)
    5 J7 X' G5 _6 z. d
  60.       {
    $ G+ J9 @# n) s0 Z
  61.         RING_BUFFER_FREE(fifo);
    * P. c, P. E% Y; w, B
  62.         return NULL;
      F: z. P+ s0 E: \# W
  63.       }
    ' T5 E$ b' R% v6 O* q+ e  V

  64. ) |# d1 t) M, Z9 [
  65.       size = roundup_pow_of_two(size);
    6 H/ [- j( B. @) m3 _8 ~. R  ?3 b
  66.     }" P5 Z6 _% z6 @6 @- b. k4 b

  67. ) d6 z- Q4 N, L! S: `3 ?
  68.     fifo->buffer = RING_BUFFER_MALLOC(size);
    5 I. m1 T9 g, g2 w" d
  69. , k. Y8 M. n9 h# R3 ?$ q3 q) l. n; ^
  70.     if(fifo->buffer == NULL)
      _. h# j4 K, T& ?; l; p
  71.     {# p: I% G0 c$ W' \+ o
  72.       RING_BUFFER_FREE(fifo);
    3 x9 O8 R, D, ?% v. Z
  73.       return NULL;- ?% K+ g" \" y$ A, M# j' x/ z' B
  74.     }8 r' _" A5 E5 z
  75. % m7 Q* G6 V' c. N
  76.     fifo->size = size;% G+ ^' [; P. \$ f9 D1 o
  77.     fifo->in = fifo->out = 0;
    # A0 \+ z4 F  r2 i
  78.   }
    # x1 e2 n0 O. \7 i& D3 L

  79. , @5 m% b9 B  U. S: {
  80.   return fifo;( g+ Q( }# p5 H3 Y
  81. }
    % m& Q7 K  C+ t# X$ c* V

  82. # M% r, E2 G* J2 ]7 b
  83. /**9 t: ?% O0 I& ?
  84.   * @brief  Frees the FIFO.
    ( Z) S# z- S2 ]2 y( X- s
  85.   * @param  [in] fifo: The fifo to be freed.
    ' _, u5 G4 K5 Z, ~% ?8 \9 k; i6 P
  86.   * @return None.
    0 c; o) g& [8 l
  87.   */
    * s# y) X: C3 x* f6 F. q( D5 u0 H# e
  88. void RingBuffer_Free(RingBuffer *fifo)" |& L# Q$ u8 t& n7 @, Z) z
  89. {4 M# w2 K; Y5 q. j  ^( P
  90.   RING_BUFFER_FREE(fifo->buffer);8 v& o% D. \. ]% q5 i; Y; x
  91.   RING_BUFFER_FREE(fifo);
    * y7 F  T; P6 }. W/ j* q  Q
  92. }
    ) f* I6 p' d9 E+ u
  93. 8 w  x% F4 z) V9 ~2 {
  94. /**
    ! l# M0 }  ]- l+ P5 J" t
  95.   * @brief  Puts some data into the FIFO.
    # q/ D  I7 d0 @, ?0 F
  96.   * @param  [in] fifo: The fifo to be used.2 C  Z# X8 h7 ?, Y0 m) J  Z
  97.   * @param  [in] in:   The data to be added.& L0 E5 g* @. b$ f! L
  98.   * @param  [in] len:  The length of the data to be added.
    4 U9 |/ y" x8 O  z) T/ O" d+ c$ G9 l
  99.   * @return The number of bytes copied.
      Q) o9 V% S4 O  e$ X% }0 E
  100.   * @note   This function copies at most @len bytes from the @in into. h& z  k0 S# n
  101.   *         the FIFO depending on the free space, and returns the number
    3 j8 a( L( H+ V/ g# h
  102.   *         of bytes copied.
    9 u7 |& ~# `7 T# \
  103.   */7 e: J8 U0 j8 `$ m2 l& ?  T
  104. uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len)
      G3 Q1 [6 I% Z' y5 C! G- n
  105. {
    . m7 N( z( C2 u4 m9 Q
  106.   len = min(len, RingBuffer_Avail(fifo));$ \2 R* l6 m2 r  O8 D
  107. , k& U; f% _" l% A  r
  108.   /* First put the data starting from fifo->in to buffer end. */, ^0 j' F9 Q; l; u$ i; S, Z" [2 L
  109.   uint32_t l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));
    8 `6 D& H! P7 y: z9 x: {+ k* P. n
  110.   memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), in, l);# Q; J, G* s- l# z* W4 c  D
  111. 6 u( s1 [! X- x1 }0 x
  112.   /* Then put the rest (if any) at the beginning of the buffer. */8 N+ u; Y( f* B' P& \. o% W; v
  113.   memcpy(fifo->buffer, (uint8_t *)in + l, len - l);2 @1 S3 D3 P+ o# S+ `4 }  g
  114. ! q4 G( c1 @% ?, H) D
  115.   fifo->in += len;
    " A5 v. ]7 d( I7 h3 R$ B0 A
  116. 3 Z; Z5 A  l. [9 }/ r4 ^3 s8 H
  117.   return len;4 d$ Q1 i6 W: G8 D. a
  118. }
    - S1 Y0 h/ P. k3 d

  119. ' A) e) P; ]6 ~+ a
  120. /**5 W# s# M6 B6 G/ |
  121.   * @brief  Gets some data from the FIFO.
    # x; M9 T8 a) b7 }) q! H8 R: D- e
  122.   * @param  [in] fifo: The fifo to be used.
    5 @4 G+ v2 i% G+ E
  123.   * @param  [in] out:  Where the data must be copied.
    $ b, _2 y8 |1 C4 U7 Z! A5 D9 {
  124.   * @param  [in] len:  The size of the destination buffer.% l, `5 c; C  R' E5 s. @
  125.   * @return The number of copied bytes.
      i7 l( ?5 b/ x, x$ p" J1 v
  126.   * @note   This function copies at most @len bytes from the FIFO into; h6 `* I3 _- L; G# o7 o
  127.   *         the @out and returns the number of copied bytes.
    7 O, u: H" G* O4 |; E
  128.   */
    $ A+ y9 C' |7 H; b1 M
  129. uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len)
    7 M0 @/ n! `9 V3 v9 i! i  a3 w' Q
  130. {) X  B/ h9 ^) t1 w4 t
  131.   len = min(len, RingBuffer_Len(fifo));
    6 [( }) R$ X+ C6 b4 E
  132. 7 @# O: i2 S6 G
  133.   /* First get the data from fifo->out until the end of the buffer. */
    $ B+ h' j6 C: j& m$ B: R9 ^. L
  134.   uint32_t l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));
    & J+ L, p, }+ }- J+ t
  135.   memcpy(out, fifo->buffer + (fifo->out & (fifo->size - 1)), l);
    1 X* |. B; q* [4 r6 X) H

  136.   v' G5 b2 x8 t
  137.   /* Then get the rest (if any) from the beginning of the buffer. */
    8 k7 z) e) m+ y9 r
  138.   memcpy((uint8_t *)out + l, fifo->buffer, len - l);
    / b) ?: M* P$ g0 \  b; r
  139. 8 j! c( q" e* r) A2 ~
  140.   fifo->out += len;
    ' Q" i) l0 V) W, V( s
  141.   a* K3 v3 X+ q( M2 G% N/ ~
  142.   return len;. K9 u, `* W. q; T
  143. }
    # V, U% l' d5 G; ^
  144. ( q; n; _: i! u! S9 h. z( x
  145. /**& I: O9 Y+ ?0 K  d  N3 r+ O3 A. F/ L
  146.   * @brief  Determine whether some value is a power of two.
    ; H" X3 \$ S3 `+ y1 z* M& d3 a! m
  147.   * @param  [in] x: The number to be confirmed.8 J5 Q5 w8 Y* o' k
  148.   * @retval true:   Yes./ m2 T. A) n7 w: Z3 G0 c0 g& y5 k3 q
  149.   * @retval false:  No./ E7 ?3 `% X$ x" z& f5 p4 f
  150.   * @note   Where zero is not considered a power of two.
    8 b, P. ?. ^" Y2 s7 q: M
  151.   */
    $ @% R+ _3 o. U$ T4 K
  152. static bool is_power_of_2(uint32_t x)
    7 @! g9 z  q* B) H9 o& d
  153. {
    4 y! }6 B4 f+ P5 i
  154.   return (x != 0) && ((x & (x - 1)) == 0);8 ~; N' i* @5 v' `9 b- ^0 Q1 K
  155. }9 d& s& L6 ]; X. e( R4 O( z. h
  156. 3 z1 u* a! v1 |% d3 J3 l! |
  157. /**
    # \+ r( p# X) o9 l) v. Z5 V+ V
  158.   * @brief  Round the given value up to nearest power of two.8 g* n+ g! v6 p( V
  159.   * @param  [in] x: The number to be converted.6 x. O  B( I/ P' S7 Q) M
  160.   * @return The power of two.
    0 D1 ~( y' _7 Q5 |$ c5 U5 U
  161.   */
    # `2 _) f/ ~3 b  I0 \6 K# [
  162. static uint32_t roundup_pow_of_two(uint32_t x)
    ! O! K+ a9 G" M, A
  163. {" `) h! T( k2 o- H4 {. R4 B2 w
  164.   uint32_t b = 0;
    2 S$ E9 z4 [' m" x$ g7 g$ t: d5 i

  165. ( _6 M& O# t/ E
  166.   for(int i = 0; i < 32; i++)
    5 ?$ _* v+ o; Z
  167.   {' d& z3 m6 ?# \
  168.     b = 1UL << i;5 \4 F% z: p5 O( g+ @' }1 `5 U9 b
  169. : C6 i( x) h, I! O' N
  170.     if(x <= b)' S& {! L( Z% \3 J* R
  171.     {1 L: D$ J% K7 S; l7 Y
  172.       break;; S: }7 i  Z# W. ~3 O
  173.     }
    2 [% ~& r# M7 S, X, v
  174.   }
    . G7 q' g; z1 H. A( H2 E4 D, O3 N
  175. 2 q( i7 W) ?  }( s
  176.   return b;! W7 B  E  g% ^- T
  177. }</div><div></div>
复制代码

* w2 y4 o" Y. L8 j: |1 v% D6 Y+ `4 W7 f+ i: f4 y* Z
CAN.h 文件
# Q! x; \1 w% ?! c- Q0 o* |
  1. /**
    2 F+ P6 }, O9 ]! k
  2.   ******************************************************************************
    ; |$ y5 q% D: {1 Y9 K4 u# d8 p
  3.   * @file    CAN.h
    4 F+ ]; |9 _8 v# t0 \
  4.   * @author  XinLi
    " G( s7 Z6 }1 n# O) G
  5.   * @version v1.0
    % a6 \: T& V. A$ P- S9 m  o+ h
  6.   * @date    24-June-2018
    7 s' H; E( X+ j0 `; H0 K' N
  7.   * @brief   Header file for CAN.c module.3 t8 k9 T5 ]- R: n# `7 u
  8.   ******************************************************************************
    * |1 D" x( J: q% v+ }  t
  9.   * @attention. a% g) O% f3 Y; y8 ~
  10.   *
    # V) h' c1 m  Y% R$ T
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    - r5 |4 I1 X1 C7 g6 L, U
  12.   *
    : I6 M5 Y( o. G0 n
  13.   * This program is free software: you can redistribute it and/or modify
    5 v( c8 w; k0 B- Z" }0 U
  14.   * it under the terms of the GNU General Public License as published by: j; v7 Y, H5 s( r' `* [
  15.   * the Free Software Foundation, either version 3 of the License, or
    - `) i0 n+ c$ _
  16.   * (at your option) any later version.1 t) }. r) _. d8 d! T. i! O6 k4 I
  17.   *. G4 ]/ c# k6 p
  18.   * This program is distributed in the hope that it will be useful,. o& u) d1 E. z! H7 ?
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    ' Z+ Z6 }! |6 g$ U' l! k: ]
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the/ m5 N3 _) ?9 O! r" ^
  21.   * GNU General Public License for more details.
    * L$ d- |! P: O" \: x7 S( j% }
  22.   *( r# ~8 r" l+ k/ I1 ~$ d& P
  23.   * You should have received a copy of the GNU General Public License
    ) ?, p4 Q1 ?8 g' h* X# w3 I
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    4 W2 o" v: B1 \+ u- g
  25.   *
    - L* v: A( b8 ]0 t
  26.   ******************************************************************************4 {$ u0 D, i2 x3 S/ i" u( y4 y
  27.   */  i0 A! w1 e6 j+ X6 z, {
  28. * Q, d! }% a4 C
  29. #ifndef __CAN_H/ @" E3 s) a, n& B/ i- ]- l
  30. #define __CAN_H
    . Y7 R0 h( Z: z8 Y( k

  31. " V3 @* L9 t" L
  32. #ifdef __cplusplus4 ]. m6 _, |0 S0 B# c
  33. extern "C" {; g  F; r/ m6 p' O
  34. #endif
    / O# A, ~1 Y) t# e  s; }. v
  35. / r' f, U/ T& o3 K0 V
  36. /* Header includes -----------------------------------------------------------*/
    ; [" H9 w( b$ `  Y* Z! e9 G) z/ l
  37. #include "stm32f10x.h"
    4 C4 c* g0 N8 V; f
  38. #include <stdbool.h>
    # `) C5 }( ]& Y+ i+ g& k

  39. / Y9 p  e$ f0 P8 ^7 R
  40. /* Macro definitions ---------------------------------------------------------*/
    1 C, x& e( x5 c$ u  _; C
  41. - ]- O9 L2 J- x/ U! P7 l2 x
  42. /******************************* CAN1 Configure *******************************/- r+ M# o" g0 Z( H
  43. #define CAN1_TX_BUFFER_SIZE        (16)3 ]* K+ |1 g( b5 A! B
  44. #define CAN1_RX_BUFFER_SIZE        (16)
    ! |" F& T+ }; x% j5 d1 j. G" P
  45. - H) a9 S! }7 F2 o9 a( Y) I0 d
  46. #define CAN1_TX_GPIO_CLOCK         RCC_APB2Periph_GPIOB* v: l2 N$ v9 j' `
  47. #define CAN1_RX_GPIO_CLOCK         RCC_APB2Periph_GPIOB
    / O  H( S6 s, j: s2 v6 s: O( G
  48. * `1 Q! ?/ ^$ G3 C
  49. #define CAN1_TX_GPIO_PORT          GPIOB) ^# M( x1 Y- c
  50. #define CAN1_RX_GPIO_PORT          GPIOB+ k" A7 z2 W1 J8 f% ^" d: e

  51. - a! F, E( p& p* I0 H4 [, \1 s2 f
  52. #define CAN1_TX_GPIO_PIN           GPIO_Pin_9/ Q* a% t& C: k0 n! j( g. y- C+ g! u  z
  53. #define CAN1_RX_GPIO_PIN           GPIO_Pin_89 J& |1 `* u6 V/ U' z  {
  54. # e# t& T2 v# ^! r. O) J
  55. #define CAN1_IRQ_PREEMPT_PRIORITY  (0)' ]( X& M4 e. \
  56. #define CAN1_IRQ_SUB_PRIORITY      (0)
    ; M5 ~6 t" i$ G( S9 }# M
  57. + L: h/ ^2 p" W$ _5 @) L7 h: [% j
  58. #define CAN1_PORT_REMAP()          GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE)
    % F/ |' {1 S6 `' C2 {0 t- N- y% I
  59. /******************************************************************************/% c; |9 `; q0 M6 E; G0 o

  60. + F* Q! c- i# U  d( g
  61. #ifdef STM32F10X_CL6 M- ~# [# E  U: a* {
  62. /******************************* CAN2 Configure *******************************/
    8 S6 M0 {5 X1 X% P7 q2 F
  63. #define CAN2_TX_BUFFER_SIZE        (16)$ j# [& ?6 [6 @4 ~  z  W8 l
  64. #define CAN2_RX_BUFFER_SIZE        (16)  J% d, m7 r7 h- n
  65. ' k! u* {! U1 `; f
  66. #define CAN2_TX_GPIO_CLOCK         RCC_APB2Periph_GPIOB+ D+ S! X3 E# P
  67. #define CAN2_RX_GPIO_CLOCK         RCC_APB2Periph_GPIOB  m$ j- ]/ L2 f

  68. + k6 R8 \9 B) x4 n4 Y6 J2 `3 Y
  69. #define CAN2_TX_GPIO_PORT          GPIOB
    ( Y0 b$ g& q4 C2 p9 H
  70. #define CAN2_RX_GPIO_PORT          GPIOB
    , s& A0 S( `0 k, Q3 q0 m# m
  71. 0 C( b0 p* ]6 V8 j* t( w: C# b
  72. #define CAN2_TX_GPIO_PIN           GPIO_Pin_13
      w9 H$ h1 V, l/ Q+ p
  73. #define CAN2_RX_GPIO_PIN           GPIO_Pin_12" k( t$ r$ q' i/ a+ s

  74. 6 A' L5 z  h" A/ g/ V9 D
  75. #define CAN2_IRQ_PREEMPT_PRIORITY  (0)# C, X! e( g7 e) S- f! D& j
  76. #define CAN2_IRQ_SUB_PRIORITY      (0)
    % ~8 ]9 }1 Y$ u! J. \0 @
  77. . h% ?9 \; V" @) j
  78. #define CAN2_PORT_REMAP()          GPIO_PinRemapConfig(GPIO_Remap_CAN2 , DISABLE)
    & ^0 ?4 P* J( \8 n( }2 h: S
  79. /******************************************************************************/2 O& z; M4 M7 u& ~: A! w
  80. #endif /* STM32F10X_CL */2 J+ I4 i0 w* w8 |6 `5 S
  81. ; W" z+ x+ Y; g- Z6 U2 c7 t
  82. /* Type definitions ----------------------------------------------------------*/1 ]: p0 Z8 P1 D8 w( Z/ W
  83. typedef enum/ g) y) S6 l2 @8 N
  84. {
    # W) w6 S6 a3 \
  85.   CAN_WorkModeNormal   = CAN_Mode_Normal,
    9 y) p4 [; R7 ~  l2 ?; B
  86.   CAN_WorkModeLoopBack = CAN_Mode_LoopBack' a% s' C( ]& R/ T& v# u9 }
  87. }CAN_WorkMode;" F1 g* _- d9 b

  88. ! G$ W& w: P, Y& H/ \2 B. a# K
  89. typedef enum
    * \; S  ]  G* w" e- Q! }
  90. {
    % s3 p" \. X; u; k
  91.   CAN_BaudRate1000K = 6,
    : d" _4 W0 Y$ k
  92.   CAN_BaudRate500K  = 12,
    & E) ~$ B! ?! f8 f
  93.   CAN_BaudRate250K  = 24,2 A& b; Z+ u7 n: X
  94.   CAN_BaudRate125K  = 48,! \! m1 ~) u; \- k
  95.   CAN_BaudRate100K  = 60,
    7 ?3 b, j" Y" ^% N' M9 R
  96.   CAN_BaudRate50K   = 120,
    4 f" p* e0 [' H
  97.   CAN_BaudRate20K   = 300,
      u  v2 F9 A6 H7 n, t$ r& x! R( {
  98.   CAN_BaudRate10K   = 6001 g  c( b: f# ]' y- v
  99. }CAN_BaudRate;
    " ]% f7 I* B6 B8 G8 I9 D: J( g- f
  100. / q! t0 P* l, K$ a
  101. /* Variable declarations -----------------------------------------------------*/
    & `7 Y6 a# t" y) i: F* p: M# k
  102. /* Variable definitions ------------------------------------------------------*/2 a1 p% i# d4 N
  103. /* Function declarations -----------------------------------------------------*/' Y7 m+ ~% ~" S- ^2 q+ m9 u4 w
  104. void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId);
    8 ^! ?5 s0 Y/ z& Z, r" {* G
  105. void CAN_Unconfigure(CAN_TypeDef *CANx);' f6 F0 h) N; e- X6 H* E$ }0 m
  106. ' C' w1 ^! |* I0 H
  107. void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));
    $ |- b! y1 {2 ^% ~; G, M
  108. void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));4 \. E; j; J' a* a; |# i8 U7 ?4 L! n

  109. 8 H! m6 G; F8 ?2 Z
  110. uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number);
    1 y6 {9 h+ @% N# N0 ?* Q
  111. uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number);
    ! W/ W; C7 {. t$ H$ L$ U1 s& C

  112. 8 a, @# t  y; X
  113. uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx);
    ; _2 g& d. n' ~! x! z/ T
  114. uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx);, W% _2 r+ w$ D( s; @
  115. uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx);8 f% x) k% I# b4 k+ o
  116. uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx);0 w6 K$ X, j2 @" a  r

  117. 2 r( f1 Z  i% h7 y" O) g+ [9 b
  118. bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx);; ]" [4 u6 v6 W- O# ^
  119. bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx);% Y& `4 v4 ]# X. ?# I& w7 c7 G
  120. bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx);( f" y; A% s0 ?1 u6 B3 q4 L( W$ w
  121. bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx);
    , w- }0 z; l; u3 O9 n' U* z

  122. # u  E& v- y! {
  123. void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx);: ]1 l! l/ T" u' E/ `& ?+ E/ ?
  124. void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx);) N4 K. O/ u1 e: r1 |4 J+ o! |
  125. 2 ?! b2 @# W1 [& @
  126. bool CAN_IsTransmitMessage(CAN_TypeDef *CANx);
    5 Z& r8 R2 S+ h

  127. ; D9 B% s  j9 m
  128. /* Function definitions ------------------------------------------------------*/, P0 ?* t, g# p1 ]0 X+ g  r
  129. + Y6 T; |' K" W( S% }1 `
  130. #ifdef __cplusplus
    : r$ Z" g; n! U
  131. }; t2 [8 |( [  U
  132. #endif
    7 q  `* a4 {* H, M0 B1 o0 Z
  133. / M, j) n' `: O( o" ~9 y0 p
  134. #endif /* __CAN_H */; k7 w" ^, `7 J5 J, \
复制代码
# d! E0 g  @6 D2 o
; E3 ?' b8 D4 q. N* I

. r% i) b6 G9 b0 Q( xCAN.c 文件
" b- N: Z- L+ s6 N, ^
* @2 |8 ~8 x- `' X  H5 P" |
  1. /**
    + x, P6 c3 a* {/ C
  2.   ******************************************************************************/ @* _; h) @6 \3 j' a- M& E3 l, W
  3.   * @file    CAN.c' ~4 p0 Y9 M2 E/ |: _1 C  y
  4.   * @author  XinLi
    7 v  R% H: n; y
  5.   * @version v1.0
    * S! r) |: D$ Q) r
  6.   * @date    24-June-2018
    , `" u& N4 ~! i" ]
  7.   * @brief   CAN module driver.0 [" j- I; z3 E
  8.   ******************************************************************************
      i( e# O' u& Z6 T
  9.   * @attention
    9 {  b- n3 ?# ^+ _
  10.   *
    5 ~& c# a* j+ f6 ^4 o5 j
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>4 m7 |1 L. i* d+ L- O
  12.   *
    / M" b7 ~8 l$ [( q: M) [
  13.   * This program is free software: you can redistribute it and/or modify
    * y3 N9 V! {4 [
  14.   * it under the terms of the GNU General Public License as published by8 C. s1 _& p* Y* t/ x6 S2 @' l& O- n1 H
  15.   * the Free Software Foundation, either version 3 of the License, or6 F  O% h8 z: _, W1 Q4 _  _
  16.   * (at your option) any later version.
    " y' Y* W! J3 {: ^/ j
  17.   *
    " p2 U# }1 ^  e9 C+ U% x
  18.   * This program is distributed in the hope that it will be useful,
    . T+ n+ X0 J# T' ?
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    9 V  q7 K* [3 N: i1 Q; p9 U
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the% J& [9 Z$ ~2 J/ i7 X
  21.   * GNU General Public License for more details.7 B; Z7 A+ d) c2 l3 B' Q* D
  22.   *
    ( A% L7 D' k6 E
  23.   * You should have received a copy of the GNU General Public License
    4 P5 v3 [: T$ Y1 X# H. A$ Q9 f9 ?
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>9 v! L% R4 B9 A; k4 L
  25.   *- P5 F# O. Y, v+ |, G
  26.   ******************************************************************************6 k! O$ ]- V0 X
  27.   */% P' A4 C- j- [/ P/ T
  28.   b8 l; q" b; t. n$ z, L3 R$ e3 g
  29. /* Header includes -----------------------------------------------------------*/
    # I5 v6 x# ^  a) ?5 p+ x
  30. #include "CAN.h", K4 W* ^" X/ g! v/ W
  31. #include "RingBuffer.h"
    % n1 v) p! O" e( v% U
  32. 2 `1 E6 s! r: I4 \! b1 C, I: O) ~
  33. /* Macro definitions ---------------------------------------------------------*/$ c9 S) D0 l' a- n* ?" }& v: I
  34. /* Type definitions ----------------------------------------------------------*/
    6 t8 m% F, ?( U6 r2 s5 r: p  R2 a  [
  35. /* Variable declarations -----------------------------------------------------*/
    + n3 [3 m( ^+ `, Y: V: x- Q
  36. static volatile bool can1InitFlag     = false;
    : k! N9 e) q: r8 G
  37. static volatile bool can1TransmitFlag = false;$ P- Z' I0 Y+ k% n

  38. ' A$ x; k6 `  F' u& N) B& G- s
  39. static volatile void (*can1TransmitFinishCallback)(void) = 0;
    ) G/ p9 p1 Z& @8 k9 h% b
  40. static volatile void (*can1ReceiveFinishCallback)(void)  = 0;
    0 N/ x4 O2 n5 o$ T+ g7 U
  41. 4 A# j* x5 `1 X8 D8 E; _
  42. static RingBuffer *can1TxBuffer = 0;
    ) Z7 V6 Y, S7 X% S! X
  43. static RingBuffer *can1RxBuffer = 0;
    . L/ J$ E: J" a2 ]' E
  44. 6 r2 m9 u1 I3 K
  45. #ifdef STM32F10X_CL
    2 u1 d2 j: l. t  V( ]2 a
  46. static volatile bool can2InitFlag     = false;
    6 M0 ?$ m& C2 g2 f( g
  47. static volatile bool can2TransmitFlag = false;
    ) b! o' ^; \$ G
  48. 1 F) c9 V3 i& M% K+ \" H) K
  49. static volatile void (*can2TransmitFinishCallback)(void) = 0;
    " s; P. c$ D3 |+ R
  50. static volatile void (*can2ReceiveFinishCallback)(void)  = 0;* y7 @, a5 P& D( E

  51. + B4 d# P8 X2 y
  52. static RingBuffer *can2TxBuffer = 0;/ s) c4 @" h! i2 ~
  53. static RingBuffer *can2RxBuffer = 0;3 q" E: B- c2 h. c; b
  54. #endif /* STM32F10X_CL */2 P7 b+ a$ Y5 J+ s- a

  55. , x- p8 V3 D# r( _8 J$ q
  56. /* Variable definitions ------------------------------------------------------*/
    . y4 K. i0 Q0 [1 m
  57. /* Function declarations -----------------------------------------------------*/0 `" x# _, j. o) H/ y  U
  58. /* Function definitions ------------------------------------------------------*/
    1 w9 x% o' v2 m, R# k
  59. & O% i" @; p$ K0 \7 Z' h
  60. /**6 A) ~$ p0 W9 K1 Q/ p8 P
  61.   * @brief  CAN configure.; T( z' i5 X' a2 E# ~/ _2 }* u
  62.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.
    6 T+ Y- G) c! D  ]
  63.   * @param  [in] WorkMode: Work mode.7 ~+ r- L* ^% a8 O2 n
  64.   * @param  [in] BaudRate: Communication baud rate.# [: h9 H* f( ]$ f
  65.   * @param  [in] StdId:    Filter standard frame ID.
    3 v2 n& v# P; r
  66.   * @param  [in] ExtId:    Filter extended frame ID., t$ V" T: \% ~5 f, c
  67.   * @return None.
    9 q1 @: ?$ `' g9 ]
  68.   */: N% j9 B$ h. E. x8 [4 F7 D: g# i+ W
  69. void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId); O/ {$ @; @- N2 C/ w6 X
  70. {6 B0 S' @" _+ q
  71.   GPIO_InitTypeDef      GPIO_InitStructure      = {0};
    , ]- k$ ~- `+ n. d1 \+ J
  72.   CAN_InitTypeDef       CAN_InitStructure       = {0};* Q5 L) O8 {! p" a0 R" N
  73.   CAN_FilterInitTypeDef CAN_FilterInitStructure = {0};
    9 Z# ~* a3 [1 P; v3 r
  74.   NVIC_InitTypeDef      NVIC_InitStructure      = {0};
    : h  B$ u6 b/ D# W9 [( w% w
  75. * ~. t# \% g3 E# j7 w, C
  76.   if(CANx == CAN1)
    ) Z7 M' X' w" y% _$ l2 s
  77.   {
    # p5 ]0 R& h# \- z. c, x
  78.     if(can1InitFlag == false)( g& ^5 ?7 U/ v8 c+ u! A6 v) \: B
  79.     {% L" v, R7 v. o. `( }
  80.       can1InitFlag = true;- f8 h1 n; J, V- \' t( N

  81. # Z% R1 k& o6 D8 Z1 K
  82.       can1TransmitFlag = false;
    ' q' T7 n" v+ F
  83. # x) S! r; a$ y! F/ u
  84.       can1TransmitFinishCallback = 0;+ a" E: w. ~* k# F/ k) a, ?; Q
  85.       can1ReceiveFinishCallback  = 0;
    8 J, X# e4 G  y5 h  i
  86. 4 K4 H8 x3 n& N1 i8 t
  87.       can1TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN1_TX_BUFFER_SIZE);
    + G" K. W( ?& ?0 T3 d6 Y& }
  88.       can1RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN1_RX_BUFFER_SIZE);
    8 c* n4 p6 e, i1 l9 Z* P# }: j  k/ D8 _
  89. ( Y, ?3 I* m/ x; j* J
  90. #ifdef STM32F10X_CL
    , h: r: \5 ^+ ~
  91.       if(can2InitFlag == false), d) L; Q! q. t! S( [2 }5 j
  92. #endif /* STM32F10X_CL */# j; T" l, g/ h5 n6 C1 U: a% U
  93.       {: Q9 `; ]# B0 L% ]3 g
  94.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);( N0 B; P) ]. f& |: t6 e
  95.       }
    " E% M0 F! o% V8 g* f2 u  K- v+ D
  96. 3 w9 T; v, z8 c% D, r$ j  p8 \; _
  97.       RCC_APB2PeriphClockCmd(CAN1_TX_GPIO_CLOCK | CAN1_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);& [. s1 @; ]6 E' b* n7 h# p

  98. . i" y; o& L" f* m% b
  99.       GPIO_InitStructure.GPIO_Pin   = CAN1_TX_GPIO_PIN;
    * [8 V- m2 z0 w( h! r
  100.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    3 I5 L, d) k. v
  101.       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;& e. X) a' u9 b  |
  102.       GPIO_Init(CAN1_TX_GPIO_PORT, &GPIO_InitStructure);
    5 C) G; q4 L! s. X! O1 C& G" |

  103. , d3 _: V4 ^% @
  104.       GPIO_InitStructure.GPIO_Pin   = CAN1_RX_GPIO_PIN;  ]1 k. {& b/ A
  105.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
    / t) `0 \- w8 Y! e$ p) u, x
  106.       GPIO_Init(CAN1_RX_GPIO_PORT, &GPIO_InitStructure);
    . o) l  J3 V* q( |+ x8 f. d
  107. % I' d. ~, p2 z/ e" r) }- p
  108.       CAN1_PORT_REMAP();
    : o6 P  w0 a+ I% a5 Z. {8 I0 v
  109. 0 U2 q0 t! g5 H; A( ]1 }
  110.       CAN_InitStructure.CAN_Prescaler = BaudRate;' h! u" P( Y' u* @& m( D. A* w% ^
  111.       CAN_InitStructure.CAN_Mode      = WorkMode;
    . g! O2 i# s$ _1 V: x6 w, i1 K7 }# |! h
  112.       CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;5 R2 ~5 z2 F  v$ a* E
  113.       CAN_InitStructure.CAN_BS1       = CAN_BS1_3tq;! Y* g9 i& P, S3 a& W
  114.       CAN_InitStructure.CAN_BS2       = CAN_BS2_2tq;
    ; Q( V. |- e1 t: r% L+ I& b
  115.       CAN_InitStructure.CAN_TTCM      = DISABLE;. q, S& f3 I$ n& u: W3 z
  116.       CAN_InitStructure.CAN_ABOM      = ENABLE;) e) L% ], O6 ]
  117.       CAN_InitStructure.CAN_AWUM      = DISABLE;9 u: A4 ?& J/ K( I, C7 O# J
  118.       CAN_InitStructure.CAN_NART      = ENABLE;
    # i0 Q$ N4 |. \# b' \( b$ |$ @
  119.       CAN_InitStructure.CAN_RFLM      = DISABLE;
    5 F4 R, H/ e: c" w9 S
  120.       CAN_InitStructure.CAN_TXFP      = ENABLE;
    % F7 w) J  y9 ]3 @2 w. w) G# [' o5 Y) |" c
  121. , u5 z" ?4 ^# V" V* k  j) ~/ w
  122.       CAN_DeInit(CAN1);
    / n& X6 L- k" b7 W# K2 `& y
  123.       CAN_Init(CAN1, &CAN_InitStructure);
      e! Z" {& {6 |
  124. 4 B; l- I4 s; F2 R" o5 a) ~3 P1 Q1 R
  125.       CAN_FilterInitStructure.CAN_FilterIdHigh         = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);7 l& c7 o( W5 g  A4 m& F4 p
  126.       CAN_FilterInitStructure.CAN_FilterIdLow          = (uint16_t)(((StdId<<18)|ExtId)<<3);0 ^/ e0 [, k- ^1 z
  127.       CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;* V% ?! }  r/ j/ B; o. b
  128.       CAN_FilterInitStructure.CAN_FilterMaskIdLow      = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;$ I) r  D; v, B: Z( {7 }
  129.       CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;2 D! e% ?6 b% A0 }' G5 Q
  130.       CAN_FilterInitStructure.CAN_FilterNumber         = 0;4 Y: A0 C( O0 }( y2 M8 g3 m
  131.       CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask;
    ! A3 V9 N- c7 W9 C4 X; O2 F
  132.       CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit;' k' D3 L8 h+ U% i, i
  133.       CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;. T$ x1 Y3 b9 M/ i! `/ f+ E6 M9 X
  134.       CAN_FilterInit(&CAN_FilterInitStructure);
    " r$ c4 C; e! u1 _& u' E. s; x) h; @

  135. + Q. A& B5 P0 u8 H4 _( T3 r* D
  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 |! N* D6 r% L- {: }) l
  137.                          CAN_IT_WKU | CAN_IT_SLK  |CAN_IT_EWG | CAN_IT_EPV  | CAN_IT_BOF  | CAN_IT_LEC | CAN_IT_ERR, DISABLE);/ b/ Z- u9 Q9 ^  {% Q! p5 S
  138.       CAN_ITConfig(CAN1, CAN_IT_TME | CAN_IT_FMP0, ENABLE);
    & Q* }1 _7 o$ i1 V4 s, T
  139. % {; O7 O& Q) q7 [$ {" k
  140. #ifdef STM32F10X_CL6 J: o4 v+ s3 p& _6 `
  141.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_TX_IRQn;
    - v0 i1 i4 S* T
  142. #else
    & Q5 [1 b2 ]2 h' Z' i+ b
  143.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_HP_CAN1_TX_IRQn;
    & W  C, n2 k; Q# n
  144. #endif /* STM32F10X_CL */
      u& X! d9 C( W' |

  145. 7 H3 m- M7 i2 t2 X
  146.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;
    / w2 z" H: @; E9 W5 E
  147.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN1_IRQ_SUB_PRIORITY;
    $ P$ z1 V& o1 c- U
  148.       NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    * D* s( _" ]# T3 D& ]
  149.       NVIC_Init(&NVIC_InitStructure);
    0 n% c: k* {" _

  150.   L' L/ w# k/ l" u/ N
  151. #ifdef STM32F10X_CL. _0 H2 B! A8 B3 z* Y  M( [
  152.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_RX0_IRQn;" Y1 I' D8 t0 J* h$ k+ d# j# _' V. S
  153. #else
    5 r# m: v( J! s. ~3 G
  154.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_LP_CAN1_RX0_IRQn;
    ! M7 B* i1 I/ l
  155. #endif /* STM32F10X_CL */( J. v  q7 X4 ?
  156. ' q, c1 S* q1 V  H& i/ b9 l; `3 ^
  157.       NVIC_Init(&NVIC_InitStructure);+ m0 s/ t4 h$ W2 X& a
  158.     }
      j; Q1 y* I! Y- M8 |
  159.   }6 n& `  U  C, m0 s7 y4 M

  160. & g! L& F: x* ^1 w7 @( L
  161. #ifdef STM32F10X_CL0 C) G$ [5 U0 R2 ^; Y5 J
  162.   if(CANx == CAN2)
    . l- R- _4 W5 ?8 w1 V* p
  163.   {
    , Y' }# k% R5 Y* Z; _$ I. r: b
  164.     if(can2InitFlag == false)
    1 K) Y- B0 Q6 `& s
  165.     {( z; a7 z0 f, V3 S5 V; s, \
  166.       can2InitFlag = true;
    8 e4 R6 I$ d' N1 a- T9 I4 V8 i

  167. 8 J, S8 V8 y" n; b2 u
  168.       can2TransmitFlag = false;
    - s# S# R  W" q# s! O3 W9 X
  169. ; {  t/ E* n7 a) t% e  [  ^7 x6 N
  170.       can2TransmitFinishCallback = 0;
    # ~: a8 o; m" Q9 ?% w
  171.       can2ReceiveFinishCallback  = 0;5 Q, e( b* K9 z/ S+ C0 N( n8 }
  172. " _2 q  f! F$ h& B4 }$ E
  173.       can2TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN2_TX_BUFFER_SIZE);
    $ d0 `: }; |6 v# b
  174.       can2RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN2_RX_BUFFER_SIZE);
    , [& F: m/ L" O6 v% i! i& B" J4 a
  175. 8 u, ?" [7 s  s: ^
  176.       if(can1InitFlag == false)
    & j1 X0 E% u) L0 x
  177.       {
    / |' j# u+ N7 X! I, G% s- j5 B
  178.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
    + l2 z0 ~+ ]: m, E. H" J
  179.       }5 N; }2 S7 \4 q, E
  180. + U4 ~, K( m4 v& B  g
  181.       RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);& N/ U: ^2 j: W5 G# [/ {
  182.       RCC_APB2PeriphClockCmd(CAN2_TX_GPIO_CLOCK | CAN2_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);' a# ?; d! P2 y8 q8 Q0 ~
  183. % ]. _' c% o& d! v1 D2 g
  184.       GPIO_InitStructure.GPIO_Pin   = CAN2_TX_GPIO_PIN;
      n0 G7 s% M# a) w9 Z1 d+ C% G3 l8 {
  185.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    * y% T$ W- o! h  V
  186.       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    6 y- ~' H- `" t/ b9 t
  187.       GPIO_Init(CAN2_TX_GPIO_PORT, &GPIO_InitStructure);
    ! ?; J4 ^+ c7 C
  188. , c; o8 l% n- M9 c" D- P; N
  189.       GPIO_InitStructure.GPIO_Pin   = CAN2_RX_GPIO_PIN;5 ^1 N5 t" s- T4 \) Q5 Z
  190.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;6 b/ ?$ w7 A/ }, ?6 C3 z
  191.       GPIO_Init(CAN2_RX_GPIO_PORT, &GPIO_InitStructure);
    , l! h" E4 ~' v5 [& k. X6 _3 p8 A% y

  192. 2 O& h  _8 X$ w1 L* I7 _/ L3 V
  193.       CAN2_PORT_REMAP();4 f  T% |- f) l7 q6 E6 Z
  194. 3 ~. Q$ O" s- e6 e8 S
  195.       CAN_InitStructure.CAN_Prescaler = BaudRate;
    . l' u: c2 _4 ?. K' Z/ i6 b
  196.       CAN_InitStructure.CAN_Mode      = WorkMode;9 w6 m% J& D, {
  197.       CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;- h# _( a: j) q; P) N
  198.       CAN_InitStructure.CAN_BS1       = CAN_BS1_3tq;! Z: W( C0 y6 O2 b: t
  199.       CAN_InitStructure.CAN_BS2       = CAN_BS2_2tq;( t7 c2 \$ C/ V. X. C
  200.       CAN_InitStructure.CAN_TTCM      = DISABLE;+ J9 a) O4 ~" ~
  201.       CAN_InitStructure.CAN_ABOM      = ENABLE;
    9 e! J, ?" j  l' a2 h
  202.       CAN_InitStructure.CAN_AWUM      = DISABLE;
    5 \* r9 o; u2 X8 q: J
  203.       CAN_InitStructure.CAN_NART      = ENABLE;
    # H0 u( a2 N$ d
  204.       CAN_InitStructure.CAN_RFLM      = DISABLE;
    1 {& m+ F# P( [7 @, H" |
  205.       CAN_InitStructure.CAN_TXFP      = ENABLE;
    8 I& E! I' l/ S% \% q. V

  206. 6 r: m  b8 j) g( y6 e) L% _; s
  207.       CAN_DeInit(CAN2);% I: t) X& U- m
  208.       CAN_Init(CAN2, &CAN_InitStructure);
    : i! c2 l" k1 M, h+ w0 N- s

  209. 2 B5 I* x. N" v+ _4 d- `
  210.       CAN_FilterInitStructure.CAN_FilterIdHigh         = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);) V8 X. d! j" q7 s& b/ w8 S
  211.       CAN_FilterInitStructure.CAN_FilterIdLow          = (uint16_t)(((StdId<<18)|ExtId)<<3);
    & f1 c: V5 ~3 b% s
  212.       CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;- H1 ^0 u+ M$ Q1 e: v" ?( J
  213.       CAN_FilterInitStructure.CAN_FilterMaskIdLow      = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;4 t) z% B- v  F; Y
  214.       CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
    * c- O: _4 |9 m% {
  215.       CAN_FilterInitStructure.CAN_FilterNumber         = 14;
    - K5 @) y7 u/ {
  216.       CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask;. o: p- m7 K% I- m0 J
  217.       CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit;, o: O- n' Q# T7 j# [
  218.       CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;
    0 W0 i2 s: d1 J, W8 F
  219.       CAN_FilterInit(&CAN_FilterInitStructure);
    ) I) W' h9 @* i1 _* q0 k
  220. ; s/ c2 J- l, A2 ?0 u
  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 |% l6 i. |& @# r! P4 G
  222.                          CAN_IT_WKU | CAN_IT_SLK  |CAN_IT_EWG | CAN_IT_EPV  | CAN_IT_BOF  | CAN_IT_LEC | CAN_IT_ERR, DISABLE);# Q- v8 X$ `. J* P
  223.       CAN_ITConfig(CAN2, CAN_IT_TME | CAN_IT_FMP0, ENABLE);
    1 x: f/ \$ j: x
  224. 1 t- b; L& x/ e7 H
  225.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_TX_IRQn;6 e: g& d7 S1 Z; _# a- S! `0 [
  226.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;( u2 W3 I4 s0 `! b$ z. v/ g+ V  a
  227.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN2_IRQ_SUB_PRIORITY;
    : f! J7 E; T8 X: ~
  228.       NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    , y3 `" A8 Q: S! W: ^
  229.       NVIC_Init(&NVIC_InitStructure);
    / V7 A( i4 f% N# ?
  230. % C7 k% C& K( D( l& j% {4 i% _" {
  231.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_RX0_IRQn;5 l. g2 k+ N# w
  232.       NVIC_Init(&NVIC_InitStructure);
    ; _& G( {" i; F+ a5 u
  233.     }. j! K/ g% Z& `3 j, c- I
  234.   }% s, r" a  g2 e7 d4 [) J
  235. #endif /* STM32F10X_CL */* v" R4 Z0 l/ [3 C* V
  236. }$ v- Y* }* ?7 I* f; M; r! H- N
  237. 4 A0 K7 U5 ^% E/ N- R5 [
  238. /**
    , C  U, Q5 T; f% E, K1 \0 X$ q/ y! v
  239.   * @brief  CAN unconfigure.
    9 e7 N- r! L/ Z
  240.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    1 {8 s2 A8 b& G+ s' `  V
  241.   * @return None.
    % m+ k( m. r" Q2 |3 y: n. p
  242.   */
    / [1 T1 w! ?( x# E* s( E
  243. void CAN_Unconfigure(CAN_TypeDef *CANx)7 P: ?: ?% o& L! Y+ Q9 b
  244. {
    6 @: g' x) M1 e  F
  245.   NVIC_InitTypeDef NVIC_InitStructure = {0};
    " n+ k9 E" P3 F7 I3 O9 m

  246. / r1 M( Q% G; D$ ?1 U  {) u
  247.   if(CANx == CAN1)
    6 N$ U6 [: U/ v$ b. c" ~! B
  248.   {2 n6 F& r  |3 \5 D# l- j
  249.     if(can1InitFlag == true)6 v3 `* W& `& S$ X
  250.     {/ v5 g9 f5 {* Z7 t0 ~' o
  251.       can1InitFlag = false;
    0 c" w# S  ]8 k, d+ |; a

  252. 5 ]+ @) y9 y( T; A) O! q  P
  253. #ifdef STM32F10X_CL7 q9 Q7 Z3 I$ _$ @
  254.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_TX_IRQn;% Q' W& ^' C0 R3 r, t% g' W1 k
  255. #else+ N2 O  s# I8 l2 Q2 h0 Q, c
  256.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_HP_CAN1_TX_IRQn;
    4 p1 G6 Y  @( ~5 t+ _9 v6 a6 K
  257. #endif /* STM32F10X_CL */
    9 P1 o, v8 L9 D, d( E

  258. : V7 K. {- Q7 Z3 ^5 ]" X6 e; R
  259.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;
    % n% r7 K0 a! z2 x6 T0 o: t
  260.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN1_IRQ_SUB_PRIORITY;
    4 Y0 m- G! X( h  [$ @
  261.       NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;- ?4 r) s: U* l5 |, M
  262.       NVIC_Init(&NVIC_InitStructure);/ q7 f( c; O, L1 v% G

  263. / K3 t3 V; i6 r. v6 @+ R2 }5 e
  264. #ifdef STM32F10X_CL
    7 K) I' I" o5 @) e  s& `. Y9 z9 M
  265.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_RX0_IRQn;
    / o1 y, L/ {1 h0 b) e
  266. #else4 R: ^! V# G1 o4 b5 [: [" g% b( W
  267.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_LP_CAN1_RX0_IRQn;
    + D. b; y6 r4 N$ ^
  268. #endif /* STM32F10X_CL */
    ' ]4 _9 @$ e8 t+ f

  269.   x# h6 D2 q, |# f# Y6 S
  270.       NVIC_Init(&NVIC_InitStructure);
    6 T+ @5 y, c* o- R8 N! q8 n' h
  271. " H, W( U' n$ \/ Q
  272.       CAN_DeInit(CAN1);5 _) p" U* o$ {9 e* l, L9 i

  273. " H+ {! V$ C( B
  274. #ifdef STM32F10X_CL
    . R( v7 p) t& V% A% q. S8 B+ X
  275.       if(can2InitFlag == false)* P. t& F* A4 t3 v- ]( L2 a& h9 V
  276. #endif /* STM32F10X_CL */, E0 @; [0 ^) {
  277.       {* Q6 v2 n  q3 d& g# Y9 \1 K
  278.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);
    ) W* V7 S( m' W% z: J
  279.       }5 R9 u6 I9 ^2 X% E+ t! m

  280. 1 Q( c3 I5 Y" Q; f8 \
  281.       can1TransmitFlag = false;
    & P2 v$ b4 T' D( F" G  e; s

  282. % R: ?. g/ h! ]
  283.       can1TransmitFinishCallback = 0;% E8 m6 _  ?8 ]
  284.       can1ReceiveFinishCallback  = 0;4 O- K" ]! ^9 ]* L9 M

  285. / q. ?3 n3 o$ K# o) c5 f& n8 Y
  286.       RingBuffer_Free(can1TxBuffer);
    # ]& _/ [& K) v; @  m
  287.       RingBuffer_Free(can1RxBuffer);
    ! y7 |; g2 F9 D
  288.     }
    0 d; F" ]1 c! h: X$ i
  289.   }4 S# f" Q- O0 J/ G# [
  290. " T, u% E# n( M: A1 K
  291. #ifdef STM32F10X_CL
    ; x! ?& I# R' u: v# a
  292.   if(CANx == CAN2)
    - z/ |+ k1 ~4 `( d5 ~7 Q
  293.   {( V1 M- r+ u2 @8 o0 E
  294.     if(can2InitFlag == true)7 ^' i  ?, T, q/ s  k% E9 a
  295.     {- p* D3 A' E- e1 D$ e: }: Q
  296.       can2InitFlag = false;
    1 o2 W: q$ _# A6 b/ F, v/ d2 c! P

  297.   b: h) `- x# o  o* @
  298.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_TX_IRQn;
    5 L: y' W( t. f$ B8 H8 _
  299.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;3 f+ e3 E( T6 D) Z3 c8 [4 D0 m
  300.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN2_IRQ_SUB_PRIORITY;
    ' g+ W& D# Q; V9 m9 g& ?+ o' |- a& I
  301.       NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;
    . _2 B2 A- W% s' x4 r$ F+ o
  302.       NVIC_Init(&NVIC_InitStructure);
    2 s" X( H' b% K) W) }1 U8 y
  303. - F' z( s% K. L3 ^0 B# B% @" D
  304.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_RX0_IRQn;
    # P& J  W' u" T: J
  305.       NVIC_Init(&NVIC_InitStructure);
    $ b& ]  s2 H- U

  306. 4 ~: y) I, L5 F4 c
  307.       CAN_DeInit(CAN2);
    / C" U, N7 R- I2 A

  308. 8 Q8 X1 k5 L$ \6 R
  309.       if(can1InitFlag == false)
    . r1 t4 Y* a! T! y. j5 z# C
  310.       {
    ' w" j& i5 l! n' ^, k6 o
  311.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);
    . p" b4 k7 r0 c) y& S( i; @$ f( o
  312.       }
    : m; c! d7 t9 x7 Q' K

  313.   N7 R( F1 z" r* i6 N0 J
  314.       RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, DISABLE);4 s1 V! Y- e8 s' L$ i0 D$ N
  315. " z* u5 D7 r7 c0 |- ^
  316.       can2TransmitFlag = false;
    % b6 U2 V# K7 C" G0 T/ F

  317. ' n0 n% a/ h5 J9 M- |
  318.       can2TransmitFinishCallback = 0;
    ; X& Q' `2 ]! Q' X3 j; e3 \. {7 e/ a
  319.       can2ReceiveFinishCallback  = 0;
    ( ]+ \9 c/ s! @9 |7 a7 w

  320. % p) t1 y4 ^/ Z
  321.       RingBuffer_Free(can2TxBuffer);+ e7 a" }3 `  {! D: A6 m" n& Q( `
  322.       RingBuffer_Free(can2RxBuffer);8 }* r" ]/ h, _% B3 h  P; x
  323.     }
    8 `; i* J/ A9 h6 H% x) M/ {' c
  324.   }8 [5 B9 {+ n3 }4 I" z
  325. #endif /* STM32F10X_CL */
    / M  F7 V5 M  o  l0 |' H/ b% n
  326. }" C+ @5 g- ?" k% _; A7 y# q$ x* C
  327. : ~% ~2 X5 J; g9 S: h+ K
  328. /**
    # d" s- ~  q) {
  329.   * @brief  CAN set transmit finish callback.1 m' k. e* p/ m/ O! d. a
  330.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.* C) f) G1 p2 ?0 y9 }6 _
  331.   * @param  [in] Callback: Callback.
    & F8 q3 j, F& \" O+ C: o$ i
  332.   * @return None.
    5 b. G( `' D% s2 a" [
  333.   *// H6 j+ {3 N; }8 `- ~3 }
  334. void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void))3 d! b# ]) r) p+ J' q& _
  335. {
    7 W$ Y3 L3 U, h3 \( D
  336.   if(CANx == CAN1)
    ! I1 d6 |2 k; v( e& R- o5 f6 A
  337.   {, U; _* A* z! m
  338.     if(can1InitFlag == true)1 Q4 Y5 d* @  a. D; {9 \
  339.     {" b- p% G( f' ^: ~
  340.       can1TransmitFinishCallback = (volatile void (*)(void))Callback;
    / S1 G" C: O8 b* n) p
  341.     }
    * L- P1 J7 S+ N5 d: D
  342.   }% D5 G5 Q/ b. Y' ~8 q0 g* Q

  343. & C9 l/ s$ x" k; i, e3 z+ y
  344. #ifdef STM32F10X_CL
    : Z/ i5 u8 o$ l4 V/ k
  345.   if(CANx == CAN2)9 h+ |5 Y+ R$ E+ \' y4 m' r
  346.   {
    , o- c( W1 Y! U5 Y% m* B
  347.     if(can2InitFlag == true), y& C5 s8 r! M1 t+ o1 ~
  348.     {8 H# G  W' f( ]6 H- ~7 t
  349.       can2TransmitFinishCallback = (volatile void (*)(void))Callback;+ M: {8 |, |$ S) x
  350.     }4 W2 c) t" V5 ?6 L( l7 J
  351.   }& q# f; Y; A; f: L& Q
  352. #endif /* STM32F10X_CL */
    % K" s1 r! U- C
  353. }3 l" [, J! @9 L/ z, T) P

  354. " Z( K3 W' S8 |- f2 m, ^
  355. /**
    - s& Z, p+ I* V
  356.   * @brief  CAN set receive finish callback.1 z; u9 m; z% o) N1 i* B
  357.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.4 W# Y( e$ U3 ]5 |7 d! Y. ]
  358.   * @param  [in] Callback: Callback.: E2 j: p! u( ]  O3 U# v" p
  359.   * @return None.
    * `* D( b0 e- y. @, }2 K
  360.   */6 M+ J( W- Y/ T! n2 r
  361. void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void))
    / t0 ~  h) P  I
  362. {; H# Q' y% J! d7 s! k$ s5 v1 |
  363.   if(CANx == CAN1)  C1 r) P- U, i. A9 o7 z2 Q+ D7 T
  364.   {7 b" D8 w( u" R2 r
  365.     if(can1InitFlag == true)
    6 `, a; z/ {+ L1 i9 M
  366.     {
    / N2 f5 c) N. V
  367.       can1ReceiveFinishCallback = (volatile void (*)(void))Callback;
    - f4 ^$ v: @9 q7 T; E' H. I
  368.     }
    , D0 L% P  V1 b2 ~' T/ h+ ?% ~) U
  369.   }( G; r- ?2 t4 ~; z  G1 H3 Q" i) ?
  370. 0 k- P' J  h. N' _
  371. #ifdef STM32F10X_CL( I* j" `- o% C1 Q; c3 h+ L
  372.   if(CANx == CAN2)
    3 b7 `  {# {! U( E! H- `
  373.   {& S9 G# J, v5 k
  374.     if(can2InitFlag == true)
    # }- E8 l& p* H
  375.     {
    0 O  U- i! V3 I* c$ m0 U- a2 W
  376.       can2ReceiveFinishCallback = (volatile void (*)(void))Callback;3 m$ I* T. u1 t$ _- _" k) X
  377.     }$ C  h4 J5 S3 f  M6 u) m$ ~. ^
  378.   }" `1 n4 n0 m5 f5 H) a
  379. #endif /* STM32F10X_CL */
    5 V, `. Z6 }8 T  H$ K
  380. }/ |5 I- K) e& r" u7 |& q# D" o% D4 B
  381. 6 V: j  u* z0 w* _5 ~4 T
  382. /**' ]) q! k( A* |
  383.   * @brief  CAN set transmit message.5 O. X- w: I% i7 `% w* s6 `7 w) R
  384.   * @param  [in] CANx:    Where x can be 1 or 2 to select the CAN peripheral.: Y4 b2 A6 p2 v) J% u% a2 J
  385.   * @param  [in] Message: The address of the message to be transmit.
    " }3 \- n; f. Q6 `, P# m( C1 c
  386.   * @param  [in] Number:  The number of the message to be transmit.
    5 n! h7 x8 d/ M' e
  387.   * @return The number of message transmit.3 V1 _$ K9 q: A* Z; M; x
  388.   */
    / ^5 X0 ~; }( a9 j2 {9 W/ k9 p
  389. uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number)
    % k. |3 ^! Z: s5 b
  390. {
    ' h" ?. B0 u6 n1 s7 K8 g5 C2 e1 U
  391.   if(CANx == CAN1), `( R" F3 H" R8 M* ]* X! [" n$ [7 o
  392.   {
    ' s( Q/ }# z! q/ w4 k+ @0 S" P
  393.     if(can1InitFlag == true)" G. L, b$ J# `% ]( \' v2 d
  394.     {9 S  G# u) H/ I2 T$ c
  395.       uint32_t available = RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);2 E4 J4 @  w2 X  p2 Q% r$ ^

  396. & W; ]7 n: a/ y) P. R& @
  397.       if(available > Number)) P5 P& Z. N5 b5 `# a( q0 Q" a
  398.       {
    % y9 {' E* d0 ^! F- `' k
  399.         Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);
    $ l  P& o! I, `* j$ t
  400.       }
    # r3 }6 y) g, I  |2 @% [+ w' V
  401.       else! {/ ~/ H* @# a" ^% N# P! V
  402.       {
    4 Y, g7 Q, C! V, L
  403.         Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);6 [  u- N9 H( H- d
  404.       }+ p3 A, ]) B3 U( V4 Y& S. i0 N' L
  405. % W. g! F& H9 d- u" ^
  406.       if(Number > 0)
    # a! X8 e9 H( z0 a; t. m* C
  407.       {
    2 s, N( J- ]1 @2 L$ W. s9 Q
  408.         if(can1TransmitFlag == false)
    " Z3 }+ @( b7 a
  409.         {% l) E% o4 z0 b5 u
  410.           can1TransmitFlag = true;+ m8 Z+ O( ?- z' Q/ {

  411. ; L) ?) p; s8 {
  412.           CanTxMsg canTxMsg = {0};
    7 d. h3 I, [* W0 L, m
  413.           RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg));, K! q  Z# h! x: x3 z3 B
  414.           CAN_Transmit(CAN1, &canTxMsg);
      L% w( b9 v( N, D# D
  415.         }
    - K4 k8 Y- ?# U4 w9 b
  416.       }! z- {( D2 c9 G& G$ g% b

  417. 7 ~( ?) V" g4 P/ d6 L. Z! H! v0 I
  418.       return Number;
    : {7 c9 I# L( V5 }9 P- M/ u1 T
  419.     }
    % S' m1 w4 E7 i2 g  Q. _
  420.   }
    8 b4 _0 s' h4 r+ H: ^: n
  421. ' @! |2 y+ U6 V# q' t% q$ U3 n
  422. #ifdef STM32F10X_CL
      M' S9 W/ n: h( e0 E
  423.   if(CANx == CAN2)( B! I% J; q5 [+ X
  424.   {
      q& G7 L+ H2 E4 A
  425.     if(can2InitFlag == true)
    3 t* u$ I% C/ @6 r" W8 L) |9 _
  426.     {
    6 Z, |4 Z6 R. C9 F" ]: x8 P
  427.       uint32_t available = RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);% @! s* s$ r9 {# V0 p. _& e0 P
  428. * }2 ^* r; B1 N  ~, M
  429.       if(available > Number)
    % G: C4 Y1 o- {3 E. r- i
  430.       {5 I( K4 I% b; g" \
  431.         Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);
    * w% q+ K( f" {2 w' t  S
  432.       }/ v+ `4 d3 K7 K1 w. }
  433.       else
    5 U5 P. V2 Q# M5 o+ Z! l" K
  434.       {# f! Y+ g5 L' d
  435.         Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);4 f* S+ Z$ Y) x, c2 l
  436.       }5 X: {. x# Z: \2 j
  437. 0 q) \5 X3 ]; o6 z# S  K
  438.       if(Number > 0). r" q* u4 S& I! ^1 s$ R
  439.       {
    ) K! l$ B' V+ w
  440.         if(can2TransmitFlag == false)/ L2 ~$ X- ^. Y2 W
  441.         {4 n, @: x6 F1 r, |# b+ m( ~" I
  442.           can2TransmitFlag = true;/ I, A0 K2 ~7 r6 X0 \

  443. 1 m. P+ q2 b( W; J! m6 f
  444.           CanTxMsg canTxMsg = {0};
    9 \- N) m7 {$ P; q
  445.           RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg));2 V  P1 ?' h1 E9 U
  446.           CAN_Transmit(CAN2, &canTxMsg);$ i4 V  J& k* \( n
  447.         }: ^" N% e- k) s: e, i% w" M9 A
  448.       }
    % w0 j* i4 C6 E& g& L) H

  449. : f0 c- l1 x- O) u
  450.       return Number;9 Z1 k! A7 {2 `
  451.     }) R: T! J4 \* J6 X
  452.   }
    ; p3 b1 E  O5 ]. z/ B. Z# J% b
  453. #endif /* STM32F10X_CL */# E8 x/ k! r& ^: ?4 _" Q

  454. * i( w8 R, Z3 @7 C+ J9 [8 H. P
  455.   return 0;
    5 N0 e) C9 u& _5 m  o, F* P2 M
  456. }
    : t2 c& r3 S1 p! G; g4 m
  457. " S# P3 v; |4 _
  458. /**# z! ?  Z1 L3 p6 z
  459.   * @brief  CAN get receive message.
    9 U& s! f' A/ [5 m
  460.   * @param  [in] CANx:    Where x can be 1 or 2 to select the CAN peripheral.
    9 R0 b1 O) z- z; B5 C' W5 [
  461.   * @param  [in] Message: To store the address of the receive message.
    7 u) o- S. A9 a
  462.   * @param  [in] Number:  To read the number of the received message.
    ) _" w1 k- n* F6 W0 j& C
  463.   * @return The number of message obtained.
    . _( a& y4 {4 V( C
  464.   */# j( {( g4 }' [6 z6 L; |
  465. uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number)7 F5 ^! Q0 ~0 N! z& q! t% M  y
  466. {1 f' `8 Q, r9 {) ~5 H3 [+ V6 }# m
  467.   if(CANx == CAN1)
    6 h/ n3 ~/ y8 J) I5 p
  468.   {- t+ D% N& J3 r3 W; n
  469.     if(can1InitFlag == true)
    3 j- ?2 v$ a9 {
  470.     {
    ) p9 R& F! X0 A1 B" v) E
  471.       return RingBuffer_Out(can1RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);7 j; _  ]4 U- R9 S8 I: E6 N
  472.     }
    - W4 ^. ~8 Z! i: x. O  J# M
  473.   }
    : ~# s' {" S1 R

  474. 3 m; H, m! Q1 H( f- A0 n+ o
  475. #ifdef STM32F10X_CL
    . y5 Z& V. D  k0 V* D
  476.   if(CANx == CAN2)
    4 h( q  y0 N3 }- B+ Y
  477.   {
    & E( T) i* h, Q$ S
  478.     if(can2InitFlag == true)- x1 l; C) d  E: O& d- i: A
  479.     {! H) t1 w+ V6 x5 U6 ]
  480.       return RingBuffer_Out(can2RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);
    6 }2 f5 t' Z) `, N% U0 }  V, j
  481.     }
    & q# v4 P' ?5 ]' i' P. D4 |
  482.   }
    ; I0 r" G8 R1 ~
  483. #endif /* STM32F10X_CL */7 g! z% X3 B( ~, P
  484. & g$ |/ S1 _& U3 _+ Z3 G/ s- w* F* w
  485.   return 0;# r& Y% B7 Y' p* {9 H8 G6 J3 J
  486. }
    6 _2 L: G1 c) D( ^
  487. ; W7 }3 Q; c* ~/ E' f6 a3 @' b
  488. /**
    # `+ H$ J8 s% R% T+ v
  489.   * @brief  Get the size of the CAN transmit buffer used.7 Z( v3 U' q! [. w
  490.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.5 ]$ m# L) A( }1 ]
  491.   * @return Used the size of the transmit buffer.
    3 L2 p' V' u( q4 m
  492.   */7 ]& g; W0 r  o0 U3 L8 j9 O! e
  493. uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx); N& O. e6 t+ ?
  494. {
    " n9 g  T% q1 v7 E# m' ?0 @/ U
  495.   if(CANx == CAN1)
    * l7 ~" A; V% ?- C
  496.   {
    & p! N9 k% ]% L, ~3 ^
  497.     if(can1InitFlag == true)
    # m: d! O* v$ U* }! G' G
  498.     {( c4 X, z' N3 g/ l9 w
  499.       return RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg);
    3 `5 U' W1 E0 }
  500.     }  C7 Z0 J: G" O- d% d: H
  501.   }" B' P2 H; o- }) e8 h  u
  502. * d" I- A3 T8 D5 b! ?& y0 D
  503. #ifdef STM32F10X_CL& ?2 p" m9 _# {* D
  504.   if(CANx == CAN2)
    5 H# t: `5 S) M
  505.   {( S! W3 v+ S2 ~# N+ R
  506.     if(can2InitFlag == true)( |5 i- D$ n" q# p
  507.     {
    0 P3 g0 M' h) g  i
  508.       return RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg);
    % b, k8 j: Y8 P6 R
  509.     }
    7 }  j) h- Z+ t& g
  510.   }3 o  t$ z7 Y0 p2 `2 Q
  511. #endif /* STM32F10X_CL */
    ' l* v8 t6 K8 u! D. X. X

  512. $ c2 y2 R" }# X0 u
  513.   return 0;
    ( y1 G# h+ q" d$ E
  514. }9 L* A- J$ q( N
  515. , h3 m; Z/ X0 Z' ~6 o
  516. /**
    1 }8 I* m" a$ y, ?
  517.   * @brief  Get the size of the CAN receive buffer used.( Z3 Z& m1 S* ?( f* V
  518.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.- J9 P( z$ I# R( T( V; F
  519.   * @return Used the size of the receive buffer.
    , z! D' F9 i2 h" E3 Z$ n$ y
  520.   */8 j7 t0 Q4 v0 `, U, u
  521. uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx)" f6 k. ?5 Q4 m! E
  522. {
    ! M# O6 {9 X6 P7 }+ o
  523.   if(CANx == CAN1)
    + \: y/ o7 k$ \$ [/ u& D
  524.   {
    $ V7 P4 D9 T: y- O
  525.     if(can1InitFlag == true), z. R" D7 ~( E5 ]; B& a2 w
  526.     {& k, [  }  B4 Z' F' {2 _, ?
  527.       return RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg);) [. `" s, i: [  e7 V$ o6 |
  528.     }* k% {3 m4 v7 V7 O
  529.   }
    + d: P# R8 ?4 q/ ~% ~) ?
  530. 5 Z% y0 c, \* M+ I! w+ f7 w
  531. #ifdef STM32F10X_CL2 c) \9 g9 q1 Q
  532.   if(CANx == CAN2)
    1 D" H* D6 I" [
  533.   {& o1 r) n, N7 ~, j3 @" B' w
  534.     if(can2InitFlag == true)8 f3 Y* }% ^: d. y! _1 I
  535.     {
    : d; ~' S  e. G* y
  536.       return RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg);
    " ^* |) @' {0 s! x* x9 a5 `: ?
  537.     }
    - Z+ B- b* B: ?" @  w
  538.   }
    & e4 [" e; S4 _) r4 _' i
  539. #endif /* STM32F10X_CL */# B! O  i8 R$ e' Y, C' c) S4 E
  540. . z5 p1 e6 P+ Q) G, G
  541.   return 0;
    ! {* L1 }  i3 F
  542. }
    - Z# r6 S5 |  ^5 _: g  N9 k; C

  543. & E0 R  @3 p; `& u+ e$ `
  544. /**
    $ O  q& j5 j+ r* j
  545.   * @brief  Get the size of the CAN transmit buffer unused.
      ]- H& a1 K$ p( ?
  546.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.  v  M5 D- m  z$ R" N+ Y9 x
  547.   * @return Unused the size of the transmit buffer.; ^  x  L: Z. E7 u( q8 e
  548.   */
    4 Z, K5 H# h! E0 _$ U$ E
  549. uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx)
    " Z0 S2 {& O5 \+ F4 \' w# j
  550. {
    5 w1 k* s1 p  E2 ?3 P; y3 x
  551.   if(CANx == CAN1)
    / P. [+ F7 x* A7 q/ P, W& I* |
  552.   {/ b+ [4 c2 c7 t2 P% d+ N
  553.     if(can1InitFlag == true)  o1 J3 _" u5 D$ q( n  Q
  554.     {
    ! ~* m. r' ?3 f7 A7 U4 U
  555.       return RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);
      L; b4 C/ H# |2 C. a: c' k% Z: L
  556.     }3 ^" b' v% U2 X
  557.   }. Q) l0 r/ H- y
  558. 9 ^- p: a8 S1 x+ L
  559. #ifdef STM32F10X_CL
    4 \3 E5 I* L! P: d
  560.   if(CANx == CAN2)! F2 z* Y4 p& T0 u
  561.   {  p9 p& T% `: d1 ^; r
  562.     if(can2InitFlag == true)
    : ?& Y. P* h0 _! S3 D- d" ]7 h
  563.     {
    4 S9 _7 K7 Y9 e, f+ p6 O
  564.       return RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);
    + P( \4 x% O3 Q3 K* a
  565.     }
    6 \' q0 u) p" D* w5 J$ |$ ^
  566.   }3 q% f+ r2 k2 `! a  f/ P( y
  567. #endif /* STM32F10X_CL */0 \# x6 C! t$ Z6 M
  568. 2 b; V0 g3 ^) H* P+ ?) B7 Q
  569.   return 0;
    - U4 B9 P+ O1 v) u4 \
  570. }+ B% p6 y1 G( g2 B. e, }
  571.   V: l3 o0 _/ i6 ]; ^
  572. /**! T/ [$ ^" k' c9 d, \
  573.   * @brief  Get the size of the CAN receive buffer unused.% c+ d2 a& o; ^# u8 J
  574.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral./ X9 e8 ?& h! V" q- E/ L) j/ I
  575.   * @return Unused the size of the receive buffer.( P# B* X' g$ I0 J$ J. {1 q1 q
  576.   */( ~% A% p( T- c
  577. uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx)
    , j0 ?+ p* [% ?1 j! a/ ~
  578. {
    ' G4 c& J  i3 [& M& ]5 R3 J6 q( @" g
  579.   if(CANx == CAN1)! l. U' J8 Z! I  g7 e* p+ n
  580.   {) Z' u0 D7 D/ \, ?4 k
  581.     if(can1InitFlag == true)* D" U4 f+ F) a9 u% m
  582.     {9 O* s9 g) F( u* _8 t" N
  583.       return RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg);
    8 G. w$ {6 w+ s  X' A- Q& F
  584.     }& W7 W3 o1 h5 B4 k1 l, X
  585.   }4 o* b! y6 O( R5 E$ h7 ]; t

  586. $ U2 @+ _3 V9 `& m3 Y; I
  587. #ifdef STM32F10X_CL- y& j. o9 x+ r9 q' K
  588.   if(CANx == CAN2)7 J: p( A( C3 K
  589.   {0 s! P0 B0 A; |# v
  590.     if(can2InitFlag == true)4 V3 D9 F( ^1 r2 l8 v" b
  591.     {7 M7 q3 q- }, Y7 e9 ^4 |' M
  592.       return RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg);
      ]( y, I: u  z+ _+ \) Q
  593.     }
    # F8 E# t, i7 a0 T5 |* S+ k& K
  594.   }
    ! w- E0 @) d* t0 w, F0 l
  595. #endif /* STM32F10X_CL */
    ) P+ g8 [+ e6 A4 a" r! r7 X6 }

  596. 9 A4 Q  S% s% r! ?
  597.   return 0;1 q1 u+ ]2 g3 [0 l& J
  598. }  m* J8 N/ K/ o  w3 H

  599. * v. B  m- F3 P  I( v$ S
  600. /**
    4 x; v8 W1 v: J
  601.   * @brief  Is the CAN transmit buffer empty?
    5 ?* K( r$ ~# ]0 H& f+ |
  602.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    ' }3 e! U: f: A3 r4 `
  603.   * @retval true:      The transmit buffer is empty.3 m" x( `: K5 O/ `2 P' b
  604.   * @retval false:     The transmit buffer is not empty.
    $ m" m! H$ Z6 f* ~# D+ i4 p
  605.   */
    . G/ p# y& A5 B4 R' v
  606. bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx)
    + u: I3 a. ~7 z) I" F, ^; Y& r! V* M; E
  607. {
    1 O/ t% V! F' X6 v
  608.   if(CANx == CAN1). _  N+ Z3 \  k- C- D1 L. L7 }
  609.   {, }: s, V/ q% e2 W
  610.     if(can1InitFlag == true)
    / I$ {/ U8 u# k! s- h8 M; [8 t
  611.     {. g1 s% R  X! U4 y. f% P
  612.       return !(RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg));
    / Q" k1 F2 W+ ~5 G* D& L
  613.     }
    . u0 Z9 x5 [# T' w6 b
  614.   }
    1 d* h0 G1 k' g1 u

  615. , Y( [" V, |8 Z9 t
  616. #ifdef STM32F10X_CL
    7 g! N5 q; [$ y! o  c
  617.   if(CANx == CAN2)
      u7 `* v5 `5 u) M* f, M5 P
  618.   {
    3 }2 H- j* [! e" j2 l
  619.     if(can2InitFlag == true)9 W: l" _% p+ z. F9 B9 Z
  620.     {
    ) Y* i! X" Z, K
  621.       return !(RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg));* K$ w" [) Z2 p! A8 s
  622.     }7 g' d$ Z7 J$ c- W& j
  623.   }- q8 E: y2 J2 m
  624. #endif /* STM32F10X_CL */
    ' c, x- y0 j8 Y. s( ^' N% g, p! C
  625. * o: S, N& H" Z
  626.   return false;
    / z# D% \, |( j* J5 w9 r- H
  627. }" m2 C3 e$ D* `1 [

  628. . \" Z9 @  m& @# e2 J- {" Z
  629. /**
    8 `. v/ P6 D$ G  N
  630.   * @brief  Is the CAN receive buffer empty?
    1 W' g+ m& W* ]0 ^) x8 m
  631.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.0 Y1 c% Y& X  X6 e" E
  632.   * @retval true:      The receive buffer is empty.
    % ^0 q% _5 D& ^1 E, h. z. o# x- I. D' N
  633.   * @retval false:     The receive buffer is not empty.6 T4 w; z1 D% k
  634.   */; S' s' `# W* b* B" r
  635. bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx)/ |! s5 K% Z4 Q- P2 C3 @
  636. {% l0 i; k4 s: M' T) b  a( q+ X
  637.   if(CANx == CAN1)2 l( U! W8 n7 f+ x2 g0 a
  638.   {' o  l% b$ _8 Z' X1 \, {0 v3 q- _: j
  639.     if(can1InitFlag == true)
    ! D# x3 I, z5 h, U
  640.     {6 d+ Q# R/ V1 b( V* O# A
  641.       return !(RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg));4 ~% j# L/ m7 r- i; j9 o
  642.     }
    ; |$ N' W! ]7 G2 R) F
  643.   }
    ! }! ^) X. a7 f% u

  644. 3 u! r6 a  G0 m4 j5 D6 }5 i
  645. #ifdef STM32F10X_CL
    % J/ i! n1 L; o4 U
  646.   if(CANx == CAN2)
    1 F" D6 n, M: h# M  R
  647.   {0 _( N: c3 y% q  r1 t( K
  648.     if(can2InitFlag == true)
    5 n& X" p: f6 ]) R4 }2 z2 [+ y
  649.     {% b& @4 Z! P& z4 @
  650.       return !(RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg));
    / i9 K" \2 k; k% \. {
  651.     }) D$ m$ C! D0 `% F9 F5 l/ I# ^" B4 b" i
  652.   }% ~0 f% M- C7 Y4 M' |# w6 W* }+ W
  653. #endif /* STM32F10X_CL */* ?  S- j8 Q7 d% J8 s% a
  654. - F% ]0 i: r5 H- o8 h/ U; Z) i: V1 k: W
  655.   return false;. \. p: ~, z2 @# d. {
  656. }
    ; M- Y9 z6 Q$ \* D2 f" z' o
  657. 1 v# l* R2 ?; c8 z8 C; \( r
  658. /**9 z- ?% h/ C( o" z8 T# S# `
  659.   * @brief  Is the CAN transmit buffer full?
    1 D1 j. l# j% m, {+ Y! m
  660.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.2 S7 @7 j* m3 W5 Z( c
  661.   * @retval true:      The transmit buffer is full.0 R! l) c0 t1 H" k5 D1 g
  662.   * @retval false:     The transmit buffer is not full.
    * ^4 p/ I0 D1 j. ^7 e
  663.   */: e0 c' M: |5 t4 n' a
  664. bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx)
    ( p+ R* R  a0 n1 W
  665. {  ^: ~+ a4 K; |/ }# E6 {
  666.   if(CANx == CAN1). e+ k1 Z- C4 g1 }. E  c3 @
  667.   {9 k  b! r  d6 ~3 M; k: p' K
  668.     if(can1InitFlag == true)# S- i8 K( ^7 N2 v
  669.     {
    8 o% v9 X  ~6 z  H
  670.       return !(RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg));3 t& S7 A+ V, w% @
  671.     }6 B7 q" o* a$ _& y0 M8 G3 W. s7 Y
  672.   }
    + ~$ v. u, k# w
  673. , g' ]0 }. I6 w* p  M& [
  674. #ifdef STM32F10X_CL8 A3 H" f6 m, t
  675.   if(CANx == CAN2)& j1 E1 Z2 g- @( L$ u( ?
  676.   {
    , Z( e9 d6 s9 V
  677.     if(can2InitFlag == true)
    - i  U' \* t1 Z! Z2 v
  678.     {
    3 ?( l) y: p- }! E: A! n9 A
  679.       return !(RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg));% b# E! y4 f) P) _
  680.     }5 n1 c! F. ^6 ?3 B) A
  681.   }: u5 \0 ?/ M' g( v
  682. #endif /* STM32F10X_CL */; E! m; h; c3 t" b% t  Y$ F" b

  683. ; m! q3 R7 K% w) q- T+ O/ H# b
  684.   return false;
    5 t- O* P: w* J
  685. }- Z( Z, Q/ V- f
  686. ) L4 E0 X, P( R
  687. /**
    ) n+ X' r5 t7 W; A) W
  688.   * @brief  Is the CAN receive buffer full?
    2 s4 O. v& L# `
  689.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    : V" R; ]& K0 N# r( Z& c
  690.   * @retval true:      The receive buffer is full.4 J) p6 k9 k$ h% T7 L: g
  691.   * @retval false:     The receive buffer is not full.; r9 C: D2 {) i2 ]7 o& O* l3 i$ y
  692.   */. K8 w+ i: n8 J& M
  693. bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx)
    ( U5 z# _8 r/ [: F( K9 O% O
  694. {1 y* a  E. n3 S' A8 ?
  695.   if(CANx == CAN1)
    # M. }& E" P6 o7 m9 h) |8 y) o/ |
  696.   {% v7 N) i' {9 }- [2 j
  697.     if(can1InitFlag == true)) c5 m2 K: I& V9 a5 Q" f9 V5 B
  698.     {
    & [  ]; `9 H, u9 r2 F% J
  699.       return !(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg));
    # t. H' E( M& \- u& [* X/ n
  700.     }
    , Y# O9 e. n3 F: q+ A2 V
  701.   }
      D. Q  W2 E& ]+ l6 _, L

  702. , P% O% m0 O" u2 \5 a) C8 F; j
  703. #ifdef STM32F10X_CL
    0 [3 ~! ?/ c* K; c$ p
  704.   if(CANx == CAN2)
    % s$ q, m6 k4 X0 v$ Z* v$ \2 H
  705.   {9 z5 v8 C4 f6 \! \9 }1 j
  706.     if(can2InitFlag == true)
    ; }; B: U( p2 a. ?" q
  707.     {+ h: ]! j" n- F- L6 ~! ~
  708.       return !(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg));
    1 r# }% ~. J6 q/ H2 \+ T' a% L
  709.     }) }7 E% m8 c9 }* X" f) O
  710.   }2 L7 N: }" j; O
  711. #endif /* STM32F10X_CL */3 D0 o8 H6 d1 J0 k/ `, S
  712. 5 W* ~+ R# [+ q& I
  713.   return false;, u) u9 ?: {$ ]2 @$ a/ O1 d
  714. }; P" Q" V- `+ S" B" @" [# b
  715. 7 P' S9 m$ p7 O3 z" r
  716. /**
    ; v# F" U" ]1 s+ p/ O' k% `$ f
  717.   * @brief  Clear the CAN transmit buffer.
    4 J" ^: e+ n9 j% D7 Q9 J% n, Q
  718.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.7 v& I7 ?' e; q+ `
  719.   * @return None.
    2 ]7 l. y- ?8 M4 G1 ]
  720.   */
    6 d+ r( B2 |9 S% l/ y6 R
  721. void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx)
    ) w9 O* G- X/ u0 P& E8 x; J
  722. {. t; ^1 q, U, U3 v. H
  723.   if(CANx == CAN1)
    8 k/ t3 W- H% H$ n* b7 f" u; g
  724.   {; r5 J% T! R% o9 i, K
  725.     if(can1InitFlag == true)0 ^; B( g3 v% N9 x- _& T9 f5 V
  726.     {% ?& U2 _  s' p0 v+ F
  727.       RingBuffer_Reset(can1TxBuffer);
    1 l* s1 P  i8 l! H0 d
  728.     }
    0 y; M4 s2 Q8 w6 o+ N0 F
  729.   }7 H  D4 g6 b2 k) J& s
  730. + d' a* C, m) O3 z* k: A5 B
  731. #ifdef STM32F10X_CL2 ^  ^7 Q; [) ]" f
  732.   if(CANx == CAN2)
    8 j  n1 N1 j; x
  733.   {) B: x7 M3 J3 `- {# u/ F
  734.     if(can2InitFlag == true)
    ) l7 q" U& U! @5 D, h
  735.     {% L  h- y3 q; E4 i$ H" x  n8 c
  736.       RingBuffer_Reset(can2TxBuffer);0 _- S+ R* X9 Q# n' s
  737.     }
    6 I/ n9 L5 J; p, ?, _' K
  738.   }$ v: J/ [$ t8 x: V3 z" m  A. H( J" p
  739. #endif /* STM32F10X_CL */
    3 r0 ]2 ?( g9 x+ z2 H9 Q5 B$ M1 A
  740. }' c/ T+ W! X: ~5 t7 D: \4 Q
  741. 6 G+ u/ O8 o% j7 R5 X/ }
  742. /**2 ]5 v  l$ r' o2 c# \
  743.   * @brief  Clear the CAN receive buffer.
    1 n! `  u' g  I3 _' o. _: h6 T4 d) ?
  744.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.& q1 a4 ?/ j; _5 `5 n. v6 t0 u
  745.   * @return None.7 M2 d" @5 n/ K! F$ f9 _3 N3 G
  746.   */
    ( s& q2 y5 z$ b8 {8 h5 X2 {
  747. void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx)
    ) b/ `/ u* n3 h  v0 T% q
  748. {7 H/ k0 A& i7 I& {# H6 c6 t, W
  749.   if(CANx == CAN1)2 c" A# h# {# L
  750.   {0 A# J. n7 W. L! s; a( \$ q9 S) _
  751.     if(can1InitFlag == true)
    - s) E0 t. W0 e- N& ~$ Y2 W0 F
  752.     {2 S9 w$ p6 T: b% P
  753.       RingBuffer_Reset(can1RxBuffer);
    ( a2 R, G; _5 o# [
  754.     }3 v6 D; e; q  J* e
  755.   }
    - _, z2 _$ L, X& k

  756. 4 }4 ]/ [3 g. \( T
  757. #ifdef STM32F10X_CL
    ) ^1 F- Z. [- z
  758.   if(CANx == CAN2)
    3 _- Y  T8 E  c0 B, ?0 J6 J
  759.   {$ R6 Y! l) ~* F2 p1 i
  760.     if(can2InitFlag == true), }! @# q1 e+ B7 |) n! p
  761.     {( i6 A3 m' \, {
  762.       RingBuffer_Reset(can2RxBuffer);
    2 K# w. \2 ~* {1 Q- S  K0 H/ k
  763.     }
    1 t# i. g0 ?7 X* L+ F5 S
  764.   }
    2 [5 j) S% f9 ]3 }' @
  765. #endif /* STM32F10X_CL */
    4 q$ s9 m# V* m! X! j- _
  766. }1 H- y) l3 g! |2 p. M
  767. & I( V' `1 X) U; ?
  768. /**
    % ~. D; O, y, F4 f) _$ }' y; d9 d0 r
  769.   * @brief  Is the CAN transmit a message?
    9 r( J  R0 |2 E8 F% W
  770.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.( s0 E! R) q- a9 N% \/ Z
  771.   * @retval true:      Is transmit a message.  Z+ [: I! H4 d3 G. E, m
  772.   * @retval false:     Not transmit a message.
    5 X- }; D" K5 I6 e
  773.   */! g" w2 r3 ~; Z  t- P" X
  774. bool CAN_IsTransmitMessage(CAN_TypeDef *CANx)+ k9 j3 Q+ K# O# K# ^
  775. {4 a  {0 s: Z. s& T' n
  776.   if(CANx == CAN1)
    9 P. o0 p5 A8 ?* v9 i: U% L
  777.   {1 v# G8 ~+ I& T( q5 @
  778.     if(can1InitFlag == true)0 w. _! e1 q' e9 P' L% I
  779.     {
    : ~2 u- _& Y) }1 T/ U
  780.       return can1TransmitFlag;( A& j! E0 B5 t4 E4 U/ T7 w
  781.     }
    ) h; w& ~4 X" _+ a9 m: E0 p
  782.   }
    % ^9 b) t0 j' K" ^( }3 P

  783. # T2 |2 c6 s- ~' G7 B6 B4 D
  784. #ifdef STM32F10X_CL- M0 m5 g+ a  A; ~1 u
  785.   if(CANx == CAN2)
    ; l/ M) B+ Y9 q1 @2 |% P
  786.   {) X' }+ _/ X0 {/ C0 e
  787.     if(can2InitFlag == true)
    8 B: [. s4 k+ t8 L- k1 j" u1 N
  788.     {0 p' c5 @7 `6 O! a; U
  789.       return can2TransmitFlag;  V, R0 {6 e2 G1 `* E$ z
  790.     }
    ) E( Y2 {- n: @  D: p# H
  791.   }
    / ?. q# z, S2 A9 V& e% a; X
  792. #endif /* STM32F10X_CL */
    9 L& i/ w. D. l! v
  793. / e; a( b! G  @4 I
  794.   return false;/ \" T: }( p5 e$ R
  795. }
    ' E/ D) _- i. I: t7 b
  796. . p3 O$ p# U$ t4 a* _+ m  `+ H
  797. /**
    0 [+ E4 m, ^& M& ^
  798.   * @brief  This function handles CAN1 TX Handler.  o3 p5 j" ?' \/ s7 ^
  799.   * @param  None.
    ) \" [6 u& J2 G: ^4 X( K; e$ Z! {
  800.   * @return None.& ^2 d7 c! B" r0 s. j
  801.   */  T) j/ I# ]; |6 f
  802. #ifdef STM32F10X_CL8 X, j5 h& e! \; r2 T2 n. G
  803. void CAN1_TX_IRQHandler(void)
    + _3 w! l  X3 }$ {! u3 f) m
  804. #else
    4 t1 Y, \" o0 L: T/ H
  805. void USB_HP_CAN1_TX_IRQHandler(void)
    . W+ \; t/ t$ v! `
  806. #endif /* STM32F10X_CL */! _1 d$ _; p" b2 d6 h; u/ x- B' M
  807. {
    2 H# K" G( {) u5 X& ^5 q
  808.   if(CAN_GetITStatus(CAN1, CAN_IT_TME) != RESET)
    ! v7 H2 h. W3 z9 y" e
  809.   {
    ; q" _/ j) D4 s" L
  810.     CAN_ClearITPendingBit(CAN1, CAN_IT_TME);/ t. R" `5 w) ]$ C2 Y& o8 I# V2 d

  811. % Q; I  x/ ^1 k; `: I
  812.     CanTxMsg canTxMsg = {0};0 e* i. }! o* Z0 r4 n$ f% i" l
  813.     uint8_t  number   = RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);, h! U, G8 C* E, E% F
  814. ; s: E% m, I* i) \7 q
  815.     if(number > 0)5 I& h; l7 d& P+ z: ?0 H& _* L8 Z
  816.     {: U% O! Z- f) m" a8 u# V6 |! I
  817.       CAN_Transmit(CAN1, &canTxMsg);; D/ ]0 `8 C% G3 q4 {
  818.     }2 W9 e1 P' w2 q8 ~' a3 e4 ?
  819.     else2 R# a$ y9 t* y3 i" h( ^( j
  820.     {' {/ L! m% O' ~. m' Z1 K+ I" T
  821.       can1TransmitFlag = false;! ?3 j' Q& D/ J! c3 O
  822. # q7 y2 O+ B- w" ]+ }6 m' e2 H
  823.       if(can1TransmitFinishCallback != 0)9 h. d4 J" e7 H8 c+ ~5 Y
  824.       {+ j+ d2 q7 P" D0 {$ ^
  825.         can1TransmitFinishCallback();7 N& ^/ f( h* a+ g1 T
  826.       }6 u( \; e% Q- D! {9 y5 g" r6 u( O
  827.     }
    0 N4 ?0 C8 F* Y- V
  828.   }
    6 `0 @3 x% d# x; y9 F
  829. }& A( |# q( [8 z2 N0 [2 c; q
  830. 6 z, |; l$ O3 A5 A5 ^
  831. /**
    - w4 f' _: o# C, f. Q1 D+ Y, }1 F
  832.   * @brief  This function handles CAN1 RX0 Handler.
    0 [2 `* S- A2 y$ [+ [9 U# `
  833.   * @param  None.
    8 L$ ^  q3 f+ B. m; o- g
  834.   * @return None.
    9 m8 U: t, H0 K3 P7 g3 j- Q
  835.   */1 l3 C! j8 }) z$ \
  836. #ifdef STM32F10X_CL
    3 e' C: J5 H+ Y) \0 b
  837. void CAN1_RX0_IRQHandler(void)
    / [/ l" ^/ o* U; ^. t- |; |. S, h8 m
  838. #else7 i; y' L3 F; y4 c4 \
  839. void USB_LP_CAN1_RX0_IRQHandler(void)
    6 M- O! @% n! T; H) _( W: K
  840. #endif /* STM32F10X_CL */: }/ R5 N# y: Y
  841. {  g+ v* Y5 [/ D/ B. ]! {& B
  842.   if(CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET)
    6 x8 g7 a2 J: t  w- X
  843.   {
    ! ~, n1 U4 ^! o9 B; X' [
  844.     CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0);
    7 M* p% M3 Y1 I7 n

  845. 4 j. O/ b  C6 K* ]8 e* t: W
  846.     CanRxMsg canRxMsg = {0};
    ! a% P4 G/ \- \+ z- V; p' V0 J' [
  847.     CAN_Receive(CAN1, CAN_FIFO0, &canRxMsg);2 B; P# R! C, `

  848. ; `8 _& ^2 h" V
  849.     if(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg) > 0)6 E3 w( r9 s% h! g( m9 H# X
  850.     {# b0 s; l. Z1 \4 H- D5 |, z* O
  851.       RingBuffer_In(can1RxBuffer, &canRxMsg, sizeof(canRxMsg));/ @, J$ }+ _1 v0 u3 T+ t. k
  852.     }
    - E3 k* T1 g6 Q$ k

  853. ) D  M' E! ]; P! M+ `* O$ H- T1 [- Y
  854.     if(can1ReceiveFinishCallback != 0)
      {5 q& f2 e* b3 ~) T. i# H) e* f+ {
  855.     {
    # f2 Q+ }5 B) @6 v* ]( ~
  856.       can1ReceiveFinishCallback();
    2 L( U( ?' e: O% ]5 G
  857.     }
    % |# U& G6 _! f
  858.   }0 L# `: n9 W3 X5 f
  859. }
    0 ?. l8 D. B" r) T

  860. 4 k. Q+ Q5 [& a7 l) Z
  861. #ifdef STM32F10X_CL8 P5 j# C" c: J3 a" Z
  862. /**
    , H& q" p6 ]# ~! c9 U* Z
  863.   * @brief  This function handles CAN2 TX Handler.) r3 M: \9 Y9 ~# `+ w( D
  864.   * @param  None.* L- c1 c9 m& b1 P
  865.   * @return None.$ [4 C* S+ `9 b$ g* z6 S' l
  866.   */
    $ x+ k  X* f4 M. ^* `2 ]  C: ^; N
  867. void CAN2_TX_IRQHandler(void)4 p8 p6 {9 Q9 t2 b& O$ o
  868. {
    6 t2 T" F. w# t0 r6 y& Z' \" \
  869.   if(CAN_GetITStatus(CAN2, CAN_IT_TME) != RESET)
    3 q( {( T% j8 x8 w! X4 C/ D# o7 K; k
  870.   {
    : I6 a* |) B8 K. k7 `! @+ l
  871.     CAN_ClearITPendingBit(CAN2, CAN_IT_TME);
    , a0 n6 L" N+ c! ?
  872. # y* G  b# z/ Y9 F! B9 e
  873.     CanTxMsg canTxMsg = {0};
    ) d4 ~% R# ]; x2 m, R+ W: r3 O
  874.     uint8_t  number   = RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);, a, U# e# u2 s& _$ ^& w
  875. 7 |  ?; c! N4 r( L; m$ J$ x1 _
  876.     if(number > 0)
    , j/ m" w! S& ]5 i7 g+ _+ `4 v3 Y9 i
  877.     {$ F/ C! D8 C& F5 j
  878.       CAN_Transmit(CAN2, &canTxMsg);0 R8 r+ g1 q+ v7 ?, x# |1 A
  879.     }3 g) R! R# ?) Y, K& B& _
  880.     else
      b) G$ a3 K4 U  A9 X
  881.     {
    # B" m# D* d/ v* z0 H6 a
  882.       can2TransmitFlag = false;' _3 ]$ c" x: m: k: D) T

  883. 0 M. ]( F' @* C( u
  884.       if(can2TransmitFinishCallback != 0)$ ~1 i6 N' X0 B+ |/ N
  885.       {
    ' O  n# r* ]( j; L
  886.         can2TransmitFinishCallback();
    % C# U. M: S5 Q1 J* [5 [+ P, c
  887.       }
    ) p1 |+ S2 W: u2 W0 f" ^+ Y
  888.     }8 Y  d7 ?! [& S  X# r4 ^
  889.   }7 A6 c% i/ r+ S( u
  890. }
      t* D& `, r0 g' B6 X' K

  891. 3 b6 `- X; D) z) a# p
  892. /**0 ?- N: P$ \0 E. R; A8 G( y
  893.   * @brief  This function handles CAN2 RX0 Handler." L/ Q5 l  R$ D! U/ l3 V$ Z
  894.   * @param  None.
    1 E; S$ ?; j% M  c  a3 r: x$ _& ]" i
  895.   * @return None.
    ' W, X3 N2 |  X* x7 A+ H" o' {8 u
  896.   */( m4 V3 V/ K9 A2 D3 I# }
  897. void CAN2_RX0_IRQHandler(void)
    ! D* v+ g* y3 j: \  r0 U  U
  898. {
    : a' N4 i+ o, f* p2 u0 o- N2 c
  899.   if(CAN_GetITStatus(CAN2, CAN_IT_FMP0) != RESET)# X- @) v% x' [' I4 e
  900.   {2 p9 Z- i! E' Y
  901.     CAN_ClearITPendingBit(CAN2, CAN_IT_FMP0);
    6 e( A0 v4 d- m4 O0 a; Q" R2 e

  902. + P; J6 `' \6 d( p
  903.     CanRxMsg canRxMsg = {0};
    / l, u3 ?  F, G0 L4 j
  904.     CAN_Receive(CAN2, CAN_FIFO0, &canRxMsg);
    , |  B# D& l/ d+ A3 Q4 v2 i

  905. ( q# K1 j% o$ K4 z
  906.     if(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg) > 0)
    ( p8 ~! Z1 J. _
  907.     {& Z, J/ Q& }, b* M! a
  908.       RingBuffer_In(can2RxBuffer, &canRxMsg, sizeof(canRxMsg));1 Y+ I. M7 u$ K' i
  909.     }9 q7 m4 `( Z' Y; z, a! E8 f
  910. * `  V  L. N/ v+ a! `& f4 `
  911.     if(can2ReceiveFinishCallback != 0)
    # ^7 ]" O* k. v) r1 p; [6 ~
  912.     {
    ; o& a! d! T, g# q/ h, m5 a
  913.       can2ReceiveFinishCallback();4 A$ D) {9 P, w$ p3 @, |, z! C
  914.     }
    ) ]7 `$ G2 p# L' \& o$ d! z
  915.   }1 K3 |. W: k  k7 ]$ |/ z) z
  916. }
      @* N2 M3 b$ U1 e3 d
  917. #endif /* STM32F10X_CL */
    * \5 [. F" W# u* T* ]. O
复制代码

8 Y1 K  m5 B$ O. }
; H8 a+ z- a/ t/ [1 H/ nmain.h 文件& l! v0 z0 g: b$ [" z: W
  1. /**
    # S& e2 M- F% m+ T; S& }" \2 N" K2 r
  2.   ******************************************************************************8 Z, t" s8 P" n! d2 h
  3.   * @file    main.h) Q  {' B" z% d8 Y
  4.   * @author  XinLi$ ?' E8 f% F1 j
  5.   * @version v1.0
    6 C% E+ X6 m" q" c0 s
  6.   * @date    24-June-20185 O, X6 W% V: q/ E3 ~- q
  7.   * @brief   Header file for main.c module.
    3 b7 p. t6 S7 Q' l
  8.   ******************************************************************************
    6 |1 T! \6 ?* s: p
  9.   * @attention
    : h! S# S3 q# J( m8 T% J
  10.   *7 @' d/ C4 D4 e+ X' M0 P
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    7 z5 `! ^5 l% U$ t' d
  12.   *. t' ^) A* S1 ^8 R4 D# s; M6 a0 i
  13.   * This program is free software: you can redistribute it and/or modify
    1 A/ h; M2 [4 {( U
  14.   * it under the terms of the GNU General Public License as published by
    2 F- ?  q4 I8 G' E; ?1 }
  15.   * the Free Software Foundation, either version 3 of the License, or
    % C; o  w- A4 o( l. u# n: ]
  16.   * (at your option) any later version.3 ]4 ~+ K: i+ R- _, ?
  17.   *, J- H" k0 {, Q! N/ q4 p3 w4 f
  18.   * This program is distributed in the hope that it will be useful,
    - }1 A- D0 o" u3 ?
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    5 t8 \8 W  l" R7 N% b
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    $ [4 O+ c$ D! b+ J- C. M# M
  21.   * GNU General Public License for more details.
      \1 M% R) |3 I- B8 j, |, O4 {5 q1 k
  22.   *
    $ M) Q6 C& _! I9 V' e, M( N* h! x$ |
  23.   * You should have received a copy of the GNU General Public License2 O' H! A9 p$ ]1 W
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>7 I4 w' n6 x2 _3 o6 ?
  25.   *
    2 K& m# o, L) H' ]
  26.   ******************************************************************************1 |  f+ ^( V/ k! ]: j
  27.   */# k, Y  b" K, a" w8 U4 s2 b
  28. ! Z  n4 U' [% _% n4 }
  29. #ifndef __MAIN_H
      O7 Q* R( O$ Z7 f
  30. #define __MAIN_H
    & X/ p1 l# e! b5 d
  31. / R, K3 S' R1 j, X/ i2 ]3 v
  32. #ifdef __cplusplus
    ) ?0 a2 n4 b, q# |8 P; D( G
  33. extern "C" {
    9 e" @: k) e, @; z1 `6 I
  34. #endif1 `+ h( s: p/ B) F) [# ^# {7 L
  35. - K9 l0 v1 U! w: H( W  ^
  36. /* Header includes -----------------------------------------------------------*/
    7 M' x( {4 _+ q0 H7 H& y% O
  37. #include "stm32f10x.h"
    3 t# ^) H8 q  H0 @6 s: `0 |& a

  38. 3 M, p. M3 Z% e3 L1 b4 \( d) q( K
  39. /* Macro definitions ---------------------------------------------------------*/
    7 g% q* s0 V/ I* S+ o3 R2 D
  40. /* Type definitions ----------------------------------------------------------*/
    ) r+ _; h& Q. {
  41. /* Variable declarations -----------------------------------------------------*/+ j  t5 r1 E& U
  42. /* Variable definitions ------------------------------------------------------*/
    2 X/ l" Q, R# d* j& x4 n" E: {7 K
  43. /* Function declarations -----------------------------------------------------*/8 @& i, l5 n- `. ?/ ]( t2 r, j
  44. /* Function definitions ------------------------------------------------------*/: A# n) I9 L& L1 w6 B
  45. ! _* J  R7 U$ D% J
  46. #ifdef __cplusplus3 y* h9 e  C; \3 s, W
  47. }1 r, B4 J/ D$ D4 s- ?
  48. #endif' S1 |+ ]& n3 H! S6 Y4 w

  49. ) ~! K$ i$ R: N6 H) S& z
  50. #endif /* __MAIN_H */
复制代码

3 g. ]  \6 ^+ X5 @4 F
4 y: c7 z# E1 [* M8 \main.c 文件' U: F) S* Y/ m9 {( K# g2 Q) _2 U/ N
  1. /**
    - d, W! U& g& _- }) [+ D) y8 ]. f
  2.   ******************************************************************************# _& u7 {( @) n; h, u9 C2 B
  3.   * @file    main.c6 G7 z  t( _" V0 t8 O0 L
  4.   * @author  XinLi0 K3 J" i; J- A2 B3 p$ o. p' l
  5.   * @version v1.0# Z0 P- x! ?: j9 g  P) l
  6.   * @date    24-June-20187 J5 A8 E( t$ B4 E
  7.   * @brief   Main program body.
    6 R# L1 q: i; N
  8.   ******************************************************************************
    / x7 F' E: k) y
  9.   * @attention9 E: D- w: P* i
  10.   *- M0 W9 Z5 U! X$ O/ B
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>( x% O) H2 ^9 Z# V5 B9 W! H
  12.   *1 }0 t" g- R3 [  V- G% c0 B
  13.   * This program is free software: you can redistribute it and/or modify
    0 }( ^0 q" K6 @
  14.   * it under the terms of the GNU General Public License as published by$ o" n: L6 f6 v1 _. k
  15.   * the Free Software Foundation, either version 3 of the License, or# V' D, ]: {1 r. n
  16.   * (at your option) any later version.2 H  |" k0 F7 r% _
  17.   *
    3 O! y' D) L2 I4 n$ _
  18.   * This program is distributed in the hope that it will be useful,
    1 t7 ]' }" z: p. R- y+ S
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of5 o  X; [8 g' w$ [) m3 i
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the" ?- x  o; H) K9 V) N
  21.   * GNU General Public License for more details.
    ' R" U1 }) t( m+ }0 N+ k
  22.   *2 @6 X; m0 h: x
  23.   * You should have received a copy of the GNU General Public License
    % P5 d) `" M: z9 [
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    6 Y5 A( \( B) w# g3 N# |
  25.   *
    : S! R, ?6 ?. w0 L) R; L
  26.   ******************************************************************************
    7 _7 S# Q( n6 y3 N* j" ^- z
  27.   */# E0 E- p% H+ {8 }# O

  28. : @" ]" [0 i4 b" J
  29. /* Header includes -----------------------------------------------------------*/
    ) N! M  K, c; p. s5 L
  30. #include "main.h"+ k$ l1 I# e: X2 L8 ~& v! t6 W( a
  31. #include "CAN.h"! c! P2 T; `+ y2 w" g7 N) C
  32. 3 W' M% T/ t9 r( h( \
  33. #ifdef _RTE_# V5 n9 m0 D  O% U- u- o
  34. #include "RTE_Components.h"% a& q3 U$ b" T% T
  35. #endif
    $ w- h$ J- F$ R

  36. ) h* _, A7 u# A" @, s) L8 X9 N
  37. #ifdef RTE_CMSIS_RTOS2& T% o) B) |- n
  38. #include "cmsis_os2.h") V- B4 T1 ~0 W+ N- e
  39. #endif
    - B! m9 d# p1 Y0 u

  40. ; C  \0 g- S, w0 W
  41. /* Macro definitions ---------------------------------------------------------*/
    0 O) t) W( w6 ~
  42. /* Type definitions ----------------------------------------------------------*/
    2 O0 i% E# H" x' G7 r$ x& Q
  43. /* Variable declarations -----------------------------------------------------*/
      ^2 ?0 V( \. Y$ C" h2 v0 j* E
  44. /* Variable definitions ------------------------------------------------------*/- ^! l& S2 K% f
  45. static CanTxMsg canTxMsg = {0};
    # U* w$ b4 w- g0 s9 m
  46. static CanRxMsg canRxMsg = {0};
    & F0 S) {  S3 P  c1 S

  47. ( Y4 ~7 C1 Z/ n4 J! z" V
  48. /* Function declarations -----------------------------------------------------*/
    4 Y7 c: R' u) p: T5 G
  49. static void SystemClock_Config(void);
      M9 U* D4 ~1 T& L- ]( |8 ?; i5 ?

  50. % e& Y# N' @" u- A# V
  51. /* Function definitions ------------------------------------------------------*/5 @, K8 T6 X- L
  52. / [5 `# k+ i5 q2 f  g; @: X4 u
  53. /**0 K6 d! A6 a! d* ]2 k
  54.   * @brief  Main program.
    1 ]; D# S- s$ [8 ~
  55.   * @param  None.
    ; ?6 k0 l% r  }* m6 B1 Q6 ^2 z
  56.   * @return None.
    * V: l; t. E8 @3 y
  57.   */& e* p& i: s3 i; ?: k
  58. int main(void)
    4 E3 s) A) v6 R6 F3 [4 I" e4 z
  59. {
    * W+ S" m' w( J- Q8 K
  60.   /* Configure the system clock to 72 MHz */- u( W% Y0 b4 ?
  61.   SystemClock_Config();
    ( e7 x5 V+ _$ h6 _
  62.   SystemCoreClockUpdate();7 @' q- a! \! q. Y

  63. 5 o9 a" w0 L9 _( }; t) B
  64.   /* Add your application code here */9 D. R: }: |8 ^
  65.   CAN_Configure(CAN1, CAN_WorkModeLoopBack, CAN_BaudRate250K, 0xAA55, 0x55AA);; G/ ~2 G! t. @' w

  66. , z8 B, O% Y% ~8 ^+ Z
  67. #ifdef RTE_CMSIS_RTOS2/ A" N1 h8 ^9 d; V# D
  68.   /* Initialize CMSIS-RTOS2 */
    6 K0 W  a+ o7 b0 ]9 C& B5 z
  69.   osKernelInitialize();
    9 K7 [# G" K& p" Z2 T6 K

  70. 5 o; S7 m4 X" L- H1 O; o9 x
  71.   /* Create thread functions that start executing,
    & L% ?  \4 ?+ K- o
  72.   Example: osThreadNew(app_main, NULL, NULL); */
    * z8 {: i% S, s. C# c8 O. J
  73. " w" c% v+ b% k+ J0 r8 w
  74.   /* Start thread execution */
    0 I+ @& U- }4 I
  75.   osKernelStart();- t: e8 A5 P5 k
  76. #endif( e1 T! p# X8 x3 X% _
  77. 8 F2 |. R' J" D5 J% c) j' r% l
  78.   /* Infinite loop */4 V5 h3 t2 C" h; K9 E* B
  79.   while(1)2 u6 n6 F. h. n  G' Y$ y* m7 j
  80.   {
    . e. g" g  |( U1 ~3 ]
  81.     canTxMsg.StdId = 0xAA55;5 X  M7 ]' r$ \7 _  ]4 y
  82.     canTxMsg.ExtId = 0x55AA;
      Y2 X4 F. R' p: v) R) I
  83.     canTxMsg.IDE   = CAN_ID_STD;
    ( D3 A. G! b, b+ W5 ^; ?3 O( S
  84.     canTxMsg.RTR   = CAN_RTR_DATA;
    1 X: b9 }1 I- b4 _$ B: z4 |2 I$ ]
  85.     canTxMsg.DLC   = 8;
    ' B1 P' {% S0 o% j4 k
  86. 6 y, l- l; k) @( X$ L# `8 M. f
  87.     canTxMsg.Data[0]++;
    9 }& z) z  S- d5 U& r
  88.     canTxMsg.Data[1]++;
    3 B& \( O7 l- D3 @
  89.     canTxMsg.Data[2]++;
    - E9 L" x6 ?& S2 _2 ~6 W# b9 L* z
  90.     canTxMsg.Data[3]++;+ w* H0 }5 o- d
  91.     canTxMsg.Data[4]++;
    : r! _! i  E+ n1 x( S8 q+ v4 l1 Q
  92.     canTxMsg.Data[5]++;
    7 k5 X9 O3 F/ X" P+ b7 @. i% F
  93.     canTxMsg.Data[6]++;
    9 J6 K/ r- H. S& w
  94.     canTxMsg.Data[7]++;
    8 J% L- u4 C  d6 ?( d

  95. 1 q/ O. j! j, h. g7 l
  96.     CAN_SetTransmitMessage(CAN1, &canTxMsg, 1);: ]  N( f1 x0 h
  97. 2 o, U) B. l! b7 d7 A; X
  98.     while(CAN_IsReceiveBufferEmpty(CAN1) == true);' e4 U4 W' o8 `3 S

  99. 3 O. G- U0 {* s( W2 _
  100.     CAN_GetReceiveMessage(CAN1, &canRxMsg, 1);; Q' |  M; ]5 B  p
  101.   }; O/ s! l6 t- m( y, r- Q
  102. }
    - x  U, _% j0 p( Y2 E
  103. 1 e& M$ R4 [5 Y' k3 K
  104. /**
    , k/ m( I  C( }# L0 V
  105.   * @brief  System Clock Configuration.
    0 H& v& l0 D) I% t, x
  106.   *         The system Clock is configured as follow : : a% q  G& R$ e, M- ^) |, o
  107.   *            System Clock source            = PLL (HSE)
    0 x* ~* Q- `9 Z, Y( n6 ^7 U
  108.   *            SYSCLK(Hz)                     = 72000000
    ) b8 j+ l/ _' c( @. j
  109.   *            HCLK(Hz)                       = 72000000- b$ P: P! k! H! X0 i3 ^
  110.   *            AHB Prescaler                  = 1& `: J, f: u4 F9 M. t) o$ b
  111.   *            APB1 Prescaler                 = 2" s1 W, m9 _8 X0 D
  112.   *            APB2 Prescaler                 = 1
    / o: A. Z5 i0 f# \
  113.   *            HSE Frequency(Hz)              = 8000000
    5 W& u' E" j: U2 u6 z- e& x
  114.   *            HSE PREDIV1                    = 1. F" }% L( ^! \* d0 \5 R# _& ~
  115.   *            PLLMUL                         = 9- I3 V$ L2 V- a1 Y
  116.   *            Flash Latency(WS)              = 2
      y1 t4 e9 |1 M1 v
  117.   * @param  None." o9 @) h. A' F/ Y9 {
  118.   * @return None.+ l5 K* n, m) w" J# ^6 p# l9 f  s
  119.   */7 C6 X3 H' u: H& U# H
  120. static void SystemClock_Config(void): |4 T4 y. d% m4 u9 T
  121. {
    * E. K/ X, q, n6 @9 a$ F2 W  v5 ~
  122.   /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration */# c5 l) d! `; z9 n; _& x
  123.   /* RCC system reset */# t; e, T* S, ~
  124.   RCC_DeInit();. l/ F% p- F7 x! w, i+ \& m4 y

  125. * l8 G" U2 Q8 w- k8 w
  126.   /* Enable HSE */
    3 v( a1 j' \, o4 S
  127.   RCC_HSEConfig(RCC_HSE_ON);
    5 c  N& q( h! S) |& O/ ?
  128. ; ?. d& l0 v; g, z6 S& `
  129.   /* Wait till HSE is ready */! v& V3 W4 W; `0 J; o& J& m7 j7 d9 |
  130.   ErrorStatus HSEStartUpStatus = RCC_WaitForHSEStartUp();- R. R4 a; s- Q: e7 Q; k" k

  131. 0 [% \) \. I: H* s
  132.   if(HSEStartUpStatus == SUCCESS)
    ; r/ R: H0 |+ Y8 w$ D6 _0 P) I
  133.   {
    ! o  |  Z" n. Z
  134.     /* Enable Prefetch Buffer */
    , }4 [4 L5 g+ X4 z
  135.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);, Q- y! Q) R1 X
  136. 8 R& ?0 {0 u( m; }( @# M
  137.     /* Flash 2 wait state */" }7 Z& `* u/ `4 E4 A7 ]# [7 m1 g
  138.     FLASH_SetLatency(FLASH_Latency_2);6 q8 e9 @$ g# G0 s! A
  139. : P) H1 G6 n8 s" j) Q
  140.     /* HCLK = SYSCLK */, K0 R0 d: T, R  d
  141.     RCC_HCLKConfig(RCC_SYSCLK_Div1);   z. R1 q5 d0 `

  142. : \; L1 x, N% u/ N- {" }. h& ^8 Q3 }
  143.     /* PCLK2 = HCLK */1 t! _0 z2 E9 k( N
  144.     RCC_PCLK2Config(RCC_HCLK_Div1); . K  I9 u8 Z' i! e* I

  145. 9 f) _  V* y0 i5 D% @; E% |
  146.     /* PCLK1 = HCLK / 2 */% L) x6 p2 K  n1 k; {# P
  147.     RCC_PCLK1Config(RCC_HCLK_Div2);/ x9 Y5 X$ a2 Z( N' U0 B

  148. 1 C7 h$ a, s. \9 P' u' Y0 j
  149.     /* Configure PLLs */9 O) e( G/ w3 A
  150. #ifdef STM32F10X_CL7 I( ^( u  i. i/ @+ q, s
  151.     /* PLL2 configuration: PLL2CLK = (HSE(8MHz) / 2) * 10 = 40MHz */
    ( d+ {% }$ X1 F
  152.     RCC_PREDIV2Config(RCC_PREDIV2_Div2);
    % g/ L8 O1 R* F* e4 D9 D/ P" b' j- D( X
  153.     RCC_PLL2Config(RCC_PLL2Mul_10);
    & _2 O- r3 O% M+ Q$ i- S

  154. " M' y& H$ |/ S& n! ^. r0 J
  155.     /* Enable PLL2 */
    : r4 Y4 l/ Z% u  w
  156.     RCC_PLL2Cmd(ENABLE);
    ' X! V5 A# m* h* l) j
  157. ' b) A2 o7 O: g/ k. J: ]( y
  158.     /* Wait till PLL2 is ready */
    ' l# Q' K2 K! N5 S, X# g3 @9 H
  159.     while(RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET);
    " b! |  i  O. |

  160.   Y% k7 H( G" M, T$ y
  161.     /* PLL configuration: PLLCLK = (PLL2(40MHz) / 5) * 9 = 72MHz */
    " K2 M3 x9 H0 j, l
  162.     RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div5);
    ' Z% q% ]% I0 i' T
  163.     RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);- g9 l3 L3 D! I
  164. #else
    ' Q. S' j/ p1 ]) w0 B" A
  165.     /* PLLCLK = HSE(8MHz) * 9 = 72MHz */
    6 _7 t* r2 v9 m  T6 O2 t
  166.     RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);7 w- n+ |: y9 u- p
  167. #endif& D& |1 b* h( V  X2 m! r2 T

  168. 3 O1 a! @$ V4 G$ j4 H5 p! O* R
  169.     /* Enable PLL */
    8 G, \8 E& g* {0 e3 _9 G& L- ]
  170.     RCC_PLLCmd(ENABLE);
    - o  M  O" M/ j% d3 [, N

  171. . w+ P8 \  Z4 ~# t0 p0 C
  172.     /* Wait till PLL is ready */6 J, S5 G9 o. O1 H! C$ d
  173.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
    % G+ L+ M- ^( m2 j

  174.   H( B: I0 y7 Y+ I2 i9 G
  175.     /* Select PLL as system clock source */: ?, M" c3 A, B  ?. F
  176.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    , s1 U, k7 _- ?

  177. % J$ G3 A; l, w5 a+ P
  178.     /* Wait till PLL is used as system clock source */6 H$ _  b; ?4 Z* P! [* L* T: @
  179.     while(RCC_GetSYSCLKSource() != 0x08);
    / Z* H3 x- _! r4 X, o# S
  180.   }: R2 t4 P$ L/ {/ t- b6 `
  181.   else
    - z% `) T2 R& ^+ h
  182.   {
    " [9 x+ E' ^) N/ k- s
  183.     /* Disable HSE */
    2 P' t9 t5 T6 u! G, b; x
  184.     RCC_HSEConfig(RCC_HSE_OFF);
    0 _' Y! v1 J$ K

  185. + u( |- B$ w8 g% w. u$ `# }
  186.     /* Enable HSI */- {: K9 A1 {' _8 \6 P8 N6 y& C
  187.     RCC_HSICmd(ENABLE);
    ) L; ?2 n& D9 }8 m

  188. $ |9 U/ U0 ^8 m/ v2 U  n# f" i% X$ v
  189.     /* Enable Prefetch Buffer */
    8 s8 N4 v, [: v! N) m1 w1 f0 j2 ]
  190.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);" l0 c7 `8 S  K) |

  191. / V; r. Z% t9 J6 ]
  192.     /* Flash 1 wait state */; y% }2 c/ d# v/ x& S
  193.     FLASH_SetLatency(FLASH_Latency_1);" P/ t* @% u  T" J
  194. 8 E2 I: B3 `0 m* W/ Z
  195.     /* HCLK = SYSCLK */
    " c4 A6 y" M$ y" S$ G# Q% @/ |  t7 W
  196.     RCC_HCLKConfig(RCC_SYSCLK_Div1); ' K* ]8 M4 x4 j. ?
  197. 6 m; R. h2 `% E. ]8 C. N+ a+ L
  198.     /* PCLK2 = HCLK */' I5 G2 R; W( D5 |5 Z+ U2 p& [
  199.     RCC_PCLK2Config(RCC_HCLK_Div1); / t/ G# u! A- K% z& V( k, j

  200. 0 F9 K3 K! A3 Z4 `
  201.     /* PCLK1 = HCLK */, P; U' g9 V8 R' L
  202.     RCC_PCLK1Config(RCC_HCLK_Div1);
    4 `% ~1 z7 o) W8 [5 K! y* Z
  203. 2 `" l2 I  `' x6 \" P
  204.     /* Configure PLLs */
    1 ?- ^; h4 B& k4 z# R
  205.     /* PLLCLK = HSI(8MHz) / 2 * 9 = 36MHz */
    " a# I" }  b0 x# H, N0 I
  206.     RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_9);: j  m6 r& w, W

  207. / X; n% ^! n0 _% f7 H& \: g
  208.     /* Enable PLL */
    - }2 D4 s8 L  |/ x- |/ b
  209.     RCC_PLLCmd(ENABLE);% k2 a/ L1 z6 W. J
  210. 2 n- j# g4 e8 F7 V9 v1 @* w
  211.     /* Wait till PLL is ready */
    * c. [. I5 f7 h7 v* W3 V- [0 B! N, q
  212.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
    8 R+ V  s* r! ?. o3 z  |5 `
  213.   C2 p1 B1 s# N- m8 J
  214.     /* Select PLL as system clock source */
    3 @2 @; b" p$ E/ R
  215.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    " v! ~2 `% [1 a7 ?5 X" r" b
  216. 3 Z: Z8 w$ j! _/ ], a
  217.     /* Wait till PLL is used as system clock source */
    - _* J; R) s* d% A: \) |- p4 s
  218.     while(RCC_GetSYSCLKSource() != 0x08);
    4 {+ n1 f2 R& [9 h% h
  219.   }% \9 \# h7 E, d" V
  220. }
      J, }) e$ n0 c. \1 N0 c

  221. 5 g. V5 l1 `9 H: c+ W
  222. #ifdef USE_FULL_ASSERT& r& f  g8 s, w! l* N- @8 D8 T
  223. /**
    $ @0 s, H4 S* @1 r5 ~( F
  224.   * @brief  Reports the name of the source file and the source line number
    . s" S. V9 ~8 O7 y* _/ v7 l
  225.   *         where the assert_param error has occurred.
    - {+ A5 C' C1 M* {  A& G
  226.   * @param  file: pointer to the source file name.7 u5 }8 A% V4 ]
  227.   * @param  line: assert_param error line source number.
    7 v- q( G1 H$ H$ N+ }: W
  228.   * @return None.
    ; `; Y5 c- D5 ?$ L
  229.   */
    7 \% w& z0 a9 `& X% X) w
  230. void assert_failed(uint8_t *file, uint32_t line)
    7 ]2 ?  ]' e7 l5 s7 L
  231. {& X" ]. Q& N& O2 t  |; y9 Z
  232.   /* User can add his own implementation to report the file name and line number,
    . d; k+ n3 E; Q2 O* f, M: A" Z& U
  233.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    6 w! F9 t$ x% |- Z  Y1 G

  234. , g+ a( b, [: m* I( z
  235.   /* Infinite loop *// D" e; A& g: \8 Q: D
  236.   while(1)
    / d% h: ~# c% r6 m3 ]* U" f" m
  237.   {
    + t# W7 s# h0 k7 Y
  238.   }
    # x: R: Z- e# Y7 q: O2 C7 S' u4 x
  239. }$ s% U( t+ Y+ U! `# J
  240. #endif
复制代码
- n1 p$ ^& y$ ?& ]
3,注意
' l9 G0 e$ {4 V0 f
7 Q( `0 g2 X& O( z4 yCAN 消息发送缓冲区和接收缓冲区的大小,可以根据应用的需求进行修改,缓冲区使用的是堆内存,需要根据缓冲区大小和应用程序中堆内存使用情况进行配置。
: ~8 d- t' ~* y1 y+ D. e
4 L4 u6 E8 y0 |' b, X1 A' U- [% Y, w. ]2 q

4 L3 ~/ c! q" W1 `; U% L% q( ~
收藏 评论0 发布时间:2021-11-26 17:00

举报

0个回答

所属标签

相似技术帖

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