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

【经验分享】STM32F1(CAN)

[复制链接]
STMCU小助手 发布时间:2021-11-26 17:00
1,开发环境$ O  z/ B2 k7 Y. H6 P

7 L; M5 h6 U! ^* @9 A1,固件库:STM32F10x_StdPeriph_Lib_V3.5.05 W5 t% j, m, Y8 @( ^; L- s9 Z
! c# t. r3 L; ?
2,编译器:ARMCC V5.06
' x" x5 g* A% `1 d; N8 ^
" E, p' r; c/ }$ [: d3,IDE:Keil uVision5+ x. R  ~$ D5 E, C
- X) |# v( _2 q
4,操作系统:Windows 10 专业版# _( |3 H8 |6 I, X6 {! O

- F7 y6 {% {' i, |9 P0 R; ~; e( V' u' w" Q) Z
2,程序源码3 {/ o3 ^# l7 L4 z  M+ F, t! Q

1 N2 ~4 `  _" {% `  h3 r0 LRingBuffer.h 文件
7 h  q' U5 Q9 {* i
  1. /**
    ) P3 x# q0 X  Z1 ]% M" b/ l
  2.   ******************************************************************************. H6 F' B9 l( {: K
  3.   * @file    RingBuffer.h8 d: I4 I( K3 }' a& G; b% q; Y4 g
  4.   * @author  XinLi0 E& O2 s4 ^: f4 V  q& P
  5.   * @version v1.1- `) W( O; `6 B. a; a
  6.   * @date    15-January-2018
    0 }, u4 h  _) _7 E+ O
  7.   * @brief   Header file for RingBuffer.c module.
    - {% `+ j7 M1 A5 C8 j7 V& @
  8.   ******************************************************************************
    ' ~* q* v/ T" p+ y/ N
  9.   * @attention
    ' W. X# t2 W9 j0 m+ S7 H
  10.   *
    4 \1 Z! N( T5 M8 [
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    9 T- ]9 A9 h2 u* P
  12.   *
    # Q; k6 E# a. l/ r  G- k2 Y; ^4 y
  13.   * This program is free software: you can redistribute it and/or modify+ c- m: M  O- @7 h1 D8 W
  14.   * it under the terms of the GNU General Public License as published by
    ' \  ~- T7 C; J3 j! r# `
  15.   * the Free Software Foundation, either version 3 of the License, or0 K7 ], v" ?  \, i8 n; ]! P. [
  16.   * (at your option) any later version.. C+ y& Q! H/ E9 z8 ]7 v. Y- U
  17.   *
    / B6 {  u" r1 F8 ^
  18.   * This program is distributed in the hope that it will be useful,/ C. e% q5 `/ m9 N& Q% j6 N
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of8 k# q3 g6 a$ J( ~: l
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the" s( K$ j) b: d1 x0 w5 O0 N
  21.   * GNU General Public License for more details.
    ' r  {5 k1 b/ ]. w8 e* Q
  22.   *
    - @- [& e" F1 r% {& R2 R& }
  23.   * You should have received a copy of the GNU General Public License
    9 e; ?0 |% l( O5 ^
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    * r6 w: m* p& ~: V
  25.   *
    : R! O9 w1 B, w4 G( K
  26.   ******************************************************************************
    0 G+ N( t9 a. P& F0 Q& m' v
  27.   */
    + S5 E4 K( L& Y6 |. K6 a

  28. 1 n8 C' D" U: X+ P
  29. #ifndef __RINGBUFFER_H
    * @1 M. O  S. z. C6 g# P* L  B( a8 N
  30. #define __RINGBUFFER_H2 ?+ i7 b( e$ O2 i
  31. % u7 e. A' D$ `
  32. #ifdef __cplusplus' j5 O5 a6 L3 m9 G$ o) k$ g' B8 }
  33. extern "C" {
    2 ^, k& s6 k( b/ t0 l+ _" E( \
  34. #endif
    " x6 f, \8 P1 x- ]( s% j! q

  35. ( Y1 H# ]$ G  U) `- j! |& [; e
  36. /* Header includes -----------------------------------------------------------*/
    4 Q. G8 O8 I& y) o
  37. #include <stdint.h>
    ) z, q9 e! r8 W# i7 O# a
  38. #include <stdbool.h>
    ( X) [; b( M2 @6 V' ^. {+ e
  39. #include <stdlib.h>4 O6 r  C) G+ s3 }. u2 D. s
  40. 0 m* @" u  H/ {0 `9 X
  41. /* Macro definitions ---------------------------------------------------------*/  u4 e, m5 Z/ }7 i. o
  42. #define RING_BUFFER_MALLOC(size)  malloc(size)2 k9 e7 O3 @# A
  43. #define RING_BUFFER_FREE(block)   free(block)$ Y5 S+ t( N7 N# w" _, L
  44. + D- r6 J* |$ r; N* S2 u
  45. /* Type definitions ----------------------------------------------------------*/
    - d6 J* p6 R5 h( ?: h
  46. typedef struct% h8 q9 c% v4 f* E; a; H
  47. {7 e% }" k3 ~/ v. i1 [( f, x
  48.   uint8_t *buffer;
    7 b+ I; `0 O% H! O+ l
  49.   uint32_t size;
    : T& T, R3 }. Y# {
  50.   uint32_t in;
    9 R2 r  ]/ O3 e2 h
  51.   uint32_t out;
    - o4 [7 k( v% V: F' k# `& t% ^* M
  52. }RingBuffer;) W" K3 E( u# v! e7 z+ o# s
  53. % Y  Q: x. D7 _+ I& o0 [
  54. /* Variable declarations -----------------------------------------------------*/5 [& I% e& D  n) Q
  55. /* Variable definitions ------------------------------------------------------*/
    . U) u. [, d4 ]9 S. \; r9 ^
  56. /* Function declarations -----------------------------------------------------*/
    0 {! q: l, A+ O7 }0 o) }
  57. RingBuffer *RingBuffer_Malloc(uint32_t size);$ g, N% u3 F- _; X: ]
  58. void RingBuffer_Free(RingBuffer *fifo);
    $ o: h8 c' b; k* |

  59. - b0 h: s: N$ u8 Z2 ?2 \5 @
  60. uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len);! p  c5 I! B7 ^& Z2 y6 o3 Q6 q
  61. uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len);  \( f# Q0 |  _$ j5 g% Y

  62. % H) J; [2 z+ k% m3 {% c
  63. /* Function definitions ------------------------------------------------------*/
    ) ]- f: G0 e2 p  Q) G
  64. ! @6 {$ M2 l0 i7 A0 ]3 d! }$ t+ C
  65. /**
      p0 r$ }5 A$ ], U) U4 n/ Z
  66.   * @brief  Removes the entire FIFO contents.
      o8 W  ?; G" y
  67.   * @param  [in] fifo: The fifo to be emptied.
    ; m1 H+ u6 a6 E: S, ?
  68.   * @return None.
    8 N. \! m5 Q( N
  69.   */- e0 x9 k2 J/ H4 g  k
  70. static inline void RingBuffer_Reset(RingBuffer *fifo)
    $ c2 H/ ^% y" e0 y- t  o
  71. {
    5 o5 J2 J' @! |3 `. T7 N
  72.   fifo->in = fifo->out = 0;
    6 U1 t1 h" x" W' w$ H
  73. }# O2 W( @# r( }
  74. , m6 V6 q: u5 F6 H3 `" z
  75. /**, |- S2 X5 T2 e$ H& c0 _
  76.   * @brief  Returns the size of the FIFO in bytes.% H: V( p) Q0 ~' X( H
  77.   * @param  [in] fifo: The fifo to be used.
    ; R* W- _" Y" O& j1 ^8 C5 P6 c9 e
  78.   * @return The size of the FIFO.* G3 F+ r8 ]' O, b6 x7 _7 h6 m2 L& V
  79.   */
    0 u0 H% e* P' x2 d
  80. static inline uint32_t RingBuffer_Size(RingBuffer *fifo)
    4 c* N$ X* r: E0 L2 k
  81. {
    7 _" P* l  r1 E% j9 P2 g
  82.   return fifo->size;
    - R, _: e  U; G) q9 W
  83. }4 r$ g: \' Y( l8 Q4 ]: @
  84. - A3 Z3 I: P. f: p
  85. /**/ h1 J* \6 o8 n: W( r
  86.   * @brief  Returns the number of used bytes in the FIFO.- U' W3 l5 t# @. P+ z+ Q
  87.   * @param  [in] fifo: The fifo to be used.
    . S  ]  [1 T1 q% u6 O1 {, x
  88.   * @return The number of used bytes.
    , X% `' {- f$ \. R0 u3 }( ?% H
  89.   */$ F: n1 E9 H. C0 z; v
  90. static inline uint32_t RingBuffer_Len(RingBuffer *fifo)
    / l; w6 O- T' z
  91. {
    " |# M: E1 ?. P  k3 }+ K
  92.   return fifo->in - fifo->out;
    ; t# B5 s. A* H
  93. }
    1 k4 l. Q; J$ T! I4 x$ O

  94. 5 Z3 v* G& ]( j2 V  G5 f
  95. /**  F# J! J0 U7 z) m  K, [1 M
  96.   * @brief  Returns the number of bytes available in the FIFO.. \# x: a; R2 K" J/ D; |
  97.   * @param  [in] fifo: The fifo to be used.
    " c$ o5 S* U( f$ @. I1 ?& D
  98.   * @return The number of bytes available.
    8 ]6 \( I. Z+ @) t1 v3 m; ~0 j0 E
  99.   */1 f, i) Y" V- Y$ }: E
  100. static inline uint32_t RingBuffer_Avail(RingBuffer *fifo)) T7 D3 H) K+ K
  101. {
    ; r" A; Z& v5 \5 O) k5 f9 K
  102.   return RingBuffer_Size(fifo) - RingBuffer_Len(fifo);$ ^# Q9 b6 C* ]' A; W$ N6 Y
  103. }
    - @$ I) R) q# F! N9 n
  104. 4 u, ]2 T! J0 [3 N$ O, x) _* ]
  105. /**$ k* F7 b9 a; w* o8 e
  106.   * @brief  Is the FIFO empty?
      e2 x1 E# ~4 J: B7 c3 y
  107.   * @param  [in] fifo: The fifo to be used.# _8 B9 ]- Y( M8 ~, Y7 ~
  108.   * @retval true:      Yes." ^5 S: }, L! j* e# r" e
  109.   * @retval false:     No.
    6 p5 J+ c4 U" Q% S+ g! r
  110.   */8 |  H$ H$ Q# V
  111. static inline bool RingBuffer_IsEmpty(RingBuffer *fifo)8 C8 o3 {  H& N# P# T' P& k8 ~
  112. {
    # a& f/ M$ d* g  K( _
  113.   return RingBuffer_Len(fifo) == 0;  r) ~& L9 Y  C! v/ V+ i7 b
  114. }2 M3 d1 b8 C& m" T& Q
  115. 0 C' n" T3 d0 N
  116. /**
    3 u. O  {8 y  A7 m
  117.   * @brief  Is the FIFO full?) K9 p) T  R! i! x  V+ Y9 [# o
  118.   * @param  [in] fifo: The fifo to be used.# w( Q4 s( s9 \2 |( i
  119.   * @retval true:      Yes.
    ) g# E1 F1 Q$ s; e" b8 ~
  120.   * @retval false:     No.) {4 j" I! c: D3 |5 A* d* r( D
  121.   */
    ' f# g& h0 W) m& O  \+ p
  122. static inline bool RingBuffer_IsFull(RingBuffer *fifo)
    , y! K! z4 x) B" ]$ r
  123. {# s8 p- K% K7 ?' [0 E+ A
  124.   return RingBuffer_Avail(fifo) == 0;" z5 m* _; \- o5 B1 R
  125. }
    " w3 P: u% I5 u* f7 u# U

  126. & B6 [$ A) k. j' M
  127. #ifdef __cplusplus
    % d  z9 {0 p# s  y  x. {% p0 `2 v6 C
  128. }) e+ ^, `7 I9 o. q7 I8 h
  129. #endif
    ! ^' q! z1 l' Z- D
  130. & @6 |- M( U/ T6 T# ^
  131. #endif /* __RINGBUFFER_H */
    1 \; I6 N1 g+ k9 _; Q8 a5 m/ y# r& ]# E* |
复制代码
. |+ z1 [! k5 Q( Y
1 |2 O8 B$ x0 P. O2 |! C
RingBuffer.c 文件
4 v2 \) n1 {# }1 O/ e
  1. <div>/**' D' L2 H4 r5 m! A, o) V$ M( a; Q; ^+ U
  2.   ******************************************************************************
    : h4 e9 L( x; m! p' [- L2 `, @
  3.   * @file    RingBuffer.c
    7 N2 x4 U+ E. }* h& ]0 k
  4.   * @author  XinLi# [% {  k  G. t5 W) N
  5.   * @version v1.1
    4 I7 I8 f/ A0 P7 {5 k
  6.   * @date    15-January-20181 u4 N- b' ~! {+ `
  7.   * @brief   Ring buffer module source file.
    7 I' u4 R" S: z8 X8 V5 L8 ~0 s
  8.   ******************************************************************************
    7 O  `9 }6 g4 @/ G
  9.   * @attention6 i4 L3 d5 V8 I0 q5 g7 l
  10.   *% O* P% I  H7 e
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>" u) E% o2 w% O& k* e: \9 @
  12.   *  _" r) S) B' r$ k
  13.   * This program is free software: you can redistribute it and/or modify
    6 Y  z1 ^3 C8 a) ~
  14.   * it under the terms of the GNU General Public License as published by
    # o  L8 C8 [" w1 C! x$ @8 s+ @
  15.   * the Free Software Foundation, either version 3 of the License, or
    : N* X7 g% q! {3 i1 j
  16.   * (at your option) any later version.
    8 R7 z1 k3 y7 A
  17.   *
    7 G& S/ T. ?7 |+ K4 M1 Y
  18.   * This program is distributed in the hope that it will be useful,
    # j+ R  m2 |3 Q  [. w
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of" U2 u' n: S& r2 B
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ' e* M% i" M8 ~4 k  M& E1 J6 l/ m
  21.   * GNU General Public License for more details.- ]2 `2 P% j4 T% S  U
  22.   *
    ' N- W2 N! s3 B2 X
  23.   * You should have received a copy of the GNU General Public License$ T# i8 [4 u' I2 t: h" C5 [
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    - V( ^* A4 n) m; u+ A2 `
  25.   *
    . t$ |# K( F; J, n- b& E* W
  26.   ******************************************************************************
    # i7 |! {6 B1 A% ]  U& B! y8 w
  27.   */
    0 E0 _5 \" f* Q7 g1 p( x: C

  28. ) e: V+ j! w* k) G1 M
  29. /* Header includes -----------------------------------------------------------*/
    2 z# b+ K$ @/ ^
  30. #include "RingBuffer.h"" J! s3 j7 W/ g
  31. #include <string.h>
    1 h$ p, i8 i/ _$ [& o! Y; V% D/ m9 f

  32. ; F: m2 a1 U3 Z3 |
  33. /* Macro definitions ---------------------------------------------------------*/
    . }' j) A+ _: l$ X8 b* V
  34. #define min(a, b)  (((a) < (b)) ? (a) : (b))* X, F2 z/ a+ d/ l% m" S1 b* m
  35. + k4 z: ~8 _, X9 ?$ T
  36. /* Type definitions ----------------------------------------------------------*/
    & r2 }8 O* Z1 n  S- ~( U; B- g
  37. /* Variable declarations -----------------------------------------------------*/
    0 Q$ {8 Q9 I5 J, n5 a- h1 K$ `
  38. /* Variable definitions ------------------------------------------------------*/
    # K6 S( p3 _  [: ^
  39. /* Function declarations -----------------------------------------------------*/) s7 P6 [) u! l4 W7 G9 }; e- H& M. n
  40. static bool is_power_of_2(uint32_t x);: v4 R- j5 @; Z- w! O1 d2 u
  41. static uint32_t roundup_pow_of_two(uint32_t x);
    ( l. t6 N7 r7 G: n
  42. 4 B0 y; ?8 C' M4 U/ v
  43. /* Function definitions ------------------------------------------------------*/3 f" W9 Y) ?$ P" [3 h

  44. - |4 T- _4 Q% l: s
  45. /**1 E. ?" a* k( y& `
  46.   * @brief  Allocates a new FIFO and its internal buffer.
    0 s, G8 r! u% U7 O
  47.   * @param  [in] size: The size of the internal buffer to be allocated.
    " ^$ r- r) w$ a
  48.   * @note   The size will be rounded-up to a power of 2.5 t. d% d, G3 m$ q/ j& n( B' D+ q
  49.   * @return RingBuffer pointer.* P+ N* i1 O# `
  50.   */
    * H5 r6 D3 i8 Z  D+ _2 S
  51. RingBuffer *RingBuffer_Malloc(uint32_t size)4 H, X$ b* R: t) L
  52. {
    # M! E3 U* m5 Z
  53.   RingBuffer *fifo = RING_BUFFER_MALLOC(sizeof(RingBuffer));
    ' |& L# \; X) ]( [
  54. 0 {9 V& m4 L' f4 d' P
  55.   if(fifo != NULL)
    9 O# C) \& \2 a! F/ q+ D
  56.   {# a- t% v, k2 M. ?% h1 `( c4 q. N
  57.     if(is_power_of_2(size) != true)
    " C" ]% P/ F6 y% S* n8 V
  58.     {4 ^2 P3 \7 w5 b8 J# m& k9 |
  59.       if(size > 0x80000000UL)
    " D3 K" n2 l. g0 i' T/ l* _( y! ^1 w
  60.       {
    & Q% L. D4 L1 y; Q* q
  61.         RING_BUFFER_FREE(fifo);- J. C; o: K# |4 E
  62.         return NULL;
    1 d! n6 o3 W) J5 A* r% e
  63.       }
    * {7 C8 H4 i6 \2 b+ y
  64. 8 p% _  P* S, ~; }3 p+ ]
  65.       size = roundup_pow_of_two(size);9 e: \' c" G) U4 t- G/ N! [
  66.     }/ _/ K/ e4 o& a$ ^
  67. ! `. y- w( w- R4 A
  68.     fifo->buffer = RING_BUFFER_MALLOC(size);! f# z4 S' T0 \2 u$ m1 e# `

  69. 7 ?" q( v& I9 `- c
  70.     if(fifo->buffer == NULL)
    ) g& A2 G5 K) T2 P4 o& G9 {* k3 O
  71.     {) `: j6 T9 ]$ z" v6 L
  72.       RING_BUFFER_FREE(fifo);
    & R/ v5 K9 ]0 J
  73.       return NULL;
    0 w- p0 ]( v3 F
  74.     }  W6 r; P0 u/ X  I& ?& v
  75. ( Z1 l- E5 l" m& S& Y
  76.     fifo->size = size;7 Y1 m  n8 \+ `8 l4 n
  77.     fifo->in = fifo->out = 0;
      Z- M! C& m% i8 ^" ?& P# @, ]
  78.   }) `0 }' M' g% R8 r: R9 x+ r

  79. ! m# d4 w, e; T& g3 q. j, v
  80.   return fifo;
    . \5 L' w, F% e! d5 x
  81. }
    + e6 c0 U4 J3 x* S! S
  82. 3 k2 {% i$ K$ \' R9 d, D( j/ z4 l
  83. /**" C% V  T1 X+ k
  84.   * @brief  Frees the FIFO.& B; t( U  u3 M
  85.   * @param  [in] fifo: The fifo to be freed.% _3 I( w5 \! D6 M
  86.   * @return None.! m% ~5 Y2 v+ y3 p* @% ?
  87.   */
    6 Q# }2 ~5 l, Y* a/ p4 M* F
  88. void RingBuffer_Free(RingBuffer *fifo), F. s3 @" s8 X
  89. {
    % S5 v0 D/ M$ }0 J! i6 M7 [' n4 h7 h
  90.   RING_BUFFER_FREE(fifo->buffer);) `# |0 O& x$ H# ^8 K. W
  91.   RING_BUFFER_FREE(fifo);/ }& ]3 @( `. W0 v9 d
  92. }
      k: a+ U/ L& z% E! ^4 y- \( l
  93. ! ~2 Q' r. |( C( ~/ D8 ]
  94. /**$ I7 c4 W) {3 |$ o: c) e% x2 K/ T
  95.   * @brief  Puts some data into the FIFO.
    : @+ |+ o2 D" S5 h2 f
  96.   * @param  [in] fifo: The fifo to be used.
    , f+ i, G; G- D4 ~
  97.   * @param  [in] in:   The data to be added.7 I1 K$ O$ N4 Z0 n. J8 r$ q8 G
  98.   * @param  [in] len:  The length of the data to be added.
    # y0 a5 M( l4 d3 ?7 f+ N4 A
  99.   * @return The number of bytes copied.
    & h; J( e' C& ], e' f- ^
  100.   * @note   This function copies at most @len bytes from the @in into- U9 E5 z% Z/ N; l. I0 m1 T  D
  101.   *         the FIFO depending on the free space, and returns the number
    8 e/ k/ ^% C( x" m2 o. G& E4 S) N
  102.   *         of bytes copied.4 W; H9 e! c, l6 ~# e" ?5 D) }
  103.   */7 A6 a. N5 W: G' I- m5 k# W
  104. uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len)
    2 o1 h% o& }! z# r) ~) K
  105. {# x0 N8 D6 i3 d. D& p9 h2 \+ O
  106.   len = min(len, RingBuffer_Avail(fifo));! [& o+ o+ Y0 l9 ?
  107. 0 `: @# X9 D1 r9 j" }+ @
  108.   /* First put the data starting from fifo->in to buffer end. */, i  t, T7 s( y3 t0 T
  109.   uint32_t l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));# j7 J5 l9 _/ v& a$ _7 Z8 T
  110.   memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), in, l);
    3 Q8 y; e. O" X8 W

  111. 6 D$ B  @7 U0 S% n$ l
  112.   /* Then put the rest (if any) at the beginning of the buffer. *// n% ~: u/ a: g, \; o3 T
  113.   memcpy(fifo->buffer, (uint8_t *)in + l, len - l);$ K: x( N0 q9 U' T5 E1 }9 \9 p. L8 e: q

  114. . \+ |  T! \5 }8 |* ~; {
  115.   fifo->in += len;2 q0 C8 _* b4 H, Q

  116. 3 t7 @: ^  P! F* `
  117.   return len;( U% x0 \# D6 k/ {0 u! v
  118. }) V( }- I* B6 j2 Z0 P

  119. - H3 z8 r8 y' |  Y3 I" g  X
  120. /**" {: k3 u% O- `; w% I* Z
  121.   * @brief  Gets some data from the FIFO.3 i( e8 e/ w5 C, \1 T
  122.   * @param  [in] fifo: The fifo to be used., d4 k6 E" `( B) O: Y) `
  123.   * @param  [in] out:  Where the data must be copied.
    1 k& r" a& G4 w1 [* c
  124.   * @param  [in] len:  The size of the destination buffer.) ^; D9 }8 h5 g5 h% [
  125.   * @return The number of copied bytes.( Q- i  j2 w/ P  g& N( u
  126.   * @note   This function copies at most @len bytes from the FIFO into/ S, l4 {/ a) A5 d3 ?( K1 x
  127.   *         the @out and returns the number of copied bytes.
    1 ~7 J7 t1 z- m3 R8 G
  128.   */
    1 G$ i* A9 s& j0 Y6 ], a
  129. uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len)
    ; L. q% z! t0 [4 W
  130. {$ A/ w0 R' I0 K6 W2 Y& _. m" m3 M' \
  131.   len = min(len, RingBuffer_Len(fifo));
    7 @1 u1 \" c& S2 j* d" c2 n
  132. / L. y- D+ s1 w% r
  133.   /* First get the data from fifo->out until the end of the buffer. */
    : t# Z. H: w" J- D2 n% B; G
  134.   uint32_t l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));% x: Y% a- q# R. k6 j# Q" K
  135.   memcpy(out, fifo->buffer + (fifo->out & (fifo->size - 1)), l);
    , i/ Y) F' e8 u5 f

  136. # s" ]# v3 T: U5 j
  137.   /* Then get the rest (if any) from the beginning of the buffer. */
      S! p& t- w# R5 o8 R
  138.   memcpy((uint8_t *)out + l, fifo->buffer, len - l);$ y& e% i- M4 j1 o1 a! q7 l

  139. # e" E/ ^  X, s5 L; J( A7 _
  140.   fifo->out += len;
    ! w7 v# [$ C" p6 y$ ]/ Z, ^$ B
  141. % P# A' P; Z+ i: e# Q
  142.   return len;
    0 `& Q' K* N) V( S% F$ x9 {8 C
  143. }
    # e+ V8 d3 j6 {3 x- H  m. B

  144. ! p8 m7 ?( n) S5 e" ~5 G
  145. /**, C9 L% D% y  `- }2 I
  146.   * @brief  Determine whether some value is a power of two.
    & O4 `. M0 Z: T5 d+ J6 R# ]" B: Z
  147.   * @param  [in] x: The number to be confirmed.
    * t* ~! O6 n4 k4 f  D: V5 A
  148.   * @retval true:   Yes.: x- L: ~  Z7 x
  149.   * @retval false:  No.
    8 K6 I2 l6 k! {" d, E: s
  150.   * @note   Where zero is not considered a power of two.
    , c: [0 `+ I2 I9 a& T3 ?1 H
  151.   */
    ) d% B  u9 C9 u( X  o+ ]  \2 e3 v
  152. static bool is_power_of_2(uint32_t x); B* ], _# C7 H
  153. {- ?, G2 e( m* r2 U
  154.   return (x != 0) && ((x & (x - 1)) == 0);
    7 \# Y; I6 L9 @9 H1 R+ m
  155. }4 L4 M" Y: c4 c; a
  156. 2 n% L5 _: N. Q9 K
  157. /**
    " X+ E9 Y: A& }3 A$ Z- x+ y" I
  158.   * @brief  Round the given value up to nearest power of two., S) e- {3 h% F" H6 L( E
  159.   * @param  [in] x: The number to be converted.  R" R5 m* M  Q
  160.   * @return The power of two.$ k! S# r; k- l0 f& q  [/ l
  161.   */
    # u; `1 {9 g% |8 F' I
  162. static uint32_t roundup_pow_of_two(uint32_t x)
    , T- {" T# V6 L) s; F5 \
  163. {2 q, U1 o0 J, Z, B
  164.   uint32_t b = 0;
    / u5 J0 f# V1 H# W
  165. 7 a) ^. W& R5 f$ m  O6 D. |
  166.   for(int i = 0; i < 32; i++)3 N+ e# Y' B" [3 e# G/ I
  167.   {6 \( l6 x3 c! M+ y  s
  168.     b = 1UL << i;
    4 B; [# {8 t1 k4 e" y( c

  169. 1 o) N# C2 b: Y8 b( v, \
  170.     if(x <= b)
    0 I2 t$ P+ B1 \7 N  X
  171.     {  I3 y/ k0 \: C. M- V# y/ K6 S
  172.       break;- r, e) ?( |& K* I$ D  h& [& h
  173.     }
    4 r4 Z/ c3 a  ~+ O; K
  174.   }5 _8 e& N1 e0 f5 |6 A
  175. 3 o1 B0 N& B" E* b4 T
  176.   return b;4 }5 s6 d8 m) a+ T3 c( Q. K
  177. }</div><div></div>
复制代码

) j3 d9 V+ z, w1 _0 s4 w4 e$ A& g- F+ a0 E) l
CAN.h 文件
+ x; v) {- D3 r. `
  1. /**" p) Z0 d' K- \# n) L  {. Z0 e
  2.   ******************************************************************************! [( \( B$ a( d4 t4 n$ }
  3.   * @file    CAN.h$ X* N6 h$ V; S" I% X
  4.   * @author  XinLi1 d, F# a2 H( ~, I( {: C6 F0 O( a
  5.   * @version v1.0
    " V4 V' b$ h# E; p% l5 a8 i
  6.   * @date    24-June-2018
    8 ^& }/ l# ~4 _, T, q
  7.   * @brief   Header file for CAN.c module.% g- }. U$ ?& m: _1 j, n* z" g
  8.   ******************************************************************************( V/ C% Q, ?) @
  9.   * @attention
    . z7 H0 }3 p7 @5 G+ v
  10.   *8 [) t8 G, h( y0 {3 \9 D, w" V; q$ A
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>& x5 @0 ^: }, V3 {9 d% n: Y; d
  12.   *: ^  k5 E$ J5 p% n, N) G
  13.   * This program is free software: you can redistribute it and/or modify; `3 R5 t: A5 A* U/ k# U3 L4 R* U+ H
  14.   * it under the terms of the GNU General Public License as published by
    " s0 B; l+ H: g8 U! V
  15.   * the Free Software Foundation, either version 3 of the License, or
    : n0 g* f# q9 F* P
  16.   * (at your option) any later version.
    1 h2 w+ F/ M  [2 ?( e" |
  17.   *$ c2 z1 X$ Y# C. M0 P
  18.   * This program is distributed in the hope that it will be useful,; `$ @1 _4 v, F' C$ b2 L
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of8 @' S' w* F# I/ `
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the; V% k& A0 {- s% e5 s& K
  21.   * GNU General Public License for more details.
      G8 \; w2 M. H) D* ]
  22.   *
    2 _/ V+ N* q  p, m
  23.   * You should have received a copy of the GNU General Public License
    0 `: s, V7 k# e) ?3 L& j. I" P
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    $ K* K  g1 L. n% ?
  25.   *6 F" Y5 g" C8 B! X. h  {
  26.   ******************************************************************************
    & n; b- h% S7 [. Q
  27.   */
    1 c9 Q! X8 R; u" O4 h; l4 g
  28. * r3 H; O2 O- V( z
  29. #ifndef __CAN_H) ?& c, a$ n2 x; c6 O
  30. #define __CAN_H
    7 D. p4 [; I1 Y# M* C+ {# R

  31. + b$ e/ A2 `) x& Z! S
  32. #ifdef __cplusplus; Q" z9 a: ]! c  ?( X- O
  33. extern "C" {
    - _1 U9 D5 j: W+ U
  34. #endif
    , P. t" @5 [* N8 j" r, w  V
  35. / [" a( A$ a# f: O! R2 c
  36. /* Header includes -----------------------------------------------------------*/2 {- d" C4 C' @9 P4 y
  37. #include "stm32f10x.h"$ g# b! h5 t0 A! d! T; w2 u
  38. #include <stdbool.h>9 n  T0 G* O. u* w+ L
  39. : \% D5 s4 R6 C* w+ A4 l: R  Q) I$ c4 O
  40. /* Macro definitions ---------------------------------------------------------*/
    ) Y8 f  |5 ^( }& Q% ?! g
  41. $ O) X, C# r1 y9 d3 l: b7 L, Z0 L
  42. /******************************* CAN1 Configure *******************************/
    + H, o& b! R1 u5 }1 y
  43. #define CAN1_TX_BUFFER_SIZE        (16)( `2 w5 R7 W: h3 A- C8 B4 d) l
  44. #define CAN1_RX_BUFFER_SIZE        (16)) ?# q# Z1 ?! ]* X# W
  45. # }% U: d: I" \
  46. #define CAN1_TX_GPIO_CLOCK         RCC_APB2Periph_GPIOB$ @3 j+ ]+ E* Y8 s4 s
  47. #define CAN1_RX_GPIO_CLOCK         RCC_APB2Periph_GPIOB( k1 a1 ~! _* D
  48. % ^' K3 S9 T) ?/ W/ a6 n2 v
  49. #define CAN1_TX_GPIO_PORT          GPIOB
    - c3 Z8 E+ _, {% |; H6 i+ M
  50. #define CAN1_RX_GPIO_PORT          GPIOB
    5 h! t4 r. ~" l6 m
  51.   X$ _/ R2 B0 N* H
  52. #define CAN1_TX_GPIO_PIN           GPIO_Pin_96 Z# L# |4 I7 h$ S/ h
  53. #define CAN1_RX_GPIO_PIN           GPIO_Pin_8; D+ ?, \! U+ b- h. I. x
  54. ( k5 G% O( w- K
  55. #define CAN1_IRQ_PREEMPT_PRIORITY  (0)
    , z5 S5 y( S7 Q9 I" P4 I
  56. #define CAN1_IRQ_SUB_PRIORITY      (0)
    ; m# T  K2 M" i' T+ c6 y

  57. 9 {& q' B6 E0 v* n* H9 I
  58. #define CAN1_PORT_REMAP()          GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE)+ d/ `0 g# H2 f5 Q
  59. /******************************************************************************/
    9 p# m. Z8 E* J- M" [1 W
  60. ; t. G  Q/ j, C% O' G0 A/ W
  61. #ifdef STM32F10X_CL, h  r' k3 Q, g& Q
  62. /******************************* CAN2 Configure *******************************/" x4 Z( H1 {9 h$ @& `+ n# w
  63. #define CAN2_TX_BUFFER_SIZE        (16)+ b, {: `: h% Q( O
  64. #define CAN2_RX_BUFFER_SIZE        (16)! d7 w! p3 P& Q: G% I& p$ I

  65. # X7 @7 N) O4 |/ w" ^! p
  66. #define CAN2_TX_GPIO_CLOCK         RCC_APB2Periph_GPIOB. _: `# t$ d" z" [. ?
  67. #define CAN2_RX_GPIO_CLOCK         RCC_APB2Periph_GPIOB
    ( b- o* O9 C6 c: q6 ?/ w  g

  68. . }2 G. J4 ~3 P2 W7 p) C
  69. #define CAN2_TX_GPIO_PORT          GPIOB$ k9 j+ v% q( M2 t0 V5 S/ R
  70. #define CAN2_RX_GPIO_PORT          GPIOB
    7 f* x) c7 A9 C( e( t
  71.   q; i1 l) F1 R7 G
  72. #define CAN2_TX_GPIO_PIN           GPIO_Pin_135 ^9 m4 |4 d% R7 X
  73. #define CAN2_RX_GPIO_PIN           GPIO_Pin_12
    ) {! [+ q; c& f+ }' ?

  74. , g  G7 r( n0 ~- T2 G% ]  ?
  75. #define CAN2_IRQ_PREEMPT_PRIORITY  (0); T) l# P+ E5 J  {" {
  76. #define CAN2_IRQ_SUB_PRIORITY      (0)/ o5 W6 f& D, t: N8 ~4 {. P

  77. 3 V" d1 n9 _3 L9 i% N# o
  78. #define CAN2_PORT_REMAP()          GPIO_PinRemapConfig(GPIO_Remap_CAN2 , DISABLE). f/ o" H' h- ^' L
  79. /******************************************************************************/* n' G, o, e" T; v" V6 X
  80. #endif /* STM32F10X_CL */0 a3 z/ f1 z: k3 V8 l/ u

  81. 5 U7 E1 B. @/ |% l3 C( r6 a/ E/ K
  82. /* Type definitions ----------------------------------------------------------*/7 a4 M8 [3 c8 V% f
  83. typedef enum
    ; p# q7 W6 o+ V. @- |
  84. {
    & A& f, p" {1 `, d1 B
  85.   CAN_WorkModeNormal   = CAN_Mode_Normal,2 T4 |3 w9 @+ S5 b* _
  86.   CAN_WorkModeLoopBack = CAN_Mode_LoopBack
    8 p# O8 c& H; q$ e) B: r8 ~
  87. }CAN_WorkMode;6 T2 v) R/ R% r3 V0 W$ t& ?
  88. * A5 Z. a* |. T5 {5 W6 y; H
  89. typedef enum
    , V8 T+ u3 ]5 J* d$ w
  90. {" }+ J; j6 P9 j5 s' {% V& M
  91.   CAN_BaudRate1000K = 6,/ ^2 t/ P3 t7 K+ J, I3 O
  92.   CAN_BaudRate500K  = 12,' ]+ E# g+ M! E+ u  v) R1 x  X
  93.   CAN_BaudRate250K  = 24,. n2 m1 ^( l5 C' l3 ?! @
  94.   CAN_BaudRate125K  = 48,) {+ G- `1 n) x* {
  95.   CAN_BaudRate100K  = 60,
    6 a8 i2 d, ?1 r4 N% @0 {
  96.   CAN_BaudRate50K   = 120,+ |6 U  t& R4 ]# q, M/ l, L
  97.   CAN_BaudRate20K   = 300,
    ; S6 q( D7 d& ?9 w7 u5 p
  98.   CAN_BaudRate10K   = 6003 E# z* T8 n9 M6 v- N( p; d
  99. }CAN_BaudRate;
    . c3 }0 B! ~4 I$ G& N- u. R
  100. ; [. `$ v! {2 U; |6 w+ O2 M
  101. /* Variable declarations -----------------------------------------------------*/
    / K7 H. ~  N% `3 ~0 n, u
  102. /* Variable definitions ------------------------------------------------------*/" |, B7 o+ ~8 B* R% C4 W; d! x
  103. /* Function declarations -----------------------------------------------------*/
    + t, C, z: J, {1 \4 }
  104. void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId);2 _4 n. A  c" q2 S8 }" }
  105. void CAN_Unconfigure(CAN_TypeDef *CANx);
    # f. d5 j+ U8 @) l$ |% j7 d

  106.   i. {/ L( A; j# F  c! K
  107. void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));* n9 W4 ~, a3 j  c# H% C/ e
  108. void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));; n. J# e& l6 `  E- y( o* |' @

  109. 8 n( I  {. X% j: c& t
  110. uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number);
    6 s+ a3 v5 b. O0 x
  111. uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number);
    $ N( B- T% B8 ^; k9 s1 t

  112. 8 t; w' ~( _; V) C
  113. uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx);
    ' O6 b: K, X. k8 [! r, \" A
  114. uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx);, ]% D1 U+ @+ t
  115. uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx);
    4 R- }! q! F. y3 t0 e# d
  116. uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx);
    1 L' i: F, u0 ^

  117. 7 {0 I5 L  W8 @, p  {. W/ g  N
  118. bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx);7 q, n; _1 u$ C6 F5 a3 g
  119. bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx);
    ; \# Q4 z/ i8 o3 L& ?
  120. bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx);
    ; a5 _. S  L/ J/ A
  121. bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx);
    # Q7 L. D7 _( j

  122. " C1 W6 Y: m8 Q3 A
  123. void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx);
    ' _: X. ^; ]  M/ }3 ?
  124. void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx);1 c" C% ~2 ]! X, B

  125. 1 k* _, [! E4 j6 X/ K( F7 N
  126. bool CAN_IsTransmitMessage(CAN_TypeDef *CANx);
    : ~- e0 r5 O4 Q4 C8 f! @
  127. ( i  d) `( L" S
  128. /* Function definitions ------------------------------------------------------*/" Z6 u% e; U9 x* m, R$ f. \: W/ ~" z
  129. ; G# r3 m0 S$ x9 W% A
  130. #ifdef __cplusplus
    ; [" u( _; r  @+ l
  131. }, P4 K9 }7 U# O1 m/ B8 S$ |
  132. #endif/ C' t. `0 e- a- J

  133. # ]9 H- D6 }7 r. O! M
  134. #endif /* __CAN_H */( ~: G$ a* k' Q, q  S5 d
复制代码

, \. C6 G/ w9 a3 y: [
2 ?+ b$ m' G! Y$ E, N' G7 C1 m
# F: C+ |* q6 y, `; K: T* B' qCAN.c 文件
  Z# c8 o/ ]2 K
5 g( M- p( b$ K; D
  1. /**- a2 m" a1 Q2 R( t+ u
  2.   ******************************************************************************
    * Y" |1 h$ [8 b; ]# t/ z4 Z% _
  3.   * @file    CAN.c* C0 X* A6 Z5 a- P( _8 q  K+ I
  4.   * @author  XinLi; }. @, n6 y6 D/ A3 M0 k+ F1 y
  5.   * @version v1.0
    & i" I: m. A( b/ o6 Y9 v1 H
  6.   * @date    24-June-20183 R! ?: k0 I# T" `
  7.   * @brief   CAN module driver., O$ ]1 }- e- t
  8.   ******************************************************************************( n' g& z; o* t1 s% H3 Y, o
  9.   * @attention
    6 B! J. n" M$ O- l2 @
  10.   *
    ' C5 w2 z3 {: E" J- Z
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    4 R0 r& x% T7 x' w
  12.   *
    ! d" j+ k+ b' M7 k' ~6 v
  13.   * This program is free software: you can redistribute it and/or modify( M, s7 d5 I; Y4 L& N) T
  14.   * it under the terms of the GNU General Public License as published by, l+ D$ u6 ^) V! s1 k8 l
  15.   * the Free Software Foundation, either version 3 of the License, or3 `" Y4 @  T: F! E* S
  16.   * (at your option) any later version.
    3 E, p% {! p2 p+ o4 ?
  17.   *7 F% o/ \9 c. h9 n* w
  18.   * This program is distributed in the hope that it will be useful,
    * S0 V0 T# z( a+ g/ U3 p4 K3 s
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    ! _% a7 q7 R: L
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the/ m4 {$ v' W- R; i4 j
  21.   * GNU General Public License for more details.
    / P& D8 g, y) |6 H% K* s" h+ p9 C
  22.   *  F! i1 L5 @& {
  23.   * You should have received a copy of the GNU General Public License
    ( T& y# b0 ?$ j& k0 {2 M% l
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    ' j- h$ Z" }3 b
  25.   *
    # A! p5 Z- X- G4 u" L. V
  26.   ******************************************************************************
    ) O* W. M# M7 ]
  27.   */
    : ^/ \9 k1 f6 z3 \$ U  b' l5 p. v

  28. / S7 R2 D! K& m+ x& y: G
  29. /* Header includes -----------------------------------------------------------*/
    - y4 c" k0 o+ G, @
  30. #include "CAN.h"2 e4 r1 N  V4 t& y8 w
  31. #include "RingBuffer.h"
    ' k9 q  q( x% s3 V4 M5 S1 O: N
  32. & F9 {7 j7 ]- ?
  33. /* Macro definitions ---------------------------------------------------------*/
    9 G7 j' S# Q3 c) L$ ]" N! O
  34. /* Type definitions ----------------------------------------------------------*/6 G" G# r. I2 Y+ e3 ~9 F
  35. /* Variable declarations -----------------------------------------------------*/
    1 e, a1 [5 V- H
  36. static volatile bool can1InitFlag     = false;
    + P* r, ~2 x) D5 l1 z9 K
  37. static volatile bool can1TransmitFlag = false;
    ' A6 @; Y/ F- u0 w& p9 U3 f
  38. " o$ D$ T! A/ S6 F6 ~; |9 O# ~) n
  39. static volatile void (*can1TransmitFinishCallback)(void) = 0;
    ( ]7 R( `5 l0 v4 F1 |
  40. static volatile void (*can1ReceiveFinishCallback)(void)  = 0;6 {2 j& ~& D$ Y  [; w
  41. . w+ a6 C: ~) X/ A. L! L
  42. static RingBuffer *can1TxBuffer = 0;
    6 Q, E4 ^' l5 ?$ E2 ^* ]0 Q3 ^, p
  43. static RingBuffer *can1RxBuffer = 0;+ |& {9 a+ c, l

  44. . I3 _9 Z7 Q3 J
  45. #ifdef STM32F10X_CL
    * f7 w* E0 j0 w0 w; Z/ N% y& T
  46. static volatile bool can2InitFlag     = false;! n3 X9 \& l. }2 B9 o  W+ o
  47. static volatile bool can2TransmitFlag = false;6 U( Z& ^) g9 C) B, j* ~  k' O7 u
  48. : O- `0 O! x/ p& {' w. A; f
  49. static volatile void (*can2TransmitFinishCallback)(void) = 0;
    6 n2 m* |2 N  R4 e& h0 c
  50. static volatile void (*can2ReceiveFinishCallback)(void)  = 0;8 t0 r* M6 I' j' E) Q% X; T
  51. : |9 @+ ^) O2 w' t  V( l7 P
  52. static RingBuffer *can2TxBuffer = 0;
    $ P* g+ t2 S, L9 f, H
  53. static RingBuffer *can2RxBuffer = 0;
    ( H8 z9 E7 }1 ?+ A! i
  54. #endif /* STM32F10X_CL */
    4 P  J1 W5 |! n
  55. 3 c$ a' D& ^5 e7 [# R+ m, r5 n
  56. /* Variable definitions ------------------------------------------------------*/4 ~1 Z9 h% |/ O
  57. /* Function declarations -----------------------------------------------------*/! \% l+ I+ ^2 [% b; }
  58. /* Function definitions ------------------------------------------------------*/! h! H/ X  V5 h% b% |5 h: \3 ?

  59. * `0 x* e5 p6 e; a
  60. /**
    ! H: ?! V) r# e/ m% f; @6 j& _+ C/ Q
  61.   * @brief  CAN configure.1 Y* J- k, E" ]' D& E
  62.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral./ T6 w  T5 S, O5 F
  63.   * @param  [in] WorkMode: Work mode.
    # f. v$ ~2 d% f+ f6 a4 z
  64.   * @param  [in] BaudRate: Communication baud rate.2 Y! }8 I+ {; b& e/ \. ~
  65.   * @param  [in] StdId:    Filter standard frame ID.  Z- }' w. ]% p3 n! K+ B. a7 h
  66.   * @param  [in] ExtId:    Filter extended frame ID.1 L$ l/ }7 v5 A# a; q+ s. e
  67.   * @return None.
    $ p+ k" H+ I6 U
  68.   */
    2 s1 g& e9 y2 N0 F
  69. void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId)7 O5 w* {/ a$ @+ k3 I4 B( W
  70. {
    9 F: D, P0 C. m5 z
  71.   GPIO_InitTypeDef      GPIO_InitStructure      = {0};. d1 }6 V5 P3 K* o7 X4 k
  72.   CAN_InitTypeDef       CAN_InitStructure       = {0};  h* l1 c& j7 g) H& f
  73.   CAN_FilterInitTypeDef CAN_FilterInitStructure = {0};
    $ X) T& X- W, r! H7 h% @
  74.   NVIC_InitTypeDef      NVIC_InitStructure      = {0};9 K' ~5 x' n9 J5 X$ {
  75. * P3 _, [, a8 {
  76.   if(CANx == CAN1)
    " @  q$ c  c! \0 t+ s) F. h. X) {' s! Z
  77.   {* D$ A; r0 l" V/ e7 f' J
  78.     if(can1InitFlag == false). a% Y; I+ Y6 L
  79.     {
    8 B% ^8 i+ w' A
  80.       can1InitFlag = true;5 W- w- j! B" r6 p5 L( x# }/ R

  81. - G: }, I( P/ t
  82.       can1TransmitFlag = false;
    " k( ~* S/ T$ p, M! y
  83. % J/ Y6 H$ Y' P2 ~7 a0 H
  84.       can1TransmitFinishCallback = 0;
    8 G; ~2 Y% k* D' F6 d
  85.       can1ReceiveFinishCallback  = 0;
    ( K% [  u2 k: P1 i" w8 S1 x
  86. # r1 Z. c9 v( ]1 ^8 L6 V' F5 a, n5 A
  87.       can1TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN1_TX_BUFFER_SIZE);0 J# g9 @* w2 `/ E) E6 L* S
  88.       can1RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN1_RX_BUFFER_SIZE);* k$ M8 `( ~; Z# C
  89. 2 ^% L' W- Y, q
  90. #ifdef STM32F10X_CL
    . Z* v( u/ s- c, H
  91.       if(can2InitFlag == false): M! h4 t) E0 N* c! b3 E4 L. m
  92. #endif /* STM32F10X_CL */- f* b' M& ~0 x% j# B0 b  w
  93.       {- M# f0 I- Z- i( \) e, s
  94.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
    - V# L; C+ t3 j( G
  95.       }
    * M- H  j8 \+ C7 U& ]

  96. ) `1 @; Y6 ~5 C& C1 L, U7 u6 O
  97.       RCC_APB2PeriphClockCmd(CAN1_TX_GPIO_CLOCK | CAN1_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);
      T7 F5 Q3 [0 |) ?
  98. 7 U9 k+ }% z/ d0 Q  K' @
  99.       GPIO_InitStructure.GPIO_Pin   = CAN1_TX_GPIO_PIN;
    : k1 B- x: A/ W+ j
  100.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;7 C0 e2 y: C: C1 N$ D
  101.       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;$ A  c3 A9 Y$ w" v+ N) n
  102.       GPIO_Init(CAN1_TX_GPIO_PORT, &GPIO_InitStructure);2 H  J5 J1 c- b- @
  103. 3 q& w' M, \! |% h8 g( ]" p4 T+ F5 z
  104.       GPIO_InitStructure.GPIO_Pin   = CAN1_RX_GPIO_PIN;. j" ]" b+ |' e6 A
  105.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;/ f2 B) r5 x' S1 V! A. P; u
  106.       GPIO_Init(CAN1_RX_GPIO_PORT, &GPIO_InitStructure);, ^4 U  G; N1 z; `) |8 S) X

  107. ( W+ N" l* _; [) V0 e5 z' \/ [
  108.       CAN1_PORT_REMAP();
    " T) W% [) ]- x. l6 w

  109. 0 c/ q7 y( e1 R' v0 I1 C$ q
  110.       CAN_InitStructure.CAN_Prescaler = BaudRate;8 t5 D8 @' m1 u) u/ l- q
  111.       CAN_InitStructure.CAN_Mode      = WorkMode;/ V3 {  E0 g2 y" g8 I" _, T
  112.       CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;
    # y3 Q: I# u% C# D
  113.       CAN_InitStructure.CAN_BS1       = CAN_BS1_3tq;2 g" R7 G" H& {- y
  114.       CAN_InitStructure.CAN_BS2       = CAN_BS2_2tq;0 U' q5 a% n+ ^
  115.       CAN_InitStructure.CAN_TTCM      = DISABLE;
    ! W* H( l* Q+ T% `* j/ r/ f
  116.       CAN_InitStructure.CAN_ABOM      = ENABLE;
    ) ]+ ~, @( ~+ ^3 Y
  117.       CAN_InitStructure.CAN_AWUM      = DISABLE;$ q# _% @6 T0 D
  118.       CAN_InitStructure.CAN_NART      = ENABLE;
    ! f" e5 Y: I  s# f+ y
  119.       CAN_InitStructure.CAN_RFLM      = DISABLE;
    % s* D: G5 A5 p. h$ K* d
  120.       CAN_InitStructure.CAN_TXFP      = ENABLE;2 H) U) j* F7 X7 n' O0 p  X6 S

  121. & q0 n+ O/ [; U9 _- P1 z
  122.       CAN_DeInit(CAN1);
    * F4 F+ F- x8 |
  123.       CAN_Init(CAN1, &CAN_InitStructure);3 U/ b& p& t: g# g6 {& z; I7 [8 n! V
  124.   w3 |3 d0 N& |- j5 ^0 Y* a
  125.       CAN_FilterInitStructure.CAN_FilterIdHigh         = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);
    2 f" B' I4 S; U# `2 K! j8 T5 `
  126.       CAN_FilterInitStructure.CAN_FilterIdLow          = (uint16_t)(((StdId<<18)|ExtId)<<3);# H/ C# y- o/ P! g, M' }5 b
  127.       CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;$ m0 E( |' A2 i/ O1 z( z6 j
  128.       CAN_FilterInitStructure.CAN_FilterMaskIdLow      = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;0 M+ O2 D* ]" v/ b% P
  129.       CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
    - P8 G' D3 M/ ?" O
  130.       CAN_FilterInitStructure.CAN_FilterNumber         = 0;& n! U  D+ ]3 s4 ^
  131.       CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask;
    . S6 D2 ~# y# Z1 G* C0 c; I
  132.       CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit;
    5 Z" n& j/ {0 b, q7 B8 Y5 ~+ h  X& ^
  133.       CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;1 a& n9 s' j1 A8 f9 \1 W9 D
  134.       CAN_FilterInit(&CAN_FilterInitStructure);, e. H. i& w1 r5 {4 O$ ]4 Q8 o! U

  135. 3 [  E6 p% \( }; j% ?
  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 |+ s/ Q8 L- x2 x7 ]- o
  137.                          CAN_IT_WKU | CAN_IT_SLK  |CAN_IT_EWG | CAN_IT_EPV  | CAN_IT_BOF  | CAN_IT_LEC | CAN_IT_ERR, DISABLE);; f' G/ P( t+ A( r
  138.       CAN_ITConfig(CAN1, CAN_IT_TME | CAN_IT_FMP0, ENABLE);4 C& h8 @( b' O4 r9 g

  139. 4 k3 z% b- l( `( z# k. b5 E) o6 J" z3 |, G  O
  140. #ifdef STM32F10X_CL
    7 [% _* H3 Z8 o+ r8 }
  141.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_TX_IRQn;
    * e8 T: J5 z; T
  142. #else
    2 U3 n1 f% a; \# n* K
  143.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_HP_CAN1_TX_IRQn;
    " h% v7 X) o& [3 Y: V
  144. #endif /* STM32F10X_CL */$ W1 f2 R# N+ m

  145. 5 j+ F& j/ C1 m. ^' C$ J9 l
  146.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;
    % t- L" N7 f5 C  ~: e2 s
  147.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN1_IRQ_SUB_PRIORITY;
    / f  H& l* ^0 c0 C& n$ _
  148.       NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;( A3 T3 b. u$ l& c, e" j- o" J# U
  149.       NVIC_Init(&NVIC_InitStructure);
    * t' p# \) H0 @( e/ G; }* w/ Y
  150. ) \& T( r# {5 n/ Q# K6 T/ t; V3 O
  151. #ifdef STM32F10X_CL+ _1 b; Z. p% K3 m! P
  152.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_RX0_IRQn;
    + Z8 e' O& A; X
  153. #else
    ) ~5 k$ b( F; m, L5 l, r
  154.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_LP_CAN1_RX0_IRQn;
    4 Y) K- j: {6 L  h: G
  155. #endif /* STM32F10X_CL */, `2 K4 A; i0 X1 L

  156. $ v& c" _9 ?- n5 ]. p8 E1 N! K7 K6 ?
  157.       NVIC_Init(&NVIC_InitStructure);
    + c: ]4 a+ L! {  K: y
  158.     }
    : p) }; ^( M6 B) j  Q. T
  159.   }( [+ `3 Y2 V% V. J" n

  160. # e4 X- }$ ^& R0 Z
  161. #ifdef STM32F10X_CL
    0 a1 E# n! o  O
  162.   if(CANx == CAN2)/ d6 I% l: }2 w! G
  163.   {
    & h  G2 m' i/ |' B/ ^: i
  164.     if(can2InitFlag == false)
    $ v& c+ _/ m/ c# Q
  165.     {
    1 x  t) T* y* B: r1 Q  j) X; w5 @
  166.       can2InitFlag = true;/ }5 H2 y9 x, Z7 f( I
  167. # W0 t7 @- k4 I+ x) R. w$ @
  168.       can2TransmitFlag = false;
    ' Y+ }2 @% N( t# y. B. R9 P2 [

  169. / ^& N$ L, N' ]# Z( Q
  170.       can2TransmitFinishCallback = 0;7 |- A+ }( v. L7 `
  171.       can2ReceiveFinishCallback  = 0;
    , `  x5 X3 [$ g+ n% A) o8 i
  172. 1 L( t" p4 h6 D- ]# Z
  173.       can2TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN2_TX_BUFFER_SIZE);
    - n* n4 h9 D; e& |( w$ H+ }
  174.       can2RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN2_RX_BUFFER_SIZE);
    % Z5 s7 }" ~0 r' y( Q& [7 D
  175. 3 x2 x# f: H1 |% R+ R
  176.       if(can1InitFlag == false)# \' E. g0 p4 p/ o
  177.       {7 M9 p* G- ~+ H
  178.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);) N& M5 j5 u. W
  179.       }
    4 k8 @) @, {+ ~& |+ V. A; L: [
  180. & R- t8 e7 H- S! Y' l. M
  181.       RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);: R7 q1 ?: L+ q' I" e4 `6 p! F" \3 s
  182.       RCC_APB2PeriphClockCmd(CAN2_TX_GPIO_CLOCK | CAN2_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);
    1 X# H7 t0 ]% {0 _/ S# p' G+ E
  183. 7 P: ]( w9 z2 [& x7 U
  184.       GPIO_InitStructure.GPIO_Pin   = CAN2_TX_GPIO_PIN;8 ]- `+ H/ {9 Q) ?3 b4 u9 y
  185.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;4 o8 J# p" s- B7 s7 m0 V- |
  186.       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    / K- s3 L$ ^8 V& X  S
  187.       GPIO_Init(CAN2_TX_GPIO_PORT, &GPIO_InitStructure);( |. z% B; ~' P3 N2 }0 Y4 D
  188. % Z9 H) w/ D% o) u
  189.       GPIO_InitStructure.GPIO_Pin   = CAN2_RX_GPIO_PIN;  f; l7 p' B1 M$ h
  190.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;& P* e# V  B7 U" q
  191.       GPIO_Init(CAN2_RX_GPIO_PORT, &GPIO_InitStructure);
    ) a/ u" \. _! C

  192. 2 x) ~! x9 u: m/ S: v
  193.       CAN2_PORT_REMAP();
    * h* ^% S0 z, r; Q3 U6 y9 @0 \

  194. - e) N  E  ]0 r9 V- a
  195.       CAN_InitStructure.CAN_Prescaler = BaudRate;4 U5 P5 W# i( i1 ?2 J
  196.       CAN_InitStructure.CAN_Mode      = WorkMode;
    ' ~4 ^+ p% C; l  ]
  197.       CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;  L0 f( k1 R) |
  198.       CAN_InitStructure.CAN_BS1       = CAN_BS1_3tq;
    & I' [; a' \' _; S1 ?% o# g7 ~' F
  199.       CAN_InitStructure.CAN_BS2       = CAN_BS2_2tq;( u* D: j" @: ?- ~
  200.       CAN_InitStructure.CAN_TTCM      = DISABLE;, D* I9 c+ s7 [: [
  201.       CAN_InitStructure.CAN_ABOM      = ENABLE;' g! A1 _2 M5 i6 P
  202.       CAN_InitStructure.CAN_AWUM      = DISABLE;
    # w% ?' }0 `% ~" R& m
  203.       CAN_InitStructure.CAN_NART      = ENABLE;* Q$ ~. M4 b' h# @
  204.       CAN_InitStructure.CAN_RFLM      = DISABLE;6 y/ w' e4 ]8 ?& t: Y: z. q0 h" m0 V
  205.       CAN_InitStructure.CAN_TXFP      = ENABLE;6 f# _& h$ @5 }4 `9 U/ y! O7 A+ }
  206. 3 I* [# C" ^$ t; J6 L
  207.       CAN_DeInit(CAN2);5 F" e1 ^1 ?; u
  208.       CAN_Init(CAN2, &CAN_InitStructure);
    $ `) T* M/ }' E. [- j. D2 v( w2 M

  209. ) D+ g8 F, r" l: b& o: s9 {6 X
  210.       CAN_FilterInitStructure.CAN_FilterIdHigh         = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);
    ' `% p. u% B# O" z) W5 {- D
  211.       CAN_FilterInitStructure.CAN_FilterIdLow          = (uint16_t)(((StdId<<18)|ExtId)<<3);, {( j- ]# T+ I5 x
  212.       CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;1 {* H- t0 k! [0 D
  213.       CAN_FilterInitStructure.CAN_FilterMaskIdLow      = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;/ G. T" O& ^1 `4 w9 A* w
  214.       CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;) G+ E% d7 N  j" D
  215.       CAN_FilterInitStructure.CAN_FilterNumber         = 14;$ ~# z2 `3 _# _- ^& m1 p$ o2 s4 h" [
  216.       CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask;! B3 p. E0 l* q: Z3 o+ U
  217.       CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit;( R/ i4 O7 w3 W( C' g
  218.       CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;3 u: c. W8 P; s8 p
  219.       CAN_FilterInit(&CAN_FilterInitStructure);' ^% J4 v" m$ Z6 R
  220. ( U" t9 ~# q8 V3 W4 O5 f! c8 A
  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 |2 @! h: T. W, W# @$ I
  222.                          CAN_IT_WKU | CAN_IT_SLK  |CAN_IT_EWG | CAN_IT_EPV  | CAN_IT_BOF  | CAN_IT_LEC | CAN_IT_ERR, DISABLE);
    % x! @8 a9 T4 ~8 M
  223.       CAN_ITConfig(CAN2, CAN_IT_TME | CAN_IT_FMP0, ENABLE);
    5 @* }3 E. d4 @  }" N! j

  224. ! T, I( U& \3 _( f- F5 v
  225.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_TX_IRQn;3 e8 [, }) N7 Q% \  ]
  226.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;
    6 w& [, D) ?9 Q8 K
  227.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN2_IRQ_SUB_PRIORITY;
    & M1 L% T/ D7 t
  228.       NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    - P# r1 d" T( o( Y: q/ F9 C' I
  229.       NVIC_Init(&NVIC_InitStructure);
    ! a' S5 B' P$ X

  230. 2 I# V8 j$ X( V; i
  231.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_RX0_IRQn;
    & d' w0 i+ E' P+ M+ |' P
  232.       NVIC_Init(&NVIC_InitStructure);
    . S& C( _0 m4 I; d4 ~- ~3 n" a
  233.     }
    2 s. Q$ Q( o$ G! _$ j9 A5 r
  234.   }
    6 {4 h3 p- J1 u
  235. #endif /* STM32F10X_CL */9 `; Z$ |; h! G3 S6 A
  236. }: ^2 G& e/ \6 I7 a7 p- e

  237. ' Y5 h7 P9 V1 H  E
  238. /**
    8 @9 F/ e) R& [/ e( y1 u
  239.   * @brief  CAN unconfigure.
    ! X% [1 _2 Z- F0 b' H# C
  240.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    6 r) J1 F. g' ]. x' W, |3 @- k. A' s
  241.   * @return None.7 M' E# \( z! i+ l2 e" }3 G( X
  242.   */
    & M  X, Z1 e& T( k% ~
  243. void CAN_Unconfigure(CAN_TypeDef *CANx)
      d! S, q/ ?( C! V7 E
  244. {
    $ i3 @+ _* F3 y- Y' s
  245.   NVIC_InitTypeDef NVIC_InitStructure = {0};% Q& P4 W. `% H: y: Q2 E
  246. # L5 _( X0 e0 q) ?4 H# S, k
  247.   if(CANx == CAN1)
    0 o/ k4 y0 n; J- z& c4 o4 B; N
  248.   {: N2 {4 x& G% [  t& \+ C! f
  249.     if(can1InitFlag == true)
    7 O$ M2 S1 r. I, ~% D6 U* F
  250.     {
    " R& |- K1 S5 @; _8 ]
  251.       can1InitFlag = false;
    , h" ^- @* s% y
  252. 0 q1 w0 a" S# |
  253. #ifdef STM32F10X_CL; `9 l  [5 U1 `! N
  254.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_TX_IRQn;
    * L8 o7 v/ ]$ s1 W( i: J/ W
  255. #else, h  s* I' y9 }
  256.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_HP_CAN1_TX_IRQn;7 m- s9 W8 k. Z  o' E
  257. #endif /* STM32F10X_CL */; M5 C; L/ Z. N- \4 B. Z
  258. : A6 I1 ^/ ~8 w+ K( N
  259.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;
    * N7 _5 d9 \3 m/ ^5 W, H0 u
  260.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN1_IRQ_SUB_PRIORITY;
    & R$ K. {9 o% b+ u2 I: Q4 ]
  261.       NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;! r1 f/ G) Z0 A, @; C' Z2 t- x' k
  262.       NVIC_Init(&NVIC_InitStructure);
    & `; X4 Y1 Z, a* Y

  263. 8 f  Y, ?1 o  |) j9 r6 Z- Q
  264. #ifdef STM32F10X_CL
    + A5 x/ ]$ b! D) Y4 t8 E" P' g
  265.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_RX0_IRQn;  L4 I/ ^0 g7 f5 E* b. B
  266. #else
    7 g% u& E; h7 H  v% \
  267.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_LP_CAN1_RX0_IRQn;0 [( W  P2 j( R* Q
  268. #endif /* STM32F10X_CL */
    9 l8 c: h( w$ z- r0 K( r
  269. 0 e( u) o- K  I- J/ N
  270.       NVIC_Init(&NVIC_InitStructure);
    " J1 a! B1 _7 |3 N3 r! q
  271. ! ?1 g2 I/ ~5 E9 Y! }: }; X6 C- N. }
  272.       CAN_DeInit(CAN1);3 e) L5 M0 _. a! L9 a% V+ S4 L
  273. / n  W* \5 q! A
  274. #ifdef STM32F10X_CL
    6 ]6 D+ a7 ~: D$ w- r
  275.       if(can2InitFlag == false)( K) F5 S. m6 A) `; ~
  276. #endif /* STM32F10X_CL *// @9 ?/ m8 E# U4 H$ U/ `+ c& ]8 E6 A
  277.       {
    0 }9 e4 x8 A8 p4 H( q* @# p7 t
  278.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);2 d* K5 B: y) e% E, m) t0 N/ _- ~
  279.       }
    # [- ~* }- r6 [/ u! z5 o4 ]
  280. : [' J8 L& K! l6 }2 e# ?1 W/ W" A
  281.       can1TransmitFlag = false;
    ( i9 ~7 U; J1 H5 \* r: g* I
  282. / R" [9 Y4 ~* P
  283.       can1TransmitFinishCallback = 0;- B% E) j# X) i8 }8 Q# Z+ I
  284.       can1ReceiveFinishCallback  = 0;
    5 p; b+ ^( ?& N5 }0 i
  285. 9 s1 O. Y, g& a
  286.       RingBuffer_Free(can1TxBuffer);: C! f% C! |0 a: R! @6 I7 t
  287.       RingBuffer_Free(can1RxBuffer);
    " j* f/ _1 k9 r
  288.     }$ c+ b: w* o7 N! l" e( J! u7 J
  289.   }" O5 c) l. L7 X
  290. - f! `: N" F7 d( G6 A& |1 V& G
  291. #ifdef STM32F10X_CL
    & Z. S& j. \, O5 D
  292.   if(CANx == CAN2)/ o" @5 M' X" Y1 J
  293.   {
      x# B1 ~1 l: n& H  r. D, ~
  294.     if(can2InitFlag == true)5 T% r0 A0 Q. H/ ~6 X  U# H, A9 k
  295.     {) z/ U( [0 X4 G( J0 E2 a3 @* h7 z
  296.       can2InitFlag = false;3 h2 l& \0 O0 d+ [) z+ x: q  L9 Y

  297. , J& ?( @& J$ K
  298.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_TX_IRQn;
    . M+ E& K3 I3 y3 H1 M- m. @* Y
  299.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;
    ! R$ |% K5 |  x& X" Y4 W# h6 r$ |/ O
  300.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN2_IRQ_SUB_PRIORITY;
    # n) h0 t; l1 K8 i8 y
  301.       NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;# P% H' S% n9 z- W  r: J6 l
  302.       NVIC_Init(&NVIC_InitStructure);- ~2 X8 c9 k. z0 F% ?! N) R
  303. & U' C# K/ f4 L( l: k  E6 I0 s
  304.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_RX0_IRQn;( \1 f3 G3 |: a/ C: h  e% g5 |; X  _4 U
  305.       NVIC_Init(&NVIC_InitStructure);' {4 n5 O. S. G; B. G$ Z) t

  306. 7 {( _2 ?8 ^/ l0 \2 J5 L) s. k
  307.       CAN_DeInit(CAN2);- V2 h1 |* e7 e* B  i+ y
  308. 2 ]; H" w( s5 Q" E! ~
  309.       if(can1InitFlag == false); @8 J1 c0 W7 E" ~, [
  310.       {
    7 R" x: g# a$ J: M! _6 O: a7 y
  311.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);  u; C4 n! [. \4 Z" u: x% Q
  312.       }& b( k1 s, w1 ^5 v& U
  313. + `2 L; k9 D$ M2 R
  314.       RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, DISABLE);
    0 _# P2 G6 n. z

  315. . C" s! e3 z# p; d  k
  316.       can2TransmitFlag = false;
    . c0 C6 Y  G/ V. d7 M# Z" x0 w* q4 c
  317. 4 `% x2 a5 n& d  N$ [- C
  318.       can2TransmitFinishCallback = 0;
    . n, n2 b, i4 Z# D! a
  319.       can2ReceiveFinishCallback  = 0;
    3 O8 \& b: G$ E/ ?  K& {" e: B+ [
  320. . [0 b' g8 O$ u' Q
  321.       RingBuffer_Free(can2TxBuffer);+ N1 ~2 k. p, Z2 e- f# W' m
  322.       RingBuffer_Free(can2RxBuffer);' v- i3 `$ m4 P5 _( t
  323.     }
    3 w9 T5 y1 U; a! ^9 N
  324.   }; @% q) m* L. ?' ]3 C! {* E
  325. #endif /* STM32F10X_CL */: y/ C0 \: C- _
  326. }- R* [+ ]1 t/ O6 E3 m7 k
  327. ' }! H1 H" O% \  Q9 g) [+ a5 {( O
  328. /**+ |* l, M+ m: O" n2 \3 T1 U
  329.   * @brief  CAN set transmit finish callback.
    6 _5 M. ^1 K; K
  330.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.
    , d# l9 z$ p* y3 k8 g% l
  331.   * @param  [in] Callback: Callback.
    ( k5 \! k: |- y" E& I8 Z0 k9 h% h" ]
  332.   * @return None.
    9 p/ q+ U4 E% H& C
  333.   */9 `7 C' c3 h6 \  C! r9 a" H# @& X
  334. void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void))2 i/ a" x  n' }2 D
  335. {
    " T5 ]6 J+ r8 J& K( V6 B8 |3 N+ u
  336.   if(CANx == CAN1)
    $ l/ `) O) I& S+ ~2 k
  337.   {
    , _: g8 ^9 ]# O. e$ p: r- V' q
  338.     if(can1InitFlag == true)
    ; h7 u  C# h1 C: Z) U6 ~- h% r
  339.     {6 b4 L, I' A' d+ w
  340.       can1TransmitFinishCallback = (volatile void (*)(void))Callback;
      s. M; ?" y: |0 G0 M
  341.     }
    : d  y* @. H3 d% @; o1 m
  342.   }4 n* g7 ~" u3 G+ V
  343. # m3 G  f  F% f& M* }
  344. #ifdef STM32F10X_CL* N6 ^1 N2 C$ z* K% f4 _
  345.   if(CANx == CAN2)8 v6 p2 r- H5 C; |3 W$ v1 r3 t
  346.   {
    ' P" p6 r- C# g* ^
  347.     if(can2InitFlag == true)
    4 o. s5 z( X$ b& t7 S* {" {, O
  348.     {
    ) R+ ?# l$ W, ?. B
  349.       can2TransmitFinishCallback = (volatile void (*)(void))Callback;
    4 y! _3 l! C9 `# T1 Z/ W. ^. F
  350.     }
    # _6 [: b, s/ ~
  351.   }9 r1 y# L% V7 y0 X# C- N1 @
  352. #endif /* STM32F10X_CL */# D1 k1 K8 M9 W! s, E4 V& {) |
  353. }
    2 A  k( I" }- `5 Z5 [

  354. 9 Q( d& G  E- ]/ `( }9 J" H/ j
  355. /**; {0 K! J/ G. C6 H4 Z
  356.   * @brief  CAN set receive finish callback.
    4 r- Z* G* }4 e
  357.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.
    ) Q* ~6 I: J7 y$ [. t
  358.   * @param  [in] Callback: Callback.
    ; O; @4 F! Q# N! {+ g$ ?/ b; e
  359.   * @return None., |0 Y4 B1 U& L' ?
  360.   */
    ) ^& n! {& M6 B( x
  361. void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void))+ w0 }* J% Y6 p6 l
  362. {) a. Z' \1 x7 g6 T, H2 f& L
  363.   if(CANx == CAN1)$ K& ^, j$ c2 ^4 i: O0 _; V) a
  364.   {
    $ d% {' u" L  S9 D, M' O, ]) b
  365.     if(can1InitFlag == true)
    ; @( H$ o9 |# o* e' m
  366.     {
    7 @$ ^: r% z7 L) T7 C8 n( y, E  K
  367.       can1ReceiveFinishCallback = (volatile void (*)(void))Callback;
    ' v) P5 J* L9 x; k
  368.     }
    4 f+ q8 n; Z: l7 O4 ~$ J9 t) X
  369.   }
    . S( w5 j0 s  a7 x9 y* B' W. L/ g

  370. 2 w. ?* i$ e, Y
  371. #ifdef STM32F10X_CL
    3 }0 I% I) L4 }4 B8 _7 f! A+ o
  372.   if(CANx == CAN2)
    + o- ?( u" l- R+ W6 ]. Q4 D# T
  373.   {5 x/ S' `  P  C+ J# ]3 q# @
  374.     if(can2InitFlag == true)4 |5 o1 T* u3 D% U) y+ P
  375.     {
    3 @& `3 e3 {8 @7 |% h1 M$ C7 Y2 g
  376.       can2ReceiveFinishCallback = (volatile void (*)(void))Callback;
    , q7 E! C& l$ l0 x! m9 r! ]
  377.     }
      l1 i3 W9 ~9 K: L2 K, K' l
  378.   }. S, o8 D: W3 e$ X3 S) S
  379. #endif /* STM32F10X_CL */& Z, o+ i3 g( b1 C6 [0 r
  380. }6 v6 _5 v- |) e9 F
  381. ) C2 b7 a& J& h) B
  382. /**6 A' Q# ]) k/ r, _% Q, Y
  383.   * @brief  CAN set transmit message.$ J. [% ^, N+ d, b- Y0 k9 u9 C( _
  384.   * @param  [in] CANx:    Where x can be 1 or 2 to select the CAN peripheral.
    ! m  C  K: |" X
  385.   * @param  [in] Message: The address of the message to be transmit.
    ) ^3 _+ b0 a5 W9 ]5 d
  386.   * @param  [in] Number:  The number of the message to be transmit., a. N$ e) A1 O  ^
  387.   * @return The number of message transmit.
    ; U( B$ {4 w5 H9 a. z
  388.   */
    $ s. j" r2 K) Y* D; D; x2 {( z1 g& Y
  389. uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number)2 r6 j0 ?' o* K. I! y0 F
  390. {0 }% O) ?$ ^6 m; ~8 V
  391.   if(CANx == CAN1)5 D9 J9 C, E/ @0 q
  392.   {* f  p0 u& R4 _$ z4 U% ?& \* e
  393.     if(can1InitFlag == true)7 W! p' e6 S0 a9 \7 r
  394.     {  z' d5 i# U2 \1 h
  395.       uint32_t available = RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);5 e7 A" x( t5 R2 o( z; @

  396. ' x. ^) C, ]$ R8 o8 [
  397.       if(available > Number)
    % r1 H  S; X  T3 f; X. j
  398.       {
    * ]8 l9 j* W0 C
  399.         Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);
    . i$ n1 @9 D: Q  F; J
  400.       }2 [" m  O' k, U: N2 a" S8 S1 h
  401.       else
    ' t6 k0 L& H2 r8 g" _5 r
  402.       {
    2 q3 Y  {. V* M# f* h: ?
  403.         Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);
    1 f; V5 J! n' _& k
  404.       }
    4 O- E: j' c$ Y+ h' A5 [5 p; T9 l4 y

  405. 2 Y* s0 f1 _8 k8 R4 U, L
  406.       if(Number > 0)
    ; W% M% Y8 I7 D3 H& D+ o8 W
  407.       {- s: A" y* [9 C. A5 e3 L( C
  408.         if(can1TransmitFlag == false)
    8 g2 r- C/ f2 V+ q1 h: h. k
  409.         {
    ; Y. o5 s. W; P+ u+ q, w
  410.           can1TransmitFlag = true;8 p( {3 s' I; c& ~! W' ~* J( B& w% ?

  411. % ~! ^$ U& \9 F7 r4 C" h
  412.           CanTxMsg canTxMsg = {0};5 j5 @( K0 [' \; |0 D) _
  413.           RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg));
    " ]8 J! P& @$ {8 u" f
  414.           CAN_Transmit(CAN1, &canTxMsg);' [# g3 B( P, @1 c1 E- T
  415.         }1 w8 w! g: N, k! J
  416.       }
    5 W3 p. @& ^2 m  z" @

  417. $ Q# Z1 [8 v4 e) V1 b
  418.       return Number;
    9 e" s4 F% i! {3 r# j) [
  419.     }
    ; p! }. m& T' X+ z* T3 C
  420.   }
    $ c, z  g  K0 ?3 I- c
  421. , [$ p, D" ~' m" P
  422. #ifdef STM32F10X_CL
    6 c' h& D# o; s( P1 j; c( m6 V
  423.   if(CANx == CAN2)1 I* c5 i( I' A- ^) O* `& l
  424.   {
    : b& N! H$ Q6 U* ]4 ~$ W
  425.     if(can2InitFlag == true)
    & l" O2 \2 \( Z$ k+ C/ V
  426.     {
    ( ?+ m1 I+ `, M1 D% ?! W
  427.       uint32_t available = RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);7 N" f" k7 _4 r/ T+ n. j( ~! ?
  428. 7 K' t3 q: w& f6 z& l
  429.       if(available > Number)" {$ k/ f8 Y7 F* U# }- e, D  R8 R7 T
  430.       {0 N1 J9 ]& A7 J' u6 Q9 {
  431.         Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);
    ; F3 P3 f# C/ j- j
  432.       }
    # I2 @+ n9 t  r; {9 @! R! E
  433.       else4 ], ?2 f7 `4 A$ m# B$ Z' P' }5 [
  434.       {" M' [- y% ?+ O$ b, l0 T  W
  435.         Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);4 \" e0 s: M/ y+ r% d& O; W
  436.       }
    # C6 f- h# e$ h
  437. . K! \( r: H+ x* x
  438.       if(Number > 0)
    & R3 m! Q. U* `
  439.       {
    : r$ a' G# y4 e/ w
  440.         if(can2TransmitFlag == false)! }+ g) d; w+ m: N( d- M
  441.         {
    " S2 L+ @& x; O) o
  442.           can2TransmitFlag = true;
    * s; \9 x; k8 o
  443. 3 C+ l4 I2 x; e. {
  444.           CanTxMsg canTxMsg = {0};" M" x! O& s" i0 J+ Y& l* K6 R
  445.           RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg));9 w, p4 A5 A0 h: L3 Y% l  l% Z
  446.           CAN_Transmit(CAN2, &canTxMsg);% n3 @+ n. y' d# W) J, A' {9 y
  447.         }
    ' [% A% T! I$ ?5 N8 _8 x. x
  448.       }& S1 l. q) E( a

  449. : M7 w( w2 K* H- t- G
  450.       return Number;9 ~% c3 {- X4 T9 w
  451.     }/ Y* i* x" e! f& @6 z
  452.   }2 Z! a# {8 G& k. M$ e
  453. #endif /* STM32F10X_CL */  W: M; @) v1 u  X! j3 k# X" `2 D

  454. * T$ i7 p  z5 E( S1 i; Q
  455.   return 0;
      m% }7 Z! h  i9 \; S
  456. }7 |  ^. {3 z5 ?& j1 ^1 G
  457. 4 |/ ^" T% @3 o, i
  458. /**4 s. I4 k' A; A. p/ v  g
  459.   * @brief  CAN get receive message./ Y, s9 E0 Q! K* ^; A# L7 f1 ^
  460.   * @param  [in] CANx:    Where x can be 1 or 2 to select the CAN peripheral.( u. f% b& o' X8 l1 C* Y4 e
  461.   * @param  [in] Message: To store the address of the receive message.7 L- x9 Y. B* ~$ @4 `  _; k
  462.   * @param  [in] Number:  To read the number of the received message.% C, c2 K2 h, K. j8 Q# b3 x
  463.   * @return The number of message obtained.4 l0 J0 t  L. ?' i6 T- E
  464.   */( T5 v7 i2 b, @' S& r# Y* q
  465. uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number)
    8 @; _( f3 |( T8 v" _! E/ g( _* X
  466. {0 b5 s$ {, }  p: o
  467.   if(CANx == CAN1)
    + Z' m# ?, P1 R' @+ a6 W" {
  468.   {
    & D; n# @5 k" V1 q, d$ m: K0 b% d8 Q
  469.     if(can1InitFlag == true)! X3 M& }7 I/ V4 D  _6 n
  470.     {
    * R3 F; L0 Y$ X3 |
  471.       return RingBuffer_Out(can1RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);( V1 n1 d) z: r: ~) B
  472.     }
    - e6 x- T7 J% |: L1 `
  473.   }! H& k  ]: S2 l* H8 s+ w
  474. " _: w0 q! [0 v4 n0 m, `; H
  475. #ifdef STM32F10X_CL4 a( B$ F& P0 h" P+ {, ^+ S' j) f
  476.   if(CANx == CAN2)( W0 u; Q: `3 I1 W
  477.   {
    ( S6 q% |2 t+ g; b
  478.     if(can2InitFlag == true)# ~: G2 Y8 B5 N
  479.     {
    9 \7 y$ z' ~% d) O9 \/ T
  480.       return RingBuffer_Out(can2RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);
    ; |  F; ]0 [: T; [+ A; H7 a
  481.     }  v* C: }- H; p9 M1 A
  482.   }. d/ m8 ^5 `( T5 H" F" |6 y
  483. #endif /* STM32F10X_CL */
    # n5 w, J, q# a3 R! ~- o) H, ]

  484. # Q; e# A, O' g: M. m) k3 c
  485.   return 0;
    # D" G4 j! c) x4 G, v2 M# N
  486. }* K3 {! D$ I: N" Q8 u0 I% c" }  |
  487. 1 G: w9 |" z& a8 d( ~
  488. /**
    ! p7 ]9 g& P5 J1 ]! z
  489.   * @brief  Get the size of the CAN transmit buffer used.
    / m- c) J5 s7 C$ U" g0 f
  490.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
      ~2 V  a" Y. J) Q8 J. v
  491.   * @return Used the size of the transmit buffer.
    + A' B7 P( v1 T9 w
  492.   */# }9 I  f% X; g9 x' a* o
  493. uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx)
      S4 v3 R3 C3 @6 W
  494. {
    * B  v# D8 ~( E' l2 o
  495.   if(CANx == CAN1)4 k0 A. G5 I$ K( O" k
  496.   {
    ! Z& U# t1 ?  ^3 ]6 C3 v# r8 T  U
  497.     if(can1InitFlag == true)- C, J3 o5 p# l- ^0 L- y# ^9 A
  498.     {
      d. |( ]: Q8 }6 l. y
  499.       return RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg);
    * J4 K% z: f) S7 R: t9 D
  500.     }
    4 \+ \, T1 I8 ~) q* p+ P2 Z* @
  501.   }: Y  v8 `% N2 ^. q

  502. * h" n0 y9 d  [; e( R
  503. #ifdef STM32F10X_CL1 e0 E' M7 w* o
  504.   if(CANx == CAN2)' h5 r3 A" L, A9 S- Y5 S! _
  505.   {
    - W) ?& N2 Z5 h) b% l% P( K
  506.     if(can2InitFlag == true), X# a$ J1 g. k9 G
  507.     {
    & i. ~; ~) e+ W+ }2 J
  508.       return RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg);# R6 v% S' B$ F7 h: t
  509.     }
    / _  g* G2 T- q
  510.   }
    ) ?/ w4 ^  a! I
  511. #endif /* STM32F10X_CL */( o( P; O, e: N" n( L5 ]

  512. 4 ^, |" I, M- E: g
  513.   return 0;3 \! T" H; ?8 |. e; V4 A1 o6 F
  514. }
    6 Q( ?6 O0 `" U$ [# F5 H9 h
  515. , e: y+ Q2 y3 F  k
  516. /**
    - _5 @/ q5 K% d' L' b/ q+ w
  517.   * @brief  Get the size of the CAN receive buffer used.
    0 j" ~4 \. S3 ~+ z" i  R0 w
  518.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    # t" \" u3 `1 r4 b$ L! w
  519.   * @return Used the size of the receive buffer.
    5 {1 \, d# w  z! x0 x
  520.   */
    ! t; P1 T" X. K( e
  521. uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx)6 W. p" A6 B. z( y7 G
  522. {
    ; s$ P4 K" I" Y4 o1 U! v
  523.   if(CANx == CAN1)1 ]6 C6 f! ~8 `$ [, H. H
  524.   {* \+ ~4 P, t& k7 k$ {% M) i
  525.     if(can1InitFlag == true)
    1 c4 E2 M) I- F- ?: Q5 r, H; b
  526.     {; d6 q9 b/ {" [1 x5 |0 a  R
  527.       return RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg);
    ; @% ~$ ~) g" W; k2 k2 L# p  H+ g
  528.     }
    ( v* o6 X  v7 A( C0 e) F
  529.   }
    ! E& `* \" Z* R2 n
  530. + W) Z% T1 ?3 G8 J: O" R
  531. #ifdef STM32F10X_CL- j& T8 h0 H/ q) u
  532.   if(CANx == CAN2)+ e0 R) }8 I  t0 @& ~, z( `
  533.   {
      K% i, f; [3 Q7 y& |% s
  534.     if(can2InitFlag == true)
    5 d% |2 U$ K, u, D9 J
  535.     {
    : d; P, f) K. @6 a9 s) z, |
  536.       return RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg);
    / k  q0 I7 ^6 b; S$ p  [6 f3 ?
  537.     }  e- r; ?+ y; P9 p/ C! R: L
  538.   }
    % i. h  R2 R9 E1 A& z7 d% {
  539. #endif /* STM32F10X_CL */) a& O1 \2 Z/ [: O4 u/ m

  540. ! k' w# R0 Q- X6 F3 v
  541.   return 0;
    ) `8 @% S- J/ S2 L; e1 S$ O- [: [
  542. }* `( w8 s; e" @( j% R3 \

  543. : v3 m' q) q* Q7 j% @4 k' i
  544. /**
    ; P0 \: A) [; D- M5 M
  545.   * @brief  Get the size of the CAN transmit buffer unused.8 `1 h7 O3 u2 x0 n- |; C% y9 i
  546.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    . A" Y' m3 @7 {( F) S
  547.   * @return Unused the size of the transmit buffer.+ {- M% V# q: W1 {  R
  548.   */: c! M/ K3 V% C/ F) u
  549. uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx)
    - P. ^7 f2 q# ~
  550. {
    % X- d$ d( ]1 b6 n- V; p
  551.   if(CANx == CAN1)) ^. ]4 C: n8 p4 `7 H
  552.   {/ I+ t9 M) b) L3 {! b0 ~
  553.     if(can1InitFlag == true)
    ' W# M4 Y4 g+ j. J+ A  I# S
  554.     {
    ( e  A+ N9 w+ W9 M) u
  555.       return RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);9 N' {& E/ |' W' D% F
  556.     }" R; ]" L. v$ j! \
  557.   }
    $ x/ w4 P* r' [: K' I

  558. . U+ j8 |9 ~. s% f+ {( Z# R
  559. #ifdef STM32F10X_CL; P' F7 F+ h: a- F1 d" k! v9 f
  560.   if(CANx == CAN2). h+ {. l) R# a
  561.   {
    ' k- d6 Y2 W: y6 N( x. J
  562.     if(can2InitFlag == true)( K! |$ X8 z, W  q2 d
  563.     {
    # h$ v$ [% E! b: \6 F- h
  564.       return RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);
    ) ~" \9 G/ t% \
  565.     }
    : n, A1 C, \; G8 g$ @
  566.   }
    2 D  h. q& m0 ^' v* }
  567. #endif /* STM32F10X_CL */
    9 Z3 |$ e# S; u' L4 X

  568. , L) e6 V* j- }
  569.   return 0;
    " n$ t- p, D; Q6 j
  570. }2 e, U7 n$ x9 u* u6 C4 n7 i$ D4 x0 h
  571. " C  `' l% a5 |8 Q( E8 K
  572. /**6 f2 l9 s- ^: ^, K9 C* W
  573.   * @brief  Get the size of the CAN receive buffer unused.1 }5 O9 x4 z3 N9 J6 G
  574.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.6 ~, `2 e) m1 Q& s
  575.   * @return Unused the size of the receive buffer.6 e* J; I: d; }2 d5 ]- E
  576.   */
    & z9 g/ B7 P. a; \+ c' c% O5 {3 j
  577. uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx)+ M3 }# j6 e6 X
  578. {
    ) G1 T) o& F( j& t' V
  579.   if(CANx == CAN1)0 W7 S" t" x) ~. ?9 T* j' \
  580.   {* X( F# w1 c& X  M0 L) }' P) {; k
  581.     if(can1InitFlag == true)
    % @9 D6 f; V2 {( c
  582.     {
    $ n/ a9 }) z' n: q5 W; g$ n( o
  583.       return RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg);
    ( W$ x( `6 l8 S' Q
  584.     }
    ' S% Z& k: K8 n" Z% w  T0 A
  585.   }' i. S8 `- z! K8 Z5 O2 n
  586. ) I5 e( h  v" x/ q, P
  587. #ifdef STM32F10X_CL, v6 m- z( ~, T! s/ g
  588.   if(CANx == CAN2). a" o7 y* J& x( p" s  R$ G+ A# K
  589.   {
    4 E8 u1 D+ a# t/ F( n3 m8 v
  590.     if(can2InitFlag == true)  i: x/ I9 Z, r4 `! l
  591.     {  E0 A, s2 l. v6 j' B
  592.       return RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg);, a- g; F# Y9 W& N9 J" D. z
  593.     }/ X( ^- q' d7 V3 e6 H  B
  594.   }
    7 q- u9 x# X* ]6 K2 s) y" ~
  595. #endif /* STM32F10X_CL */
    * @7 q1 g" s8 `! z0 j/ Z
  596. 6 k* m/ ^* A  [4 v1 i7 s/ g
  597.   return 0;
    , p# Y2 ~& g8 T- ]0 z2 X
  598. }- s" _6 U/ c% v; Z; o/ P
  599. - ~  i( N1 F, ^* t6 X
  600. /*** h4 B/ _% A" k* S& [) c3 X
  601.   * @brief  Is the CAN transmit buffer empty?9 u8 l, H( h2 ?) ?! {5 ^% R
  602.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    / _4 ?6 @/ Z/ y: M9 y
  603.   * @retval true:      The transmit buffer is empty.  e8 u7 H5 Q" i# i) h4 ?
  604.   * @retval false:     The transmit buffer is not empty.
    % k# k( c+ @6 _6 t# m+ |
  605.   */( v) Z( h* N, K* k" Y7 [2 i* n
  606. bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx)
    6 E6 f/ k8 t9 y8 g8 b2 A8 M9 {: n* D
  607. {
    3 l. {5 W* F. S, \* u2 v
  608.   if(CANx == CAN1)% ?4 e0 u' R( j( q3 K
  609.   {+ u: H2 b  K) [3 r
  610.     if(can1InitFlag == true)
    ! G  |% g8 r0 f( h/ I( O
  611.     {# f( s' r% J$ ]; ]
  612.       return !(RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg));8 o" N$ e3 M+ J, C6 d
  613.     }
    % Y% I# R8 P. B
  614.   }
    4 Y9 H. U+ Z" k+ u. R

  615. / N8 e& C# H2 L. S4 `& |  f
  616. #ifdef STM32F10X_CL. c1 ^# j- U/ k9 n3 ?+ x) D3 D5 F
  617.   if(CANx == CAN2)
    $ q! t5 G* K% V* p- \( h
  618.   {& ]- }3 E9 U: c' N4 Q1 k$ U
  619.     if(can2InitFlag == true)& _, Y* r- y: y9 k! R. o
  620.     {
    / ?1 w6 e; ~1 L* r# k
  621.       return !(RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg));
    2 h2 g" ?* F8 d5 N! c/ C
  622.     }% j8 _' w" z0 n
  623.   }0 q% f; U) Y' n( B
  624. #endif /* STM32F10X_CL */
    4 m- c' C/ ?' P- A& A  m0 |

  625. 4 t  z, Y  S' R6 c" i, \7 T/ t
  626.   return false;5 H  X: d7 v) U3 S: |: \/ @+ [
  627. }7 f$ P' a" ^  C9 L. V& c9 O
  628. : S2 ]7 E0 h- O- q: U
  629. /**1 J( f% F) |, w* h& ^( T3 g8 R0 J8 V
  630.   * @brief  Is the CAN receive buffer empty?. R, @# ^( X5 F: o* z) ?0 L9 k& q7 k
  631.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.* A! c, I! n+ L% M+ G; \
  632.   * @retval true:      The receive buffer is empty.: l; L' {+ f1 t) W$ [( R! f
  633.   * @retval false:     The receive buffer is not empty.0 Z6 B. W: i. R" {# J
  634.   */8 B% d% A+ e. x* @& s& V
  635. bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx)
    # c( I( C* E6 }" G$ I, x
  636. {
    ) x9 b3 L) ~4 X
  637.   if(CANx == CAN1)
    : X' Z) U" I) |2 g! ~9 y' }
  638.   {& }' S9 R# T+ h3 Q, B9 @" ]
  639.     if(can1InitFlag == true)0 j: ^* s8 Z1 |3 z* p0 V: d
  640.     {
    0 e, m7 |7 y( o/ v7 ~$ N! j% `8 o: g
  641.       return !(RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg));
    ! X" s' x4 |2 C0 b( i; N& I/ _' S
  642.     }5 h' t  E  _. ]4 ~, B  h" {6 c/ K; |
  643.   }
    - C4 f1 e) R7 `- J+ ?

  644. % m6 Q- e; W; g
  645. #ifdef STM32F10X_CL
    9 d* ^% X; M0 E3 G4 b4 M. d
  646.   if(CANx == CAN2)
    ; p, g9 {" Y+ @" U
  647.   {; p, ~7 H- p9 [& l
  648.     if(can2InitFlag == true)
    ! Q0 a; k: |$ V
  649.     {! @  p: P% f: e0 ?6 y, V
  650.       return !(RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg));
    ' y  Q2 Q2 o7 C) L/ f! @( x
  651.     }8 C: A) u+ d  B- {) S8 x
  652.   }3 V: i( I% q. Y  I) M' J3 [
  653. #endif /* STM32F10X_CL */6 g( d2 {! [0 ^
  654.   r! x. N4 Z  Y: ^
  655.   return false;
    8 v, q1 V8 p) j7 m% }
  656. }
    . i' Q+ [" u+ Y9 t' J4 X8 b
  657. + @0 I6 d) l( y& Z0 _( e
  658. /**3 w/ ~$ h  ?0 L
  659.   * @brief  Is the CAN transmit buffer full?
    ; w; \3 M' }  {0 S
  660.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    ; y# l( B4 Q( H
  661.   * @retval true:      The transmit buffer is full.* E3 |: o: e* n8 H
  662.   * @retval false:     The transmit buffer is not full.
    + g' o/ s( U- r0 @. N- t( w4 J& ]
  663.   *// }5 S: a+ v, i/ l
  664. bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx)
    3 w+ u/ S9 z) w' \! ?% }, _' G. L
  665. {( N+ y1 \% @, `& P& t
  666.   if(CANx == CAN1)
    1 b- _6 a  n* Q: |
  667.   {$ p$ v8 Q6 F: A3 O+ A6 r% o- b: V
  668.     if(can1InitFlag == true)
    ) r0 q5 N/ o) ^! S+ k: E
  669.     {3 U3 E& K/ T1 ]- A9 m. p
  670.       return !(RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg));2 c5 R6 \( D( a6 w8 S7 [
  671.     }. B6 p. C2 A. A9 @* Q# I  v
  672.   }& x# {3 [" O, I* p5 ^1 d

  673. 5 j. d0 V5 a: Y) |9 V; U7 \8 B
  674. #ifdef STM32F10X_CL2 U% z+ ^6 r0 M$ G2 }
  675.   if(CANx == CAN2)  }  Y" l" R, P5 O% C
  676.   {
    $ o/ o, l- B4 ]9 V8 t8 `$ C5 k3 w
  677.     if(can2InitFlag == true)
    ( c' ]( P% ~5 L* d7 A+ n& h* i" o
  678.     {! ?1 ]9 w9 h% q- }; t% q
  679.       return !(RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg));
    7 A& G' q; p# M7 `1 e! F9 I
  680.     }
    3 B# g- q4 h$ w2 m+ c0 E
  681.   }
    ! D0 d: y6 X# k5 a
  682. #endif /* STM32F10X_CL */) U! d- X2 @, p! q; [4 H+ q

  683. & x4 ~0 u; w4 [4 G: [" |1 y, ?
  684.   return false;
    * Y1 w! C& Y, V3 U7 @
  685. }- d" O& O) W) E: r& W3 f! s

  686. , J  J" f) Q7 @& Z, l4 ~/ }
  687. /**
    0 {" L) ~. ]4 j
  688.   * @brief  Is the CAN receive buffer full?
    : v% i+ I8 ^# V7 ^
  689.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.8 x6 X! P7 M8 x  ]' y$ _! L* z
  690.   * @retval true:      The receive buffer is full.& ]6 I6 O6 g# @
  691.   * @retval false:     The receive buffer is not full.
    / ?- B3 m; i8 z% e0 L* K4 y+ L0 d
  692.   */8 D( E% H% w$ T) F
  693. bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx)% |/ }! Q' F( J' V6 X) T6 x0 A  g
  694. {
    7 G, C9 T; Z8 z5 q4 ^; ~' N( A
  695.   if(CANx == CAN1)+ p, e9 J9 D' m7 ?* W0 v
  696.   {
    ! c* d3 v8 \/ R* h0 U6 d# u/ |
  697.     if(can1InitFlag == true)7 R9 P; V! d4 z/ V3 }. o& J
  698.     {
    7 v+ _: D/ I, i/ d
  699.       return !(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg));8 k, u5 k$ t6 X2 z
  700.     }
    " R. p7 j- h+ Y+ {/ }' H
  701.   }- ]1 Y$ c5 `0 Z0 X
  702. ! d' V) h( u% [- e1 C4 U
  703. #ifdef STM32F10X_CL( i4 Y/ N8 T9 ?9 p& D
  704.   if(CANx == CAN2)
    1 u. O6 g# \! B- J" ~
  705.   {
    0 x9 M9 z! d, T% i" m$ X. S
  706.     if(can2InitFlag == true)& z; e; r+ G5 w
  707.     {& R3 c6 q3 h+ f" u1 O! X1 ?$ {7 p. \0 H
  708.       return !(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg));+ p; p( P, X6 t( K! A- a
  709.     }% a1 [# M; K1 @2 s; T; [( p/ G
  710.   }" W) [' \. j# r- _3 k$ \
  711. #endif /* STM32F10X_CL */
    ' S" Y3 Z! F) g, v5 `! ?! O
  712. ' |/ X2 c! E% B6 W. Z* E
  713.   return false;
    # ]' W: I. `2 k( m% ^, E' U
  714. }# h. O- H. N/ Z# k! r% J

  715. ' @# i( B; \3 @0 c( j! P; ?2 x
  716. /**- @7 N' v6 u0 P' e. Z
  717.   * @brief  Clear the CAN transmit buffer.
    : Y0 u- a4 C* R# I" q6 A4 Y
  718.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    4 H' `2 t% s+ K4 Q2 y1 q7 h
  719.   * @return None.
    ; v$ p, n" F; P. l6 Y( \" f9 P
  720.   */
    9 }9 e6 A( i. T: F2 c8 t. N
  721. void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx)
    . i( E3 y# |- n7 A
  722. {
    ' R; F3 L0 k5 T* w% A3 \3 e
  723.   if(CANx == CAN1)3 U% F# V- E1 w
  724.   {
    7 e* V" f9 I4 g
  725.     if(can1InitFlag == true)( t* u/ E( X( D) v: n
  726.     {0 V; e3 d7 u2 t/ Z4 j
  727.       RingBuffer_Reset(can1TxBuffer);
    0 {) Y3 n* b$ l# Z
  728.     }* J( l3 p) I, c6 x3 E5 O
  729.   }
    " k6 V9 i% w% V0 L/ k

  730. 2 N* ]) D7 ?, l" Y5 ]" p6 B
  731. #ifdef STM32F10X_CL
    # \5 P8 y  b. `4 u0 p, e, u
  732.   if(CANx == CAN2)
    6 n7 e0 G- P. i' b
  733.   {) k1 }, U. N/ ~5 e
  734.     if(can2InitFlag == true)% K5 K1 k/ {( T2 \* {
  735.     {- U  w( ^1 {% W% L
  736.       RingBuffer_Reset(can2TxBuffer);
    0 X2 u9 B" D2 U5 H; v
  737.     }1 K6 b! o* ~* R6 X
  738.   }
    " s8 S( O" m" p* M9 S
  739. #endif /* STM32F10X_CL */; p5 J* W1 Z9 a) t" j; o- V; G* E3 Y
  740. }
    + D. Z; S1 K, O( n+ z
  741. $ d, ^8 O9 V0 P) e" x3 j  b6 g
  742. /**
    ; j( U& ~. `5 E4 E- n
  743.   * @brief  Clear the CAN receive buffer.
    / r! \6 W7 x( c7 J) e
  744.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral., Z: T! V5 |% s1 W
  745.   * @return None.
    # L  ]$ N9 P, E/ e
  746.   */
    3 ~2 p5 A4 a% y3 `$ U  V- }" f7 H
  747. void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx)! W0 |9 J% s" K$ I1 ?, {9 x
  748. {& y8 c; e; Y, w. \
  749.   if(CANx == CAN1)& t5 S+ Q8 T) }+ [
  750.   {
    ( U1 P- K* Q/ @
  751.     if(can1InitFlag == true)
    4 O1 a8 h' I0 |: w# `, |
  752.     {" L' R% W2 W# ]( v8 Y% j
  753.       RingBuffer_Reset(can1RxBuffer);7 K' _1 [/ G6 b4 S7 v: i+ V
  754.     }
    ) D; P$ M% i6 [
  755.   }2 K- ~% B' i( `& F
  756. ( e$ [+ p3 C/ ~) @+ N% R( |! g4 {: D
  757. #ifdef STM32F10X_CL
    ) @! y% Y; Y* s% m
  758.   if(CANx == CAN2); [/ v3 F- S! `3 `# g
  759.   {
    " P$ i& L) S5 i- u2 h: C: z. U
  760.     if(can2InitFlag == true): R  d' I: A1 O: u4 {8 D. n
  761.     {* b7 n1 a; B0 V: ?* V; O
  762.       RingBuffer_Reset(can2RxBuffer);
    3 E1 j' @& j: O+ j2 R9 r( N
  763.     }1 e# t! ~/ T4 O  A2 |
  764.   }
    ; o6 G7 `" [. N6 N+ \! d' A% E
  765. #endif /* STM32F10X_CL */- B$ N1 Q' l* K3 H5 L) d
  766. }, h; P" a0 o. M- K

  767. + S8 c5 x5 w# G) @/ C- g
  768. /**6 v/ s5 h. k5 Y2 x2 r  G* k
  769.   * @brief  Is the CAN transmit a message?
    0 e: `! G. [7 E4 y; ~( R
  770.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.6 b1 @: `& G' p' p
  771.   * @retval true:      Is transmit a message.
    ! ^9 O5 U0 h! k3 u! Y' {. p+ Z
  772.   * @retval false:     Not transmit a message.* x. |* E9 U! b# f6 |! D. w$ [
  773.   */
    6 i1 A- j/ K8 O4 k3 X; G$ t' K
  774. bool CAN_IsTransmitMessage(CAN_TypeDef *CANx)
    3 {6 k# c2 n2 V
  775. {+ r: r- p. p; G. X
  776.   if(CANx == CAN1)) ]! j( l/ U( H+ X
  777.   {( S" U) r. F+ {' D3 h( x- ?
  778.     if(can1InitFlag == true)
    3 t6 c9 n% X1 X) ^' K9 z: q6 U5 o
  779.     {4 f+ a/ K9 p3 S0 f
  780.       return can1TransmitFlag;4 I9 u- L5 L8 ^) M' P5 Y, H3 G& t
  781.     }
    * a. s. y& I3 B' ^$ c) `6 ^/ `
  782.   }
    ; q5 A- y2 S( l- u9 }- Z& ?/ S

  783. ( m' W* H# d; |+ }5 Q( s
  784. #ifdef STM32F10X_CL7 ^* N3 H! [/ b0 D0 g3 T
  785.   if(CANx == CAN2)) o7 U6 P8 @# h: z1 E" a$ q- t  r
  786.   {2 {$ x8 k, l$ |" I) g
  787.     if(can2InitFlag == true)
    * K/ B* r9 U4 K5 d
  788.     {' L- ?. [* Q/ H. Z, q! d
  789.       return can2TransmitFlag;# A: k( e$ ^- G7 p- `
  790.     }6 U9 \' ?( V8 x( E
  791.   }; l! p  L& Y" X9 ~8 p2 C% P
  792. #endif /* STM32F10X_CL */
    8 b% i% t* U; ^4 ^( x, f

  793. % f2 C9 O1 T; H8 d2 _
  794.   return false;
    " m. k) p' p" v" f' y" \
  795. }7 H, P) T  F9 a2 T7 F& o- Q7 T' ^5 |
  796. $ |3 I" i+ ]2 h( e, o0 ]
  797. /*** g% c6 k  W+ U
  798.   * @brief  This function handles CAN1 TX Handler.7 \" b2 Z/ N) E+ X) X* d
  799.   * @param  None.
    . e1 q3 G3 o0 T, F$ j# w3 m/ G$ M; n
  800.   * @return None.% v/ w  i' A. ^0 a
  801.   */
    ! n8 v, t! {- A  D7 I
  802. #ifdef STM32F10X_CL; z! v( W9 e+ L1 d
  803. void CAN1_TX_IRQHandler(void)3 y3 |5 ?, J% c( ~; s
  804. #else) A1 {& U# `. _2 o
  805. void USB_HP_CAN1_TX_IRQHandler(void)
    # d+ [: B, o' ^1 c
  806. #endif /* STM32F10X_CL */2 e: S5 `4 J. W
  807. {4 t* F8 x4 y* q' g- t3 Y
  808.   if(CAN_GetITStatus(CAN1, CAN_IT_TME) != RESET), g8 q$ k" h2 N
  809.   {9 k) x6 P+ h9 I9 l1 `
  810.     CAN_ClearITPendingBit(CAN1, CAN_IT_TME);' q% v  T8 L7 @* `. b

  811. + r% M0 m) d0 ~: A- X6 y3 H
  812.     CanTxMsg canTxMsg = {0};" @# O, e8 ^1 ?0 \+ n
  813.     uint8_t  number   = RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);; i0 x, o- M9 [# h5 q, G
  814. 7 U  v( A2 V8 x8 d. i
  815.     if(number > 0)
    ( Z8 x$ f2 f% a
  816.     {
    1 ]8 a$ V- O7 r
  817.       CAN_Transmit(CAN1, &canTxMsg);
    * ]. F5 S# @& J! d. S" ^* s, `: G
  818.     }+ X; W- J8 @& s: Z7 B
  819.     else
    6 i) \1 d1 o) q' N4 Z$ M
  820.     {. ~  x4 U. d* L1 h& J
  821.       can1TransmitFlag = false;7 D. g& M  D' o- a% p: h" D5 ?

  822. ' T' v) P. d1 p1 u/ U% L
  823.       if(can1TransmitFinishCallback != 0)
    3 d" Z8 |. B, l/ k2 t
  824.       {. k4 [- M. v' \% ]
  825.         can1TransmitFinishCallback();$ m0 {3 F% V+ z" [) x( z5 u
  826.       }
    & k' O: I- F, @0 B, T
  827.     }
      [. G4 ]" b7 t! a/ `/ T
  828.   }
    1 n" C6 Q- @1 d  z$ t3 ]+ e! h
  829. }$ O5 V: u( ^, h4 y0 M
  830. , ^+ e/ F: |0 N  _! i7 l) b9 \
  831. /**
    & v6 X5 v) n% [" B1 Q- n
  832.   * @brief  This function handles CAN1 RX0 Handler.
    # s2 q' a$ \, K; }  u
  833.   * @param  None.) h4 r3 y1 h: G7 k) w$ D
  834.   * @return None.
    5 }2 J, Y. J1 f
  835.   */
    . a& }1 q2 P7 o8 D! r* o% H
  836. #ifdef STM32F10X_CL8 G! z3 N; K- X7 _
  837. void CAN1_RX0_IRQHandler(void)$ n! D3 d% [1 D( T+ }# [
  838. #else" G" b- M' A7 U4 t
  839. void USB_LP_CAN1_RX0_IRQHandler(void); e" R  Z; Y! m0 d: i7 G1 f
  840. #endif /* STM32F10X_CL */
    * [. V9 T# }( W( I! x7 z# S
  841. {, t8 {7 z1 B& I& |9 C9 p* I1 d
  842.   if(CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET)4 h( E7 [) n/ f5 s1 V& g) u( U/ T
  843.   {- N- m# {2 N6 w
  844.     CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0);5 {; m% _5 B% H$ Y0 ?, ~( Z: f* b# |

  845. ! g6 @, ?& E6 y' S
  846.     CanRxMsg canRxMsg = {0};
    5 n4 O6 H7 I5 O( d4 S$ h0 y& f6 G8 E
  847.     CAN_Receive(CAN1, CAN_FIFO0, &canRxMsg);  g7 E  q9 w, O- u& c+ m8 F: S/ ^

  848. # W( v3 h" |. S& ]% M% e
  849.     if(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg) > 0)1 E! g4 x6 @7 E! g! f: f4 Z
  850.     {6 Z2 f  d) h9 q( d) J4 W# g
  851.       RingBuffer_In(can1RxBuffer, &canRxMsg, sizeof(canRxMsg));0 i% U5 g6 o( A: C% s" R
  852.     }
    , S6 P6 T  I, C

  853. / _9 \8 c: [- H5 U
  854.     if(can1ReceiveFinishCallback != 0)6 n7 \# B7 h' ^* Z$ y: F
  855.     {
    , z/ P1 M4 B' q4 k. @$ m2 m
  856.       can1ReceiveFinishCallback();
    : a5 M7 w( I% l" b) I3 W
  857.     }
    3 a( A* _" [$ S( D7 `
  858.   }
    + F- O0 K0 J+ p7 t9 j, ]9 G0 H
  859. }0 [8 f% S& ]' S* h

  860. - ?' y% m+ q' `- R% @; C
  861. #ifdef STM32F10X_CL
    8 k7 C6 W9 U$ Y5 Q
  862. /**
    2 E0 I" K) T. X4 C1 L
  863.   * @brief  This function handles CAN2 TX Handler.
    & H5 D4 d' r; V9 {2 a6 ^+ D9 T
  864.   * @param  None.
    5 `7 ], ]1 }* e' A+ f; f# U: y' W% D' z
  865.   * @return None.
    0 X& P& ~4 v* A6 B+ U% z' n+ a) g
  866.   */
    0 g; x; i6 S/ y1 C: T& r" l% y
  867. void CAN2_TX_IRQHandler(void)
    8 A7 |4 s+ m, E( e9 u
  868. {% P& L# w3 A1 ?) N. E: F
  869.   if(CAN_GetITStatus(CAN2, CAN_IT_TME) != RESET)
    0 z3 J! ]7 n3 P
  870.   {
    4 |1 n$ p$ B/ K) @, Y, G' {
  871.     CAN_ClearITPendingBit(CAN2, CAN_IT_TME);/ V* g# p# L  {  u
  872. 6 o; x- \5 M6 D. ]6 q( ~3 m1 |
  873.     CanTxMsg canTxMsg = {0};
    + w$ E6 H$ z5 j* k( Z1 C7 k; O* {# v
  874.     uint8_t  number   = RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);
    % Y6 S( M3 Y* L+ v+ Y
  875. 0 Q, v" B% D1 ?) J; |9 P
  876.     if(number > 0)
    : J/ b! L) D* ^* J+ z) ?# A3 a5 H$ i& W
  877.     {' C" K+ y+ z% b4 r! R
  878.       CAN_Transmit(CAN2, &canTxMsg);
    # g6 |( p1 h( W& w. u
  879.     }. q# u& v; n- g5 o8 C& r
  880.     else8 T/ }( S1 r1 N
  881.     {6 Q2 O! F9 z( x6 w' e
  882.       can2TransmitFlag = false;
    % K0 A5 b' D7 O

  883. # S& ]. h  }9 W% s  A1 r% N
  884.       if(can2TransmitFinishCallback != 0)! \; m9 x4 j% u, j4 y( L' M
  885.       {
    / Z4 C" k: \. s2 R/ ~- E5 b) Y
  886.         can2TransmitFinishCallback();
    8 w! V' N; U- s# X3 T' F$ e5 f: {
  887.       }) N) ^' q( v8 i6 N) _3 h5 |
  888.     }! T1 H0 Q3 F0 _
  889.   }
    8 w/ B8 Q; K  y, e( A5 F# L
  890. }
    4 ~1 ^5 k7 X# |7 }' }) q& L
  891. 0 T  U! \: m! r! U  B3 u+ @
  892. /**8 B  J9 Z* X, Y3 }8 v$ F# W
  893.   * @brief  This function handles CAN2 RX0 Handler.
    ' K3 l- ]( u! Q$ G! a( O
  894.   * @param  None.7 L& n1 O1 [" k& I1 y5 |0 x
  895.   * @return None.6 a& k1 E* q3 U7 [! Q
  896.   */# b7 c% Y9 [# o. s: y; p' O$ Q
  897. void CAN2_RX0_IRQHandler(void)
    * d. R' i: z, b3 W$ }
  898. {
    , I; [& ?, {# D/ w
  899.   if(CAN_GetITStatus(CAN2, CAN_IT_FMP0) != RESET)
    + C- E3 Y% Y! F6 G% m
  900.   {
    ' @' H. J3 |5 b- T2 ^3 T$ M
  901.     CAN_ClearITPendingBit(CAN2, CAN_IT_FMP0);- @5 r* b4 N# u" k
  902. , m# h8 H7 f# S8 k; R+ h' `5 o
  903.     CanRxMsg canRxMsg = {0};2 G* o. i: R1 x1 E0 u2 ]& E# U" c
  904.     CAN_Receive(CAN2, CAN_FIFO0, &canRxMsg);' T+ x5 h# `& v# H. L) G: a

  905. 3 v8 z5 \0 d2 E, `) T: a  \9 s' Q
  906.     if(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg) > 0)
    7 K; |* Q% [( a# A7 B) V' k
  907.     {
    " y8 o  h# m% w; M9 }: W9 W
  908.       RingBuffer_In(can2RxBuffer, &canRxMsg, sizeof(canRxMsg));
    9 P# L1 y3 i  {: `  R
  909.     }: Q' s5 m. P5 C0 [' Z7 E

  910. 5 P; v3 ?3 R& v: G% D' p
  911.     if(can2ReceiveFinishCallback != 0)  w$ Q5 \- ^7 _- {5 V
  912.     {
    9 _" w' f5 Y. p: d
  913.       can2ReceiveFinishCallback();
    9 I7 O7 ~" ]+ ~9 k
  914.     }; R( u  b  U2 z' c' P0 M9 k, t( m
  915.   }
    6 L  }, j% |: n- K7 M# T
  916. }
    9 ^1 d: Q/ [4 E( T$ v3 R+ g+ d
  917. #endif /* STM32F10X_CL */
    8 c+ Z+ `& V. N. \* ^% H
复制代码

9 b' ?$ W# ~6 K/ f( I" D6 ]1 X* Y4 B7 a# L2 @/ y) _
main.h 文件
. }, y/ v& T' D! R2 G8 x
  1. /**
    9 [: p& `& V/ i8 t( f
  2.   ******************************************************************************
    $ G( A" R, i" P% I9 `
  3.   * @file    main.h( H, ]' \. H8 }4 f
  4.   * @author  XinLi, Q8 [; v0 K6 q
  5.   * @version v1.09 x  K/ S4 W  E$ Z2 i! Y
  6.   * @date    24-June-20180 }" F) K) n! ]
  7.   * @brief   Header file for main.c module./ l  H  J. r- Z1 z
  8.   ******************************************************************************, ?# P3 ~; `$ `. i, K& g  Y! ^
  9.   * @attention
    9 l7 B8 H( I2 c& v1 A+ I
  10.   *
    ; x0 X  `6 z; x, h
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>/ F, r. b8 p; J' U0 D% u
  12.   *0 D& {. H7 T+ J! a3 j/ f! o- `
  13.   * This program is free software: you can redistribute it and/or modify
    + u+ q2 q* ]: u4 N5 I( A3 _/ `$ p
  14.   * it under the terms of the GNU General Public License as published by
    + x: K& d9 U" P
  15.   * the Free Software Foundation, either version 3 of the License, or
      l8 s( J# \+ l1 O$ ~, Y
  16.   * (at your option) any later version.
    % Q0 q1 v8 X9 W6 y, y* ]; m7 I
  17.   *
    $ T1 s/ E, b% y5 v. E7 M3 U5 r' v
  18.   * This program is distributed in the hope that it will be useful,! i$ y0 a6 _$ q" {( n& k
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    8 U) P- l7 s! O
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    , l7 H! F& P- |/ E( d
  21.   * GNU General Public License for more details.
    4 v% b6 d# i; }% z6 r$ U0 r
  22.   *
    " z( E+ W$ Z3 a
  23.   * You should have received a copy of the GNU General Public License
    + P' A9 y, V: x" @2 v0 h
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>2 Y5 o6 J5 N) V" ^; v
  25.   *6 a  X! g3 h( V& G; Y
  26.   ******************************************************************************
      J. o1 L5 t/ l0 V; W4 f
  27.   */
    ' N! S' o5 {7 ~  c5 {
  28. ! q9 |! c2 `9 Y* N, w
  29. #ifndef __MAIN_H
    # L. T# s( c. N" A4 _, O( ^
  30. #define __MAIN_H) W1 F4 b4 o  p; T
  31. * \- F( o% _( L' d
  32. #ifdef __cplusplus* G. e/ M% a  T$ `! D3 H2 L
  33. extern "C" {9 l9 s! H% N5 V5 T% j% c
  34. #endif2 J, T# U: T/ B
  35. 2 H; N9 D& u- a. e# a$ F
  36. /* Header includes -----------------------------------------------------------*/
    9 p" @: J; b: U9 |* e
  37. #include "stm32f10x.h"' J! T2 y  l8 [* R: f
  38. 5 B8 V6 j* T/ [( S
  39. /* Macro definitions ---------------------------------------------------------*/
    3 k6 Y& D' U2 p- q( y
  40. /* Type definitions ----------------------------------------------------------*/
    ' A8 r0 S4 c( a" F" p
  41. /* Variable declarations -----------------------------------------------------*/
    $ k2 [6 ?- c; i- |
  42. /* Variable definitions ------------------------------------------------------*/& E" h) T  c) u7 T
  43. /* Function declarations -----------------------------------------------------*// h- E' z2 Z% B9 x6 `4 ~
  44. /* Function definitions ------------------------------------------------------*/! I5 h1 X0 t* _; u" W3 s% Q

  45. , S  \4 Q6 X5 X  v$ V* {7 s
  46. #ifdef __cplusplus6 ]# p+ \3 q% o/ g  C- B% O) B1 U
  47. }
    5 R2 p; h% ]2 b7 x/ Z. [, Q8 I
  48. #endif
    7 C4 [% E# k; |8 _. f
  49. ; e4 q4 z" |  \% a: y' w) a& l) P
  50. #endif /* __MAIN_H */
复制代码
' W8 b) ~2 P: z9 C/ A9 v
0 r' ~) ~/ Q$ p6 F
main.c 文件
- P" `& k3 x- a) ~
  1. /**
    8 ~5 ], ^- X' ?# i% b
  2.   ******************************************************************************
    - F, e- R# l, Q. _/ Y0 e
  3.   * @file    main.c/ J7 M, p, V# }' q5 ?
  4.   * @author  XinLi" k+ J1 y# s/ z. }3 H7 l4 Z4 W6 z
  5.   * @version v1.0
    ! g" c( l& ~1 M4 z( p: d, m
  6.   * @date    24-June-2018
    4 g+ Q) |$ T) `- i4 I
  7.   * @brief   Main program body.% u( B, Z- U, w8 t3 a! m
  8.   ******************************************************************************% U/ b7 ^/ _7 c+ s
  9.   * @attention
    8 `1 o4 y( Z+ A  K5 M' \. L
  10.   *
    : F# Y# U% y8 ?$ \
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>" |7 S4 x* F; @* M& T
  12.   *) g# W$ \4 s" g- W8 F* ~5 |) L
  13.   * This program is free software: you can redistribute it and/or modify* ]1 S$ Q$ k, }* }# o
  14.   * it under the terms of the GNU General Public License as published by
    2 i" R$ k: }+ ?; D% T( N
  15.   * the Free Software Foundation, either version 3 of the License, or- r9 N+ q0 s8 w
  16.   * (at your option) any later version.% l, P7 a( }7 j4 j! }( Q* ~
  17.   *( N5 c0 k! U$ N% V% @, e
  18.   * This program is distributed in the hope that it will be useful,; j4 I) @, ]9 K6 U8 h
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    - I8 y5 v: a  E# K( V
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the8 C0 I) S' P, m9 H2 {# K* ^
  21.   * GNU General Public License for more details./ }$ d( X2 _7 o5 L) @
  22.   *$ ~! Y; G) X* v: R+ k7 ]( j* j
  23.   * You should have received a copy of the GNU General Public License) A: F) T" y* |3 f. V) y
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>: I( |. c4 |' }* ?7 b5 m/ |
  25.   *
    2 ?7 @1 C' B' S; x8 O5 m" [
  26.   ******************************************************************************
    ! y) c3 U- S. x: B8 h! s6 d3 Y
  27.   */7 [( k0 y) X0 R& P' _0 j

  28. / H$ e9 a3 u' j
  29. /* Header includes -----------------------------------------------------------*/
    2 I( v6 K; u' j# _
  30. #include "main.h"3 [) |0 q$ H0 O+ w1 i$ P( @
  31. #include "CAN.h"
    9 p9 f$ h5 ?2 S5 Q! V

  32. / T2 V) u  n; ^* V9 n( z; @
  33. #ifdef _RTE_: R6 P% u/ [: B/ O" U( u9 M
  34. #include "RTE_Components.h"+ |% B4 A' F! f, P- C, |5 @
  35. #endif
    : X" n; _2 ~3 t; C5 p. _1 o+ c
  36. 9 {+ e4 L. Z8 H/ ]/ U# _
  37. #ifdef RTE_CMSIS_RTOS2
    & X; `9 r1 ~* [( v) z
  38. #include "cmsis_os2.h"- Z1 {3 e0 \0 z2 ^$ S
  39. #endif: n& L( F, z! r' p8 D+ ]
  40. 0 g* `) Z/ G2 @7 \
  41. /* Macro definitions ---------------------------------------------------------*/
    : f! M! @: I& j
  42. /* Type definitions ----------------------------------------------------------*/2 _" s5 `. Q* F# z# F& S1 S( y
  43. /* Variable declarations -----------------------------------------------------*/) J% ^3 K7 \$ V; o
  44. /* Variable definitions ------------------------------------------------------*/$ m( ^+ U# w& y( b0 Q) |- S
  45. static CanTxMsg canTxMsg = {0};$ b  S3 ?3 e4 b- e+ X
  46. static CanRxMsg canRxMsg = {0};
    1 ?8 }% Y- y8 R. `6 ?1 s- I

  47. : \/ O8 n& h: C$ E" [' R
  48. /* Function declarations -----------------------------------------------------*/
    & g* u& g# f9 R/ z8 H' N2 y
  49. static void SystemClock_Config(void);# |, P  P' P8 X* w% j/ x; {

  50. 3 w8 L* u- {# ?! a' b6 U+ t
  51. /* Function definitions ------------------------------------------------------*/
    0 m& }9 s# Y: p& S7 Q
  52. - u4 P7 U# y/ }- _
  53. /**' X; p' Q4 Y4 @# g4 j$ s& p3 k6 `: z
  54.   * @brief  Main program.
    , `5 s" d" v* E2 S; S, T
  55.   * @param  None.* t; u5 D) v; m
  56.   * @return None.: t% A: f; p. n
  57.   */' k* I# ~* Q4 I' H
  58. int main(void)
    6 ~. p! e9 W6 N$ |1 w
  59. {. @; r) u/ h& @, j3 ]
  60.   /* Configure the system clock to 72 MHz */
    ! _. p% Q  g$ _" F) \
  61.   SystemClock_Config();* ]7 u, Q, }2 a
  62.   SystemCoreClockUpdate();) |' \  d4 s7 m2 U3 i& s9 B) s' @
  63. ' ~* v! ?1 Q9 x
  64.   /* Add your application code here */
    3 `- M) T7 y! [2 I2 q$ }* M
  65.   CAN_Configure(CAN1, CAN_WorkModeLoopBack, CAN_BaudRate250K, 0xAA55, 0x55AA);
    & B% Q' V% U+ \

  66. % R8 D  K! X3 X" F
  67. #ifdef RTE_CMSIS_RTOS23 U6 _3 c$ M, o( F
  68.   /* Initialize CMSIS-RTOS2 */
    + ]! p, r* I$ G+ `
  69.   osKernelInitialize();
    2 l' ?; N- t* ~4 w

  70. ) R1 Z7 F& U4 P3 C/ A5 \) x# D, F7 w
  71.   /* Create thread functions that start executing,
    0 U& X9 Q4 N/ ?$ d9 n3 n6 U
  72.   Example: osThreadNew(app_main, NULL, NULL); */1 f/ T8 r9 x& C# U) `8 o6 `
  73. * e9 V8 b; c; e5 N, v- l5 t
  74.   /* Start thread execution */+ D: Y; H3 `1 C' _- O. M; V
  75.   osKernelStart();
    ; ]$ G" i! [  U, [
  76. #endif
    - c" {. H" T- s& Y, r

  77. 1 Q0 V, w' F. a2 H
  78.   /* Infinite loop */6 f! a. V7 H: y8 m! z
  79.   while(1)
    ; l7 g% A) _7 I/ i( F- T
  80.   {
    8 U* q7 H9 M! H9 m& i+ b) p
  81.     canTxMsg.StdId = 0xAA55;3 F/ }6 Z7 q0 V5 U8 ]% c
  82.     canTxMsg.ExtId = 0x55AA;; B9 v6 Z8 l$ m6 }; [/ w
  83.     canTxMsg.IDE   = CAN_ID_STD;5 K3 d/ ~8 d, k# D" H3 V+ T; j8 n
  84.     canTxMsg.RTR   = CAN_RTR_DATA;/ A. N+ E1 m% d$ |( _. P: z. ^% z' z
  85.     canTxMsg.DLC   = 8;+ y* ^2 @  J& D6 b0 j( z

  86. ) C/ s& K& i3 T4 J2 w7 K+ F
  87.     canTxMsg.Data[0]++;
    2 O8 H8 ~- \9 P& v7 B
  88.     canTxMsg.Data[1]++;
    3 i) q8 g2 U% w8 k( @5 O: f
  89.     canTxMsg.Data[2]++;2 A& `8 d/ W2 p: i- g4 Z
  90.     canTxMsg.Data[3]++;+ l- |! D: F5 J! J
  91.     canTxMsg.Data[4]++;/ U$ e! I7 _- f3 ?3 {! V6 ]/ W
  92.     canTxMsg.Data[5]++;
    6 c& I# {: \* ^' _, m# F( \6 T  s. c$ ?
  93.     canTxMsg.Data[6]++;
    : v& \. V6 l+ Q2 z0 B; X  O( S
  94.     canTxMsg.Data[7]++;* e8 e9 Z# |& z

  95. , {$ y" o" E* _/ y! Q& c( t8 U* Q
  96.     CAN_SetTransmitMessage(CAN1, &canTxMsg, 1);" y& L# ~+ s9 N) D! J5 J' X; M

  97. 2 X0 c, T  ~# q$ x6 D
  98.     while(CAN_IsReceiveBufferEmpty(CAN1) == true);! ~& G7 d# w( j! s5 ?' \' Z

  99. * {" E  v4 P5 {2 H, r
  100.     CAN_GetReceiveMessage(CAN1, &canRxMsg, 1);
      M4 _! D4 n. ]% Z( R! }$ X
  101.   }
    9 {& d) _0 V* n: [
  102. }  f  e  h8 R0 X/ q! ?; d
  103. $ {$ _. f, |7 ~- z+ l
  104. /**. O' L3 u. G  Q
  105.   * @brief  System Clock Configuration.6 z& S7 F1 ?* Y
  106.   *         The system Clock is configured as follow : 2 P$ m  W% M5 x2 A( a
  107.   *            System Clock source            = PLL (HSE)& u2 O7 {' A/ u8 s
  108.   *            SYSCLK(Hz)                     = 72000000
    ' S* M1 [/ D9 g5 k4 P: F( m6 P
  109.   *            HCLK(Hz)                       = 72000000
    & U( T9 {7 @. @, f* D. s1 m
  110.   *            AHB Prescaler                  = 1
    ) w9 K& \) |2 E1 b4 A1 e
  111.   *            APB1 Prescaler                 = 2
    " Q) d/ @$ U( Z
  112.   *            APB2 Prescaler                 = 1: H' |% G' f, k& X
  113.   *            HSE Frequency(Hz)              = 8000000
    ( F' q4 I& _: [, ]7 v9 N5 U
  114.   *            HSE PREDIV1                    = 1
    8 \5 Y( O* X8 E+ e% f0 F
  115.   *            PLLMUL                         = 9( s6 I; m8 x( e! T& w4 ]2 ~
  116.   *            Flash Latency(WS)              = 2
    ! Z" V+ J: b" w4 ]4 R& g) H$ `/ H3 t
  117.   * @param  None.
    1 T, ~; F7 n: _1 |( g: S
  118.   * @return None.
    2 C# ]: m; i1 M5 m* M( V2 M
  119.   */1 ~# }! [: Z8 a6 {0 f4 Z- X& [/ K2 I
  120. static void SystemClock_Config(void)$ s5 Q6 I. d3 b, S* B. E
  121. {2 N# y; \' @* g1 V' \
  122.   /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration */2 P" h! A* m: V1 U6 G4 G
  123.   /* RCC system reset */
    - H' M8 ?9 A1 z6 F1 _) v$ R# b
  124.   RCC_DeInit();
    1 |- Y8 B: g6 X9 o% @1 N
  125. ; H6 q0 o, Q+ B9 a, H
  126.   /* Enable HSE */
    $ z, B5 J! y, \9 P: Z8 c" |
  127.   RCC_HSEConfig(RCC_HSE_ON);1 x0 @3 D2 ~! f5 x$ l. P
  128. ) P+ R* r, N6 f
  129.   /* Wait till HSE is ready */: d- q# l' A1 K3 r
  130.   ErrorStatus HSEStartUpStatus = RCC_WaitForHSEStartUp();) N0 x6 D& z" a& _% O% B
  131. ! |& z8 ]* L! \/ W& A! p
  132.   if(HSEStartUpStatus == SUCCESS)
    " \% L4 Z9 l$ U* m* X
  133.   {! ~& _" p9 k6 G$ n' |; C8 P( `: X
  134.     /* Enable Prefetch Buffer */- G, S% R# ]2 x6 c
  135.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);& r) X  O) p% [' p1 }+ R
  136. " Z. B$ I/ |$ q- c* `& c- ]
  137.     /* Flash 2 wait state */$ c. [$ Y! X% D& h
  138.     FLASH_SetLatency(FLASH_Latency_2);, c$ h' i; k; u0 _
  139. ) W7 L  i& x  c; \
  140.     /* HCLK = SYSCLK */
    , s* [0 L, W; S: L, b
  141.     RCC_HCLKConfig(RCC_SYSCLK_Div1); 4 I! {0 m: [7 M* o( P4 C; M2 |' F. s
  142. 8 `& M2 p( @3 q. ^+ R8 c. d$ h! R
  143.     /* PCLK2 = HCLK */
    * A% |, S+ [+ F' Y2 C
  144.     RCC_PCLK2Config(RCC_HCLK_Div1); & Z7 t1 m$ f5 U' V. S1 g6 x
  145. - W8 i& K4 s  Y7 C
  146.     /* PCLK1 = HCLK / 2 */
    / F0 d" X$ Z+ ~& g1 b# ^
  147.     RCC_PCLK1Config(RCC_HCLK_Div2);# H2 o& l6 H! T( v

  148. 7 C( Y. M7 f4 {2 j
  149.     /* Configure PLLs */9 N9 w1 w! l" _! P, S# e
  150. #ifdef STM32F10X_CL
    & J- X- U$ m& N& f9 f" P
  151.     /* PLL2 configuration: PLL2CLK = (HSE(8MHz) / 2) * 10 = 40MHz */0 _0 [7 \4 H$ v+ c' x
  152.     RCC_PREDIV2Config(RCC_PREDIV2_Div2);
    * y% \  N$ u8 p; @
  153.     RCC_PLL2Config(RCC_PLL2Mul_10);9 o# Z* Y9 P. _( [& A# |; V. r
  154. ( y+ }/ i9 h0 O: W9 a# T
  155.     /* Enable PLL2 */6 X6 Z+ C1 ^  z' B4 H+ W0 K
  156.     RCC_PLL2Cmd(ENABLE);
    5 Z3 o3 F+ G) R$ x' W+ Z6 L
  157. 0 c" j5 h% p3 H0 ]
  158.     /* Wait till PLL2 is ready */
    ( U6 V& R( T! g# G4 i- o
  159.     while(RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET);
    ! S0 P0 }' w2 _

  160. + V8 Z- I% R" ~1 Z5 Q
  161.     /* PLL configuration: PLLCLK = (PLL2(40MHz) / 5) * 9 = 72MHz */
    , |* j  `' i/ `# F3 s/ j3 I4 y, Q
  162.     RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div5);' }! P# N+ \7 {
  163.     RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);
    - a  U, G9 S* g; V. J# s' F& s0 z; a, s
  164. #else
    6 K5 E/ U$ X  O
  165.     /* PLLCLK = HSE(8MHz) * 9 = 72MHz */
    * Q! ~  ]0 e$ Q3 C2 g% ~, Z
  166.     RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);2 n$ U( ]+ T! S- C- p% d
  167. #endif
    2 O9 ^* K$ Z  V" d* G$ g$ _
  168. 3 z2 {: s3 Q1 n% Q9 _7 h) f* I
  169.     /* Enable PLL */+ p! v% E5 U1 c5 C$ [. R
  170.     RCC_PLLCmd(ENABLE);
    0 W" U% M/ p* l- t) ^1 Y$ i
  171. 1 o! X2 N4 K! z  U
  172.     /* Wait till PLL is ready */
    ! g+ \5 P7 E8 h
  173.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);! e4 h1 H/ ~( i' R' L

  174. ! \4 W# \! y' @5 L
  175.     /* Select PLL as system clock source */
    ; N, w: B, ~% T+ M6 h
  176.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    # i. B( y' p0 j, z- @- z

  177. , I  `8 M4 f" ]/ c& ~
  178.     /* Wait till PLL is used as system clock source */
    0 i% O8 w% L: ~/ h
  179.     while(RCC_GetSYSCLKSource() != 0x08);' m# C3 y6 `2 x
  180.   }
    7 j3 w. a* n+ a4 j$ W
  181.   else
      e/ }6 g& a1 Z* I8 f5 q4 m5 l; \
  182.   {
    % E0 N8 O6 J( J* c6 d" F1 K
  183.     /* Disable HSE */
    " W* m- j+ J5 Q: J
  184.     RCC_HSEConfig(RCC_HSE_OFF);/ X9 Q% x+ L& B4 U
  185. 5 d' [7 c$ u* l3 x
  186.     /* Enable HSI */( S; T' R$ h6 _1 f2 ]
  187.     RCC_HSICmd(ENABLE);1 S6 y$ `. ?' h( o
  188. $ w' ?8 K# D# L: G# h
  189.     /* Enable Prefetch Buffer */
    ; l0 f( Z0 n& z  s, S1 V. |. w
  190.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
    1 U6 ?; ~2 a8 r( O5 `- Z: B8 C7 ?
  191. + g% N# g: [' @
  192.     /* Flash 1 wait state */
    5 M% ]0 R1 l2 F; ~; G+ k
  193.     FLASH_SetLatency(FLASH_Latency_1);
    + M# R! D* v7 E0 K( l

  194. ; e3 h  q% `  i: N3 u. Y2 P% l
  195.     /* HCLK = SYSCLK */
    - T4 a1 w1 Z2 h, h3 A
  196.     RCC_HCLKConfig(RCC_SYSCLK_Div1); , P. k/ g+ T/ f  k6 h6 V) l1 J

  197. / B: U1 x* K9 ^* F- _, {' o
  198.     /* PCLK2 = HCLK */
    & {! j- ~, U4 h$ K4 @
  199.     RCC_PCLK2Config(RCC_HCLK_Div1);
    2 u8 r2 P) g3 Z6 B, C. A2 F
  200. % E" p6 O% d1 R! K$ _' P
  201.     /* PCLK1 = HCLK */
    $ I% S; l- h1 o/ Z  t
  202.     RCC_PCLK1Config(RCC_HCLK_Div1);
    + [9 ~) c! d5 W0 l1 @

  203. 6 Z' r% j, s( N% L# F+ J2 t
  204.     /* Configure PLLs */
    % A* m/ W1 ^( s# p* F; r
  205.     /* PLLCLK = HSI(8MHz) / 2 * 9 = 36MHz */- l5 |- P( @5 _( K5 H
  206.     RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_9);
      T; @- O7 Q! i8 H* w
  207. / b" e3 e% ?, h/ |1 B
  208.     /* Enable PLL */" N6 {9 m7 i+ s% X4 n' v  w
  209.     RCC_PLLCmd(ENABLE);- }. p6 R0 s1 R  b5 N( V7 r$ i
  210. , p/ d. c/ A" G7 k# \9 _5 ?
  211.     /* Wait till PLL is ready */
    1 P+ G3 a. |! O- r3 J
  212.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);, G; O3 f$ {, {/ C  B

  213. + s1 [( ]( \9 |5 |, a9 v! i
  214.     /* Select PLL as system clock source */5 U/ f$ a3 T" o1 }
  215.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    4 U3 }0 {" M* _

  216. + X/ G( @& p2 X( i2 {5 `1 G
  217.     /* Wait till PLL is used as system clock source */
    . ]% Z& b* t7 z
  218.     while(RCC_GetSYSCLKSource() != 0x08);
    0 f- M4 s, ~, c. ~! x& L& L6 `9 V
  219.   }/ R2 w9 E: s1 {
  220. }5 g6 K; @0 {# Q% u$ n- q

  221.   {: B7 H- `: s- b0 [6 j" t
  222. #ifdef USE_FULL_ASSERT& g4 p* C- {% w% F7 b. C
  223. /**# F' G' c& @% m5 W
  224.   * @brief  Reports the name of the source file and the source line number
    " {# T/ _8 Q0 w- e/ D
  225.   *         where the assert_param error has occurred.; l4 M# ~* g& d9 z) U! {
  226.   * @param  file: pointer to the source file name.2 z) H5 s) C7 @% I8 |* M8 l
  227.   * @param  line: assert_param error line source number.
    " {. H0 j! }$ s+ T0 o
  228.   * @return None.
    2 {8 b6 v. b" w  f* s# l
  229.   */
    : P4 C1 P/ p3 @+ t. V
  230. void assert_failed(uint8_t *file, uint32_t line)
    # W; P! o& l( U+ [1 A
  231. {
    4 D$ p' q5 E: `
  232.   /* User can add his own implementation to report the file name and line number,/ f' F( y( a' {. A0 h# _8 P
  233.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */$ ?2 r6 A5 V5 d/ y7 v

  234. 9 L! }; h5 m5 _
  235.   /* Infinite loop */2 F  o" q! P1 y
  236.   while(1)$ ^* |5 V6 p: v$ x* k$ O: a  h
  237.   {9 r7 H4 s# J# p9 o" y1 ?8 t( b) r3 o
  238.   }
    $ J( p! |! x7 N9 p) t8 V3 U% E% b
  239. }& X6 [( u$ ?0 u- x  T& Q7 }
  240. #endif
复制代码

4 H5 c  `7 K9 d, C/ `+ S3,注意
8 K/ \$ [) K4 n: K* U! {
7 j  e) U7 a) I8 F- i. h) WCAN 消息发送缓冲区和接收缓冲区的大小,可以根据应用的需求进行修改,缓冲区使用的是堆内存,需要根据缓冲区大小和应用程序中堆内存使用情况进行配置。  s9 u0 |) `  V' e& R" t

3 o, S4 G. w7 ~4 t# Y
# s2 l9 e1 U- ~' `  o0 g3 o5 V- D
$ X1 y6 L$ A# f- j+ s! X
赞 收藏 评论0 发布时间:2021-11-26 17:00

举报

0个回答

所属标签

相似技术帖

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