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

【经验分享】STM32F1(CAN)

[复制链接]
STMCU小助手 发布时间:2021-11-26 17:00
1,开发环境& X  j* S- S) K9 I# E  V, ~
, a; L8 ]( E3 x" x1 X% B& ^4 Z
1,固件库:STM32F10x_StdPeriph_Lib_V3.5.0/ L0 u% r* Q* S  o; \7 y' O& u, ^

8 e9 ]3 A5 Z0 E2,编译器:ARMCC V5.06
- m" b* R" F/ u. u
/ C! v0 f+ C5 X( y3,IDE:Keil uVision52 @: `+ g: y$ v5 e0 Z. z
& W/ A1 h: F) `$ j! L3 e3 [
4,操作系统:Windows 10 专业版( }# k; e0 M1 P+ o& t( @

6 ]6 a7 L6 a4 \& G  \( G1 X
" P1 g6 k5 {' r4 }  h6 F2,程序源码
7 N/ `" l( P) f+ F9 r* n3 t7 Q9 V
8 R$ x0 m0 Q/ o8 q* wRingBuffer.h 文件2 D$ |0 f2 t4 Q/ P
  1. /**
    4 ~: B* E' I9 I5 ~
  2.   ******************************************************************************* R3 x+ g) n3 H# m& J! b
  3.   * @file    RingBuffer.h7 d2 u; c1 T+ a  U7 j$ D
  4.   * @author  XinLi
    7 `% R, \3 n3 l
  5.   * @version v1.1
    0 ?8 N6 `( w3 x% j, J6 A
  6.   * @date    15-January-20185 i0 n1 {  i- T& m( p9 A
  7.   * @brief   Header file for RingBuffer.c module.
      A2 e- {6 p- q' p
  8.   ******************************************************************************% {$ g  e1 t8 R  I  M7 S- Q0 C+ {1 R1 {
  9.   * @attention
    3 _1 O' g5 ]- G( v( |
  10.   ** [" Z5 P* S  d* q
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
      [1 F7 J- ]5 ]( f
  12.   *
    8 H6 U7 a) c1 r( H1 L4 y$ H5 `, Q3 b
  13.   * This program is free software: you can redistribute it and/or modify1 y, i% j- t4 [9 f% f
  14.   * it under the terms of the GNU General Public License as published by; c# P1 V& ~* T
  15.   * the Free Software Foundation, either version 3 of the License, or
    5 O& E, {. |8 @4 |
  16.   * (at your option) any later version., D3 k$ H8 Y2 i  p  n7 B9 Z7 q
  17.   *
    2 T  B3 z+ A1 [2 e3 T8 b" f
  18.   * This program is distributed in the hope that it will be useful,/ L4 I' j! O: V
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    : C( u  t" B) L
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3 l: W$ n  s# Y. q  e2 u
  21.   * GNU General Public License for more details.. C  x: \2 x2 N( z
  22.   *% E9 S5 c# z$ J$ ^) e0 J
  23.   * You should have received a copy of the GNU General Public License
    ! m' l: M: r8 q8 c# c6 z
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    6 w1 Z8 j% [: M$ f6 Y" ~) y
  25.   *" G4 r: g& }2 j, P9 z3 w) D4 ^- ]
  26.   ******************************************************************************. K) N$ q9 ^2 r% n0 {! T! [7 ]
  27.   */
    5 ]9 h  z+ V& R7 G" [; C/ V
  28. 6 p) }) K. t  A( H( s& W) S
  29. #ifndef __RINGBUFFER_H* C9 N, q3 q! Q) _9 }
  30. #define __RINGBUFFER_H
    / t, C4 \/ h/ c4 Q3 e, D
  31. ; D5 N: g2 y" D+ \  m  p
  32. #ifdef __cplusplus. @! l7 @  {9 j' m
  33. extern "C" {
    3 ?& H( C. H% M7 V/ I
  34. #endif
    / S7 Y1 `& ^* h

  35. ( O* l0 V% f7 b6 r$ k
  36. /* Header includes -----------------------------------------------------------*/
    5 F. r& c+ @0 s6 L- H% f6 H
  37. #include <stdint.h>
    1 ]3 w3 R9 g3 f. o1 E
  38. #include <stdbool.h>  a. l  d7 g. N+ L
  39. #include <stdlib.h>
    6 W9 ?% M9 R3 t6 m

  40. ) S! K* q  U/ X7 R  S
  41. /* Macro definitions ---------------------------------------------------------*/
    8 X6 k; r% ]7 d3 k
  42. #define RING_BUFFER_MALLOC(size)  malloc(size)* X$ O9 b3 ^4 D& R5 W* |/ Q
  43. #define RING_BUFFER_FREE(block)   free(block)
    ; K# R. Q  E4 Z

  44. 6 r# Q: C0 f- y' Z$ n. f
  45. /* Type definitions ----------------------------------------------------------*/1 Z5 q  v2 g1 E" Q* l
  46. typedef struct3 g% W/ B. @7 J$ L* V4 Z; z4 K8 z
  47. {4 [, O% U& G. ^+ _! Q5 I
  48.   uint8_t *buffer;
    0 M  j8 X) x- _
  49.   uint32_t size;
      V3 S, e' `# I, R/ N4 u& \2 r: o
  50.   uint32_t in;
    9 V9 J- g9 c! w8 B" n
  51.   uint32_t out;
    5 [' D- \2 b' G' {! F1 S
  52. }RingBuffer;* C! f+ n3 L: C3 _* M

  53. 1 \( M6 R1 z: V( q2 Q
  54. /* Variable declarations -----------------------------------------------------*/4 l+ v+ P) J# N: Z, q$ M0 \  N
  55. /* Variable definitions ------------------------------------------------------*/
    6 x  X/ |" W$ u0 E! q6 C9 w
  56. /* Function declarations -----------------------------------------------------*/
    9 c. ]9 B  t+ A1 \5 @0 \! y
  57. RingBuffer *RingBuffer_Malloc(uint32_t size);: K; K1 O# D( \" A' k+ Z
  58. void RingBuffer_Free(RingBuffer *fifo);! N2 o- A- n# @) p7 j( X3 ?" z

  59. 2 ^  P% [1 v8 Y, R+ o' M. u7 _
  60. uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len);/ P: j% ]& b) F2 S
  61. uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len);
    ' Q1 {, _  j' q# L' i" h

  62. ( A# w  g& I+ l
  63. /* Function definitions ------------------------------------------------------*/
    1 q& E+ K! c" u" {& N! I4 C' \

  64. 3 T; \; {9 {8 g( \7 d* y, T
  65. /**! Q: y# A6 ]3 V
  66.   * @brief  Removes the entire FIFO contents.
    * @8 B3 g+ B! H( h; k
  67.   * @param  [in] fifo: The fifo to be emptied.
    & M. [3 B' V! F$ D- m
  68.   * @return None.
    5 R$ g, K2 [* m) P" C% a
  69.   */
    1 t# M! ~1 R" u1 M" i4 s
  70. static inline void RingBuffer_Reset(RingBuffer *fifo)' p7 w8 n( t0 q: \5 |
  71. {
    + a# s& Y3 Z8 e) _  P* }4 I
  72.   fifo->in = fifo->out = 0;
    2 O$ Y& n+ g$ y$ l9 o% l) k) e
  73. }* M% R( Y  G9 L/ K8 D6 g; v. M3 {0 P

  74. 9 V. _) b5 g: v/ g
  75. /**
    ' J% h+ P; m1 Q! k* ?
  76.   * @brief  Returns the size of the FIFO in bytes.
    , w* w9 R4 }6 G- q% H
  77.   * @param  [in] fifo: The fifo to be used.
    # {7 H: q/ U* ?  a$ h8 L5 t
  78.   * @return The size of the FIFO.
    $ c, }( J# |0 _- }- p8 M
  79.   */
    9 x# \) u, Z1 E( ^& o
  80. static inline uint32_t RingBuffer_Size(RingBuffer *fifo)
    " r' u- J4 ?6 A% G8 |& m
  81. {4 y" M6 a9 ~6 Q/ _0 ~7 y2 P! t% b
  82.   return fifo->size;- M, r: z: |% L9 ~
  83. }
    8 X3 B8 G( ?: [4 @6 w( E

  84. ! v- g0 x, Z0 @8 G6 S* B
  85. /**6 w0 u; E+ Y$ ^0 Z& n3 I
  86.   * @brief  Returns the number of used bytes in the FIFO.. @/ J. f& R2 D/ p- x6 x
  87.   * @param  [in] fifo: The fifo to be used.$ m, ]% G2 y9 W- P5 M; [  P2 o
  88.   * @return The number of used bytes.
    # T( {5 B+ j9 t# e. b' U. a1 `, A
  89.   */
    3 e6 m) ]( w2 c7 ^' K) A$ H2 c
  90. static inline uint32_t RingBuffer_Len(RingBuffer *fifo)
    - T1 J. K3 x0 e$ Q' l
  91. {6 N9 D& A5 Q: ~# X) B4 X
  92.   return fifo->in - fifo->out;  j3 w+ |+ C3 m% t% T" N
  93. }! E3 q" j- m& _. n9 H" m8 s

  94. % U. p7 A' s# I4 y) `5 l2 J
  95. /**' E7 \1 ^7 Q) X
  96.   * @brief  Returns the number of bytes available in the FIFO.7 S- j$ T5 H$ k. O: `0 l9 B9 s
  97.   * @param  [in] fifo: The fifo to be used.
    8 n, s; R. S- _1 m3 f; g
  98.   * @return The number of bytes available.
    , Y; P0 w/ s2 }; T1 B
  99.   */9 ?' W/ M5 g% y# N* Y( G4 R
  100. static inline uint32_t RingBuffer_Avail(RingBuffer *fifo)$ F- D( w( T0 d2 P
  101. {
    5 J8 M% i  S) J
  102.   return RingBuffer_Size(fifo) - RingBuffer_Len(fifo);
    6 E0 G1 J4 ?. R
  103. }
    6 U! r5 m- ]0 D
  104.   p& w3 e# B/ Z3 i/ Q2 p
  105. /**
    . @0 B- v9 r8 a, Y  P' C* i( E6 A3 P
  106.   * @brief  Is the FIFO empty?
    ) c9 X5 W2 F7 J
  107.   * @param  [in] fifo: The fifo to be used./ c, t3 ]) c$ _- v9 B
  108.   * @retval true:      Yes.
    4 n) O  L, j( ~9 t/ g
  109.   * @retval false:     No.
    ) @/ o& G7 p6 ]9 u
  110.   */8 S# @5 ^* B0 B- {& l+ t3 a2 i
  111. static inline bool RingBuffer_IsEmpty(RingBuffer *fifo)8 x. k' E2 ^4 R* i1 {
  112. {- n4 T/ W% z* l2 T
  113.   return RingBuffer_Len(fifo) == 0;' G% v8 b- _0 L, {
  114. }
    % b: m5 J. v2 t
  115. 0 G/ O  G* g# u
  116. /**
      O# E+ ^3 J9 e/ f  G% o
  117.   * @brief  Is the FIFO full?
    % f! |7 j! Z3 Q3 X* k
  118.   * @param  [in] fifo: The fifo to be used.
    : c% H( n) z# M* Z/ Z4 A
  119.   * @retval true:      Yes.8 U: S) {1 G. w
  120.   * @retval false:     No.8 v- @0 o! _! `1 O7 Y9 p5 C% y2 r3 G
  121.   */
    ' q  ?5 P% S% t% \- y
  122. static inline bool RingBuffer_IsFull(RingBuffer *fifo)/ ^3 f5 w/ }: m6 u  i  Q
  123. {
    % e5 e# n6 {& T( T# F1 M7 Y
  124.   return RingBuffer_Avail(fifo) == 0;- R5 d5 ~' w9 ]2 \, v" T- _
  125. }- Z0 _+ i- T1 y3 C' P( v5 m9 ]

  126. 7 w$ `  M2 b/ P9 H. ^
  127. #ifdef __cplusplus
    * W: Q5 ~* T/ V& x$ ~
  128. }
    ( `% r2 F5 {4 K% g) q6 I
  129. #endif/ e) [6 @4 y! }1 C) K
  130. 8 R, u  i& k" J6 o( N/ L- e; c( |
  131. #endif /* __RINGBUFFER_H */5 O9 Y+ C: u) M/ Z& I7 U
复制代码
7 V+ m) o, ?0 `9 _! e0 ~# L

( m5 C1 O9 a# w& ?RingBuffer.c 文件
5 w" b/ I) b/ G0 z
  1. <div>/**
    ) `2 w+ B$ j( T  {' ?' ~, ?" c
  2.   ******************************************************************************- x& J/ h( G$ r/ \3 W
  3.   * @file    RingBuffer.c  K# h+ \9 O/ V" y/ n
  4.   * @author  XinLi
    3 V" w3 P) e9 m" [
  5.   * @version v1.1+ b8 n+ J! t! i% U
  6.   * @date    15-January-20185 T$ [! T+ g# l' ^& p+ y: s+ T
  7.   * @brief   Ring buffer module source file.
    , H6 |! W$ |( d* {5 p& T
  8.   ******************************************************************************7 f: H; I! ^! t. M4 M1 z, \  ]/ u
  9.   * @attention
    5 k4 u3 H. K5 m, N3 A
  10.   *4 C9 p$ `; c) {/ U  n7 {
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>4 H3 V0 `  m0 c5 ^3 Z  q+ h
  12.   *
    2 l7 K8 C% }2 L2 x- k) H9 q2 c: W- r
  13.   * This program is free software: you can redistribute it and/or modify
    3 R1 h; K/ ^  W( d
  14.   * it under the terms of the GNU General Public License as published by, q4 p5 R3 r) Q9 g: ~, r7 @& v
  15.   * the Free Software Foundation, either version 3 of the License, or3 ]+ i  e4 d1 p; j0 c7 z8 P
  16.   * (at your option) any later version.
    ! w/ S. V( d& C; J% f! y) B6 n
  17.   *
    6 o. H4 A6 @! F7 O% \1 u
  18.   * This program is distributed in the hope that it will be useful,
    % U& j/ R; G$ Z4 e
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of. k7 A- Z& l& \) h' e& L
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    : }: G$ r% H& d4 x2 U# a* W
  21.   * GNU General Public License for more details.9 I& T  j* o6 `9 X4 y1 G
  22.   *
    + u( d% P- S" B! b' I  O
  23.   * You should have received a copy of the GNU General Public License) y: c+ Q$ S/ Q4 m, n
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>) N1 l. j* t3 x* Y
  25.   *
    0 t* f( N: ^, P0 E7 [( W
  26.   ******************************************************************************9 I: z3 I" ?& F, ~
  27.   */
      o: S5 J: D2 I9 @( Z5 p& n
  28. ) }* o, O/ a) J1 z* U
  29. /* Header includes -----------------------------------------------------------*/, Y4 t- }: @" {" j2 K, h
  30. #include "RingBuffer.h"; d$ Y3 Z1 L/ c: Y' x! ]
  31. #include <string.h>
    . z" i. x0 l% p0 D

  32. : x( v$ M9 G0 T- v+ C- |0 ?- G
  33. /* Macro definitions ---------------------------------------------------------*/
    % n2 d# [  e2 c  r$ w: u
  34. #define min(a, b)  (((a) < (b)) ? (a) : (b))* j/ X; k6 ]1 S

  35.   ]7 U( f( J/ Y6 o$ R
  36. /* Type definitions ----------------------------------------------------------*/
    . H  o9 M2 T. ]* x
  37. /* Variable declarations -----------------------------------------------------*/& d% b5 Q* F5 A+ E: ^% O' ]
  38. /* Variable definitions ------------------------------------------------------*/
    2 c/ R; c0 e# x; A. p8 x/ g
  39. /* Function declarations -----------------------------------------------------*/
    ) Z6 u5 H+ D& o! W3 S
  40. static bool is_power_of_2(uint32_t x);
    ' d# B3 V" T# Y! D& i% V) Z
  41. static uint32_t roundup_pow_of_two(uint32_t x);
    1 {, ]# P1 _! y, U7 @1 c

  42. ) W6 H& c) [+ L% T& P9 H' X
  43. /* Function definitions ------------------------------------------------------*/+ z2 K! ?2 L6 d

  44. * M, F0 i0 @4 N( Z* L  ~/ D$ @! @
  45. /**$ s/ T6 }0 {0 x5 b" J$ ?! I
  46.   * @brief  Allocates a new FIFO and its internal buffer.
    5 T3 @/ k& j9 N1 v
  47.   * @param  [in] size: The size of the internal buffer to be allocated.
    & P1 D; F* S/ ]- l6 d  {" b
  48.   * @note   The size will be rounded-up to a power of 2.
      G9 B. S# p( g, t4 v3 e
  49.   * @return RingBuffer pointer.
    ( U! g- C- l. f& \  q6 c" e! ~0 }
  50.   */; K$ W% I% `# C, I+ T' E
  51. RingBuffer *RingBuffer_Malloc(uint32_t size). G5 y, }+ w; L* B( Z
  52. {
    2 a3 H0 U% s0 A5 R3 A0 g
  53.   RingBuffer *fifo = RING_BUFFER_MALLOC(sizeof(RingBuffer));+ P6 e8 L) _  O% U% I
  54. 5 G* v( x" B/ I6 L5 a; Q; \5 S. Y
  55.   if(fifo != NULL)
    8 y7 ~: _1 F4 |$ M$ o; O
  56.   {
    , i- q, U& |9 p5 r: p
  57.     if(is_power_of_2(size) != true)4 O/ V1 g) z  ~: m1 Y
  58.     {
    7 [+ h8 c3 ?# h; q
  59.       if(size > 0x80000000UL)/ t) Q8 @; ~; `, y
  60.       {+ f0 \: w1 ]; G: L( _
  61.         RING_BUFFER_FREE(fifo);* D8 j  o$ I* U& E0 \: l' C
  62.         return NULL;
    & \5 [+ V2 S& j$ d! V% _0 s
  63.       }: U: G: n* n) a0 q/ f

  64. ( Q. @$ @- n4 E  ^5 t* R
  65.       size = roundup_pow_of_two(size);% t# U! \1 P! P1 e. Z* A
  66.     }$ v0 ^8 N/ p  f+ P
  67. ' ]8 z: _, u  r: P0 I$ z2 @. a: |
  68.     fifo->buffer = RING_BUFFER_MALLOC(size);
    * m' @* T5 k- D

  69.   r) C# F9 V' q) _& ]7 r; N6 y
  70.     if(fifo->buffer == NULL)
    5 F; E! f- k4 X1 X* I
  71.     {
    ; B! Y9 z: J2 Y; [; n+ [+ n! k
  72.       RING_BUFFER_FREE(fifo);
    0 F& C0 k: P- D' c
  73.       return NULL;* p# K- r8 C# |4 L" ]3 S. r; ^
  74.     }2 t4 |  m. a! K" d
  75. $ d, C% O0 ]. O& c# C; L# h
  76.     fifo->size = size;
    ( S3 _3 v) X. i' ~* w8 S
  77.     fifo->in = fifo->out = 0;
    1 Z5 I0 F5 H5 `' w' F! U0 d3 P
  78.   }0 J. I' H0 g# g2 x, \

  79. 1 V( i0 M* D* z# b
  80.   return fifo;$ y- J; a' |/ W6 a* W; |
  81. }9 g) N% |- n" H0 A$ Z7 e+ Y
  82. 0 c) j% k& ?! p
  83. /**
    8 y* k8 U  {5 {
  84.   * @brief  Frees the FIFO.2 k" c* Z( Z1 X1 W. D
  85.   * @param  [in] fifo: The fifo to be freed.4 i: q" M- n0 g/ L
  86.   * @return None.8 @; B# r: n& \
  87.   */$ g. B9 ~9 g% a0 `8 S
  88. void RingBuffer_Free(RingBuffer *fifo)5 u) x5 L* G4 L% x* O3 Q
  89. {8 o9 y- `6 z$ B4 l7 h
  90.   RING_BUFFER_FREE(fifo->buffer);
    + _  p1 S0 Q, |* T3 t+ R; s
  91.   RING_BUFFER_FREE(fifo);9 @  g' ?, ~9 A6 E1 I( e
  92. }1 |$ j. r' `; M( |5 z
  93. 4 l3 `% A+ J& ~% R$ Q1 L
  94. /**+ h, W; l4 {5 ]* G
  95.   * @brief  Puts some data into the FIFO.
    ' o! H- Y0 G$ L; o  K0 l1 z; W  Z
  96.   * @param  [in] fifo: The fifo to be used.
    " X  t: C0 O+ k( [5 e
  97.   * @param  [in] in:   The data to be added.
    5 K! `$ h7 L( p  Y% s0 |. B, t
  98.   * @param  [in] len:  The length of the data to be added.
    0 u( W5 W6 X" _  L3 _1 I& k8 D
  99.   * @return The number of bytes copied.; H7 |- a" [# s: P0 h4 D( Q
  100.   * @note   This function copies at most @len bytes from the @in into) Y6 G- b9 n7 X( i7 d/ x' C
  101.   *         the FIFO depending on the free space, and returns the number: h7 ]4 @: S8 r3 g5 D1 e3 `
  102.   *         of bytes copied.4 b% Y% ~) g' k
  103.   */2 A! p& C2 W7 Q- O; C: s, G+ c% D
  104. uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len)9 ~0 h8 O$ i- P& _, d
  105. {6 z2 L4 ^9 i* V2 ^
  106.   len = min(len, RingBuffer_Avail(fifo));% |1 A, Z8 T8 W6 Y& y
  107.   z6 ~; B7 M6 M# @1 Q
  108.   /* First put the data starting from fifo->in to buffer end. */
    ( _: H" O# H7 \6 J8 P( j
  109.   uint32_t l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));
    ! L) E  ]. G: V4 H
  110.   memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), in, l);6 `. e7 k$ ?, z: d% b
  111. 4 L; G& C1 E* u4 m3 J8 A9 Q  g
  112.   /* Then put the rest (if any) at the beginning of the buffer. */
    3 p+ U$ ?7 a8 l# u0 t, |
  113.   memcpy(fifo->buffer, (uint8_t *)in + l, len - l);
    " ?, K5 G9 m+ z1 L( M( c- ]' T
  114. / _5 k1 ~8 w/ g! h
  115.   fifo->in += len;
    5 x; y* Q. o0 N, i

  116. : i0 u- v+ p5 Z6 t
  117.   return len;
    % d) ^. J5 ?" _% m  D" n- j5 g$ \# |
  118. }% Z2 v, H, n, r: J& W: B
  119. . y# I" B# d/ r. i$ Y' x: E% ^) `+ P
  120. /**9 s' y- F+ `3 w3 `; s
  121.   * @brief  Gets some data from the FIFO.
    - M) Z" `- b' c
  122.   * @param  [in] fifo: The fifo to be used.7 W) }" e5 S  p1 b1 U3 E( H6 F
  123.   * @param  [in] out:  Where the data must be copied." s, N4 ~, w& `- |( G2 ~3 r& n( d7 P
  124.   * @param  [in] len:  The size of the destination buffer.
    , \( {! y! f) w$ A% y. `+ X( A& b5 E
  125.   * @return The number of copied bytes.
    0 H2 |2 n, @% o( O) B0 A
  126.   * @note   This function copies at most @len bytes from the FIFO into1 s0 N1 Z! y; C" i" r$ p3 L  w' e* s# [
  127.   *         the @out and returns the number of copied bytes., o# _. ^6 c2 m, b
  128.   */
    1 Y6 G! I2 C) C* s3 P. D
  129. uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len): b7 O; b# v& w1 I+ ?3 I
  130. {% m0 m# [! X- E6 Z
  131.   len = min(len, RingBuffer_Len(fifo));  `4 y0 X' K8 A* k: J8 I) D' l# t
  132. & `5 o. B3 n3 P) L/ \! b
  133.   /* First get the data from fifo->out until the end of the buffer. */
    8 G* m: ~6 P& ?
  134.   uint32_t l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));: y9 S# Y; c: @2 ~& W) \% |
  135.   memcpy(out, fifo->buffer + (fifo->out & (fifo->size - 1)), l);
    4 v+ a  C) R1 _0 h* q

  136. . A0 H% G, `$ J& i5 ^, L
  137.   /* Then get the rest (if any) from the beginning of the buffer. */. z8 M, \# ~7 D. R% S4 U/ ?
  138.   memcpy((uint8_t *)out + l, fifo->buffer, len - l);
    % U: u; x: r. U( Q

  139. 5 P7 ~3 }  Z  M, G# v, \
  140.   fifo->out += len;
    " L1 n& B8 H3 u. h' [" _5 h! d
  141. ) }3 i0 ~' r7 H; M9 M) U+ l' |
  142.   return len;
    / U) U% Z  R: {
  143. }1 ~9 N0 A- O2 B! I' {& Y9 s! M

  144. 4 {( P& t  }- b" i# E
  145. /**: u$ t% `& O! l3 o* u  o
  146.   * @brief  Determine whether some value is a power of two.
    - S% F- Z; G) {  c- t0 H  Q8 E, N
  147.   * @param  [in] x: The number to be confirmed.* ^& F$ L) |3 |8 z& c, T
  148.   * @retval true:   Yes.! y! b8 Q+ J3 j& G
  149.   * @retval false:  No.4 J+ F( x2 a2 N% b: h, Y- r
  150.   * @note   Where zero is not considered a power of two.2 R4 ~% t/ M1 F8 I' [; V9 R4 V5 {
  151.   */
    3 ?, o+ t2 f5 c2 j4 U
  152. static bool is_power_of_2(uint32_t x)
    1 ?7 E! J9 B" h9 }6 z
  153. {% e1 Y% P* Z4 @  R0 y5 d
  154.   return (x != 0) && ((x & (x - 1)) == 0);* p3 N+ e7 ~; x- z/ A% B- z
  155. }! O" \6 e# E% N" J! o
  156. $ i1 d3 b' Z% x5 b' c
  157. /**& i" H; I9 ^9 A) K  ]1 o# D
  158.   * @brief  Round the given value up to nearest power of two.5 V6 n+ n  K# w% h- o  Z( D7 L
  159.   * @param  [in] x: The number to be converted.
    , A+ y* v* k4 U
  160.   * @return The power of two.* R: g" Q. Q3 `: L5 S
  161.   */( u0 \; G; Y2 g; O' T
  162. static uint32_t roundup_pow_of_two(uint32_t x)7 e. p: z3 k6 T  r  y$ P) e& T* `
  163. {5 c) B( h" R5 _
  164.   uint32_t b = 0;
    ; [7 N' y( p3 ^7 j$ {0 x3 s

  165. " ~: f1 p3 ]! |; g+ c& D: v
  166.   for(int i = 0; i < 32; i++)
    . u. E7 B( u/ B. C$ ?5 b* [2 F2 R
  167.   {
      {6 Z7 z) z, f( [2 q8 O3 m  }
  168.     b = 1UL << i;' `/ ]/ i$ ^( n4 p) \9 n; ^2 p0 M

  169. ; B+ x1 o9 ^% y1 v8 Z5 f' R; P
  170.     if(x <= b)
    # B6 q. K7 J8 b) b. F1 {4 V/ c
  171.     {# P) ~, b- F( j+ q  n8 e
  172.       break;
    # b0 }  x7 C7 ~9 v( V
  173.     }
    % @6 s8 _) r7 ~: X
  174.   }1 `' W9 P! _) C: w; K5 f: V8 ~

  175. + w3 m1 G/ D2 P" a; z) J
  176.   return b;  N" C3 C% E4 v# P  Z! v  F
  177. }</div><div></div>
复制代码
" e" g; f0 F( r

- c: J2 }9 S0 y/ _% f  ?/ ]CAN.h 文件
- B( m) \8 x3 j2 ^* p: s# ]
  1. /**" y0 W; g/ `( l( D3 A; r& e& V
  2.   ******************************************************************************
    9 O, k4 x8 U  {, w) F3 X
  3.   * @file    CAN.h) R! p8 ?6 s( Z% U9 ^
  4.   * @author  XinLi: m5 h; c% v1 W3 l
  5.   * @version v1.0+ S' o: n( C, D& |5 f, H: g
  6.   * @date    24-June-2018
    7 {$ H) b5 I2 c) m
  7.   * @brief   Header file for CAN.c module.
    ! O' g5 ]( G7 Z% g8 @, P0 ?
  8.   ******************************************************************************- _; E. o* ?4 l- J1 ~: A& Z+ T
  9.   * @attention$ f; Q% ?9 _8 v/ L. d
  10.   *
    . Z) R# }+ d) f  `
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>- E+ {- n/ Z1 Q: l
  12.   *3 ]7 o0 O# `4 A. t% m
  13.   * This program is free software: you can redistribute it and/or modify
    % _1 s: {& h4 ?% U7 g5 v4 F
  14.   * it under the terms of the GNU General Public License as published by
    7 A) V0 P+ }6 k+ W- C2 M  C
  15.   * the Free Software Foundation, either version 3 of the License, or- X  x+ r1 }  o5 O
  16.   * (at your option) any later version.
    ( ~' g3 J) D( R+ B, A0 ^8 s7 l
  17.   *' O0 i& D1 [2 }( K- C
  18.   * This program is distributed in the hope that it will be useful,. O  T# m2 H' B$ P/ ]4 p- A
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of: b, l7 A; B* `) i7 e
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      P/ i* Z; e: g
  21.   * GNU General Public License for more details.
    ) l! S  m! I/ ^4 k/ p
  22.   *
    ' ]( N/ L) a. |$ W# a) G
  23.   * You should have received a copy of the GNU General Public License
    - f4 Z9 _7 `+ F9 j% R) G8 _* p$ [5 Y  n
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>. x4 h( r  M) S# y6 @
  25.   *
    6 U. R7 u! p: n1 b6 T/ W
  26.   ******************************************************************************
    # ]9 N( k  Z8 [2 h
  27.   */4 R: j5 U1 Q7 U! ?0 a0 n
  28. 1 @9 w2 Z5 w. o9 N2 b& d
  29. #ifndef __CAN_H! z) B5 k$ o" V% E
  30. #define __CAN_H
    ! Z  c) p, S0 X# H
  31. ( U; \" \1 \+ E, s  p5 y* M. d5 n
  32. #ifdef __cplusplus
    / J& J3 a$ E3 x- X. d4 C
  33. extern "C" {
    0 ?+ s. i, H4 H0 K$ M( k
  34. #endif
    ( m) {" u& {: v1 @. @

  35. 5 L$ i: e8 s/ p* e
  36. /* Header includes -----------------------------------------------------------*/
    ) k& E' Q' k  _3 h# |3 X
  37. #include "stm32f10x.h"
    : q% A% ]5 s+ h* w7 ^' A) y3 y& ]' [
  38. #include <stdbool.h>( D. m5 ?/ B* n1 a9 Y
  39. 2 }3 w: G& d5 Q+ m  a3 ^* h
  40. /* Macro definitions ---------------------------------------------------------*/; c+ C8 [# t' |2 e$ f. t

  41. + w6 @/ ?* W. i) B
  42. /******************************* CAN1 Configure *******************************/
    . K5 [* a& W# Q
  43. #define CAN1_TX_BUFFER_SIZE        (16)- F; C0 W  ~' @6 L
  44. #define CAN1_RX_BUFFER_SIZE        (16)) R* l; P. r! v! o3 H

  45. ) f  _; b/ {$ e4 k' K1 ]2 w0 O
  46. #define CAN1_TX_GPIO_CLOCK         RCC_APB2Periph_GPIOB
    6 r$ l$ E) {( M' G8 L- K" d
  47. #define CAN1_RX_GPIO_CLOCK         RCC_APB2Periph_GPIOB
    ' {" S* n3 e3 N1 |$ ~$ i
  48. - B1 Y5 q! s) ^' ^+ G) I/ S/ W
  49. #define CAN1_TX_GPIO_PORT          GPIOB& {: ~/ F3 g' }0 `% i- m# N; S, P
  50. #define CAN1_RX_GPIO_PORT          GPIOB
    5 u, j7 W' }7 [( f
  51. 8 p' Z. g# M. d0 F( P9 }
  52. #define CAN1_TX_GPIO_PIN           GPIO_Pin_9% o- K1 Z: r; Q7 d  B4 E
  53. #define CAN1_RX_GPIO_PIN           GPIO_Pin_8
    . V6 s- X( I; D* ?9 L
  54. % s# @( ]- U: N& B) C0 n' O* N
  55. #define CAN1_IRQ_PREEMPT_PRIORITY  (0)0 N! n# O5 {( j( N" m% u
  56. #define CAN1_IRQ_SUB_PRIORITY      (0)
    ( P# x$ V/ b* i6 x3 F- F4 A7 r

  57. / f& W& f3 P+ X* S' X- b
  58. #define CAN1_PORT_REMAP()          GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE)
    1 q: ]- W* W1 O" J" w: X
  59. /******************************************************************************/$ a  l' P" Z$ J& {

  60. 1 {- `% U# @0 g
  61. #ifdef STM32F10X_CL
    7 O1 K. ?: e# ]( X; T' A
  62. /******************************* CAN2 Configure *******************************/
    8 D; R6 ?$ {5 x+ R1 c! [
  63. #define CAN2_TX_BUFFER_SIZE        (16). F4 U2 F, H2 s' U+ s1 M
  64. #define CAN2_RX_BUFFER_SIZE        (16)
    & \; W3 A9 T; z8 R6 i4 [. B3 o

  65. & z9 J# A2 p) b  O
  66. #define CAN2_TX_GPIO_CLOCK         RCC_APB2Periph_GPIOB+ v* W' X& P+ I% z7 {
  67. #define CAN2_RX_GPIO_CLOCK         RCC_APB2Periph_GPIOB6 m( ~: C+ b( G
  68. 5 q# }5 h0 i3 h& \4 [' Q
  69. #define CAN2_TX_GPIO_PORT          GPIOB4 X6 E' D! A3 h4 k) g. y
  70. #define CAN2_RX_GPIO_PORT          GPIOB1 Z7 s+ x& X0 v
  71. 1 E3 U! _$ C) L/ a2 z3 {; x
  72. #define CAN2_TX_GPIO_PIN           GPIO_Pin_138 w' \0 }% T/ ], i9 C" m
  73. #define CAN2_RX_GPIO_PIN           GPIO_Pin_12$ t$ u( f8 U+ C! O4 d0 h

  74. $ {5 N5 M# l' Q
  75. #define CAN2_IRQ_PREEMPT_PRIORITY  (0): I* v2 }$ }5 v* C& s
  76. #define CAN2_IRQ_SUB_PRIORITY      (0)
    5 S; a8 T9 o. e1 {% ~2 Z

  77. " K5 n: _+ ]% v: X/ d* j
  78. #define CAN2_PORT_REMAP()          GPIO_PinRemapConfig(GPIO_Remap_CAN2 , DISABLE)
    - g1 s, ?5 x* K1 c' g. F7 p0 k0 v
  79. /******************************************************************************/. H; b6 z" R9 K
  80. #endif /* STM32F10X_CL */: @1 m( m6 @. M- t( g
  81. ; G4 H; ~2 R7 ~7 Y  `' Y
  82. /* Type definitions ----------------------------------------------------------*/# G& Y% X8 E, \( D: p
  83. typedef enum
    0 T' ?4 l% X4 N( p! w
  84. {
    & ?  i9 F& f/ U9 z
  85.   CAN_WorkModeNormal   = CAN_Mode_Normal,1 E) O. P9 I3 d9 ]. ~
  86.   CAN_WorkModeLoopBack = CAN_Mode_LoopBack
    : A6 e/ b2 r4 F- g
  87. }CAN_WorkMode;
    ) y( [6 `7 _$ P  A0 x4 H0 |3 k
  88. " J- v) e5 j% k+ w) \2 A' ]
  89. typedef enum, F- Y- I* v" \- C5 r  B
  90. {' m" D. \+ b) R& t8 i" K
  91.   CAN_BaudRate1000K = 6,% p: z) C7 c- U+ ]
  92.   CAN_BaudRate500K  = 12,1 m3 {0 D: F0 W& f& s# C
  93.   CAN_BaudRate250K  = 24,( _, W0 h% l% l: l1 i* x
  94.   CAN_BaudRate125K  = 48,
    & M- g5 {% o$ K+ s
  95.   CAN_BaudRate100K  = 60,
    4 T" U! X( J$ ?. d
  96.   CAN_BaudRate50K   = 120,
    7 P9 E* }" w$ y
  97.   CAN_BaudRate20K   = 300,
    4 e& z: f$ A4 x8 r) |! J
  98.   CAN_BaudRate10K   = 600
    : s3 Q" Q3 D& p7 n+ [0 ^$ i
  99. }CAN_BaudRate;
    . _; f! o8 @# L2 o- w$ N
  100.   e& {1 o8 c, e: r
  101. /* Variable declarations -----------------------------------------------------*/
    / @3 f1 c" O- B. a. _( r: _
  102. /* Variable definitions ------------------------------------------------------*/
    ( y: [4 X/ M3 m+ l
  103. /* Function declarations -----------------------------------------------------*/
    * T. A1 A  r: n$ s4 M
  104. void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId);
    . \1 A# f. a) }  O0 @) d8 w
  105. void CAN_Unconfigure(CAN_TypeDef *CANx);
    ; V1 N# }6 q) c8 d
  106. 0 M8 h" e5 K; c: @8 P
  107. void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));) F& `% ~, p9 P) b: z
  108. void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));: |1 \% ]! d" I7 r3 V5 A% u
  109. ' A' y) H7 S4 z# ^& k2 R* P/ L
  110. uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number);
    * E- m+ [2 c( h1 r* [3 X8 p
  111. uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number);4 i3 C8 p& M* R4 ~8 j+ R
  112. 4 [' A. E. |$ e3 k( v. `
  113. uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx);/ ]5 l/ J6 Q! |0 F
  114. uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx);
    - c% s% u5 t% H3 ^
  115. uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx);$ w) O9 K! ?* Y8 [1 \
  116. uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx);
    : O" Y. [" S# |6 l

  117. + f" X4 n% I5 p' A/ t, r2 A" j9 V7 S
  118. bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx);
    + _- Z' I5 g; b: Y; d3 u% z' a
  119. bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx);: G. u! J/ V$ [3 {1 n
  120. bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx);" P0 h2 i- H. p  \8 E5 z
  121. bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx);- ]! f5 b. A' [% x  E0 U
  122. ! c# z0 N3 I: g6 `) h
  123. void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx);
    $ b5 f* C+ z- [; r' t
  124. void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx);- `6 a5 x2 z5 K# n8 }

  125. ! g3 l4 S% v5 ]
  126. bool CAN_IsTransmitMessage(CAN_TypeDef *CANx);
    * t5 j: \  m" a; }$ |5 ?

  127. 4 q+ e/ U2 V0 y, Q! o, `$ x
  128. /* Function definitions ------------------------------------------------------*/. K5 ^+ v. M! Y, }% x1 r2 V0 S4 }- ~
  129. ' ?+ i' q% }% |! p% `2 d
  130. #ifdef __cplusplus
    ( D: r  ~& f& e! {" }
  131. }" ]4 n* F$ U- [3 J
  132. #endif
    9 E5 s3 g* J! [3 g

  133. & O! G, ~( X) @$ J, z/ ?8 Y
  134. #endif /* __CAN_H */5 ]7 d+ \6 V6 \
复制代码

/ P' _1 O: b' {  V+ N) r+ T! p- j# H% [" a7 `# u- v
) l! l6 i  `, W8 l) d0 ~
CAN.c 文件/ ]- L$ s: m) j& {' Z2 b
5 E. J' h/ _& z3 N' c
  1. /**8 @5 u6 X# R4 y% ~! ^  y& {# k
  2.   ******************************************************************************
    # d1 l) y/ _8 t6 x; c
  3.   * @file    CAN.c. f; k# U. W% \% @# b. A$ D
  4.   * @author  XinLi/ G. M! D5 ?6 ^: S  Z
  5.   * @version v1.0" C) C5 K1 [9 E, U
  6.   * @date    24-June-2018) y  E* p; c( r: Z+ C+ q0 T& N7 ?# s$ m6 x  e
  7.   * @brief   CAN module driver.* O1 d1 t* ^3 j9 H' Q
  8.   ******************************************************************************, L% q* [- x$ X1 b% w- Y$ s$ T* x- s# p
  9.   * @attention. Z* k7 v$ t% g  o, Q8 U2 d8 {' _
  10.   *
    6 A# U9 b, p+ w+ G
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    ) r* |! O4 R$ g2 |2 B- }0 d
  12.   *( J' _( A5 w% ~
  13.   * This program is free software: you can redistribute it and/or modify
    : I8 T* O3 D4 F- J8 I7 S# V# }: [
  14.   * it under the terms of the GNU General Public License as published by& o7 T' d3 w/ F3 R2 P  K; N
  15.   * the Free Software Foundation, either version 3 of the License, or1 x. ]+ K5 S$ {' O2 ^( ^) Y
  16.   * (at your option) any later version.8 Z. V; F% c. F, `3 P8 x/ W: ~
  17.   *+ H( @: n( X/ |5 D5 w
  18.   * This program is distributed in the hope that it will be useful,; E2 ]& l2 x) n/ M" ^
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of6 W% G+ |* Q2 q8 d8 y. S
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the, m- s3 m4 ?' A; L
  21.   * GNU General Public License for more details.
    # c2 z% w: U7 B# L5 ]: O
  22.   *
    9 ~6 D6 l# k1 {2 z2 U, w# V! Q$ [
  23.   * You should have received a copy of the GNU General Public License: a% t# j- V6 z( o  n4 `$ S; |
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>* e2 u, q6 h0 \3 y( p& d
  25.   *
    ! u4 q+ a9 ~0 H
  26.   ******************************************************************************
    ; X, O" m6 p. |" L/ g
  27.   */5 p6 {6 I0 ~) C% u7 ]5 k7 {- r
  28. , J1 T8 C% L. n' s5 U
  29. /* Header includes -----------------------------------------------------------*/
    ) y8 }' t- Z! x) A( N. d; [0 m
  30. #include "CAN.h"$ e* z9 Z2 [7 C+ v# }) ]" X4 f
  31. #include "RingBuffer.h"
    , |) R+ H. w; o7 e7 v( y2 X4 ?2 b

  32. 4 g& l- W4 l( e  ^) x, q
  33. /* Macro definitions ---------------------------------------------------------*/
    6 ~) b+ E' N; I+ \
  34. /* Type definitions ----------------------------------------------------------*/% B, v% _1 Y6 G/ E& Z) r
  35. /* Variable declarations -----------------------------------------------------*/
    / V# D; K6 J# r% I% q0 r( A
  36. static volatile bool can1InitFlag     = false;# q4 p* Q5 S3 s: E9 h: x/ ]
  37. static volatile bool can1TransmitFlag = false;9 ?& S) j+ o4 |2 q5 Z. u, S. C
  38. ( u: [- O( W6 ]2 \5 _
  39. static volatile void (*can1TransmitFinishCallback)(void) = 0;
    7 Y9 g' y" \) C  t, V
  40. static volatile void (*can1ReceiveFinishCallback)(void)  = 0;
    - I- T9 V7 q: I) \. K( U
  41.   R" H4 A1 w$ C8 u/ J$ V, m8 j
  42. static RingBuffer *can1TxBuffer = 0;
    % b  E/ Y# g- E8 ]) K; m- G
  43. static RingBuffer *can1RxBuffer = 0;
    9 y2 W( }5 ?$ |7 I+ _
  44. : c" U& E7 E# |6 l# l1 R$ @7 P" c
  45. #ifdef STM32F10X_CL
    . |' k* h# f  N
  46. static volatile bool can2InitFlag     = false;
    8 z2 r. j' e# a7 |" c3 l; k' O
  47. static volatile bool can2TransmitFlag = false;" P/ S, a+ B: E, R3 p. M7 q

  48. 9 {$ m! _6 r% J$ V+ E3 V
  49. static volatile void (*can2TransmitFinishCallback)(void) = 0;% Z! g) A6 ~/ x" x/ C
  50. static volatile void (*can2ReceiveFinishCallback)(void)  = 0;
    9 S: Q# Q- c2 s. X6 P$ V

  51. * E4 Q# s; T; m: z
  52. static RingBuffer *can2TxBuffer = 0;. T2 Q; p- _! I- Q
  53. static RingBuffer *can2RxBuffer = 0;9 N6 s: d' b4 b4 ~
  54. #endif /* STM32F10X_CL */
    5 r- \! z0 @" G( I+ d
  55. 6 k3 t- w2 j$ N
  56. /* Variable definitions ------------------------------------------------------*/5 n" L" H: Z3 A- o' {( s. z
  57. /* Function declarations -----------------------------------------------------*/
    ) U% X( \- q: N, A9 }4 Q
  58. /* Function definitions ------------------------------------------------------*/
    1 J5 a8 _2 |2 c9 x, {

  59. 3 U+ i% l0 i% P  n+ w' x
  60. /**
    5 m- E6 l- Z- K- Q# B  w1 _
  61.   * @brief  CAN configure.
    . X* Y. f' J6 L2 O* v
  62.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.2 C. a/ O' p' ~
  63.   * @param  [in] WorkMode: Work mode.
    4 g2 o! V9 ^8 o1 p0 g. P# ?* M
  64.   * @param  [in] BaudRate: Communication baud rate.8 O; r7 l# @4 q1 J$ l
  65.   * @param  [in] StdId:    Filter standard frame ID.
    4 d* B& i1 B: _; A& e+ H
  66.   * @param  [in] ExtId:    Filter extended frame ID.. E2 t- ~1 a1 y, c0 h6 {8 h
  67.   * @return None.' m* c% o! H% [7 x( A. x
  68.   */% d7 w; d) Y# T
  69. void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId)9 B& H. s, U8 I5 S- d; w" M+ a+ l& E
  70. {
    , T. x: e: B" ]
  71.   GPIO_InitTypeDef      GPIO_InitStructure      = {0};$ {3 c4 L8 x& E, ]( N: ?  L4 X
  72.   CAN_InitTypeDef       CAN_InitStructure       = {0};, {8 i7 ?* Y4 [3 U3 g
  73.   CAN_FilterInitTypeDef CAN_FilterInitStructure = {0};; M' Y+ P3 g6 n) O/ R$ p8 ]" C
  74.   NVIC_InitTypeDef      NVIC_InitStructure      = {0};
    $ _/ A9 {7 ^1 H+ ?+ ~

  75. . r, B7 G5 n8 z' V: V3 r* c
  76.   if(CANx == CAN1)
    5 M8 w3 G' e8 X0 N2 R1 w) \" {
  77.   {
    6 H) Q# K  Z* j- P; f$ O) X7 Y
  78.     if(can1InitFlag == false)
    : ^2 |. H" n8 b* g7 _
  79.     {) x( I( I% H8 @$ `
  80.       can1InitFlag = true;7 O# B+ P9 q# t+ o3 X
  81. ' Z; x% P, H( o& ^: i9 D
  82.       can1TransmitFlag = false;
    0 Y3 k4 G# m/ f8 h: [7 _
  83. ) G5 [6 Q- ~: d; I% t
  84.       can1TransmitFinishCallback = 0;$ |( S; j" l2 Z: G
  85.       can1ReceiveFinishCallback  = 0;
    ( A$ ]/ X, n- ^2 Z' |- ?3 ?) E
  86. - o( _1 \4 i$ ]6 K/ A1 W
  87.       can1TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN1_TX_BUFFER_SIZE);  y% {2 ^; i& F* M; H/ M9 e' A
  88.       can1RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN1_RX_BUFFER_SIZE);
    * ?2 p( {9 G& C3 I5 B4 Y
  89. 0 A. D% A; x& V, H3 r
  90. #ifdef STM32F10X_CL
    5 I5 S: h$ j1 a9 O. _, W4 v- X; _5 c
  91.       if(can2InitFlag == false)
    + d' L9 E! Z% B
  92. #endif /* STM32F10X_CL */) @; n8 e( M7 A% ?
  93.       {
    + _% n* V5 y. H; j  S
  94.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);) X% h" G! }, W- R0 u' w7 E) z
  95.       }
    ! s* C; v/ `7 }; V
  96. 9 H$ @- l* O9 L  }. D
  97.       RCC_APB2PeriphClockCmd(CAN1_TX_GPIO_CLOCK | CAN1_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);1 r, d1 e& n+ f
  98. 2 ?! d+ I( f3 i) V
  99.       GPIO_InitStructure.GPIO_Pin   = CAN1_TX_GPIO_PIN;
    ( U5 F: |3 |+ i! g
  100.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;+ M( [" J- |% O/ R& R% ^% Q
  101.       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    8 G3 L7 a& E8 c. b$ S7 n
  102.       GPIO_Init(CAN1_TX_GPIO_PORT, &GPIO_InitStructure);
    ; s  Y, H* y( {( p4 m
  103. , \* i' M3 b, h7 }0 q; \9 k
  104.       GPIO_InitStructure.GPIO_Pin   = CAN1_RX_GPIO_PIN;
    . z$ v  D: ?# _' K4 X( Y' M
  105.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
    0 W( A9 t1 d# O4 b/ @  G! Q+ ]
  106.       GPIO_Init(CAN1_RX_GPIO_PORT, &GPIO_InitStructure);$ g  @  p, v" _

  107. 4 \- c! f$ x/ v. u
  108.       CAN1_PORT_REMAP();5 {, p0 j" h2 g( W  X* R) e. z
  109. 5 x" f# T3 ~0 q. ^& P( p: u
  110.       CAN_InitStructure.CAN_Prescaler = BaudRate;
    9 D0 G9 \+ |/ h: r; d5 E
  111.       CAN_InitStructure.CAN_Mode      = WorkMode;
    3 U7 P7 x- f; h1 I4 ]
  112.       CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;6 q& b/ j/ A% O# x& z8 L
  113.       CAN_InitStructure.CAN_BS1       = CAN_BS1_3tq;# S$ M2 ^" g0 i+ m
  114.       CAN_InitStructure.CAN_BS2       = CAN_BS2_2tq;
    / U* M, T% h7 L3 L
  115.       CAN_InitStructure.CAN_TTCM      = DISABLE;( h- Y+ D; f6 q9 Q) C
  116.       CAN_InitStructure.CAN_ABOM      = ENABLE;# B3 h2 G& b5 Z% U& ~
  117.       CAN_InitStructure.CAN_AWUM      = DISABLE;$ C( U( h- Y) K8 c2 A
  118.       CAN_InitStructure.CAN_NART      = ENABLE;
    4 S6 A% h8 U# q/ ]  u3 f% o, e
  119.       CAN_InitStructure.CAN_RFLM      = DISABLE;6 g" a$ S+ |- R- T+ d3 u& K
  120.       CAN_InitStructure.CAN_TXFP      = ENABLE;; b; y6 d1 V8 A

  121. $ z  e+ j, \0 D: q# v/ m0 o
  122.       CAN_DeInit(CAN1);) @; U& X, D4 |, I% `/ Q
  123.       CAN_Init(CAN1, &CAN_InitStructure);
    : ^4 a. R# [9 P6 e$ H" M$ V  x( l
  124. 1 A9 U5 j' ?5 b. y3 t
  125.       CAN_FilterInitStructure.CAN_FilterIdHigh         = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);6 j8 \& V8 ^* B. c9 V
  126.       CAN_FilterInitStructure.CAN_FilterIdLow          = (uint16_t)(((StdId<<18)|ExtId)<<3);
    # F% |- `  e" m) v1 A
  127.       CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;
    # e+ U; Z! u. h7 s$ u
  128.       CAN_FilterInitStructure.CAN_FilterMaskIdLow      = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;
    ( K3 c; N' O4 h- Z8 _; B7 q8 B: l" b
  129.       CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;, q% w) k; E0 c0 {1 e3 m
  130.       CAN_FilterInitStructure.CAN_FilterNumber         = 0;( U$ x" W( |) R% l
  131.       CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask;0 E) i- D' n# w- M) L1 C
  132.       CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit;3 k- J) l8 l' ~( x* n
  133.       CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;. H$ n# Q6 J. p/ U" `& Q0 I- F
  134.       CAN_FilterInit(&CAN_FilterInitStructure);
    1 Y6 N1 x' Z0 e6 a9 ^& j; F1 r& x

  135. $ ~/ r' x8 n- O) ]6 `
  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 |* d8 f+ E" _0 H
  137.                          CAN_IT_WKU | CAN_IT_SLK  |CAN_IT_EWG | CAN_IT_EPV  | CAN_IT_BOF  | CAN_IT_LEC | CAN_IT_ERR, DISABLE);; A- G+ q. n! ^% P8 H- X4 A
  138.       CAN_ITConfig(CAN1, CAN_IT_TME | CAN_IT_FMP0, ENABLE);
    2 t8 i7 d7 s% T* I8 p
  139. 5 S" v( |( N1 D# E+ P
  140. #ifdef STM32F10X_CL
    ; k6 Y, G! A: U9 L2 h
  141.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_TX_IRQn;
    * \! `6 E/ r$ `5 B" n+ o
  142. #else
    1 P# }* s* P5 w8 v) C8 ]- V( i! K
  143.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_HP_CAN1_TX_IRQn;
    ! M3 e$ a, g5 j1 e3 H) H( E9 ^
  144. #endif /* STM32F10X_CL */1 {+ X4 ~) ^' d7 P

  145. $ L: D$ J- S5 x. U+ Q$ v7 K. S9 Y
  146.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;
      K3 |. F- D" r& X# u
  147.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN1_IRQ_SUB_PRIORITY;' z1 z5 b9 z0 k; a% f
  148.       NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    ) O. R0 X& P6 w! A6 a
  149.       NVIC_Init(&NVIC_InitStructure);
    * V! k; R) g% D  A

  150. 1 j3 d) e$ x" K8 Y( _, f+ H
  151. #ifdef STM32F10X_CL
    ( Q. f1 S9 J9 u# N& i
  152.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_RX0_IRQn;. a+ p6 Y; C# d
  153. #else* S/ A' @% M9 O! b
  154.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_LP_CAN1_RX0_IRQn;
    ! p- a% [* P' ~8 w3 f# p& V
  155. #endif /* STM32F10X_CL */
    . ~+ k% L( f; A5 X
  156. & J$ S$ q- T# h; f7 b; v# Y" N+ Z
  157.       NVIC_Init(&NVIC_InitStructure);' a3 S) Y8 A* q9 F2 J0 b
  158.     }
    ( K0 K! G$ {) S. K% h
  159.   }( k. m4 m- N( P' U: N' ?+ p
  160. & }9 j" U8 Q( @' R  z. M; B7 s4 o
  161. #ifdef STM32F10X_CL% }# {) X' S6 h8 B4 k4 M
  162.   if(CANx == CAN2)
    5 b, U. R! j" z3 Y  f1 t, J
  163.   {1 v# J6 G4 Z7 g. H
  164.     if(can2InitFlag == false)
    & Y0 f; g, ]3 r/ R, Y
  165.     {
    ( D; _. y3 |9 ~# v
  166.       can2InitFlag = true;* u4 e* {- ]; `! ?2 ^0 @/ \* r

  167. / z+ w# E' Y" A) _1 L/ i! ^
  168.       can2TransmitFlag = false;5 b) Y" l* R0 r( L, J4 ]' \
  169. - ^2 a) N" \1 ~6 z: b, P
  170.       can2TransmitFinishCallback = 0;
    % U0 R7 a* `3 K4 f% O3 t, ?
  171.       can2ReceiveFinishCallback  = 0;
    / `6 |8 m9 t% i$ _- R5 _

  172. 1 S5 Z* ~- x+ r  h3 G# I
  173.       can2TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN2_TX_BUFFER_SIZE);7 P1 i' \9 G: b! c0 i
  174.       can2RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN2_RX_BUFFER_SIZE);! o2 w0 `8 o7 ?( R0 h/ r

  175. 2 L5 B3 |+ x5 @! J" l  S
  176.       if(can1InitFlag == false)3 ]6 V% {3 r% B8 A
  177.       {
    0 [$ h: p% R/ \3 x
  178.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
    % {% d  G4 ?# y* [8 k
  179.       }
    : e4 _/ c7 ~) g

  180. . C1 G% I2 M* J0 U' {% w$ K; J
  181.       RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);6 ?2 y" j, R6 K) I* M
  182.       RCC_APB2PeriphClockCmd(CAN2_TX_GPIO_CLOCK | CAN2_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);
    ! H. {0 ^+ V, K+ W
  183. ; b8 I  n0 t. u
  184.       GPIO_InitStructure.GPIO_Pin   = CAN2_TX_GPIO_PIN;- U  c2 G& k+ C3 M  @# E: d, g
  185.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    5 O9 C0 B  C, N4 s& G" s, N5 ]
  186.       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    9 B7 J: L+ d) M  }  O$ F1 K: W
  187.       GPIO_Init(CAN2_TX_GPIO_PORT, &GPIO_InitStructure);: _/ I  ?2 F: f) Y" R2 S8 e7 O) v
  188. ( ?2 h: h7 y0 n' R7 O
  189.       GPIO_InitStructure.GPIO_Pin   = CAN2_RX_GPIO_PIN;3 f" @+ ^% T+ W
  190.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;/ v, X5 o3 q% E: [/ ^; V
  191.       GPIO_Init(CAN2_RX_GPIO_PORT, &GPIO_InitStructure);" j1 `( P/ d: i
  192. 6 k/ v+ d; O( @
  193.       CAN2_PORT_REMAP();
    ! G- q0 Z5 ]+ A/ i9 J2 d

  194. 6 f. H' W) y& u# C' G
  195.       CAN_InitStructure.CAN_Prescaler = BaudRate;
    9 w$ q/ `7 V7 I
  196.       CAN_InitStructure.CAN_Mode      = WorkMode;
    / H/ I! l4 {, X0 h: u3 ^- r
  197.       CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;9 f) f, }2 w: P9 y7 k
  198.       CAN_InitStructure.CAN_BS1       = CAN_BS1_3tq;
    ; n2 R7 t  m: M
  199.       CAN_InitStructure.CAN_BS2       = CAN_BS2_2tq;* f$ k& C4 B  o
  200.       CAN_InitStructure.CAN_TTCM      = DISABLE;
    % V1 t  k. v, |! {" Q7 |, n
  201.       CAN_InitStructure.CAN_ABOM      = ENABLE;
    . ?) [% s! n9 {" h  B) q, e
  202.       CAN_InitStructure.CAN_AWUM      = DISABLE;
    # c  B3 H0 F0 l
  203.       CAN_InitStructure.CAN_NART      = ENABLE;
    " @1 I; E0 S* G3 S8 Q) ~
  204.       CAN_InitStructure.CAN_RFLM      = DISABLE;: A) J$ H; {: K' B. s
  205.       CAN_InitStructure.CAN_TXFP      = ENABLE;4 z( g2 J4 o1 s# [

  206. % q( n7 I) _6 V' }& H( ?
  207.       CAN_DeInit(CAN2);
    % N$ N# Q4 c4 q6 D2 k9 _6 Z
  208.       CAN_Init(CAN2, &CAN_InitStructure);- z6 V! o* S7 W) M

  209. . }+ ~. m" s/ G
  210.       CAN_FilterInitStructure.CAN_FilterIdHigh         = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);
    9 B2 J  H1 C6 R- Z1 r% r, [
  211.       CAN_FilterInitStructure.CAN_FilterIdLow          = (uint16_t)(((StdId<<18)|ExtId)<<3);
    2 h- N. X6 Q' `1 a2 u0 H
  212.       CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;
    ' ], O5 |! Y6 ~6 k/ C* K) j9 J
  213.       CAN_FilterInitStructure.CAN_FilterMaskIdLow      = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;. b/ C. a$ i" V# _% n2 }
  214.       CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
    2 M9 N! y% y) J
  215.       CAN_FilterInitStructure.CAN_FilterNumber         = 14;0 M$ r; y; T- W( r8 v2 H. ^$ @
  216.       CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask;! i" D% x/ d6 }/ @
  217.       CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit;
    * P6 K; f( ]0 ~; [; z5 a
  218.       CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;
    ; B) {( P5 U! J+ ]; R4 t
  219.       CAN_FilterInit(&CAN_FilterInitStructure);
    4 ~5 @0 @5 H5 K- I4 v" I1 b' `
  220. 9 C/ e, p" b8 O- @& 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 |
    6 }: N; ~2 {/ c5 Q, r; v
  222.                          CAN_IT_WKU | CAN_IT_SLK  |CAN_IT_EWG | CAN_IT_EPV  | CAN_IT_BOF  | CAN_IT_LEC | CAN_IT_ERR, DISABLE);% _: R: D. d$ o2 v7 ?
  223.       CAN_ITConfig(CAN2, CAN_IT_TME | CAN_IT_FMP0, ENABLE);6 X% l( x) i5 v

  224. , q& n" j& A  c# a# G4 ~' }
  225.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_TX_IRQn;$ I, L* b' v0 N2 j8 F) I( O# m. r
  226.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;) U1 c5 O  C) V% l  k
  227.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN2_IRQ_SUB_PRIORITY;: A4 A/ v+ _! W+ ~8 I9 F5 T
  228.       NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    ( \) {  D0 K% e
  229.       NVIC_Init(&NVIC_InitStructure);; @* `& n4 P+ p( Z! o. S3 y

  230. ) I, A) q* u. m9 q. f* n% M' J  q; V
  231.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_RX0_IRQn;3 w! x; ~0 o3 ?4 X
  232.       NVIC_Init(&NVIC_InitStructure);+ `8 g+ o) K5 J& C( `
  233.     }
    0 f9 t; D/ t* ^6 G/ ~
  234.   }6 ?1 F2 ?9 A8 f: i
  235. #endif /* STM32F10X_CL */
    0 z7 ^9 w0 O! T- U4 b- N
  236. }" D0 ]* G' c2 y* D# F8 ^8 J

  237. 2 U" |7 n9 c5 E2 b% [
  238. /**) }+ z5 [6 Q: C* i- w( h; n
  239.   * @brief  CAN unconfigure.
    8 U; [' U, G$ j
  240.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.! s7 x; e  _: z/ R- i
  241.   * @return None.' V# W0 x0 ^+ V
  242.   */
    " `! M' b& m* {( O( G' }
  243. void CAN_Unconfigure(CAN_TypeDef *CANx)$ v/ b! }& ~, w( A
  244. {
    8 ~2 m7 w9 y6 E$ M6 J
  245.   NVIC_InitTypeDef NVIC_InitStructure = {0};( \3 J7 L; Y$ j8 `8 i/ |3 }0 @1 w! e0 H

  246. 1 k% M* B! X* }: T
  247.   if(CANx == CAN1)0 p$ X) T4 a( D' M) X
  248.   {
    9 l4 E6 _& z$ g  R; H
  249.     if(can1InitFlag == true)
    ' ~% Q4 C0 ]5 k$ K& R
  250.     {
    7 F* h' I  g3 P+ x: T' g
  251.       can1InitFlag = false;
    % w3 q7 }3 x) B% o! v& y* S' q
  252. 6 B7 `1 W% e' O
  253. #ifdef STM32F10X_CL0 U) b1 N9 g1 }) r) Z
  254.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_TX_IRQn;
    ) B5 K% m) L8 H' J! u$ c0 B3 H
  255. #else1 ^% F6 f: G  m1 F0 `9 R
  256.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_HP_CAN1_TX_IRQn;
    0 l: W$ @! B4 Z  J
  257. #endif /* STM32F10X_CL */  M2 |8 X: e8 I7 ~+ K
  258. " j# W# G' i# e
  259.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;$ P0 C! o) d8 n
  260.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN1_IRQ_SUB_PRIORITY;
    : k# l. R& S& ]! v/ [* ]
  261.       NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;
    , ~3 s6 R  Y$ ?- z
  262.       NVIC_Init(&NVIC_InitStructure);
    # {* Y$ ]0 w2 Z- u+ _4 O) T3 J& g! |

  263. ! b- ]: l( K( K0 {0 X! c8 j7 ^& ^
  264. #ifdef STM32F10X_CL
    5 N( |* p# B( u, T# a
  265.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_RX0_IRQn;
    / }# T# a$ w% I! D
  266. #else4 f" m3 h" k. n3 n8 k1 u4 @$ T  f( r0 Q
  267.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_LP_CAN1_RX0_IRQn;/ l1 g+ C/ i0 B$ P" O, i
  268. #endif /* STM32F10X_CL */0 I4 O7 d+ H5 m  z9 y2 M- ^, F1 Z! a
  269. 5 `/ n4 j: A3 [2 d& O& p# z- H. p' z
  270.       NVIC_Init(&NVIC_InitStructure);  Q* X% f) W1 ?* N& a- V) y# K* }+ L
  271. - h& v0 Q' G: Q, i) n
  272.       CAN_DeInit(CAN1);
    9 J' n: o7 a4 n7 X( E

  273. 5 t: C& m9 {2 ~9 |* G5 V% F+ A
  274. #ifdef STM32F10X_CL
    " J$ w* ?- W; `1 E7 b
  275.       if(can2InitFlag == false)
      ~: m% N. b1 F- ^2 }5 g  B: c
  276. #endif /* STM32F10X_CL */" O( m8 |( a# q7 I' _* c( {
  277.       {9 `; p7 z* T8 U- K, O( b, U& w
  278.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);7 j% E5 E* }  ?: d: @
  279.       }- i/ J* p& X1 A8 Z0 i& C* }! z

  280. 9 W' m" m4 N* r* Z6 M' c
  281.       can1TransmitFlag = false;* O0 R+ L8 E. M4 s4 C: D
  282. 4 G5 Z- v5 J: s' V1 h, m
  283.       can1TransmitFinishCallback = 0;
    , b( `' m/ R4 o7 U8 B( X1 B- P( p
  284.       can1ReceiveFinishCallback  = 0;
    4 ?8 C8 c( Q  C, q9 x/ l

  285. 2 Z( ]: k3 ]2 l- K/ I8 u4 i
  286.       RingBuffer_Free(can1TxBuffer);
    9 Y  _/ A( T$ X: }
  287.       RingBuffer_Free(can1RxBuffer);9 K2 s2 l1 r& u2 b
  288.     }& S4 ?! Q# H5 C( ~1 V/ w  o( N
  289.   }& N! m2 T- r8 W  Q
  290. * y. h4 G7 _. d! a
  291. #ifdef STM32F10X_CL
      s: r4 _1 D. H  P& [# Q
  292.   if(CANx == CAN2)
    ; F! @. B! N, y( C9 H8 e7 l
  293.   {9 q, z. ?8 w8 P
  294.     if(can2InitFlag == true)
    3 Q( ?& P. |! z7 N+ q; S" J
  295.     {
    0 z6 W1 k7 }9 p: v3 X. }% u
  296.       can2InitFlag = false;
    - Z) L7 w: G* W

  297. - \6 j+ B/ N: B/ C
  298.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_TX_IRQn;
    ( a3 }9 }' F+ e2 b9 ]% x+ u
  299.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;
    , `; N& I' R: _  M# L  p- y- ?* ^: ?
  300.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN2_IRQ_SUB_PRIORITY;
    - G8 a3 w7 U& u3 z7 p
  301.       NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;
    , |$ I: r& n8 ^8 B" q0 o7 a
  302.       NVIC_Init(&NVIC_InitStructure);/ b4 F; i* v5 z7 m3 J- {9 h! ]

  303. ; Q7 h8 i0 [3 W8 g7 [% q' T
  304.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_RX0_IRQn;
    , I5 H, H0 a1 Z. q- a! }' o
  305.       NVIC_Init(&NVIC_InitStructure);# ~: K9 d. y' M0 J8 t. [% D& |. G
  306. $ A+ q6 C/ O5 Z5 P6 g8 q7 K
  307.       CAN_DeInit(CAN2);
    6 @; T$ K+ q, u' f0 u6 {
  308. - m7 u; k# V) G+ {+ I! n
  309.       if(can1InitFlag == false)% E; _8 o) {  N+ ?( _; \
  310.       {; q, N; V: {) M/ q  r% ^" ~
  311.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);. y5 c* t4 Y; S- W2 r3 G, l
  312.       }
    6 c9 n' \6 e6 T4 H5 |  x, C. K+ u6 ]
  313. # T9 H" }$ `0 H# D  n
  314.       RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, DISABLE);, g) e4 G& i3 r
  315. 5 [/ h1 D' Z/ _6 o' ~7 ?) x
  316.       can2TransmitFlag = false;& Y) L# P0 _( p, m, A

  317. " U& h# k0 W7 w4 u) Y  G; U
  318.       can2TransmitFinishCallback = 0;
    . F7 C  ^( C2 |$ f/ U3 G+ m
  319.       can2ReceiveFinishCallback  = 0;
    4 @. l; R, e7 B
  320. , M" H' Q3 m7 v2 N: f
  321.       RingBuffer_Free(can2TxBuffer);
    0 M' \9 o- S8 p# Q0 E- ^; p
  322.       RingBuffer_Free(can2RxBuffer);
    & ]. j+ y9 d3 D1 Y7 a5 w
  323.     }: B* P1 x) l: ~  b- `9 c- m% ^0 u
  324.   }
    8 z3 z4 m3 @% D( D
  325. #endif /* STM32F10X_CL */
    : z; S2 i( |! E" J8 O) w3 G
  326. }4 n2 V1 l# T* v4 Q; n8 E

  327. 4 k8 W, T) R- M, U1 H# M) M
  328. /**3 W2 V9 ?+ W  |, W
  329.   * @brief  CAN set transmit finish callback.
    0 w, U9 u% m+ w: K3 q
  330.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.# A/ n; l$ L3 v5 Z. a% e: G2 u
  331.   * @param  [in] Callback: Callback.
    ) g8 W$ P" q' g2 i* d
  332.   * @return None.. M$ F3 X: t' J& ^' {
  333.   */
    0 r2 ]8 [3 [" o- j+ \
  334. void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void)): f7 v- r5 p$ B4 s$ J
  335. {
    2 w2 P; G  Y* H( W2 t
  336.   if(CANx == CAN1)( e" G4 A: k) G- A1 |" O  c% U+ A
  337.   {
    7 Y' X) O$ M; `: T# w
  338.     if(can1InitFlag == true)
    7 \% F0 [/ Q! ^* m) \$ J- d
  339.     {
    9 M0 @  i! h$ c: [0 w3 x* n
  340.       can1TransmitFinishCallback = (volatile void (*)(void))Callback;
    ! }! S& {  ~% H+ v+ k! w
  341.     }
    ) l* |" b4 g( I: A/ k- x
  342.   }
    % i# D# h/ d. X" R0 l

  343. / b$ M  r& q( F7 \" k# x
  344. #ifdef STM32F10X_CL
    $ C: O/ L* C7 S+ z( X
  345.   if(CANx == CAN2)
    / t; d' z" U% G( X5 q  v1 ?
  346.   {( j6 o- G- S, h% O: F+ j! x) {! f
  347.     if(can2InitFlag == true)2 U$ d, c6 x! [. a
  348.     {2 k' O, y+ C$ ~% ]) [
  349.       can2TransmitFinishCallback = (volatile void (*)(void))Callback;
    # o( Y  h  q4 J. q  ?% V+ Q6 h
  350.     }& i) ]! t* P4 @1 K1 O: `
  351.   }8 ~8 t  y3 F9 P5 B1 M) P* a  y
  352. #endif /* STM32F10X_CL */
    5 M! u$ Z2 M$ ]8 u% j: L
  353. }
      B* ~, P- O9 T7 L4 l

  354. 0 o" K. t. {. _# I
  355. /**
    % f3 T& U3 r& e# X
  356.   * @brief  CAN set receive finish callback.
    : N) D% I4 T: ~. b+ o  [
  357.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.
    9 L5 @# {, s8 y! |
  358.   * @param  [in] Callback: Callback.* Z3 J7 z8 S9 X2 [0 O. N  G: S
  359.   * @return None.+ k, Q/ ~# j- n* f
  360.   */
    1 w2 ?) B" x4 {" i0 k
  361. void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void))* R9 Q3 t- v9 {6 f8 m3 E+ |
  362. {. }! ?- B4 ^; A# b
  363.   if(CANx == CAN1)
    9 p" V: k- ~9 A
  364.   {
    + Y4 T) e8 x* y- d" c
  365.     if(can1InitFlag == true)1 J) b2 E! U  m: H
  366.     {1 m( _/ ?1 b; J- @4 T  `
  367.       can1ReceiveFinishCallback = (volatile void (*)(void))Callback;
    & ^/ V7 e+ J( r; F7 s, P7 ~: z
  368.     }
    ( ^* F' o$ m; ^) y
  369.   }
    + R9 w! x8 o' [

  370. $ d4 y4 b4 N: S  n
  371. #ifdef STM32F10X_CL
    : r1 Y3 @. M' n
  372.   if(CANx == CAN2)
    / W/ Z  u. T# l& R" P1 W! }$ f
  373.   {/ j" h6 D- K) J4 E) x* ?4 _
  374.     if(can2InitFlag == true)
    ; j! n1 o. N" ~3 r4 U6 b% {
  375.     {; C3 F# m. \- v% ?) p
  376.       can2ReceiveFinishCallback = (volatile void (*)(void))Callback;" U; i. t- q! ~  {$ h
  377.     }1 O$ g: a% G6 ^
  378.   }
    6 t5 S  U4 D% Z; V- Y
  379. #endif /* STM32F10X_CL */
    . o. j7 y" A: Q
  380. }6 ]5 A1 H2 X6 m( r& o$ Z
  381. $ v. C5 d2 N6 ^8 @
  382. /**# n& `- ~* n3 B
  383.   * @brief  CAN set transmit message.
      u. F' i3 ?" _# H7 a1 f
  384.   * @param  [in] CANx:    Where x can be 1 or 2 to select the CAN peripheral.
    - v. N1 h, S% {  a$ E! j) {
  385.   * @param  [in] Message: The address of the message to be transmit.
    . ^" _4 q; \( D# j! T: y& q
  386.   * @param  [in] Number:  The number of the message to be transmit.$ E( i% _# r/ }
  387.   * @return The number of message transmit.
    3 @6 b# w( \; g: ^! [8 T4 G7 O
  388.   */
    / z; y/ z' n, O* y4 F
  389. uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number)
    ! h! j4 n; m  _& H$ g/ s. i  X
  390. {
    * T. Z/ R. m# r. |+ U
  391.   if(CANx == CAN1)' J9 Z* @2 O+ `5 O4 L
  392.   {
    , r: r+ p& S  H8 d1 r5 V8 ?
  393.     if(can1InitFlag == true)
    + Y; z2 h+ \7 f4 g/ ~: m- Z
  394.     {3 `% K1 {7 }2 F0 b
  395.       uint32_t available = RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);: Z  n# @) h7 o- d

  396. 5 d1 v: u# V/ F
  397.       if(available > Number)) J- ~3 X1 M! D' s' b1 x
  398.       {) y! l$ e, e5 O5 L) N
  399.         Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);9 f5 j) ~) M0 M$ j
  400.       }$ b& C1 B: |/ a6 c% u- R
  401.       else3 v9 s* T& ]* o
  402.       {6 ^" Q8 Z' u8 A, K6 L
  403.         Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);( N/ m5 O4 \% X+ A0 s" `6 W
  404.       }
    / F1 L5 _3 t: B! U+ a
  405. 8 p% Z5 E: W- x- e6 D3 Z
  406.       if(Number > 0)
    # `' s; `) v( d# Y. M8 a6 C
  407.       {1 |9 t6 y6 R7 Y% C' x
  408.         if(can1TransmitFlag == false)
    6 \5 t" F0 v- @6 @2 v  ~* v3 _
  409.         {
    0 g( d7 N8 F: l" t3 h! }
  410.           can1TransmitFlag = true;
    - s) y3 w. U7 L0 g; j0 W% H* C

  411.   T  V" a8 h2 t1 B% k
  412.           CanTxMsg canTxMsg = {0};
    ! p- `! Y9 k9 g- d) J3 a3 t! U
  413.           RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg));) J% @3 ~1 i" N
  414.           CAN_Transmit(CAN1, &canTxMsg);
    9 U  J$ F; j& t+ H! w3 G
  415.         }
    $ a; p  Q' q: Z' b: ^7 U' e
  416.       }
    ; G$ M0 i0 L& w: ^* |
  417.   L( a2 Q9 e) q
  418.       return Number;
    ) u' M' \( j/ O, T1 q
  419.     }
    - S7 ~$ g+ _; _
  420.   }
    $ d- x8 y! n* ~) J3 ]- z

  421. 3 j" J1 r) R: E) j# y
  422. #ifdef STM32F10X_CL& }; n2 V* @- V9 e. H
  423.   if(CANx == CAN2)- g) D. \3 E. W: p
  424.   {
    , M2 T4 i' L3 _: l* |. O$ v
  425.     if(can2InitFlag == true)
    7 o( u3 ^' _" [) T- B/ @
  426.     {
    / k" w" T( U, H4 s( U0 P
  427.       uint32_t available = RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);
    3 p* q4 K: j8 Q8 n
  428. 2 v* S3 w8 r; k4 J. o! N2 b0 x
  429.       if(available > Number)
    ; h  F1 c3 ]4 m8 e) r
  430.       {, N% b5 B2 U4 f% O: v* l
  431.         Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);0 ?, Z; k3 F9 u/ e* R' Z5 h/ H
  432.       }/ R. B( `4 _( D2 ]" c$ s; R
  433.       else$ w+ Q' \1 `* v! c& u5 A" i
  434.       {
    ! C; H6 b2 r6 C/ ?
  435.         Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);0 I- E  H( K2 c$ p
  436.       }( ~1 `, y; R1 L8 W, B

  437. ! K& @- c+ f7 o" g6 j
  438.       if(Number > 0)
    4 S" B/ [% I: ~# b* H
  439.       {$ a# Y: D. i& Y/ g, q/ |8 ]
  440.         if(can2TransmitFlag == false)
    / z& R8 Q3 f: T+ C. ~1 |& ~  P
  441.         {- ?  D4 y0 F' J$ \; |0 {
  442.           can2TransmitFlag = true;
    1 B* Z& x3 n8 }( O! O$ s7 n% K

  443. 1 e$ Q! Z/ j. k- I1 D. ?/ u
  444.           CanTxMsg canTxMsg = {0};8 u/ r5 o! E, Q3 v
  445.           RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg));( ~% F0 m+ H( H4 Y9 P7 O' L
  446.           CAN_Transmit(CAN2, &canTxMsg);
    8 O: J& [" d& i. B# m# i
  447.         }) \" R6 k& O  D0 M, i
  448.       }
    " ~4 [1 x5 Y4 y: X7 I% t

  449. 6 ?3 j. }# K' w
  450.       return Number;
    ! z( N" w& K$ ~0 x  {) D
  451.     }
    4 ]5 E' [7 J% i9 s) b
  452.   }
    8 s! q$ g! W+ I+ ^' c. _) |
  453. #endif /* STM32F10X_CL */
    4 [1 {& e6 _1 _
  454. - z" `, }, g4 J  ?9 X! Y; S7 o
  455.   return 0;4 j' \( M5 N, K- u
  456. }- z: c2 ]! }7 m3 Y( [
  457. : j/ c3 r* ]2 l8 _( y7 H( T5 n
  458. /**
    ; C9 h3 l( B, R' y, U
  459.   * @brief  CAN get receive message.
    " `3 t9 ^! r7 }2 I! m
  460.   * @param  [in] CANx:    Where x can be 1 or 2 to select the CAN peripheral.
    : M( c8 v% s$ v0 w. w& W; q
  461.   * @param  [in] Message: To store the address of the receive message.
    : T: Q  k0 ]# m, M" A2 P2 O) j( T
  462.   * @param  [in] Number:  To read the number of the received message.- A0 j! {. J$ k2 h2 ~* W
  463.   * @return The number of message obtained.0 n( Q7 r! V% N2 \
  464.   */4 ?3 G9 l4 ^) }' H. a
  465. uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number)) Y9 B* w3 A: `# v+ H
  466. {# R" t' r; }' C' w1 H! N; i& h' n
  467.   if(CANx == CAN1)% f3 A6 i; r# i  K) ]: E
  468.   {
    ' o( A7 x' T- \3 h
  469.     if(can1InitFlag == true)0 \: V3 i: f3 i$ k
  470.     {
    # |% ]) `$ d9 i% K5 y
  471.       return RingBuffer_Out(can1RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);
    ; B/ @/ V8 D' M. t' [* I4 K
  472.     }! |# t; g2 @- _
  473.   }% ^, Y& _4 g1 P9 O; S; t

  474. ( y; ^& j& z' Z& c
  475. #ifdef STM32F10X_CL/ k7 q' |3 O3 N2 f
  476.   if(CANx == CAN2)
    ' v! L- r) ^2 g
  477.   {
    - T' X& T+ i" q: T, u8 `
  478.     if(can2InitFlag == true)
    # T3 L/ J) N# Y- N, }9 t
  479.     {
    1 p9 b4 F0 Q/ Q. ~; Q; M, v% n
  480.       return RingBuffer_Out(can2RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);4 D; J- ^  p) z: \6 U
  481.     }
    5 O6 Y  _  R1 D" ?! V' I
  482.   }  W" y% @# c% m4 z' [
  483. #endif /* STM32F10X_CL */9 `* _3 J& ~; R

  484. 2 C( C8 b2 e& D- q# A7 v
  485.   return 0;
    : r5 e. K+ `4 A9 U, C
  486. }
    5 H; H# \# m0 a0 r0 \

  487. 1 g3 ^6 m& P0 Y  Z+ q, j
  488. /**8 A) M& n2 c1 W+ c
  489.   * @brief  Get the size of the CAN transmit buffer used.
    2 w& P" A. F- a  F
  490.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.5 f; z5 X# s- {4 V7 o3 U
  491.   * @return Used the size of the transmit buffer.( _5 W7 z) [8 D, B  s0 W& L# a
  492.   */
    6 M9 n' ]5 p6 Q; K
  493. uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx): h. v. ^) W1 u2 J& ~1 b. q
  494. {
    * N5 p; [3 L& u/ w
  495.   if(CANx == CAN1)
    6 {, B: a$ ?/ V
  496.   {( j) v& @  r9 h" [& q
  497.     if(can1InitFlag == true)
      r8 }/ H+ f  b" H6 a  u
  498.     {
    7 G' T5 H8 Z- H! {0 Z/ C7 o* v
  499.       return RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg);
    0 n# N( C1 P& Z3 ^! Z3 f3 o
  500.     }
    * M/ i% f1 e! B4 C0 V5 g0 k
  501.   }
    9 L0 z( y. Z1 H3 c5 p% v. n# \% G

  502. 7 u; C* G3 [! {
  503. #ifdef STM32F10X_CL0 S" x5 U: \0 Z( y$ h. E. {
  504.   if(CANx == CAN2)+ Y' g+ H; R, J, k# B9 Y3 x( r
  505.   {
    ! ^3 g# K- I5 l. W% h. y4 _5 Y
  506.     if(can2InitFlag == true)
    4 K) G, k9 n' q3 Z  t
  507.     {, i0 T  H* K' d" D6 h2 o+ {  f
  508.       return RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg);
      N6 v, L0 s3 @/ S& x' h, r
  509.     }8 v/ u3 K+ H4 e- E3 Y. D4 ^
  510.   }& I" T" U' M( l3 n/ d& `
  511. #endif /* STM32F10X_CL */
    7 ^3 o+ V' g6 ^- G7 r
  512. * Q9 I4 c  e" l9 j
  513.   return 0;7 n  {5 @& u8 Z! q2 h* f! x& o' g
  514. }# m, t- x3 \2 Y2 v

  515. % T4 f' v% L) b& i% N
  516. /**
    1 I3 {  R& v! x" ?- e  Q$ O
  517.   * @brief  Get the size of the CAN receive buffer used.: ]% P* E. D: j9 Y; C, M
  518.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    , V7 N  T8 H8 o- n+ E# i
  519.   * @return Used the size of the receive buffer.2 H9 l& [# w) i# A0 B: L
  520.   */
    " n2 ^3 u# t! W( L6 b
  521. uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx)% V0 E* D! ]- _# L: Q7 m2 s+ w  D
  522. {
    $ J% V4 Z& v: ^2 P
  523.   if(CANx == CAN1)
    7 ?/ x- P+ {9 Q* k$ n
  524.   {# Q: _$ @) A/ f: P0 H- e2 }! [
  525.     if(can1InitFlag == true)
    4 @* ?" l0 ]2 Z9 E5 V
  526.     {  c; g1 g8 `5 z7 G5 x
  527.       return RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg);; W4 C) f) R; k9 ^5 f' `6 N
  528.     }
    2 ^; r- E, y% y! |* W8 e0 A( y
  529.   }
    : T' R7 h2 k8 K: I8 _2 j8 P' W
  530. 8 F) Y1 o! k5 p- T6 O! x& E
  531. #ifdef STM32F10X_CL
    : o7 _# X2 [( W  A7 F
  532.   if(CANx == CAN2)
    # W8 Z) Y- ~: _5 a6 ]# T7 l! ^/ W; c1 M" E
  533.   {& @3 W% O( g+ |5 T- c0 B
  534.     if(can2InitFlag == true)
    # X! m5 I+ ^7 ^
  535.     {
    # A; x, ]# b2 P# X$ n7 c
  536.       return RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg);
    : r8 `& }* b* s$ {0 T% k# z
  537.     }
    & ?6 `) O/ v  |9 h3 \9 K& _2 q
  538.   }2 M1 O$ Q  u& C, c% P' H
  539. #endif /* STM32F10X_CL */2 Z' e3 r! h' [6 }- P
  540. 5 {% u: H7 m) e4 ?, I/ ^
  541.   return 0;
    : t* l3 B& d# A0 a8 r
  542. }# q; L$ Z, g9 {

  543. : \5 i; A/ N7 n$ t
  544. /**
    + j) ~6 N$ l& W/ u
  545.   * @brief  Get the size of the CAN transmit buffer unused.- a+ ?+ y  H+ Y, H0 l1 S
  546.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    3 W$ Y! d3 Q. T. A  }
  547.   * @return Unused the size of the transmit buffer.+ f7 o  K9 T3 R# U' A6 F
  548.   */( t0 I: G9 z" }  s# ?8 ~
  549. uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx)
    ' _) V( x) d& W0 r; c1 A
  550. {  b4 `' V5 r0 U% ^
  551.   if(CANx == CAN1)
    8 A$ P# _4 a* N8 H8 N* `+ r% R
  552.   {& O* ~  }+ V$ a9 ~/ S9 V
  553.     if(can1InitFlag == true)
    2 v. A7 Y9 \4 V: Z; c% ?0 f! h
  554.     {6 u9 `) d7 [) F( t: @" L- U
  555.       return RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);
    " y; p  A/ ]) i; s' p
  556.     }
    , a2 u% X, f) Z4 V+ C- h1 g
  557.   }
    3 q% B1 l, r; r# I* {$ h
  558. ! E9 [# {5 _& J! k7 t8 N5 R/ \
  559. #ifdef STM32F10X_CL  V7 K- O! |* G, s) _3 |6 W+ r' l
  560.   if(CANx == CAN2)
    3 {2 E2 V( K, W/ n- A& r( g1 N
  561.   {
    & l' q7 U' g5 Z) l  z5 E5 r
  562.     if(can2InitFlag == true)
    + P0 f  x/ Q, x8 o
  563.     {" P: R! h+ J5 A$ [
  564.       return RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);2 d8 K( o0 W+ J# r
  565.     }0 u" H9 w5 e; ~: i3 ^
  566.   }( c; Z  r& w7 t, @4 N: W  u3 A
  567. #endif /* STM32F10X_CL */( L1 F7 Y8 [  w3 i0 E; k7 f3 O& \

  568. / c# h" z! u( b$ }
  569.   return 0;
    . X! Y+ C$ \5 d- \2 ?3 H# h
  570. }
    & D( d6 m) T, x( F
  571. " z! w9 m( w3 o1 p
  572. /**
    9 [+ M% e* |8 H! T  n# a6 A: x
  573.   * @brief  Get the size of the CAN receive buffer unused.
    2 R7 H/ d. w3 y* s' u; p" o6 z
  574.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    # N3 _% I# f  w* c  `9 ~
  575.   * @return Unused the size of the receive buffer.0 A6 h9 W! N# I
  576.   */  T' M+ Z" p: ?
  577. uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx): ]; S2 k% o+ @% s) P% ~( d$ e
  578. {9 [" o+ C8 W+ `1 ]
  579.   if(CANx == CAN1)- d0 \. p) [) d. T) Z
  580.   {! ~+ f) W% k! i9 b' Z, H4 I# Y
  581.     if(can1InitFlag == true)' j( U7 T: Z% Q6 X- x4 Y: S: x' v0 B
  582.     {3 y  M2 z0 j& A
  583.       return RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg);. _: @* j* r" X
  584.     }) V  d9 e7 G- K% w; e! I
  585.   }
    2 n# J7 f- N. V0 j8 n, r

  586. - P, Z8 p8 {9 \7 \9 j
  587. #ifdef STM32F10X_CL
    8 w7 l5 v/ E3 X% Z; o
  588.   if(CANx == CAN2)
    ) C& O) H" j. }: u. z
  589.   {2 x# o" q- }- Y* P
  590.     if(can2InitFlag == true)
    / K' Q' b" T) }8 `4 y
  591.     {* |# m' @/ s% j& w
  592.       return RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg);
    , j' Q' U) ?1 L) d0 t; h
  593.     }
    ' f% Q9 G9 k- c
  594.   }; |  v( G+ S' M+ a8 n- e
  595. #endif /* STM32F10X_CL */
    7 a2 f4 z" D* n* O; y; D* Z
  596. 8 S) W9 m( [& T0 |7 q7 }
  597.   return 0;- {, p2 W1 m6 K7 N/ z( v! Y, Q
  598. }; ]' q% B- b9 G( i/ C
  599. 9 c( b" X- S" Y. u+ c  ^% C
  600. /**
    ; f- K1 z$ J. o% T) Z) v% @
  601.   * @brief  Is the CAN transmit buffer empty?
    7 {. W: r) E/ ?; i
  602.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    / {3 m) X+ I0 c4 s9 c
  603.   * @retval true:      The transmit buffer is empty.
    + h- {% c$ ?: G) C+ r
  604.   * @retval false:     The transmit buffer is not empty.
    # M: g* ^! K: Q/ u
  605.   */4 E. Q6 |2 O- K$ B; i
  606. bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx)
    . E8 T  v" {7 Y1 _; `0 ^! Z
  607. {
      t* X" g: D3 D9 Q1 T1 U- N1 N
  608.   if(CANx == CAN1)
    7 `  F+ e: u. ]1 X; s% w, k9 D
  609.   {' l! v9 [) P  J* t' E
  610.     if(can1InitFlag == true)0 o* q/ m  Y- c' |
  611.     {
    ' |' L7 q; B1 F1 o/ }6 Q. B) }
  612.       return !(RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg));7 y# A. p1 o& g0 r
  613.     }5 d. t* H. {% g
  614.   }
    ; b% d+ ~: T; v' U  O. u9 u- ]

  615. 3 T! G+ M7 E6 I# t
  616. #ifdef STM32F10X_CL
    / n" g$ l% i& v4 F+ r
  617.   if(CANx == CAN2)- ]" Z9 ]* L) K2 {$ J4 x& o3 S
  618.   {
    , G9 H; x3 M, n/ A
  619.     if(can2InitFlag == true)
    7 w% B9 ~7 [0 u$ J5 Q! \8 z
  620.     {
    # k( N$ [/ [% M+ P
  621.       return !(RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg));
    * {) U' ?7 R# l
  622.     }7 P7 Y% `) Q( q5 D: F
  623.   }
    5 m: Y+ @" \3 r& B( o
  624. #endif /* STM32F10X_CL */  O1 f7 {1 S, R) D
  625. " T' T1 r* o9 t: t1 B
  626.   return false;
    # L+ A! }( r" A7 k- C: }+ |
  627. }
    1 z3 _  p' N7 c1 y6 p( q" q
  628. " h* V. y* {/ \' C: u
  629. /**
    2 X- G) M& A; r* N: m6 V% O
  630.   * @brief  Is the CAN receive buffer empty?( K, U! G5 ~( v
  631.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.' w1 ^8 {" @( J
  632.   * @retval true:      The receive buffer is empty.& j) R$ K9 S9 L4 X4 g
  633.   * @retval false:     The receive buffer is not empty.7 f5 o& f6 ?: H/ f/ W) m
  634.   */+ O# }5 M2 Z. F5 s
  635. bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx)
    6 u0 J5 w* ^6 t) \9 M  w6 f) R
  636. {$ _3 E. E3 r" |+ E& J" d; L
  637.   if(CANx == CAN1)
    8 T) `- v+ }) D# y
  638.   {7 w. q( \+ E" `& `5 {9 H/ P; o+ f) q
  639.     if(can1InitFlag == true)
    - P% A4 a8 t& R/ O2 s. I4 ?* j4 H
  640.     {' \& f- Y3 i& B( a- z8 m
  641.       return !(RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg));
    & \+ I1 _) v9 a4 k7 v( _* J% \
  642.     }
    # f) a  w& ~7 F9 u
  643.   }! E! O2 C+ k/ M" Z% L, u* ^

  644. - T7 D, q4 C- Y% ~1 i. J
  645. #ifdef STM32F10X_CL
    * |  h# w! l( M2 e
  646.   if(CANx == CAN2)
    5 y* O  |" D1 Q  l+ R& O2 z
  647.   {
    ) O' o9 v2 e: o% E# l
  648.     if(can2InitFlag == true)
    , E' h) u/ Q* p% G
  649.     {
    . J1 Q* ^2 G, Y/ v' j# ~8 b
  650.       return !(RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg));1 K; i  h) `7 F1 Q
  651.     }
    # A  }7 ~' _* L6 G# \
  652.   }* _+ i/ I' O6 E" l; O4 x2 n
  653. #endif /* STM32F10X_CL */9 N$ f6 i/ ]7 i+ R
  654. * ]! h6 O: U" F$ S7 B" u
  655.   return false;
    6 V: A  Q$ L0 J: s. @) z2 B" q
  656. }, r: K* o2 `4 s$ @( [
  657. 9 M& a# ]) N% v
  658. /**
    ( a9 C7 j- e  F" H" K
  659.   * @brief  Is the CAN transmit buffer full?; t0 ~! l( M+ ~# P
  660.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    ; R* v; |( w7 Y- `" W7 E' Q2 Y" S/ S
  661.   * @retval true:      The transmit buffer is full.8 U0 Z( a- |6 P& G
  662.   * @retval false:     The transmit buffer is not full.
    / e1 s' h" v% v- k" \
  663.   */( g* F+ Y- v) o' @
  664. bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx)
    # r+ s; Z9 ^% [* U& ^
  665. {, N9 t7 U% J7 Y% q3 x# {& U
  666.   if(CANx == CAN1)/ T# c  G. A& G/ E: J  {- Q
  667.   {
    : H1 }, B1 N" D, Z
  668.     if(can1InitFlag == true): Y4 W+ X$ r+ P3 `. b; g. W
  669.     {! S+ s) T# |& M+ f0 B. x
  670.       return !(RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg));
    5 @2 N4 G( B& n- O0 k0 x
  671.     }8 O6 ?% L" `3 p; ]4 O. @$ T* s& u) V( K
  672.   }+ m% o3 F, x0 [  _6 ^5 @4 j
  673. # J' u' H$ e& d; J* s/ l: N
  674. #ifdef STM32F10X_CL& o3 U! g: `+ k& q( t$ u, E
  675.   if(CANx == CAN2)
      U) N0 K* z" v: \0 K6 A2 [1 f
  676.   {$ G4 h0 G+ q. j$ G& R* D& x' T0 g8 b
  677.     if(can2InitFlag == true)" p" H, O4 I& _! u) O8 T; d8 X5 m
  678.     {
    ; ?' a; s6 |  T/ m2 i4 A3 k; ?
  679.       return !(RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg));6 b1 B' [& ^, _( N  W8 ]7 k
  680.     }- a4 t8 Y) ^! ]4 Y$ G
  681.   }
    . ?- z5 P" H' G
  682. #endif /* STM32F10X_CL */7 f- ~4 D* I: z' @9 i7 R( j
  683. / n6 A# v+ S* \' u) b7 F( [1 s% ]
  684.   return false;
    5 \* v7 P6 K; O) B
  685. }, Q1 S2 _( s) }5 ^0 ~5 K& Q

  686. 7 B& T( w) z$ p) S
  687. /**3 M4 \6 u/ e: F# m* `: j7 g
  688.   * @brief  Is the CAN receive buffer full?5 W' h- D; x, e9 ]+ F- g& `
  689.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    ( Q5 G  B% B6 m( V; N
  690.   * @retval true:      The receive buffer is full./ v8 X. ]; J- _3 g2 @
  691.   * @retval false:     The receive buffer is not full.
    , B. }7 h+ b6 a' v
  692.   */
    * {: a) l$ m8 P( h/ _. M4 `
  693. bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx)
    : c8 l9 f( t; G. h" J) m
  694. {/ b% j! e9 b! _
  695.   if(CANx == CAN1)
    ! v7 C, ]* D& ~8 |$ G9 @3 t9 ~  }* a
  696.   {  H) P* _2 x- p) N1 N. }# J* i
  697.     if(can1InitFlag == true)
    - C' x4 F5 k: D6 v
  698.     {
    0 g+ Z9 d! }* h$ O* \" h' x
  699.       return !(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg));+ s! C. ?5 G! u0 c8 [: Y" D
  700.     }+ Y: T; C9 o% i# Z1 J7 D
  701.   }+ Q8 D4 D! d! ?/ R
  702. 0 f. R# I1 H+ X: f9 y) [, F, ?
  703. #ifdef STM32F10X_CL
    1 c" M- v0 C) v  S
  704.   if(CANx == CAN2)% u1 o/ D4 N% M0 _6 N# J* y
  705.   {
    6 B# Z4 m# t* ^5 y: F+ e2 }
  706.     if(can2InitFlag == true)8 }5 |7 c; q8 y. F* r  A
  707.     {2 e% j( D0 d; g! H) F# q$ T
  708.       return !(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg));
    1 _$ z/ G3 r, ^+ h$ l; M
  709.     }* {. {7 }6 A/ ~& G. {* q% i8 c
  710.   }4 I5 p* @& V/ V8 s/ Z$ [5 y% T
  711. #endif /* STM32F10X_CL */
    , m4 Z$ Z9 m/ M5 k- A1 w$ P
  712. - g# P* E% q" E0 ?
  713.   return false;
    * ]; ]9 n0 R! J7 _7 B
  714. }9 O, P2 h  T4 H% Z* w4 Q

  715. ' r5 H) y6 q; b( c' r$ s" g
  716. /**
    . @4 A  Y+ q8 u; c
  717.   * @brief  Clear the CAN transmit buffer.% p" r# n3 ~) ]: ?* r
  718.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral./ Y( z5 w5 k; B' e2 z7 J
  719.   * @return None.
    , C! r! h. r2 W; X2 h4 C
  720.   */- v6 z0 X, u5 e
  721. void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx)5 ^& @2 e5 c' b) v& Y
  722. {! `) U7 i6 o- o  t$ a" t7 s
  723.   if(CANx == CAN1)8 n5 Q% a- J: D
  724.   {
    ' e% Y  }! f9 U; T/ l$ b; G
  725.     if(can1InitFlag == true)
    / E' a) @( ]7 P9 V) l9 ?" C, w
  726.     {5 Y* r2 W) K9 T/ \& ^( o" d
  727.       RingBuffer_Reset(can1TxBuffer);
    " o! P  M# m. a
  728.     }3 \5 ~6 t0 s$ D$ _
  729.   }# @% q- k9 ~4 {0 |# k7 i$ a, Q7 Z5 r

  730. 2 s- j) E6 c, O9 p/ s1 m
  731. #ifdef STM32F10X_CL) ]$ a4 K9 I8 K6 z1 E
  732.   if(CANx == CAN2)5 z/ N  {/ |, o# d6 w
  733.   {# }1 N* r+ t0 R$ N  `9 |
  734.     if(can2InitFlag == true)
      q* }$ U7 r8 v
  735.     {
    ) V3 ~7 _7 }5 w" k
  736.       RingBuffer_Reset(can2TxBuffer);
    1 U6 b' F; V1 J% R- U# M
  737.     }8 N4 g/ v% ^# F0 l  P- U- N
  738.   }: x( I) L* y. E
  739. #endif /* STM32F10X_CL */
    % A9 P2 Z) C+ }4 R5 f% Z6 ?) J
  740. }
    6 W. J- n/ D5 _: N' t; B
  741. - a( m# _9 n- h. Z7 P; j
  742. /**+ H: s7 O$ A% D! ?
  743.   * @brief  Clear the CAN receive buffer.1 |1 f9 u* @) A& E7 e( Y$ U' h
  744.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.2 a9 }0 ]0 ^$ [% H2 {9 ?+ Y
  745.   * @return None.; y( f4 T% V+ w) ~: f5 S* o
  746.   */5 [6 }0 t; E0 P/ V
  747. void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx); D9 K( a; }4 a8 V+ A
  748. {
    * Q: j" U: d) i
  749.   if(CANx == CAN1)5 o9 W' C, S2 C; m2 x6 U  _, P
  750.   {. ^; D5 ~7 v' ?
  751.     if(can1InitFlag == true)
    . u$ a) o% |2 [( Z
  752.     {
    3 F5 e6 g" j5 d) W/ ^; D
  753.       RingBuffer_Reset(can1RxBuffer);
    8 j( K1 }3 H6 O! \
  754.     }
    ( @2 W# R  V; p  a2 C2 s& s5 m
  755.   }
    1 Z9 A- e& K  v1 X* Q; ~

  756. $ L7 p: s, J$ A7 y% G( [1 R
  757. #ifdef STM32F10X_CL
    , Z9 K1 E4 c  [% j8 p1 x8 k$ h" S
  758.   if(CANx == CAN2)
    1 R" t2 J2 u- [4 Q7 m
  759.   {
    * p- V1 J& G, G+ L! G
  760.     if(can2InitFlag == true)
    ' v' k+ ^% o; N; x) E! Q6 @; |1 A
  761.     {
    & ?" B% y0 Y/ B4 \' K$ F
  762.       RingBuffer_Reset(can2RxBuffer);
    : Y. ]7 b# p# W0 J: i1 f! A
  763.     }" s3 y3 \: J  X; O, |
  764.   }
    ! R* j2 a2 s- G" w3 ~" {
  765. #endif /* STM32F10X_CL */" g' \8 c: {- O7 d& ?
  766. }
    5 V) [( x- g) v7 l

  767. ! L" ^6 u; g0 ~, v
  768. /**  b1 x0 I" z3 @$ E; A# L
  769.   * @brief  Is the CAN transmit a message?
    . C" d) u7 c- C  G
  770.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    $ B% |+ x& a- H; @/ c
  771.   * @retval true:      Is transmit a message.
    4 W* Y& A3 p3 k- C7 }
  772.   * @retval false:     Not transmit a message.5 t- Q3 v/ a; Z7 t+ O4 P
  773.   *// r3 l/ M6 ]3 C  \
  774. bool CAN_IsTransmitMessage(CAN_TypeDef *CANx)
    " ]  Z6 M& v. k( A, K$ L6 @
  775. {9 g  z1 S) a5 C& s
  776.   if(CANx == CAN1)% L  q3 ]3 L; ?& h$ }# r
  777.   {+ E0 p0 l" M. U9 T; L# G
  778.     if(can1InitFlag == true)
    0 O" @1 a/ H, u) d9 x
  779.     {
    1 {; R; a/ _" _4 T: i& e
  780.       return can1TransmitFlag;% w5 `& s* o$ ?  v6 i5 S1 L" g
  781.     }
    - b4 }3 `. \. \* _
  782.   }/ |$ u- z8 x( P

  783. ) W5 b" ^/ u  I4 q" [
  784. #ifdef STM32F10X_CL0 h- u, h9 k4 V9 N, t
  785.   if(CANx == CAN2)
    5 A  T& N. r* p
  786.   {
    ) {: [" s" D% D
  787.     if(can2InitFlag == true)' l7 `1 i3 l! S2 U7 Y' g' L/ t
  788.     {
    % S, L* N1 S9 _+ J+ k" R: A5 a3 v
  789.       return can2TransmitFlag;* e0 s4 |  w2 D* b0 `* F) y4 t+ f
  790.     }
    6 m# Q! O; w2 R2 j
  791.   }" z9 [# v( C! J; y" |* O; U
  792. #endif /* STM32F10X_CL */! O/ n& K' o2 w
  793. : k3 S  j$ |7 {1 h
  794.   return false;0 `9 K! c! V5 o/ j2 c- }2 _: j: ^
  795. }
    ( ^4 t5 O2 t. O: f2 c% k
  796. / @% D$ S6 Y* _- {2 ~+ J5 u
  797. /**
    * e& A+ F! K# V1 M# M+ Y
  798.   * @brief  This function handles CAN1 TX Handler.- \( f6 T7 o/ n, e6 `  s  N
  799.   * @param  None.7 h( r7 k8 l( h! x
  800.   * @return None.  R+ q7 P4 T" x! @! }  K4 E
  801.   */2 G4 ?4 f5 F. J& B2 `! O
  802. #ifdef STM32F10X_CL! S" p1 \. X: D& s
  803. void CAN1_TX_IRQHandler(void)
    # y6 c8 y9 A! w& r" Z2 M' s
  804. #else0 Z  i2 g7 G$ S( |- q+ o8 g5 D' W7 Y
  805. void USB_HP_CAN1_TX_IRQHandler(void)
    ) Y9 f, [2 P" I+ Y7 _% M9 B
  806. #endif /* STM32F10X_CL */6 E' C% {4 C0 C2 ~) K8 x; J6 S
  807. {8 K% D( T% G& O- S( X8 t( }
  808.   if(CAN_GetITStatus(CAN1, CAN_IT_TME) != RESET)
    7 @% q( C% L- k) @% D: a. D7 F
  809.   {4 \: ~3 V3 U, Z* Z& x
  810.     CAN_ClearITPendingBit(CAN1, CAN_IT_TME);9 ?# R2 s8 n2 |$ `; w

  811. 9 S) Z+ W. n6 s
  812.     CanTxMsg canTxMsg = {0};
    9 @# r! b  A, t' h% Q7 f
  813.     uint8_t  number   = RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);' a. }1 [/ `  _6 j. I+ R1 L
  814. / P6 Q5 X  ^4 Y0 x' f* x
  815.     if(number > 0); P9 }* P" r* J, E
  816.     {# {! F0 `2 {2 @( L' c  H/ t
  817.       CAN_Transmit(CAN1, &canTxMsg);
    8 a" J, h9 U3 s! M- o% M
  818.     }
    6 h' ~7 ?( X  U, L5 M4 {% L
  819.     else
    , k7 A1 N$ h9 ^3 g0 Z# j, m  G
  820.     {3 O0 H/ _! b9 g, O0 _5 |2 ^
  821.       can1TransmitFlag = false;
    5 i# a/ f8 M6 [0 L9 Z) q8 I% D( r
  822. 4 ]; w% H4 S, N1 {
  823.       if(can1TransmitFinishCallback != 0)1 f$ Y+ s9 Z3 v+ C0 _
  824.       {( O6 H9 p( U8 d5 c, R7 X2 h8 G
  825.         can1TransmitFinishCallback();9 Z. u- m3 L( B7 b6 P4 S
  826.       }
    - B/ V% T8 w  \2 s! Q& b: q
  827.     }
    5 X  G/ o, L6 ?' _1 w0 k' x
  828.   }; p( @8 ?# g3 [/ |; A1 j
  829. }
    + B# |7 w& z+ J5 q. }

  830. : M3 w$ U, k$ t! s
  831. /**
    & X/ |8 u0 g4 x# l. ^# F
  832.   * @brief  This function handles CAN1 RX0 Handler.; P4 M$ w; U4 e2 x" v& A" T! x5 P
  833.   * @param  None.  K4 x' H3 p% ?& h$ s) w6 L
  834.   * @return None.
    6 l" M2 G) L. h8 k9 j: p
  835.   */* [/ n# O( N" L. E! t+ w7 M3 D
  836. #ifdef STM32F10X_CL' q: D4 [+ l$ ^; ?5 r! A
  837. void CAN1_RX0_IRQHandler(void)7 I1 }6 A, |) q; @) L
  838. #else
    ) P) C; G* V& x4 t+ f5 [
  839. void USB_LP_CAN1_RX0_IRQHandler(void)6 R3 U8 Y' e5 t2 n% S
  840. #endif /* STM32F10X_CL */: X4 J* h1 B4 L1 O! K- x
  841. {
    ' L9 ]8 W  A& t% X$ |- |
  842.   if(CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET)+ u* o, v7 y( g1 b; l8 a
  843.   {5 A* G, p7 J' Q& k' |1 j1 a# _  E
  844.     CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0);) W0 b. _8 f5 O+ |3 ?

  845. 7 t0 J8 t2 H! p9 ]* V0 S
  846.     CanRxMsg canRxMsg = {0};/ Y9 @5 T) A- s9 a7 z+ c( x8 J
  847.     CAN_Receive(CAN1, CAN_FIFO0, &canRxMsg);9 g5 r6 O- b, q
  848. ( C4 k! f1 a, A
  849.     if(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg) > 0)
      j( t% g1 J; _5 g- t; g( ~2 W
  850.     {5 v+ W8 h1 s6 h. o7 @( ^$ E% z
  851.       RingBuffer_In(can1RxBuffer, &canRxMsg, sizeof(canRxMsg));1 i' ]0 g0 x0 p" ?: R" J
  852.     }
      h8 ^3 V  a& R) F3 Z3 _, o/ u- J
  853. / n' |2 P9 H: F7 K" t8 T5 a) h
  854.     if(can1ReceiveFinishCallback != 0), ~5 h8 Z! C2 n) D+ e, A
  855.     {
    2 `; T$ a8 e: g$ A7 f# p1 h
  856.       can1ReceiveFinishCallback();3 F0 \. H+ g2 c1 e
  857.     }
    ' J: [- I3 ^, H+ K6 U1 v- d5 o
  858.   }
    % A" S$ L( g8 \' U- T  c4 {. r; G& Q
  859. }1 L& t( S/ [- v# b

  860. ) Q2 B4 c5 q3 {' u  ]
  861. #ifdef STM32F10X_CL4 c/ P8 E7 P) `
  862. /**
    ) F( t. z5 ^6 M6 ^* f0 O
  863.   * @brief  This function handles CAN2 TX Handler.
    ' |$ o) U: s$ i
  864.   * @param  None.+ l' q% [* X. a) s; D3 }
  865.   * @return None.: U& n  i) c$ y5 n4 ~$ m1 y$ }
  866.   */
    7 }# r# V/ \7 M% g+ C
  867. void CAN2_TX_IRQHandler(void)
    , A1 F& {- L! l6 g' Q
  868. {4 B; O8 h1 H5 k/ `
  869.   if(CAN_GetITStatus(CAN2, CAN_IT_TME) != RESET)2 _4 X( R% g0 N
  870.   {; i7 |) {) t3 w) [. U) T
  871.     CAN_ClearITPendingBit(CAN2, CAN_IT_TME);
    ) `/ r$ K. M: o" L( t

  872. " h% }4 V' m& A8 [. R# X
  873.     CanTxMsg canTxMsg = {0};! P; r  N# _4 s: |" I0 P) v
  874.     uint8_t  number   = RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);
    * t) s' c( e7 R# O

  875. + D5 V; H. m+ z/ M8 x; |
  876.     if(number > 0)
    ! \' F# R2 b5 _
  877.     {8 t. p  r% t8 Y5 \0 {. w' Y
  878.       CAN_Transmit(CAN2, &canTxMsg);
    7 M( t8 K3 V6 d" p5 {$ H
  879.     }, P& ~: g" b6 [1 L; F
  880.     else4 H, Z7 k% n; _& N9 z5 h
  881.     {; K: M5 |& O% L) Q; d9 a
  882.       can2TransmitFlag = false;3 c# {9 R  X4 n% Q
  883. 4 Z2 ^) W7 D% ]! Z( q6 p, d2 @
  884.       if(can2TransmitFinishCallback != 0)
    4 t5 C& Y/ u% O. I% f- q: a
  885.       {8 s; b) z' i; Q' y4 J) }" i
  886.         can2TransmitFinishCallback();" F" m# @, W% ]% k$ U. q  p2 c
  887.       }# u, a) N* u6 _+ S4 I" K, {1 R
  888.     }
    ' U' B: f9 w6 y( a3 a+ ^2 C2 K4 V
  889.   }* x9 ]) T' {5 P6 n0 x% a
  890. }. E9 k8 J) T# ^9 ]8 W' p$ X

  891. * R9 E$ K" a; p5 G5 R
  892. /**' s6 d& @# |+ U  |7 G+ E
  893.   * @brief  This function handles CAN2 RX0 Handler.+ v2 C! Y* e* [% z- ?/ u
  894.   * @param  None.
    . }/ O/ G$ U6 _1 W' D  R, m
  895.   * @return None.4 q) r+ R% y$ g2 @- M+ ^
  896.   */
    ! F( g6 k+ `! l0 h4 k1 D. [
  897. void CAN2_RX0_IRQHandler(void)
    7 Y* o; |! s3 E7 v2 ]: c+ i
  898. {) P8 j! O& R6 x, T2 ~5 `" l0 f
  899.   if(CAN_GetITStatus(CAN2, CAN_IT_FMP0) != RESET)- m; ]3 r# k4 X0 [3 E2 r
  900.   {* x- Q7 S4 t$ s0 f8 t. ]
  901.     CAN_ClearITPendingBit(CAN2, CAN_IT_FMP0);
    4 _" Q7 C/ D8 m7 j
  902. - C4 Q) l0 X6 K' a, e. C" T+ i8 K
  903.     CanRxMsg canRxMsg = {0};) ]  o5 ]0 U8 e% w
  904.     CAN_Receive(CAN2, CAN_FIFO0, &canRxMsg);
    ' p. D0 k* J( k" D
  905. ! O; B, o: b9 |  {9 a" C
  906.     if(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg) > 0)) r- o/ o$ U; O& W( F" O7 u* ?
  907.     {
    $ ~- w: P1 R. P5 H) d
  908.       RingBuffer_In(can2RxBuffer, &canRxMsg, sizeof(canRxMsg));
    2 J. L0 U+ `- [+ p. S
  909.     }% t$ Z/ w+ ~5 J
  910. 0 J" i& A, b3 Z4 @
  911.     if(can2ReceiveFinishCallback != 0)
    * n- |  @# O/ F! p/ P7 ~
  912.     {2 c) c: R  B: h2 V
  913.       can2ReceiveFinishCallback();
    9 E  E; s  u, H' U; i
  914.     }
    ; y! B6 _$ C1 N8 `+ N
  915.   }, W# C" [& E2 P
  916. }# C% c& B; L6 Q% q
  917. #endif /* STM32F10X_CL */! X; B; O' ?3 X3 j
复制代码
1 F' ]7 U2 u; I" k8 {( C' N$ v

" ~, q; i/ P/ ?4 zmain.h 文件, F1 \$ o5 ~& T0 C
  1. /**4 a: |" Y' J; T" h( |% T0 e
  2.   ******************************************************************************
    / ?5 ]! Y4 ^8 b& a, n1 M
  3.   * @file    main.h
    / A" `. R  M. b9 i. k/ Z5 n9 {' r
  4.   * @author  XinLi! A6 K  U$ R7 \3 [, l) @, u) j
  5.   * @version v1.0, Y/ i# c4 f, e8 @$ b% e$ i* V- I
  6.   * @date    24-June-2018
    1 C3 z; w. t. m
  7.   * @brief   Header file for main.c module.
    0 N" ?. Y$ y' w$ x, s' c* o: \% x
  8.   ******************************************************************************
    & g( E) o5 B/ A- a2 ^% P/ }
  9.   * @attention
    : A7 f/ o. D# s
  10.   *" v- Q# X2 ], S8 R: O6 _+ E
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    : I/ }5 }% s/ P0 P$ j+ F. b
  12.   *
    0 E- M$ N8 N! u4 @
  13.   * This program is free software: you can redistribute it and/or modify4 M& G% @: `& ]) _* c  Q
  14.   * it under the terms of the GNU General Public License as published by
    - T# U; [( B' u2 ~0 g/ K* B
  15.   * the Free Software Foundation, either version 3 of the License, or) |' w4 D1 w$ l% X, J) C- x
  16.   * (at your option) any later version.
    - f5 D1 Q$ g7 k( m/ c
  17.   *3 |9 p4 e. q4 ^0 j
  18.   * This program is distributed in the hope that it will be useful,4 I" l* A0 ?0 V5 [
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of4 w; b7 v/ N' H
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the3 b: j) L3 F+ ]4 l& u9 L; A' C
  21.   * GNU General Public License for more details.
    , B2 }$ }) p5 H, t. Y; @0 X
  22.   *
    5 @! @$ e7 q3 j# @" b! @: ~
  23.   * You should have received a copy of the GNU General Public License
    : ], Z8 {5 y- v0 G" j5 a0 z; _
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>! J( L+ C8 X3 X% n( b
  25.   *
    9 |1 N, Y5 I3 y/ w, ], l' F0 L$ \
  26.   ******************************************************************************
    5 ?5 _. S5 f3 D) I7 c+ {2 c
  27.   */2 r8 V. c5 p8 ?
  28. : {. a' Z, _/ d! g
  29. #ifndef __MAIN_H
    3 u+ s  k' I7 d6 p* R; \7 S9 Y1 }
  30. #define __MAIN_H
    * r: O4 j$ I" |6 V  v9 ?+ n# ^
  31. 7 T4 Q( }( S; g# F) d9 m* ?9 J
  32. #ifdef __cplusplus; i( f5 x5 Z5 S; z  ~
  33. extern "C" {
    1 W( [" t; @5 D3 m6 ]8 b! m+ M
  34. #endif( O7 m4 t/ n; S) w6 }
  35. + a8 E8 X3 a6 D7 m$ k- \2 z
  36. /* Header includes -----------------------------------------------------------*/
    , _; Y6 Z) i- o" L
  37. #include "stm32f10x.h"- m7 G+ ^; U1 t' f6 T+ d

  38.   N+ D$ t* Q6 X5 H% Z2 @
  39. /* Macro definitions ---------------------------------------------------------*/
    8 @9 ]- m5 ?5 O: t
  40. /* Type definitions ----------------------------------------------------------*/
    9 W) G. f/ ]6 P) F
  41. /* Variable declarations -----------------------------------------------------*/
    $ I2 \* a8 B( N; p  q$ I1 J
  42. /* Variable definitions ------------------------------------------------------*/
    . y2 ~7 g1 J% I6 V/ t7 e( |7 N
  43. /* Function declarations -----------------------------------------------------*/+ N) |$ u/ \, `4 @& j
  44. /* Function definitions ------------------------------------------------------*/
    6 y( D+ z1 h9 S& D  R
  45. ! l. }  @; b/ a" B5 M5 W, w9 A
  46. #ifdef __cplusplus
    3 T( H" [+ F' e& x" y6 G7 t/ @9 Y
  47. }
    / B9 H* T5 W; [
  48. #endif" g1 `2 @- X& _8 a- y0 j

  49. 7 `* y8 ?$ _- ]7 [/ h( C
  50. #endif /* __MAIN_H */
复制代码
& M! |+ }0 p4 s  L

. @$ I8 h0 F+ e5 g8 K3 Y0 jmain.c 文件* y$ L( @) ~8 J! a+ H# k
  1. /**
    4 {0 h: U' V* e6 R8 t
  2.   ******************************************************************************% W$ z/ ?$ _" v- {$ d6 z% A
  3.   * @file    main.c0 A/ F- w" V- U1 ?1 l
  4.   * @author  XinLi: P( S+ a6 k' ?* ]: u: C' e
  5.   * @version v1.0
    # R8 s5 i- F  D% l4 P
  6.   * @date    24-June-2018
    + m3 W0 V6 x4 R9 ]8 K+ r
  7.   * @brief   Main program body.% n: t. C% l4 r9 @4 E* T( b
  8.   ******************************************************************************
    5 J, q! U% u+ M4 w
  9.   * @attention
    ! a( s/ [* y! b: g* ?1 N
  10.   *8 \2 M) b  A# X% p
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    0 T8 T, G# Q! c0 Q  A9 T
  12.   *# a1 S% u$ G  [' K2 M
  13.   * This program is free software: you can redistribute it and/or modify- x! @  b9 |% ^, p% B8 [2 G
  14.   * it under the terms of the GNU General Public License as published by5 r! |* y1 o- {' u  g: [' q
  15.   * the Free Software Foundation, either version 3 of the License, or0 N' [2 j* c! T* K. s) d
  16.   * (at your option) any later version.
      h- x% }$ b3 D
  17.   *9 f: j  L& \% V
  18.   * This program is distributed in the hope that it will be useful,
    ) q/ e( H2 n' j8 s/ X% Z' s2 d
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    " _, A& f% N  @9 U# g% |+ w
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    . D7 N- D0 ?, L3 ~6 P5 L  h% p" b
  21.   * GNU General Public License for more details.
    " o/ ~8 t/ J4 X: ]5 ?/ ^
  22.   *
    7 q) j6 n* ]# |4 v* m1 {6 a
  23.   * You should have received a copy of the GNU General Public License
    8 K- C; N/ \8 U: W) n$ @: q$ c
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a># Z% ~: [4 R' n! y2 V/ W! D) a
  25.   *0 |% o* g! J9 l  {
  26.   ******************************************************************************
    1 t: r+ _9 @9 W& G8 f
  27.   */  V6 h5 Z( b- C) R4 G6 }

  28. ; a) j" f) B& Y. c4 X* ]/ I
  29. /* Header includes -----------------------------------------------------------*/
      @0 G5 q) X: @* d$ B- n
  30. #include "main.h"" v( U& j/ I8 s- Q9 J2 r' j7 _1 k& g
  31. #include "CAN.h"' k) S+ Q! y9 B7 r2 D2 l& X

  32. 2 j+ M& F& r0 Z( ^4 e3 g2 W
  33. #ifdef _RTE_
    ! C' V/ T! N6 v" f! k' _& P
  34. #include "RTE_Components.h"
    * d1 |$ Z! J' Z; Q5 @
  35. #endif8 n, [+ R6 D% d% i9 @9 N% ~
  36. % y  v$ d' b. r! f6 a* I
  37. #ifdef RTE_CMSIS_RTOS2
    ; n2 {5 ?' d" p, o- g
  38. #include "cmsis_os2.h", y. p! t  o' H; A) b. g
  39. #endif
    3 k4 D% J- l6 u" e3 s
  40. ( ^2 F" p7 h) [7 x
  41. /* Macro definitions ---------------------------------------------------------*/
    ; @3 _# c1 d$ v. T$ f  X
  42. /* Type definitions ----------------------------------------------------------*/3 B: k9 v; o" M& E: u( B% j
  43. /* Variable declarations -----------------------------------------------------*/
    - P- P9 z" P) v( z
  44. /* Variable definitions ------------------------------------------------------*/
    ( P0 I& g9 b4 F
  45. static CanTxMsg canTxMsg = {0};- `* [/ u0 k& i* ]6 s
  46. static CanRxMsg canRxMsg = {0};
    & n6 g# O0 @8 r* R
  47. " w' F; X" ]4 o+ j& \. G5 O5 Y
  48. /* Function declarations -----------------------------------------------------*/. \' o* g9 Z! D4 O
  49. static void SystemClock_Config(void);
    7 ~3 S2 S" D# x& k  n6 d
  50. % g+ B& j) i, x, N
  51. /* Function definitions ------------------------------------------------------*/
    ! A. t! m# G+ B& Q' r9 r5 Q3 k

  52.   Q; Z/ r8 r6 F8 I$ D7 b+ m
  53. /**
    ) a  Z1 D# e6 s5 [/ m1 F: O
  54.   * @brief  Main program.
    ! u- @' u: {8 t2 K1 `! a0 u+ I
  55.   * @param  None.7 p! c9 S& a3 \$ ^
  56.   * @return None." W3 W# B* K9 K3 m: T
  57.   */
    ; W: ^; b, V$ i
  58. int main(void)4 b" {7 u# t5 l% b% m) g* z7 \
  59. {
    , t0 S8 p2 T% X& H1 i$ y0 h
  60.   /* Configure the system clock to 72 MHz */
    0 s4 C9 q' @8 t3 r3 p4 j
  61.   SystemClock_Config();
    6 O+ O2 P: P8 ~+ m) `
  62.   SystemCoreClockUpdate();
    9 M- b; P6 r5 d/ v
  63. 2 j% [! A9 ^0 o& Q
  64.   /* Add your application code here */5 q! E4 y9 \0 b9 P# s
  65.   CAN_Configure(CAN1, CAN_WorkModeLoopBack, CAN_BaudRate250K, 0xAA55, 0x55AA);
    4 m3 {' H( p: {" m
  66. " @9 S& B& d* c/ K- P
  67. #ifdef RTE_CMSIS_RTOS2
    ' I* [" N2 E4 H3 I
  68.   /* Initialize CMSIS-RTOS2 */
    # r2 o/ v* m. q, a+ y
  69.   osKernelInitialize();
    8 _' W0 l1 g1 h! j0 _. i& `

  70. * J0 D% ^1 R& ~; Z
  71.   /* Create thread functions that start executing, ; L$ @& U# m3 L( L1 H9 W- h% \* T
  72.   Example: osThreadNew(app_main, NULL, NULL); */0 R( o. I* A4 n' b
  73. / F: e' s( J  m4 g' T' z* z
  74.   /* Start thread execution */
    4 p3 f5 R* E- E+ w
  75.   osKernelStart();
    0 W9 U$ T  z% z3 b  Z$ M! O
  76. #endif$ C) g6 x' I$ D6 W' |" T+ ^1 ]. b" P

  77. ( t9 l) ^: e& a0 d2 c
  78.   /* Infinite loop */& ~/ b2 L9 Q, N; f6 y
  79.   while(1)4 B# E; P# s% v! H) ~  K" M; V
  80.   {
    ! f: }( ^2 T- Y
  81.     canTxMsg.StdId = 0xAA55;
    $ b" v2 f/ z6 n# T0 e
  82.     canTxMsg.ExtId = 0x55AA;
    . V4 F1 S# t- y) v
  83.     canTxMsg.IDE   = CAN_ID_STD;
    9 V- S2 d; k7 z, t) G0 ~$ y, X$ N. Z* m
  84.     canTxMsg.RTR   = CAN_RTR_DATA;
    * c2 |8 D" J  I4 G! R
  85.     canTxMsg.DLC   = 8;
    . V; R, o- g# ?( j+ ~) V* s
  86. & ^/ g9 \8 w2 a& j, Y7 Y
  87.     canTxMsg.Data[0]++;/ M" p* }. }3 k8 k& R
  88.     canTxMsg.Data[1]++;
    ; p5 W( n( M: ~& o5 M  m/ G/ s
  89.     canTxMsg.Data[2]++;8 [6 @9 F' H  T& j% M
  90.     canTxMsg.Data[3]++;- U# H1 C9 H0 n1 I0 Q
  91.     canTxMsg.Data[4]++;% E8 n& v4 x+ m  e! P! M
  92.     canTxMsg.Data[5]++;
    ; r4 s7 \- X9 @0 @6 X: x
  93.     canTxMsg.Data[6]++;; g! r/ [' a( r% [5 G, w7 L/ j
  94.     canTxMsg.Data[7]++;4 ~) \1 X; I, A0 E( S

  95. & j2 v* [/ k; ~
  96.     CAN_SetTransmitMessage(CAN1, &canTxMsg, 1);
    & V3 ]/ L- M7 L8 W0 M$ ?+ j! T" w

  97.   H* a; i* }( D& m7 r
  98.     while(CAN_IsReceiveBufferEmpty(CAN1) == true);, P7 D' E; {' ^
  99. 2 c& Q9 G2 b6 i/ g% x8 k/ f: m. j) i
  100.     CAN_GetReceiveMessage(CAN1, &canRxMsg, 1);/ E: \  y- P/ R( t0 u
  101.   }
    : Y4 p4 V1 w" p$ l$ z& z
  102. }
    ; o& ^( s2 J" L: ~+ @, H
  103. & ^* x# A9 R8 X# }. r
  104. /**1 o5 {2 I" R- x2 \6 I5 H
  105.   * @brief  System Clock Configuration.# G0 n: }6 U2 q% u6 l5 k
  106.   *         The system Clock is configured as follow : ) g9 M4 ?% b! Q5 j  j* M
  107.   *            System Clock source            = PLL (HSE)
    ! _3 t% V% v* G- Y
  108.   *            SYSCLK(Hz)                     = 72000000# g& ^$ j7 K8 H4 J: M
  109.   *            HCLK(Hz)                       = 72000000  U5 F% _* o$ A$ n' r& }
  110.   *            AHB Prescaler                  = 1
    " M) y, |) a- l' U/ w+ N
  111.   *            APB1 Prescaler                 = 2* J1 q  i5 d% ~0 C3 I
  112.   *            APB2 Prescaler                 = 1
    1 l. U9 L, h( D
  113.   *            HSE Frequency(Hz)              = 8000000
    3 k& q. ?. l. m/ V% e
  114.   *            HSE PREDIV1                    = 1
    ; R' p2 q: u4 c7 U4 ~1 }4 u, `' W
  115.   *            PLLMUL                         = 9
    ; g+ T2 ^0 \9 N$ O
  116.   *            Flash Latency(WS)              = 24 Z) s. N* K+ i' P! C
  117.   * @param  None.- q- J; i* ]8 t! ]& m, B
  118.   * @return None.# l* ?5 U- c# I$ E
  119.   */1 C* Q( h7 [% }; C
  120. static void SystemClock_Config(void)
    4 ^7 i0 ~, _5 n7 L9 |
  121. {
    8 B/ Z1 Z& z! X
  122.   /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration */
    1 T1 J& S7 v1 |9 x! b
  123.   /* RCC system reset */
    # i) [9 F& [& ^  d% Q2 z
  124.   RCC_DeInit();, Y" y, V% g1 U9 p2 e% J
  125. + @9 Q3 ~+ }6 X' b; R
  126.   /* Enable HSE */
    1 V4 x; n4 F/ ~6 I8 I
  127.   RCC_HSEConfig(RCC_HSE_ON);3 ?/ S9 F6 ^$ [+ u
  128. $ a; X6 w9 v" Y2 k/ o
  129.   /* Wait till HSE is ready */
      s: O, n! J7 s. r9 O* h
  130.   ErrorStatus HSEStartUpStatus = RCC_WaitForHSEStartUp();
    # L) n% H. q# s# W! }" T

  131. 0 M( Q1 v  m6 h, i4 ]3 d
  132.   if(HSEStartUpStatus == SUCCESS)% \7 d1 S3 K' _) R* \. l# S
  133.   {! A2 l* ]& C4 Q8 z8 D# j
  134.     /* Enable Prefetch Buffer */6 C9 b/ ?/ W& d' ?" V9 {8 h$ b' ^
  135.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);8 V, l" K, d/ U. x5 w4 h0 L% e

  136. * \; X# k, C- @
  137.     /* Flash 2 wait state */! y+ F9 O6 C: n, ~
  138.     FLASH_SetLatency(FLASH_Latency_2);
    ( d. ^9 z! ]4 I$ R

  139. 6 ^: j) X! A0 y6 h2 b
  140.     /* HCLK = SYSCLK */5 s5 \, c4 @0 L4 `, n1 x* B
  141.     RCC_HCLKConfig(RCC_SYSCLK_Div1);
    # B+ d  t# e# o8 J) }+ T

  142. . \+ _4 ?+ R' o2 M1 V
  143.     /* PCLK2 = HCLK */
    1 n: e$ G8 h* H: A) m* Z
  144.     RCC_PCLK2Config(RCC_HCLK_Div1); 1 q1 {! d" [" `- Z

  145. - i7 v# m' i& \& i  I
  146.     /* PCLK1 = HCLK / 2 */
    2 }$ M. T/ f& W# A2 K8 ?' d
  147.     RCC_PCLK1Config(RCC_HCLK_Div2);
    ' S9 R# T6 {# e9 ]/ a! s* L8 i) V

  148. 9 v: H. T: K& u) Y3 H1 F
  149.     /* Configure PLLs */9 n; g- ]7 G7 r6 _8 O. c0 ^8 B% P
  150. #ifdef STM32F10X_CL
    3 b1 ^% v! a7 b0 f( I5 {, p4 _
  151.     /* PLL2 configuration: PLL2CLK = (HSE(8MHz) / 2) * 10 = 40MHz */6 ~- ]# }8 J/ _3 _& @% K* z* V
  152.     RCC_PREDIV2Config(RCC_PREDIV2_Div2);3 Y$ q8 H5 b- m6 l  L
  153.     RCC_PLL2Config(RCC_PLL2Mul_10);
    3 r8 X, w" u' f6 ]

  154. ' o- R3 P5 z: Z  W: |
  155.     /* Enable PLL2 */7 m* F3 Y( K; }+ k: x  v! r
  156.     RCC_PLL2Cmd(ENABLE);; H2 A; D2 W. i9 \

  157. : |" f! `6 H7 W! O+ K& ]
  158.     /* Wait till PLL2 is ready */5 S; m6 R. x8 i/ R6 y/ E
  159.     while(RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET);6 G) ]/ L. O9 m( d7 P: M1 Z

  160. 3 V. R* j; m" W8 z8 @6 y
  161.     /* PLL configuration: PLLCLK = (PLL2(40MHz) / 5) * 9 = 72MHz */
    2 ^1 I9 k2 w; i' d5 Z, t0 g
  162.     RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div5);& g8 H7 ]( k4 |2 |3 \7 @; n5 G
  163.     RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);
    ' q" n4 t7 d1 o* @
  164. #else
    * B/ A& L3 Q  I: D  y/ d
  165.     /* PLLCLK = HSE(8MHz) * 9 = 72MHz */
    $ J# @" E+ z8 g1 ~9 C% N& t$ \
  166.     RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);) @' J& z- |! p" t$ N
  167. #endif# V% H4 b2 V/ J! @9 }+ ^2 W- ~

  168. $ I- ?* ^/ j8 y( e
  169.     /* Enable PLL */
    - M- E8 z8 ?4 y* y, C
  170.     RCC_PLLCmd(ENABLE);
    : Z# s& w, [' H4 e

  171. $ D3 I: Z  b- x5 x) q
  172.     /* Wait till PLL is ready */
    9 e: q1 `( s* o6 O3 \
  173.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
    ' c$ ~( M; l! |, o* L

  174. 7 h( ], e- W; Q* a
  175.     /* Select PLL as system clock source */
    5 F: l$ [; ?/ P1 G
  176.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);7 _5 o, S& a" G( j0 |! F2 i; z, i- }

  177. ' {+ p: u% G9 C, U, x
  178.     /* Wait till PLL is used as system clock source */
    8 ]6 [/ ~: D# L; c. ?
  179.     while(RCC_GetSYSCLKSource() != 0x08);- M( m, T7 e- M
  180.   }
    ' l6 v* N7 {7 d, f! U* |
  181.   else
    8 T2 U3 h+ a) Y3 c
  182.   {
    8 u/ w- q+ @: H2 U4 I
  183.     /* Disable HSE */# \) Z3 N8 J+ I! G9 v: z
  184.     RCC_HSEConfig(RCC_HSE_OFF);) h6 g- Z5 ?; s- {+ B5 G% G' k

  185. 7 O5 d7 ]4 X8 I. {9 f
  186.     /* Enable HSI */3 F0 W; n8 d% S9 [' ^
  187.     RCC_HSICmd(ENABLE);
    * B8 `  j& c2 k3 @

  188. + a2 @; {6 z% S$ G6 t# e& K, y
  189.     /* Enable Prefetch Buffer */
    + y) g8 b1 Z6 f; n* K! s1 J
  190.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);, ^5 z; R  d8 ]2 s

  191. 5 M+ P4 P: I. W. n
  192.     /* Flash 1 wait state */
    ! {4 A  h6 \# [& b$ ?! T, `
  193.     FLASH_SetLatency(FLASH_Latency_1);
    6 f4 t6 \' }; Y+ M

  194. * k# Z) b) k5 k9 [
  195.     /* HCLK = SYSCLK */
    * q& q- P) H/ F
  196.     RCC_HCLKConfig(RCC_SYSCLK_Div1); 9 Y2 d3 o- t5 Z4 B
  197. ' |* Q0 D, g: Q3 B  Y; I
  198.     /* PCLK2 = HCLK */
    & O6 e  D3 p: D8 m7 h) D3 v
  199.     RCC_PCLK2Config(RCC_HCLK_Div1);
    ; ^1 `9 n% \$ g. R$ O* S; E
  200. ; ?" i0 z8 t& ?) f' W4 o
  201.     /* PCLK1 = HCLK */
    ; c" R' ^$ Z  z9 b
  202.     RCC_PCLK1Config(RCC_HCLK_Div1);
    3 s5 d  B- u! Q. `6 n* |$ F+ F6 s( w

  203. 8 ^( v$ a1 }% C6 [4 z: i# N
  204.     /* Configure PLLs */
    9 K+ r4 Q5 i! `  O, z' o) Z1 M7 S
  205.     /* PLLCLK = HSI(8MHz) / 2 * 9 = 36MHz */6 I7 P9 Z0 S2 U9 Y
  206.     RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_9);8 X5 ~% G5 ^, `. J& I# U
  207. ! Q- f" a; h0 F/ M9 B
  208.     /* Enable PLL */
    2 G6 V9 e  j2 b8 ^) V! J: v7 H$ c" l
  209.     RCC_PLLCmd(ENABLE);- o& u, B+ _+ f7 F/ z

  210.   M. o: d/ W% q2 Y0 s
  211.     /* Wait till PLL is ready */
    4 c1 I* ]2 v7 O: }0 ~* K
  212.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
    . \6 w) _! `; Z0 S9 F4 ~- E) v+ N

  213. ( I) V/ r4 l5 _" A# E( E4 l7 M. z
  214.     /* Select PLL as system clock source */6 q8 }2 x$ d9 V' g3 K; g  H- K
  215.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);5 o1 a6 y) z1 ~7 t2 G+ p

  216. ! ^* r6 I3 R! q: u( H
  217.     /* Wait till PLL is used as system clock source */
    # d' _4 I( j# F* H2 U2 a
  218.     while(RCC_GetSYSCLKSource() != 0x08);! ~; t* o/ v! J
  219.   }
    / V# p8 ]3 ^, z" Z0 s9 d* Z
  220. }
    0 E8 N& [9 ]4 u0 L! ?

  221. " n8 B) ^" \0 A/ B, t
  222. #ifdef USE_FULL_ASSERT
    " ~9 _- d( x: H2 X' d6 T# O
  223. /**
      n  q9 j, o. J, _) h
  224.   * @brief  Reports the name of the source file and the source line number
    # F* @# |. {4 s" o% O, R/ k3 w2 L
  225.   *         where the assert_param error has occurred.
    , `/ `. L! c% o
  226.   * @param  file: pointer to the source file name.
      i) u6 X! |+ {6 e8 @
  227.   * @param  line: assert_param error line source number.
    * o1 V: v7 j! `* M( e% ^( H. E: v
  228.   * @return None.
    # ^7 n) L4 X2 T
  229.   */: g& g9 z' T# n8 V6 m+ ^
  230. void assert_failed(uint8_t *file, uint32_t line)1 p( b3 S- P6 L% u. o+ E& M2 w0 E  U
  231. {/ K! S- f( y! q0 @. s# \# R  x) s
  232.   /* User can add his own implementation to report the file name and line number,
    9 D3 s0 {+ j9 }) b  e: ~3 V
  233.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */+ N$ f+ o  |, W. @  c; Q
  234. , T+ ]3 J7 F$ M! h' {) O% B
  235.   /* Infinite loop */
    4 X' {  ^$ j8 k! J( b
  236.   while(1)- P6 d4 _+ K+ w; v" B* u( _8 P) w4 C& ?
  237.   {  a1 K. x2 b& @4 L0 u" G! o, d
  238.   }! q! I+ y  t. F& @3 u
  239. }9 c' R. x7 d8 L
  240. #endif
复制代码

# U2 |2 C0 m  M) z3,注意6 D5 o4 |. d' g$ B  {6 T7 d
: w3 o8 w/ @! Y, o) g5 A
CAN 消息发送缓冲区和接收缓冲区的大小,可以根据应用的需求进行修改,缓冲区使用的是堆内存,需要根据缓冲区大小和应用程序中堆内存使用情况进行配置。: G, \6 m6 n. }, ^( W

) J) C/ Y& W! }, T  W9 i
1 D. R/ q' S2 h; B# c" B* C- d: L& D( s8 V/ r2 z
收藏 评论0 发布时间:2021-11-26 17:00

举报

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