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

【经验分享】STM32F1(CAN)

[复制链接]
STMCU小助手 发布时间:2021-11-26 17:00
1,开发环境
8 H0 W8 k& P( t; j: Q, P( ?2 U  R" ^, v" G; T0 m! q
1,固件库:STM32F10x_StdPeriph_Lib_V3.5.03 X9 Z/ I* i/ a3 a

  @# P; X7 \2 q  K% ~! o0 O2 C2,编译器:ARMCC V5.067 e; w5 O6 i. s# M; c# U* t

" N: w% t3 k1 X3,IDE:Keil uVision5
" @" R4 u& x) z! u- T
" ~4 t8 _, c3 e  r9 t  j* N- p4,操作系统:Windows 10 专业版
1 @6 i: R. L! i" Z9 U7 M7 H' V# b$ _1 W5 O0 I  c

/ |& G( t! u% b8 g& \/ E" U2,程序源码
. `! a9 i5 R( \! T* p. J
8 I/ [! W8 ^4 U6 jRingBuffer.h 文件
1 v# E1 |6 J7 z, Y. ]* e; ?
  1. /**. F" ~3 L; C4 d2 G4 D
  2.   ******************************************************************************( z3 A- P, p/ W8 J
  3.   * @file    RingBuffer.h7 e0 k# p& {7 ]. g
  4.   * @author  XinLi0 w: J, E0 A  l6 N
  5.   * @version v1.1* G. Q+ Y6 K( v3 ~/ E
  6.   * @date    15-January-2018' b" P  O9 `9 ]- \4 ^$ g( [* v
  7.   * @brief   Header file for RingBuffer.c module.1 N; o3 [% Z- ?7 r2 n! J$ z5 l
  8.   ******************************************************************************8 ]1 v3 b+ Y) e2 Z5 [* X, Z$ V0 q
  9.   * @attention6 k3 E, c1 M+ Q0 B. E
  10.   *
    ) p& Y% p8 J) B0 I' {$ }* u0 e- y
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>9 M' P6 n% g; r( r- m- h/ k
  12.   *
      D7 e' X4 L. V7 J1 ^1 \) ~8 b/ r
  13.   * This program is free software: you can redistribute it and/or modify
    - I" V" Z; o; r0 {/ @
  14.   * it under the terms of the GNU General Public License as published by
    2 s* A- ~# W2 o$ \5 |' O3 t
  15.   * the Free Software Foundation, either version 3 of the License, or; F2 s* i% B8 \/ S  [+ x7 M
  16.   * (at your option) any later version.
    , d# c# T( n3 j4 C' v# |# x' ?
  17.   *
    - V9 k8 ~1 I. C
  18.   * This program is distributed in the hope that it will be useful,
    % \2 i( m- }0 y. n9 J& W
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    . w: h8 }' e2 \. n8 o# O
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the) d& J0 v) E, w+ e
  21.   * GNU General Public License for more details.
    9 i& d  ]6 u6 n4 G( r* [( F+ T
  22.   *
    . x- @, C6 Y9 P1 j5 r
  23.   * You should have received a copy of the GNU General Public License
      z. U/ S5 I- v+ j8 J
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>4 I! n4 j/ S: B. W/ f
  25.   *
    & y4 o: g3 c! w1 b5 q' M
  26.   ******************************************************************************
    3 l+ U* a0 z( b' ~
  27.   */
    8 j8 C8 [6 {2 L! C0 p

  28. 6 Y0 D, `2 W1 O8 z, s6 k
  29. #ifndef __RINGBUFFER_H
    7 j2 L% i: e2 ]+ I# s; V9 Y
  30. #define __RINGBUFFER_H
    ( b; y4 ]1 l8 |

  31. : W% ^2 p( x( j9 `1 u8 f! l4 U; w
  32. #ifdef __cplusplus4 Q, |# \- g: a4 i5 ^
  33. extern "C" {8 t# S) w8 W$ f' d+ h4 I: I
  34. #endif! N7 U2 g2 k2 N( G

  35. + ]1 |1 r$ ^+ E4 k7 n% B* u  b
  36. /* Header includes -----------------------------------------------------------*/2 t' n# [* A" G' J8 J4 \
  37. #include <stdint.h>) I/ K. Y5 d- q2 N! I
  38. #include <stdbool.h>
    . C3 q- B. x8 P0 d. M+ d
  39. #include <stdlib.h>5 p8 Z5 L$ V% m# s7 ]
  40. 0 d8 v/ j. {) u/ W" m
  41. /* Macro definitions ---------------------------------------------------------*/5 p; F" q9 [( l' ~
  42. #define RING_BUFFER_MALLOC(size)  malloc(size)/ W. D+ M  Z* v. |8 F
  43. #define RING_BUFFER_FREE(block)   free(block)" \. l! {/ V, m; J3 |, ]

  44. # m  J3 S, S9 Q4 S8 @( w
  45. /* Type definitions ----------------------------------------------------------*/
    $ `7 }, U$ z; [2 r1 ]4 d% V1 u" u
  46. typedef struct5 g6 J1 }6 t3 C1 _5 R6 ?
  47. {4 Y4 r7 d( {# G& R" M, S* r
  48.   uint8_t *buffer;
    : |. A5 }+ E* ?7 @
  49.   uint32_t size;# r3 f2 w) G' r- r
  50.   uint32_t in;* O1 G4 m5 V$ B
  51.   uint32_t out;  E( v5 \" U2 C6 ]% ]* ]& Q) d
  52. }RingBuffer;
    1 o+ m/ Y1 |+ t/ l3 A. k
  53. * |; s, R. z3 W
  54. /* Variable declarations -----------------------------------------------------*/
    * a" ?5 C! G" r' h
  55. /* Variable definitions ------------------------------------------------------*/
    1 Y$ d3 l5 l- E9 i
  56. /* Function declarations -----------------------------------------------------*/* W0 \( @6 F& w5 D6 \. V
  57. RingBuffer *RingBuffer_Malloc(uint32_t size);
    " _4 B9 z+ Y' W1 a/ x
  58. void RingBuffer_Free(RingBuffer *fifo);
    : ?) b% ?9 s( N0 V
  59. ' r8 V3 L7 L# e+ v  D# T. q
  60. uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len);3 Q0 k/ ]# m4 D: X* P; |& z8 n
  61. uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len);4 p* x2 B& g- K# K
  62. $ a" u8 T) ]- Y; Z
  63. /* Function definitions ------------------------------------------------------*/  @1 e9 F( p" ^: @. z

  64. 7 Z- Y& s! }$ X  S! M
  65. /**& K- m! X9 f3 h& E6 M% C
  66.   * @brief  Removes the entire FIFO contents.- z1 X7 v' |/ C; P
  67.   * @param  [in] fifo: The fifo to be emptied.
    8 ~9 a$ ^, B' e$ f
  68.   * @return None.
    5 O4 }' t( d; F% I8 j" C
  69.   */
    + ]( a) A$ \% T" d
  70. static inline void RingBuffer_Reset(RingBuffer *fifo)# D- p( @, U2 |9 h: Y: ~
  71. {* k! g% u, O& C3 h: E3 D
  72.   fifo->in = fifo->out = 0;8 w0 _2 n7 G- W; R
  73. }
    ' _+ I- A  ?1 ?. H0 n9 t
  74. 4 D6 \- @# V1 O5 W
  75. /**/ d# C0 Y/ p8 i. Q' [
  76.   * @brief  Returns the size of the FIFO in bytes.4 o& j1 T+ D; |# P3 n; W; m
  77.   * @param  [in] fifo: The fifo to be used.- y3 Z* c) n  M% l) X" R
  78.   * @return The size of the FIFO.
    / }9 b8 ^- `2 c: H3 O- K
  79.   */5 N& v6 ^8 }( B7 c* x, H3 b7 J
  80. static inline uint32_t RingBuffer_Size(RingBuffer *fifo)
    : ~% a& @3 B2 o4 h! |  y
  81. {
    * p0 W. {. K' q1 D
  82.   return fifo->size;* G* p6 Y) f: U
  83. }
    ; h2 E1 I1 p8 D! r7 u8 a

  84. ; M5 ]$ C4 u1 v$ }: E6 E( Z
  85. /**3 ~/ l$ N, `0 n  ?6 u/ r% x/ N
  86.   * @brief  Returns the number of used bytes in the FIFO., [5 ?9 }+ |; ^! T8 |: c
  87.   * @param  [in] fifo: The fifo to be used.& i* c3 s( d/ a
  88.   * @return The number of used bytes.
    ! x* D' R" e, V4 ^% x+ |  U& x
  89.   */
    2 R5 F9 S& B) `9 }
  90. static inline uint32_t RingBuffer_Len(RingBuffer *fifo)
    / D* e9 G: O: f
  91. {
    8 E+ C& i, f* y' P3 g, M! M
  92.   return fifo->in - fifo->out;
    ( j, }. `8 y7 s: l
  93. }* H2 e! c5 Z- ~+ ?3 j4 t' W
  94. 1 o0 P( \7 c$ c, C/ I# _' l2 ?0 @- [& o4 x
  95. /**5 n! W$ T: B0 R* x2 q. X
  96.   * @brief  Returns the number of bytes available in the FIFO.6 _6 y# W1 O  \" \6 V# J
  97.   * @param  [in] fifo: The fifo to be used.
    3 `/ y: t# u( ^) p- \% i
  98.   * @return The number of bytes available.: y# ]7 Z$ S' q! _; P; k. t4 `7 t8 _
  99.   */
    ; Q  T+ `! k* j+ {
  100. static inline uint32_t RingBuffer_Avail(RingBuffer *fifo)! F6 I2 ]+ n5 C: z9 c0 ?( o
  101. {
    4 x& B3 ]/ ]  T" M3 u& p
  102.   return RingBuffer_Size(fifo) - RingBuffer_Len(fifo);
    * @1 C% M+ `( i% e) E
  103. }. ?- I# X$ E/ S# Q5 U. _  h
  104. ( @& ?7 b8 h: p3 y- h2 H: X6 f
  105. /**
    % B6 V$ ^1 N/ M
  106.   * @brief  Is the FIFO empty?! q7 F4 k! E" ]$ c! {# a
  107.   * @param  [in] fifo: The fifo to be used.+ H. \4 n- O; P$ q, \7 J! c
  108.   * @retval true:      Yes.9 t+ V9 v0 S6 w  m5 ~( E3 R( Q9 X
  109.   * @retval false:     No.8 I2 F( L4 M% M
  110.   */+ n& L' \7 D% S4 r% H% ]. B
  111. static inline bool RingBuffer_IsEmpty(RingBuffer *fifo)4 l9 C% Q% s. m9 _
  112. {
    6 F2 ~+ z% f7 ]
  113.   return RingBuffer_Len(fifo) == 0;
    7 a5 j$ i2 h4 _$ P0 S( G
  114. }9 C2 d3 j/ }+ M0 M6 C7 l

  115. ! J0 y, [, Q7 Z0 Q: L
  116. /**
    3 G% I. N5 g% U0 |- g' S: b
  117.   * @brief  Is the FIFO full?
    ' W# m1 O/ ~/ H3 c5 V8 ?4 F; `
  118.   * @param  [in] fifo: The fifo to be used.- Q. F' {) j0 r: X$ S
  119.   * @retval true:      Yes.$ y( N/ v% \+ Y  m$ u3 T
  120.   * @retval false:     No." n, q4 R/ R. n; N
  121.   */
    3 r; `1 D5 q  r3 z- J
  122. static inline bool RingBuffer_IsFull(RingBuffer *fifo)
    # @  o6 w9 T* C: R; X5 F7 K
  123. {; {& `3 c, ?, `+ U+ ]9 b- s' O
  124.   return RingBuffer_Avail(fifo) == 0;2 q2 q. w/ G8 t4 T5 u$ u
  125. }
    # C1 X& v: ^2 Y) W

  126. * _7 u2 g5 v6 A6 i* W- U. r
  127. #ifdef __cplusplus; T, a' T* ~. S0 l. p$ l* q) G& `
  128. }
    ) Y8 J0 E0 U% j7 z6 @% [
  129. #endif* h( A" t: z1 }

  130. * d/ C& H+ a3 I! h: `  r) S
  131. #endif /* __RINGBUFFER_H */% _2 ]# {6 L. Q
复制代码
! @: Y5 D  J7 L: D& m

" S) x# O4 b* T7 P* }RingBuffer.c 文件  r$ V1 S" E: ^9 a# u: |% i1 \! O1 [+ T
  1. <div>/**
    7 B, d9 x: U6 l) g# ]
  2.   ******************************************************************************
    ; J$ U3 H$ W2 S2 l
  3.   * @file    RingBuffer.c* n  c0 G5 T' j% j0 u
  4.   * @author  XinLi
    1 j, Q* g- o" ~0 r1 {  L
  5.   * @version v1.13 C- t9 p: m( v$ H
  6.   * @date    15-January-2018
    1 D/ C, d& F" m' ?) b: q5 F2 j0 d. d2 o
  7.   * @brief   Ring buffer module source file.
    % m! ]5 i7 G- E3 ~" m
  8.   ******************************************************************************7 A1 J% ]" _6 w" R
  9.   * @attention
    ! p' V1 a# X$ ?: U0 h
  10.   *
    1 C$ }' A" q4 q+ n
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>) G5 V" B* s/ ~# d! j' X
  12.   *4 d! i$ o0 B' `; g+ R
  13.   * This program is free software: you can redistribute it and/or modify2 U3 ?; C  ~' a; J
  14.   * it under the terms of the GNU General Public License as published by' q6 u2 ?& S: {$ L( M
  15.   * the Free Software Foundation, either version 3 of the License, or/ o- D3 ^7 |+ _/ Z" k& S5 h
  16.   * (at your option) any later version.: d7 C9 Y6 d& w
  17.   *
    , a7 ~2 s7 J0 ~/ V$ ~6 X
  18.   * This program is distributed in the hope that it will be useful,, x! S# K, F3 k4 S1 s; C
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    * v8 O  o- Z2 ^: {
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    + [& @9 c; @2 a
  21.   * GNU General Public License for more details.
    ; Q7 Z* E6 e. S3 O
  22.   *
    5 Q: _9 s' I9 q4 W; n* }. q
  23.   * You should have received a copy of the GNU General Public License
    9 F# k8 i  z7 W- N, n
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    : _$ t  g9 _) }. {1 x
  25.   *- o# Q( y6 X- h1 z
  26.   ******************************************************************************
    0 P; C( i5 X9 j; K* q
  27.   */
    ; R! [) X* u+ P5 ^" C6 Q

  28. 2 \/ y) t: b+ v. R) }
  29. /* Header includes -----------------------------------------------------------*/
    ! V( H# t  a, x& a2 C' n
  30. #include "RingBuffer.h"! S; r1 o+ F, V: T
  31. #include <string.h>) f3 A8 N2 D8 P0 e5 \/ d
  32. ' {7 U! W# N0 y
  33. /* Macro definitions ---------------------------------------------------------*/
    0 |( d- }( @: u: N6 C3 n
  34. #define min(a, b)  (((a) < (b)) ? (a) : (b))
    6 W' u; D8 \8 `# T" {4 Y
  35. 8 [  Q8 E9 A. a1 ~: h4 u2 V
  36. /* Type definitions ----------------------------------------------------------*/
    ( \$ \( c8 H( n( M  T! b
  37. /* Variable declarations -----------------------------------------------------*/9 l3 n9 Q* ~0 f) K4 Q- F- H
  38. /* Variable definitions ------------------------------------------------------*/
    $ H& H" a6 y9 x& N
  39. /* Function declarations -----------------------------------------------------*/
    2 H. A$ b# J' _0 A9 H
  40. static bool is_power_of_2(uint32_t x);4 S( r% z* A( t8 }: {/ ^
  41. static uint32_t roundup_pow_of_two(uint32_t x);% m9 U* w4 h& ]) l4 x* O
  42.   v7 f2 ?" i& t
  43. /* Function definitions ------------------------------------------------------*/
    9 @8 K, N& e2 e% }. U

  44. + S' g3 [; J+ s5 E: \# S3 k9 X
  45. /**, p/ c7 b9 o1 T/ J# H- J
  46.   * @brief  Allocates a new FIFO and its internal buffer./ x" p$ f7 h' n9 ~6 A% b
  47.   * @param  [in] size: The size of the internal buffer to be allocated.- ]  L1 d' f  I/ J7 `( \
  48.   * @note   The size will be rounded-up to a power of 2.0 x/ L% k9 g' g4 h- ?" q1 z
  49.   * @return RingBuffer pointer.4 A+ W) z) }2 E0 c
  50.   */
    4 y, N5 e4 g+ {( n  q/ {
  51. RingBuffer *RingBuffer_Malloc(uint32_t size)
    4 H) J* u* ~" e) e% ]8 P
  52. {. r, o# [9 C+ ~3 q$ }
  53.   RingBuffer *fifo = RING_BUFFER_MALLOC(sizeof(RingBuffer));* q8 L% a) E6 B

  54. $ V" s7 S. g/ l! {( `! u7 F( t2 r
  55.   if(fifo != NULL)
    1 ~7 x( m1 z6 F3 [( r6 ~) g$ a
  56.   {' x+ d. Y6 Z: A& J. y
  57.     if(is_power_of_2(size) != true)
    ( N! [; W' w% p5 t$ t5 v
  58.     {
    $ t8 w2 z3 A# Q" A4 K7 [0 L
  59.       if(size > 0x80000000UL)7 X% Y% F- @$ I/ T( R
  60.       {# z( z- i, q8 D0 M, P( f
  61.         RING_BUFFER_FREE(fifo);
    1 X/ v: c* N* g* S
  62.         return NULL;$ B# V3 S/ @- |% a* H& C  n
  63.       }, _( v1 ^6 Q2 {! e" {* h/ Z

  64. ' [+ g4 r% s/ E% k* r6 ?, N  [7 I
  65.       size = roundup_pow_of_two(size);& k" }; u; `0 l) [  l2 g" j
  66.     }3 [' ?% K5 w2 u' ^3 ^
  67. 5 `6 l0 r2 k+ x  y2 F& g4 \5 D: B( s
  68.     fifo->buffer = RING_BUFFER_MALLOC(size);
    ( Y! e5 r% a! O3 Q* d2 ~

  69. 0 I& s: N6 p0 y1 |# R
  70.     if(fifo->buffer == NULL): G2 ^; U5 h7 L3 C$ o  A
  71.     {. R+ M4 s* o& P: f
  72.       RING_BUFFER_FREE(fifo);5 I6 s0 Q+ U) u
  73.       return NULL;
    0 z) T0 y/ T- [. J& e+ D0 |
  74.     }/ \4 A+ F) J' K4 x' c
  75. ' k3 j1 R* n* y- p
  76.     fifo->size = size;0 f$ k& R  a) X* n/ _- e; P, p
  77.     fifo->in = fifo->out = 0;' Q. f5 y! |  R- N+ {6 z/ G4 s
  78.   }! Q6 W% g  x4 {" W! N4 ^
  79. : M" C9 b( c% f/ o, z
  80.   return fifo;
    & f) o# D4 c5 Y; G  \" \
  81. }) @: M. {# Z# t" d9 f
  82. * r. Z& x0 Z2 H$ x$ S* B" W* `* `7 j
  83. /**2 Y: R% \- ]. H" p, B6 O
  84.   * @brief  Frees the FIFO.
    & ^0 y& N- A2 |, y8 \
  85.   * @param  [in] fifo: The fifo to be freed.
    - v0 L. |/ ^; ~6 ?- {- Q
  86.   * @return None.4 a) k7 T' S# S2 ?! ?+ P- g# `7 C* O3 G
  87.   */" Z" ?$ p9 C9 C& _) j
  88. void RingBuffer_Free(RingBuffer *fifo)
    + }; R+ O9 Q, Y
  89. {
    " j1 Z% V' o4 [( z6 I+ x- h
  90.   RING_BUFFER_FREE(fifo->buffer);# f' W' c" \$ H) z
  91.   RING_BUFFER_FREE(fifo);
    " ?  {, d2 T2 r
  92. }
    9 {/ c/ c" q  I* u" Q

  93. ( E, I  k( Q9 N5 C5 S
  94. /**
    6 i) D* v, ~, l, V" m
  95.   * @brief  Puts some data into the FIFO.
    - t0 b$ `, T& x
  96.   * @param  [in] fifo: The fifo to be used.
    8 h3 d" D' d" Y8 i9 @1 }9 k
  97.   * @param  [in] in:   The data to be added.
    ! {8 R6 ?) a. J0 P% O( S
  98.   * @param  [in] len:  The length of the data to be added.
    $ ?! m& B! y5 t5 r0 e7 y) A. w6 J
  99.   * @return The number of bytes copied.
    7 K% X; ~! @! C
  100.   * @note   This function copies at most @len bytes from the @in into
    2 G4 n  q7 \: Z2 }- z
  101.   *         the FIFO depending on the free space, and returns the number  f! p7 W% r+ a, X7 ~3 \, F
  102.   *         of bytes copied.. ]" D9 h' \  |
  103.   */
    * d3 R$ M; B5 \, G1 A
  104. uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len)
    8 u. O" c  m6 g! d" d
  105. {
    ) B" c+ m& Q( V2 E/ w. \' x1 [) a
  106.   len = min(len, RingBuffer_Avail(fifo));4 F  g* `. c2 r7 l: P
  107. ; u9 b+ x, O# r/ y
  108.   /* First put the data starting from fifo->in to buffer end. */* ~5 C, R2 `4 ], l: G0 n
  109.   uint32_t l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));' [5 |9 {/ {2 ?& r5 S4 K) b' g1 M
  110.   memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), in, l);
      @) V' A- y. J- Z
  111. - i5 u" P. H7 G
  112.   /* Then put the rest (if any) at the beginning of the buffer. */
    / `  }; L7 a7 c4 ~& G8 t; i
  113.   memcpy(fifo->buffer, (uint8_t *)in + l, len - l);/ X* M% ~* \- [. G, V  {
  114. 7 V3 G6 d8 H' U' v9 c+ P
  115.   fifo->in += len;
    . D; [) L7 `- `4 \, o; f5 ~; g

  116. 7 u& H- l# Y3 g/ f: g
  117.   return len;, P9 V& A) Q! x2 b; W' L
  118. }6 v: g4 Q* F+ d  O/ s
  119. 0 s/ D! D1 @7 I
  120. /**. v: C* }1 N7 _4 i  V! G/ `
  121.   * @brief  Gets some data from the FIFO.
    & _' a. Y% [" l# Q# Q8 B- l
  122.   * @param  [in] fifo: The fifo to be used.6 h+ b( ^8 {& Q
  123.   * @param  [in] out:  Where the data must be copied.- Z* l$ z/ Q- h; D( a* Z  t
  124.   * @param  [in] len:  The size of the destination buffer.
    : C( [3 A$ |4 a: N, P- v
  125.   * @return The number of copied bytes.8 {6 H% Q  E# f6 J5 @) c( c) C
  126.   * @note   This function copies at most @len bytes from the FIFO into
    " T% q" b- O$ j; C
  127.   *         the @out and returns the number of copied bytes.
    4 d8 g$ i6 b' l
  128.   */
    . k9 I$ u+ n5 V
  129. uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len)8 h# U: \% ?0 J# {0 C4 X1 R9 g
  130. {
    3 x9 I! B2 P# ]7 E' h
  131.   len = min(len, RingBuffer_Len(fifo));
    ' d( y! @* E/ h
  132. , N$ j+ n6 C5 `  u3 T4 [  H- `7 q+ Y
  133.   /* First get the data from fifo->out until the end of the buffer. *// q! K" ~$ L$ v% Y0 f7 f6 @# ?
  134.   uint32_t l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));
    . I4 N: j* Z: j
  135.   memcpy(out, fifo->buffer + (fifo->out & (fifo->size - 1)), l);
    2 R( t8 ^) i% x' F" P6 a
  136. % I! N3 E( p: a! y: ]- h
  137.   /* Then get the rest (if any) from the beginning of the buffer. */: v6 b; P: k. J+ ]; e6 T
  138.   memcpy((uint8_t *)out + l, fifo->buffer, len - l);
    8 U7 B3 a0 K( Z+ `" E6 [0 B

  139. / y1 Z) R  Z" _/ z/ ]
  140.   fifo->out += len;/ G. C1 F8 }- o9 {+ P$ r

  141. * D: z6 z( J& L  S
  142.   return len;
    4 `# j0 v; `) l' g) [/ n
  143. }* ]! @. d- J8 J8 L! g8 [
  144. + F" T% q9 l% a8 J1 T5 }& ^
  145. /**
    / x1 F3 I1 M/ k
  146.   * @brief  Determine whether some value is a power of two." J% T2 A  E3 F$ w2 m5 k" T) a
  147.   * @param  [in] x: The number to be confirmed.
    , s$ L( a+ {. ?3 P( J
  148.   * @retval true:   Yes.
    / p/ N+ i: l, {1 I) R" l
  149.   * @retval false:  No.7 L/ o( I- C! m* @
  150.   * @note   Where zero is not considered a power of two.
    9 g' C$ @# s( V; ]
  151.   */
    # g+ {! K( z* F  B, Y! W  b
  152. static bool is_power_of_2(uint32_t x)
    % u+ Q- k) g7 b, J0 W7 D
  153. {" b) U) X4 J! a8 O
  154.   return (x != 0) && ((x & (x - 1)) == 0);
    4 h8 {- @0 V- L, t$ T
  155. }
    & w: W7 l" W% S, y
  156. 5 Z9 j( v, H9 j7 I  `8 b2 H' ]) v
  157. /**
      K3 w& }4 n/ ^2 W6 r
  158.   * @brief  Round the given value up to nearest power of two.
      J& H/ J8 T( s" C5 |, n! _! \! N
  159.   * @param  [in] x: The number to be converted.5 T% Q1 [9 I7 c0 c
  160.   * @return The power of two.
    2 x/ ?+ l$ _4 v9 f
  161.   */$ l3 }0 ], L' x
  162. static uint32_t roundup_pow_of_two(uint32_t x)& j$ n& ~1 K, a$ i5 s
  163. {& y9 g" _$ w7 J) `! t. r
  164.   uint32_t b = 0;- c) [, j1 w2 x+ o6 D5 J

  165. 4 p- t2 v7 v( I: o
  166.   for(int i = 0; i < 32; i++)
    1 w( A, u3 h. C8 D/ M1 b7 `) b& a
  167.   {1 \6 a2 Z, N/ c: v% p7 a
  168.     b = 1UL << i;4 J* n4 x3 X; |# }7 p1 O! n

  169. # S: `, P2 H1 V* C% {" A+ s# d8 ?
  170.     if(x <= b)" p( Z* R  N' ~9 j
  171.     {
    . _5 u+ B! }$ ~, I+ Y
  172.       break;. y, c- U, v( d+ u2 S, \0 ]: N# v- t
  173.     }
    1 L+ E# C+ b5 {7 O" s8 P/ A2 e# J2 i
  174.   }
    1 C( B- V5 v- z$ Q% i! E

  175.   a/ @) `  ~3 N8 i+ T+ B9 e& }2 E
  176.   return b;9 r5 v# K# g6 f$ D6 }; J# Q
  177. }</div><div></div>
复制代码
: y* v  B' L" v) r3 X. h
) U* t6 M& f2 [) F6 Z) G
CAN.h 文件
# N5 V9 n3 c9 u) [3 E; V% l
  1. /**6 t. U: U3 g3 b0 Y( \0 D$ b
  2.   ******************************************************************************
    4 O1 X3 P; ~! Y% b9 w
  3.   * @file    CAN.h
    7 _7 C( ]) d  O# w9 C
  4.   * @author  XinLi
    9 L3 \1 H, o; O, X- K' r% j/ B
  5.   * @version v1.0$ N, E' |1 [+ X  {, W
  6.   * @date    24-June-2018
    # ]" ~! J% ?) g1 Q5 ^: f
  7.   * @brief   Header file for CAN.c module.7 U3 h. @% ?5 u; v# @3 f- f
  8.   ******************************************************************************
    * K7 m: S- q8 M
  9.   * @attention
    1 x* L% Z0 \' o$ J  g) {" T* `" ^
  10.   *
    5 q- J) y. P& I+ d, }0 J& V! k
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>8 U. B! `7 k' P: P0 _4 b& C
  12.   *; L8 T/ j, a# B" n  k. a
  13.   * This program is free software: you can redistribute it and/or modify
    & |, k- J, E# K+ C. D- Z/ z
  14.   * it under the terms of the GNU General Public License as published by
    $ n) j5 m* X& k. q" h: P
  15.   * the Free Software Foundation, either version 3 of the License, or: b; G; |, q5 z4 \$ I0 T
  16.   * (at your option) any later version.( m$ Z+ c% h0 h
  17.   *
    " n& A4 Z) L( r; H3 z
  18.   * This program is distributed in the hope that it will be useful,
    % w1 ?* d1 a7 Z* t/ b. `
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    + T& p( B4 O1 E6 m& v: d: t2 a
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      ~0 N7 ^; t$ @# t
  21.   * GNU General Public License for more details.
    - n& T$ g/ I! j7 e
  22.   *
    4 }  W8 \7 _$ S4 f* G4 E9 c
  23.   * You should have received a copy of the GNU General Public License
    2 u" l; `' m* u. H! C
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    # U1 J& w: c7 s, k" s( e0 y" L
  25.   *
    $ Z) ?8 i/ ]9 J6 F6 I
  26.   ******************************************************************************0 f  H  P7 C: w4 _4 {3 S5 \
  27.   */
    2 k+ H" w( d% m
  28. 0 M, q/ b0 I% O; Z4 S
  29. #ifndef __CAN_H
    " b4 R9 `. ]$ O9 b9 g% T; k5 i
  30. #define __CAN_H. C4 k* l/ O' Z: m6 [1 T6 B/ S

  31. 5 I- M% B8 r" e7 l6 \' j2 r- G0 ?
  32. #ifdef __cplusplus
    + x- i+ A4 p4 r. ~" O4 H# h
  33. extern "C" {
    ' ~3 J: C( _' f; m) Q2 s$ Y4 T- s
  34. #endif: @  M. @" B' l9 B! N- @

  35. / L2 @4 x- u7 S! _" [8 q
  36. /* Header includes -----------------------------------------------------------*/5 t4 U9 G! o% [; R# [
  37. #include "stm32f10x.h"& m9 j- \' t. p& k) j. Z
  38. #include <stdbool.h>
    # }- P2 S2 t- J, Y0 d% Z( U! `$ \
  39. & D9 A" c1 i# h7 A* _/ E2 D% H2 Z/ q
  40. /* Macro definitions ---------------------------------------------------------*/* @% \7 t& m. k# S
  41. $ s* G* v' w$ P/ Z
  42. /******************************* CAN1 Configure *******************************/. d" A5 a$ J/ e
  43. #define CAN1_TX_BUFFER_SIZE        (16)
    ( |8 F  {* a5 O7 {" k$ W& `
  44. #define CAN1_RX_BUFFER_SIZE        (16)
    ( d0 C7 Z3 p" h; ?5 h
  45. " _! x- g! u% z; O- k* Q
  46. #define CAN1_TX_GPIO_CLOCK         RCC_APB2Periph_GPIOB
    . K9 D8 H8 U. s$ t
  47. #define CAN1_RX_GPIO_CLOCK         RCC_APB2Periph_GPIOB9 t. m, ?: ~" J# b/ f1 h9 v

  48. & |6 \$ g  n: q
  49. #define CAN1_TX_GPIO_PORT          GPIOB. M+ ?  Z. ^2 i# P7 k* J2 `
  50. #define CAN1_RX_GPIO_PORT          GPIOB
    3 l/ x4 X1 Q% {- W4 y# U

  51. # |4 k( {$ s, r5 T/ E' P! l
  52. #define CAN1_TX_GPIO_PIN           GPIO_Pin_9
    6 U; @; \0 C. ?9 [) q7 [! N* v( l3 P
  53. #define CAN1_RX_GPIO_PIN           GPIO_Pin_86 ~5 b& p/ E) r8 B8 O
  54. 2 `, S3 T9 J9 m* M5 N* m, X
  55. #define CAN1_IRQ_PREEMPT_PRIORITY  (0)
    ) z$ V; f2 \( Y2 ^& s7 A. L
  56. #define CAN1_IRQ_SUB_PRIORITY      (0)# k+ m: X6 r! U$ Z4 b
  57. ; q. U# h- o' ]% _" Y" M3 I9 F
  58. #define CAN1_PORT_REMAP()          GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE)0 u3 |: ]% o. `0 x8 i5 y
  59. /******************************************************************************/
    # d+ d  G% q: b; a: l' t1 ~

  60. * O$ e$ k! h. E/ V( ?. J0 c3 Z
  61. #ifdef STM32F10X_CL; \5 J4 G: H- |) V. A' b! C6 f* A( R
  62. /******************************* CAN2 Configure *******************************/
    0 s% l% J2 a9 y8 t# X# O
  63. #define CAN2_TX_BUFFER_SIZE        (16); d' i3 X! c: G+ q
  64. #define CAN2_RX_BUFFER_SIZE        (16)
    ' @( D4 }/ j% O. T* u# B% a4 z

  65. " ]; U+ u. ^1 ~  X% R' {/ T
  66. #define CAN2_TX_GPIO_CLOCK         RCC_APB2Periph_GPIOB# A0 l/ A( F+ P$ A! v+ X
  67. #define CAN2_RX_GPIO_CLOCK         RCC_APB2Periph_GPIOB' y4 Y3 Y9 i6 c
  68. 4 _& |6 I! c' ~: [8 [7 Z, ?" V+ m  P
  69. #define CAN2_TX_GPIO_PORT          GPIOB
    2 F! O, u3 H% R. `: r
  70. #define CAN2_RX_GPIO_PORT          GPIOB
    0 Q8 V2 C* N8 ~" w# ?% @
  71. 3 _6 u8 J+ v& g# `) f" q( t/ W) i
  72. #define CAN2_TX_GPIO_PIN           GPIO_Pin_13
    # W" O6 A( A7 a4 e. I+ T# {' `
  73. #define CAN2_RX_GPIO_PIN           GPIO_Pin_12
      o; B$ |8 R3 k! v" y$ I# x0 @6 w
  74. 3 G$ O% v5 i& }) O  g
  75. #define CAN2_IRQ_PREEMPT_PRIORITY  (0)$ X! h6 S' I4 }) A9 x+ T
  76. #define CAN2_IRQ_SUB_PRIORITY      (0)
    ; V9 G5 ]/ t8 ~+ k+ E, H9 V: ?
  77. 1 A' |$ b& S& l# ~8 W+ O
  78. #define CAN2_PORT_REMAP()          GPIO_PinRemapConfig(GPIO_Remap_CAN2 , DISABLE)
    / \. A% T, s0 \" i
  79. /******************************************************************************/
    3 W$ S6 Y9 x% S9 G* H9 S* ]: Z
  80. #endif /* STM32F10X_CL */
    1 I( J0 ~! E3 ?) l3 c( e
  81. 0 d2 h0 M) R) o) j4 a% m" l
  82. /* Type definitions ----------------------------------------------------------*/7 C. L. I' _4 V9 b" [) l
  83. typedef enum* D( s& h) \8 r! x: ^3 K4 z
  84. {
    / ~/ |; p4 S) R! a" Y+ B  C
  85.   CAN_WorkModeNormal   = CAN_Mode_Normal,
    6 `& B0 ^( Z, V& X( G7 {
  86.   CAN_WorkModeLoopBack = CAN_Mode_LoopBack
    " ^5 A, t/ ^) a
  87. }CAN_WorkMode;/ P3 R8 V6 c9 B' _
  88. 0 z6 j2 ~7 X6 ~- }: G" n
  89. typedef enum4 L# ]5 N, z* R% b* @! V1 z/ ~% p$ p% j
  90. {; [9 L2 s8 b$ `, o% C; s
  91.   CAN_BaudRate1000K = 6,- Q5 X* I: I$ P" ^- u; p& w
  92.   CAN_BaudRate500K  = 12,
    ( j: t3 o, }2 B8 E  M! M% ?
  93.   CAN_BaudRate250K  = 24,
    % D' K' t4 M" u1 S, D. g0 g. u0 ^
  94.   CAN_BaudRate125K  = 48,
    # I" q, F; ?6 R
  95.   CAN_BaudRate100K  = 60,
    " M$ r% U6 o# ]4 B3 y+ m
  96.   CAN_BaudRate50K   = 120,
    ; \2 G* u3 M1 {- w! D8 j( b: W
  97.   CAN_BaudRate20K   = 300,
    3 o: P. ?7 Q4 b, _9 O' L
  98.   CAN_BaudRate10K   = 600
    ; ^6 a$ W- Q- P" T7 U# ^1 w
  99. }CAN_BaudRate;
    % E4 m/ M) w7 m0 l
  100. . \% k. d; x' M' l5 O5 t$ d
  101. /* Variable declarations -----------------------------------------------------*/6 Z0 u/ Z1 e$ P3 S; F5 K
  102. /* Variable definitions ------------------------------------------------------*/. k4 t  y8 P. G$ t! M0 }2 y
  103. /* Function declarations -----------------------------------------------------*/0 X4 `6 c, ~8 f; D# d9 d# l: K. o4 a
  104. void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId);0 Y5 W; b9 b$ A/ S7 u
  105. void CAN_Unconfigure(CAN_TypeDef *CANx);. Y% K7 [0 f5 T9 y

  106. 9 ?% I0 r- e0 @. R
  107. void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));
    4 W! [3 m- Z+ X) x
  108. void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));' q/ T0 B0 S8 {& _

  109. + M- E; \4 h# h$ `% X
  110. uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number);1 ]0 S5 p1 E. Z! d7 P
  111. uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number);
    3 Z+ b4 r) T& q/ i! Y$ m* [
  112. 5 U2 p8 f8 [5 W1 Q. N4 z
  113. uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx);6 ]) A1 _+ y% T! `! j* G' H7 r. V
  114. uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx);( L" Y, r9 y6 Z: s) S  B
  115. uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx);
    & t0 t& U) e( _  z# q& }
  116. uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx);: r! F0 ~6 A+ w+ j2 j; h1 a$ s

  117. / S6 b: B3 z; C% @* V) B& j
  118. bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx);
    " n5 P- g. v0 e* m3 N7 h% @+ f* k
  119. bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx);- e9 X0 Y( S8 g' t: D) B
  120. bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx);9 b- o* a8 Q4 i* h/ W% }& ~
  121. bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx);! A7 D! u% c0 r, M7 f  P1 k& n
  122. 0 @- O4 h7 u. C2 M% `" i  L' p
  123. void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx);( w2 k6 M. ]1 |* K& D
  124. void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx);- {7 I5 r3 s/ g0 P9 {0 Y
  125. ( Q6 K" t! b9 P, }5 U
  126. bool CAN_IsTransmitMessage(CAN_TypeDef *CANx);
    1 {+ q- y4 B5 H2 S. K( G2 f5 B

  127. ' a+ \9 {( k# M& s/ {2 J3 Q3 X
  128. /* Function definitions ------------------------------------------------------*/! ~+ b$ O. ?& r% s
  129. - O; c5 @0 B$ b9 V6 h+ W
  130. #ifdef __cplusplus% f+ j7 T: c6 r) N" U; Z
  131. }9 u7 Z8 X* _7 `" l" E) |
  132. #endif
    5 L! A+ U; |- P1 R( C

  133. ' N( h- }7 @1 B" s' W- l' `
  134. #endif /* __CAN_H */
    4 W$ A* \0 ^9 Q# R  @) R4 [2 C9 c
复制代码
: u+ F6 g& r( {
1 z2 c9 g  S2 g. ?% F

- \; i7 Z8 e1 l2 ICAN.c 文件* Q% g7 t( ^3 I4 m* n4 \& [

1 s+ A( G4 z, p. E" {
  1. /**
    + }3 j4 S6 X/ M" r$ f% I6 b/ k
  2.   ******************************************************************************! ^& f: `% M3 h- m/ l! D
  3.   * @file    CAN.c
    $ i7 A5 a, @4 n4 \- [$ ]0 g
  4.   * @author  XinLi6 T3 r, j% @" s6 {; G  x
  5.   * @version v1.0
    + x; p; _  M3 `& t. o' K
  6.   * @date    24-June-20185 R, d8 ^' v! J4 D' w3 o
  7.   * @brief   CAN module driver." a6 z7 r+ K. X; k- e
  8.   ******************************************************************************6 U! m- P& m" w- \. R9 }4 L
  9.   * @attention
    ( J& K* F" z7 B/ O: d$ J- x
  10.   *
    # a3 `2 A' ~+ \* b+ w
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    4 ?3 S/ V( t0 n8 K( P
  12.   *
    6 K9 u, L) R' ?9 Z6 ?/ l' Z
  13.   * This program is free software: you can redistribute it and/or modify
    $ ^8 C4 b+ U" S/ s6 k$ S8 U
  14.   * it under the terms of the GNU General Public License as published by
    . r7 b# M% e$ e1 G$ B, E. K: F4 k  a
  15.   * the Free Software Foundation, either version 3 of the License, or& Y2 ^- Z* C# E% e% [0 I4 x  z, K
  16.   * (at your option) any later version.
    ) N4 o4 H  @& P! ?5 H1 D" O3 T
  17.   *
    ( {9 P8 b  C9 \0 h9 K' L
  18.   * This program is distributed in the hope that it will be useful,) w: N6 [; N. p. x7 Z0 p
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of, p, [9 x# ?- w1 I( I& R2 ]
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the& [" _" h" r) d$ }  Y3 n" W
  21.   * GNU General Public License for more details.
    5 K  H; j  I4 _6 d8 ]3 C+ `
  22.   *2 n8 L- ~) ~/ ~  S8 x
  23.   * You should have received a copy of the GNU General Public License
    ) g, X2 K# t* @) F
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>  |' ~4 }4 `. y4 E3 E" `: y% E' e3 A
  25.   *0 f0 z- M! j1 c/ G# H  I
  26.   ******************************************************************************' [, M6 t+ i1 {7 q. C$ j4 O
  27.   */
    2 v1 {! P3 t" _. |0 A
  28. # R7 F* O' Z1 B) w6 m3 _
  29. /* Header includes -----------------------------------------------------------*/0 c* Y7 D: K& U5 _- L
  30. #include "CAN.h"2 G3 t6 O0 \; ~+ x
  31. #include "RingBuffer.h"& D* W6 H! F* r! T6 r
  32. 9 l, k3 U: ?+ v! d7 @5 {
  33. /* Macro definitions ---------------------------------------------------------*/1 v- F2 x" V: L& Q; y3 V; K' s# i
  34. /* Type definitions ----------------------------------------------------------*/
    ( z2 _  A6 m4 }$ \
  35. /* Variable declarations -----------------------------------------------------*/
    7 w- f$ e3 C3 B
  36. static volatile bool can1InitFlag     = false;
    : f. z" `4 @; c/ D
  37. static volatile bool can1TransmitFlag = false;( A# u. }6 j! E8 K- N" i/ m

  38. ! ~6 c/ `# i1 B; C" K$ M
  39. static volatile void (*can1TransmitFinishCallback)(void) = 0;
      e' b$ I; j. a# U# B; X% V
  40. static volatile void (*can1ReceiveFinishCallback)(void)  = 0;
    $ L. j8 O5 [2 ?+ X. x# R2 l

  41. 3 E5 _) \- \7 z' q. T5 v+ \6 N
  42. static RingBuffer *can1TxBuffer = 0;
    % C$ N+ N- U$ {( ^% B& S- h: k3 J
  43. static RingBuffer *can1RxBuffer = 0;& z9 |) V: o* H' x

  44. & I0 I5 o' d5 B5 l
  45. #ifdef STM32F10X_CL9 H; r- ^% s. W) s. s7 Z9 A
  46. static volatile bool can2InitFlag     = false;
    6 K  E& ~6 ]( Y9 f
  47. static volatile bool can2TransmitFlag = false;
    ; c3 y1 F6 q% B: \

  48. % D+ }9 i5 P  O4 w
  49. static volatile void (*can2TransmitFinishCallback)(void) = 0;) m3 n% z8 ]2 \3 n! S
  50. static volatile void (*can2ReceiveFinishCallback)(void)  = 0;. o" d  o/ t' D/ [1 d

  51. " e" o5 n$ _8 f) E
  52. static RingBuffer *can2TxBuffer = 0;
    $ \: t+ }$ |) h
  53. static RingBuffer *can2RxBuffer = 0;9 j( F1 i3 ^" g+ G) t# T
  54. #endif /* STM32F10X_CL */
    9 B9 o6 c; H4 H  f. m( F( N4 u
  55. ' ^8 n* O- @5 w( S  ^
  56. /* Variable definitions ------------------------------------------------------*/
    . K" v) L/ h6 p2 ^( u1 E
  57. /* Function declarations -----------------------------------------------------*/7 b- X& w( k& J% d2 N" p2 ]
  58. /* Function definitions ------------------------------------------------------*/( ?. K' v& V1 Y( ]' I! `: O% O
  59. 1 ~0 M: j! f) l2 V6 O
  60. /**! h- K$ T" s; s
  61.   * @brief  CAN configure.
    5 o' C9 e5 g2 K- z2 ?) p; R1 t; }1 Y
  62.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.8 E! r$ f5 E( g" X# s  @1 h
  63.   * @param  [in] WorkMode: Work mode.
    9 e) ?  _3 b: y+ e' a' s) H8 I
  64.   * @param  [in] BaudRate: Communication baud rate.6 y- z: U. k2 d- z2 S
  65.   * @param  [in] StdId:    Filter standard frame ID.
    4 c5 {+ ~5 U( D% ?. e/ `" {' F
  66.   * @param  [in] ExtId:    Filter extended frame ID.
    - C+ ~' P1 D+ w  w
  67.   * @return None.' W0 t$ V5 L5 {
  68.   */8 e( d' K" c& F' U/ A
  69. void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId)
    , _, r. H/ z& O
  70. {" E; ^+ e1 Q# f, ^, \( T, ~
  71.   GPIO_InitTypeDef      GPIO_InitStructure      = {0};
    + C0 R; N3 s  P1 d4 |+ x5 n
  72.   CAN_InitTypeDef       CAN_InitStructure       = {0};
    4 b0 l: v8 d1 c$ G. ?
  73.   CAN_FilterInitTypeDef CAN_FilterInitStructure = {0};: _% e5 \, p$ ]( D! o( U, x) o
  74.   NVIC_InitTypeDef      NVIC_InitStructure      = {0};  W! P+ G8 B. T. n  G% o
  75. , m3 L# J4 n* V" b( M. x- s1 i; V
  76.   if(CANx == CAN1)
    / h" }- t2 ]/ r$ U7 k
  77.   {
    : K; R5 y7 [4 C) P# K
  78.     if(can1InitFlag == false)
    / A. Z2 j+ y4 W. B  [
  79.     {$ v" `* V8 X, ]# Q: @( Q. a: T! }
  80.       can1InitFlag = true;
    + m1 T) m* n& W; T! N( {  m

  81. # @% n5 o- ]  q$ z6 K) ]
  82.       can1TransmitFlag = false;4 E( Y% w( F  X  s
  83. 6 [" b9 ]$ R2 ]) m
  84.       can1TransmitFinishCallback = 0;
    * {" `/ N( s5 {9 X$ ^/ a
  85.       can1ReceiveFinishCallback  = 0;; \6 ^/ v2 [8 H6 O, X6 T; p

  86. % m$ I  w$ F- g, {
  87.       can1TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN1_TX_BUFFER_SIZE);' D7 e+ E0 J# U& s8 I
  88.       can1RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN1_RX_BUFFER_SIZE);/ B" ?7 ]2 E# F- W
  89. 5 T/ B: U* R4 y1 _0 X) K6 U8 E. M
  90. #ifdef STM32F10X_CL3 A% v" A5 e3 W0 |* Q1 ]# u
  91.       if(can2InitFlag == false)
    # s) @* s/ e% ~9 e
  92. #endif /* STM32F10X_CL */6 l8 ?+ h0 Q+ O, \- ~8 P
  93.       {& a5 N, w, K* X, R. w
  94.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);6 k( t: Y" P% `8 i$ G/ f" N3 \) s- Y
  95.       }; k6 F6 E0 ^; w) [; _
  96. 5 j( U, P8 |; ^
  97.       RCC_APB2PeriphClockCmd(CAN1_TX_GPIO_CLOCK | CAN1_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);5 \# o& q5 S3 M0 `7 z; z  Z

  98. % J- a7 O$ F, u: ]4 |
  99.       GPIO_InitStructure.GPIO_Pin   = CAN1_TX_GPIO_PIN;
    ! |" ~  c2 x$ W- H) Z6 X" V/ Z
  100.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;) b. a2 R7 p  X- z8 I2 z0 _: j+ V; d
  101.       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;4 G2 s9 m. m  w9 b. s
  102.       GPIO_Init(CAN1_TX_GPIO_PORT, &GPIO_InitStructure);
    * e3 R6 h+ ^- C& i
  103. , g6 |  P3 D6 R' G% y! _
  104.       GPIO_InitStructure.GPIO_Pin   = CAN1_RX_GPIO_PIN;1 }$ _# V/ \6 g1 I: L/ h8 d6 H6 b) S
  105.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;# Q& J7 Q/ S! f1 S7 y+ S1 V
  106.       GPIO_Init(CAN1_RX_GPIO_PORT, &GPIO_InitStructure);5 X2 X/ j6 R+ Y8 n& b) A+ J4 H

  107. ' w1 {) c# w% ^; m$ y$ g
  108.       CAN1_PORT_REMAP();
    . r$ L9 W1 `+ W# n

  109. / F3 ~8 r7 T9 Y, S2 |  @# v
  110.       CAN_InitStructure.CAN_Prescaler = BaudRate;0 W, |: `) B/ S2 J; x* ^3 D
  111.       CAN_InitStructure.CAN_Mode      = WorkMode;
    9 K3 h6 g0 b1 ~. h1 z3 `! l  e- \$ }
  112.       CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;
      t" r* y7 L1 t; {) ^
  113.       CAN_InitStructure.CAN_BS1       = CAN_BS1_3tq;
    ( c0 Y  j  D2 ~) r: O3 a
  114.       CAN_InitStructure.CAN_BS2       = CAN_BS2_2tq;
      E1 X6 y% G3 ~* \) Q3 M; P
  115.       CAN_InitStructure.CAN_TTCM      = DISABLE;2 I! Y8 E- _- f. s: k0 G& o
  116.       CAN_InitStructure.CAN_ABOM      = ENABLE;2 v; \8 R# c* i+ ^0 P4 ~% B/ |
  117.       CAN_InitStructure.CAN_AWUM      = DISABLE;. \! q, S) ?0 B8 v7 U% W1 D
  118.       CAN_InitStructure.CAN_NART      = ENABLE;
    6 s; d# c# C! L- w# N3 i
  119.       CAN_InitStructure.CAN_RFLM      = DISABLE;& B8 ^! }7 z7 P" R8 C- C
  120.       CAN_InitStructure.CAN_TXFP      = ENABLE;' _9 J) ?+ {1 B2 m+ {$ c* U3 j
  121. ; K4 C! x0 j. |" v
  122.       CAN_DeInit(CAN1);& q8 m. N1 ]4 o1 R; e" O
  123.       CAN_Init(CAN1, &CAN_InitStructure);
    $ i- [; ~" P/ }: r( q
  124. 9 ~% L$ x8 b5 R7 e
  125.       CAN_FilterInitStructure.CAN_FilterIdHigh         = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);8 _4 b# k) C/ ]$ v! }( R, O
  126.       CAN_FilterInitStructure.CAN_FilterIdLow          = (uint16_t)(((StdId<<18)|ExtId)<<3);
    ) c% F2 x4 W0 g4 S% `& `7 |
  127.       CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;
    6 {, [  J2 J; U2 E: |; _
  128.       CAN_FilterInitStructure.CAN_FilterMaskIdLow      = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;
    5 ?/ Z( Q( {9 ]7 n- E
  129.       CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;* P# k) q! L* R( R) E- s
  130.       CAN_FilterInitStructure.CAN_FilterNumber         = 0;0 J  i3 Y9 t* N
  131.       CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask;
    ! x# E+ d1 I$ J4 v
  132.       CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit;
    * b, z9 P" V+ F" v
  133.       CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;, a8 k/ Y. ?2 l4 i1 d3 A# u& h8 I( E
  134.       CAN_FilterInit(&CAN_FilterInitStructure);
    & C, D0 H, T& D- L- G- ]

  135. - b6 q3 d7 _. V- V' G: A1 n4 p
  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 |
    0 V# o, {7 M  \& m5 K8 o' `
  137.                          CAN_IT_WKU | CAN_IT_SLK  |CAN_IT_EWG | CAN_IT_EPV  | CAN_IT_BOF  | CAN_IT_LEC | CAN_IT_ERR, DISABLE);
    $ \8 u" E$ Z) e
  138.       CAN_ITConfig(CAN1, CAN_IT_TME | CAN_IT_FMP0, ENABLE);6 P  J- D' E' A

  139. ' T7 M& ?; d1 a& B5 N
  140. #ifdef STM32F10X_CL$ |/ A* s, L1 [0 e, |7 Y# _
  141.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_TX_IRQn;; E9 v0 R" ~. x
  142. #else' u0 h. W+ n9 p' X
  143.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_HP_CAN1_TX_IRQn;
    & R" J# l; q5 l0 C! ?
  144. #endif /* STM32F10X_CL */
    2 H# a, |4 C! F7 s# N

  145. * G* R4 k& x. ]* Z6 y
  146.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;
    * L: G% y. S6 Z4 D7 I
  147.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN1_IRQ_SUB_PRIORITY;
    3 ?( ], V& U( D" u
  148.       NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    , R7 U' d9 o* R5 Z/ T" [8 r, E
  149.       NVIC_Init(&NVIC_InitStructure);# G0 _. d* @9 W; s$ Y
  150. ( i% \" J3 P' U5 L! d
  151. #ifdef STM32F10X_CL& S; B% S% @1 x' x
  152.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_RX0_IRQn;
    & D" p3 o) D7 n0 N$ e3 U& E: L
  153. #else
    - O' W2 W8 Y3 _% @, _
  154.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_LP_CAN1_RX0_IRQn;& s  D. g* b. I6 h% i1 O: r
  155. #endif /* STM32F10X_CL */' b! X6 s- L( V
  156. * h* r+ {% S" f3 w* `
  157.       NVIC_Init(&NVIC_InitStructure);* k5 j2 t2 Q9 d" ]8 A" T
  158.     }! i: x! W6 P9 m& ?
  159.   }
    ) _4 K. Y3 o3 K5 P. ^, a# K. k

  160. " Z: \+ D, \2 m* T
  161. #ifdef STM32F10X_CL  \" t2 |4 g4 v/ V* \
  162.   if(CANx == CAN2)
    8 s1 D4 |4 d/ {1 \; p0 n
  163.   {
    % |9 b2 P% [5 t. x- u' b0 F
  164.     if(can2InitFlag == false)
    ) k- P! D7 Q! \. E8 G- }
  165.     {, ~1 g' o# Z' S, W9 u( `6 I
  166.       can2InitFlag = true;/ y# r0 b. ^0 N' V
  167. - e0 j' @- t5 M$ ?# L
  168.       can2TransmitFlag = false;$ U; {& n5 {5 t, }
  169.   ?( k: ~- p) ]- d
  170.       can2TransmitFinishCallback = 0;( h3 z3 n& l+ {, R) U  G" c
  171.       can2ReceiveFinishCallback  = 0;
    4 E5 T' `! x, y/ M3 \& i) h- Q7 Z6 v

  172. : p1 b6 F2 Y# e' }- `  i
  173.       can2TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN2_TX_BUFFER_SIZE);- y5 V3 l! Z/ M5 X; Y/ G* M
  174.       can2RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN2_RX_BUFFER_SIZE);9 _; v. I" w5 C  \9 ^6 K

  175. + X5 J4 ?4 B. [6 I" p
  176.       if(can1InitFlag == false)
    - B8 b) @2 B$ G2 }; B! B7 F
  177.       {
    : {' W# X9 H  g/ W0 u0 Q
  178.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
    , c7 V3 U7 P7 H" |. i& n
  179.       }7 J7 ~6 V3 k3 [) r# }. o
  180. 4 Y. g# R/ L' J1 s
  181.       RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);
    ' Y, a% b0 i6 F! W7 l
  182.       RCC_APB2PeriphClockCmd(CAN2_TX_GPIO_CLOCK | CAN2_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);* @1 ^8 q+ ^$ w( C4 D

  183. # K2 L  P1 x+ k2 o& X* Q( X' `
  184.       GPIO_InitStructure.GPIO_Pin   = CAN2_TX_GPIO_PIN;
    ) B2 y- J# i# H2 F# d! o
  185.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    - p- n. v# p  h3 F1 s$ R
  186.       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    , p( H* }& r" W' |/ u+ y% ^& M
  187.       GPIO_Init(CAN2_TX_GPIO_PORT, &GPIO_InitStructure);( j  s$ V% ^0 K8 ^& z/ Q, K

  188. - C* S- |3 ?" k2 E: p/ S
  189.       GPIO_InitStructure.GPIO_Pin   = CAN2_RX_GPIO_PIN;' d/ c- P* e" O2 N. f8 v, G
  190.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;, ^0 z6 r& K" |$ Y
  191.       GPIO_Init(CAN2_RX_GPIO_PORT, &GPIO_InitStructure);" ~+ F. z1 _0 c# W  b
  192. & h8 A8 I. r" _6 c) q
  193.       CAN2_PORT_REMAP();
    - e) g0 ~& d/ _4 W& ?; C
  194. 7 P7 V6 M5 \# r: j
  195.       CAN_InitStructure.CAN_Prescaler = BaudRate;
    - C" S1 N6 w! I
  196.       CAN_InitStructure.CAN_Mode      = WorkMode;
    0 }& d' a- k! z' I3 C
  197.       CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;; }) g/ H/ f: V3 M0 D
  198.       CAN_InitStructure.CAN_BS1       = CAN_BS1_3tq;
    7 O, I& B& H3 p1 z% N. A/ P, N  H% ?
  199.       CAN_InitStructure.CAN_BS2       = CAN_BS2_2tq;* j3 {; y" o: l1 H2 W0 v. V
  200.       CAN_InitStructure.CAN_TTCM      = DISABLE;
    ' M" l) A& W- W0 ]
  201.       CAN_InitStructure.CAN_ABOM      = ENABLE;* q( ^$ U4 m& k1 {
  202.       CAN_InitStructure.CAN_AWUM      = DISABLE;
    4 j: ~: A2 B( A1 A- B+ y5 \% ]
  203.       CAN_InitStructure.CAN_NART      = ENABLE;
    ( B. j/ Y" B' ~
  204.       CAN_InitStructure.CAN_RFLM      = DISABLE;. o: e/ @: F5 s- {# M
  205.       CAN_InitStructure.CAN_TXFP      = ENABLE;- o0 S0 I- s- X  v4 ^( K" z* Q
  206. 8 l( [6 r3 |( O: |
  207.       CAN_DeInit(CAN2);. d6 [' J. A7 R8 G0 \% i( d# N" ?5 _
  208.       CAN_Init(CAN2, &CAN_InitStructure);: G; O# V; C; B' g

  209. + _7 Z- g& @/ O* f; ^: ~, i3 ]
  210.       CAN_FilterInitStructure.CAN_FilterIdHigh         = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);
    + F+ W, K! m$ w5 X) ]* s$ J# I
  211.       CAN_FilterInitStructure.CAN_FilterIdLow          = (uint16_t)(((StdId<<18)|ExtId)<<3);
    2 `+ N7 l% Q  H0 |' M  K
  212.       CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;9 Z2 R: O/ n5 ?; U
  213.       CAN_FilterInitStructure.CAN_FilterMaskIdLow      = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;
    # b+ H" b! g) _1 V% g* x: j- J
  214.       CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;$ [4 b+ O" u; M& M" `
  215.       CAN_FilterInitStructure.CAN_FilterNumber         = 14;/ M  \6 C; l9 X9 a: e
  216.       CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask;
    % Z7 Z0 w9 T+ C+ m0 {3 S- H- o
  217.       CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit;
    ) A/ s+ V& t6 u( h+ N
  218.       CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;
    % f2 D: _% I) h) N
  219.       CAN_FilterInit(&CAN_FilterInitStructure);( K* y& u. Q  t4 _. V" Z/ `
  220. 2 \6 Q# k; `2 r; U6 r, S* G6 Q
  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 |
    - z& e4 y3 p5 m& e+ b: ~
  222.                          CAN_IT_WKU | CAN_IT_SLK  |CAN_IT_EWG | CAN_IT_EPV  | CAN_IT_BOF  | CAN_IT_LEC | CAN_IT_ERR, DISABLE);
    3 G5 F9 N6 v( B
  223.       CAN_ITConfig(CAN2, CAN_IT_TME | CAN_IT_FMP0, ENABLE);0 X( q6 c5 j/ U. w! @

  224. ! k( l  Z& o( L( L$ ~6 }
  225.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_TX_IRQn;+ M: {( z9 [$ O  u1 u4 ?
  226.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;0 P4 ~8 V/ D9 n( @# `: G7 y
  227.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN2_IRQ_SUB_PRIORITY;# {7 Z. C. @0 D; A1 m) \3 e/ N
  228.       NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    % k3 w/ f" L* U$ Z/ `
  229.       NVIC_Init(&NVIC_InitStructure);
    % s4 P) x# t. F7 X/ o+ Y# n

  230. 9 y! O! N. g8 ?# L, ~/ f  S  N
  231.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_RX0_IRQn;" J: [( ]1 L  |7 I# x- q  _5 E
  232.       NVIC_Init(&NVIC_InitStructure);
    # P8 m, U1 X1 |4 M7 a
  233.     }$ \' ?- f1 f5 |! p) h
  234.   }
    / ^) ]5 X8 H$ E8 T5 h+ X  @3 k( R
  235. #endif /* STM32F10X_CL */, `$ ?/ k: x& P( L7 M4 I1 S
  236. }$ X- n9 J$ T/ s
  237. 1 o" E1 r1 K; ?4 E4 R7 Y
  238. /**
    6 O; v. G4 U/ _
  239.   * @brief  CAN unconfigure./ {9 L8 [; k9 `: z
  240.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    4 U6 {5 m' q: E! }
  241.   * @return None.! F1 @$ O$ h6 {' n
  242.   */
    " ^2 L2 r% N: w; \' z, p; ]! b
  243. void CAN_Unconfigure(CAN_TypeDef *CANx)1 T1 A6 [' c, N/ e
  244. {" @; l2 a1 i) a) y
  245.   NVIC_InitTypeDef NVIC_InitStructure = {0};6 U- D6 K, s& Q% r( Z, k& @
  246. ) o2 h7 t: W+ O/ K; e: R! ?
  247.   if(CANx == CAN1)6 Z3 k( f! r) X+ z) N9 E5 O
  248.   {/ E, I1 N# q; @
  249.     if(can1InitFlag == true)
    ! \$ @! E. |% N
  250.     {2 b/ w9 G" l# u; c' j7 t' `6 M
  251.       can1InitFlag = false;/ Q' V  T* l8 `; T% V, X

  252. 0 d1 S( c3 l  b% ~) d
  253. #ifdef STM32F10X_CL; J( h* J1 l7 s( |
  254.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_TX_IRQn;8 x6 o  h! h+ e0 G- @! Q, g+ m
  255. #else
    ! k5 R6 \. h( Z% v( z( u0 Y
  256.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_HP_CAN1_TX_IRQn;
    ( y# S8 D% e* |8 o4 A! A9 t
  257. #endif /* STM32F10X_CL */
    * F6 [) ?- b# G4 M4 X/ O; w) r
  258. ! l% Y7 y) O1 D; z2 N$ H
  259.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;
    8 o8 p2 ~! H& [2 {
  260.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN1_IRQ_SUB_PRIORITY;& s3 i! D5 i, y/ F4 x% E% }
  261.       NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;
    ! D: x7 ?6 R. v1 t$ I( V. ]
  262.       NVIC_Init(&NVIC_InitStructure);# C5 r7 L8 U" [- h7 F& C& R3 k

  263. 5 V& u; m8 C7 z& `/ A; T
  264. #ifdef STM32F10X_CL
    ( \. \: Z0 h. N3 W
  265.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_RX0_IRQn;
      M2 o0 z1 ~0 E
  266. #else0 U* H% S% r6 P# o
  267.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_LP_CAN1_RX0_IRQn;/ Z  w- K, J9 `  O
  268. #endif /* STM32F10X_CL */9 j8 i) T6 `) j8 q! Y# \

  269. ; U- C3 l  k/ c8 E) E& \  V
  270.       NVIC_Init(&NVIC_InitStructure);
    1 H$ R+ f' L( v. W" @

  271. . U" S: R. E1 v  n6 n9 `" Q/ D
  272.       CAN_DeInit(CAN1);
    * K/ c: t  d# Q& S! ^  R

  273. % `  q/ [) U9 I- g& b% G
  274. #ifdef STM32F10X_CL
    2 }4 p! I' g1 r* n5 l( y; P5 W- F2 X
  275.       if(can2InitFlag == false): q5 z0 G! U7 B7 [5 q5 @
  276. #endif /* STM32F10X_CL */
    ; W% L3 P3 T, M& Y% {
  277.       {/ O' [  O4 Y# D6 I6 {7 n; A
  278.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);# a% U. e) n* Q) g3 K3 i
  279.       }
    " N1 x% \) ]) O* ]! p+ T& y5 b

  280. 8 i; r! F$ F6 ?/ p' j
  281.       can1TransmitFlag = false;
    + \  H) n; W' ~% \: ~9 d4 G

  282. $ j8 S  d+ p# I5 ^$ }5 J% o, d
  283.       can1TransmitFinishCallback = 0;! F8 z& S9 }4 D# U7 x- }
  284.       can1ReceiveFinishCallback  = 0;
    ' b& S1 D8 P( j3 w- c' H2 v

  285. 3 A1 q* U. X( S9 t6 J
  286.       RingBuffer_Free(can1TxBuffer);
    : _4 q  n& K, d% K. f9 E
  287.       RingBuffer_Free(can1RxBuffer);2 a, m9 M9 @5 m* C, I2 i* R* l
  288.     }
    - c4 Q$ j1 v: `4 ^3 m- Y
  289.   }
    " |# l& a& E7 J0 H
  290.   _, f  ?2 R! K# f: D7 {
  291. #ifdef STM32F10X_CL
    : a% \) t9 u4 J3 j# r) W$ M
  292.   if(CANx == CAN2)! h, a+ Q: U7 \0 J# I) M; Y
  293.   {
    % S( d+ i! f3 N2 s' O* ?
  294.     if(can2InitFlag == true)8 o1 _* Q0 Z8 E* v
  295.     {4 U) ^' `7 c3 z% l, \
  296.       can2InitFlag = false;
    . k% V$ \& t! J# O' d0 V

  297. ' U5 D, ?, r  i3 o1 H
  298.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_TX_IRQn;
    & ~) A6 Q! a4 [3 x, K/ r6 a) G
  299.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;. ]" }1 c4 `- _( |. E5 [0 w- J$ z4 ]) p
  300.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN2_IRQ_SUB_PRIORITY;7 Z  L+ w& V, K6 M* c0 |+ ?
  301.       NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;" b8 W, e7 b7 A3 n) L- x
  302.       NVIC_Init(&NVIC_InitStructure);- r* s9 ~- K$ O* d& C9 \  @

  303. ' W, ]9 Y6 h1 W; D8 d" `
  304.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_RX0_IRQn;% B' V0 l* J- ~# n
  305.       NVIC_Init(&NVIC_InitStructure);
    ( w; X  y6 N/ U8 R& r

  306. 1 \' O2 w# y( R1 ^
  307.       CAN_DeInit(CAN2);
    / A, Y* k5 g- d! |: _( g: e- a

  308. $ Y: @3 I) ^3 f' R8 p
  309.       if(can1InitFlag == false)
    1 S6 a5 K; C2 O% m* m# ]' ?
  310.       {# w' f: Q8 e7 b  {; V. I; v
  311.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);
    ! c$ t( Q- X9 L" Q& [
  312.       }
    2 o( ^0 k! g% {' i2 s
  313. ) L7 q# |1 z! b) f+ T/ U' [9 S3 O
  314.       RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, DISABLE);- r( F2 {8 c( S1 D$ Z: h' j5 C& V
  315. # j6 j$ F0 t/ N3 s( m# L+ z
  316.       can2TransmitFlag = false;
    % Z4 e7 _+ s3 N6 S  X# d

  317. . K- |' ~; \+ }" V
  318.       can2TransmitFinishCallback = 0;8 I# U. j- p% b6 C* u' V" a  B3 [
  319.       can2ReceiveFinishCallback  = 0;& U2 a! i/ {# ^$ `) C- \+ g
  320. 0 o3 q: X4 D4 u" z, g/ R+ C2 k& F) I
  321.       RingBuffer_Free(can2TxBuffer);: G( O8 \# A! H4 Y' m
  322.       RingBuffer_Free(can2RxBuffer);. `! F. H2 c; b0 n6 E1 R
  323.     }
    5 L) T1 q. b2 ]3 l
  324.   }
      K1 p$ U1 J, c* D
  325. #endif /* STM32F10X_CL */
    5 o# `% Y' A5 F5 o5 J& U1 I; f
  326. }  H/ q7 }' Y& G/ O8 r, g

  327. * E2 l/ @5 G7 {% \+ u3 T' U
  328. /**
    ' R' @9 g6 L; T* l0 H
  329.   * @brief  CAN set transmit finish callback.) H: M* t- U  S% E5 o8 B& F1 a
  330.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.6 S# w, p# A! a+ F# T" i
  331.   * @param  [in] Callback: Callback.* \# F" {4 T3 Z
  332.   * @return None.
    7 m7 H( R; g/ Y: d  v: l, ?
  333.   */
    $ K2 C* m" F4 _# t! N  D; M
  334. void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void))4 O* Y+ }% O8 Z( F9 V
  335. {) b4 I* K# p1 G: _# i, R* x
  336.   if(CANx == CAN1)
    ' [5 }; |1 [3 ]* Q4 |# Z
  337.   {% O$ d# ~/ Z" o6 Z3 d: j3 N
  338.     if(can1InitFlag == true)' K7 n4 W& k2 t8 `/ X/ s
  339.     {
    , r! N, g3 ?; [3 l, ^$ [
  340.       can1TransmitFinishCallback = (volatile void (*)(void))Callback;+ s$ A- @$ t: @; `
  341.     }) c; H9 a$ }% ]3 D5 r/ M# t  O
  342.   }' A7 W, j1 I5 ~+ r0 Z
  343. ; U/ y% w' c* b/ {% h5 ^4 _( l
  344. #ifdef STM32F10X_CL
    + c/ w4 U5 m3 m$ S- I  e1 D, F
  345.   if(CANx == CAN2)
    4 D5 X% H1 S. G# h; E+ d5 w' ~
  346.   {' M' v1 u% p+ w7 H" j
  347.     if(can2InitFlag == true)7 ^/ z  \+ |, T2 a* G1 t$ L! i( u! @
  348.     {( K) P- D/ a; Q5 w, u4 C) d
  349.       can2TransmitFinishCallback = (volatile void (*)(void))Callback;
    9 G# P; A5 F5 z( ^
  350.     }
    - K- o) m: N9 j! I
  351.   }% }  H+ {! U! L- h0 ~
  352. #endif /* STM32F10X_CL */  W7 c1 P6 n1 v
  353. }/ R- i! I8 P( C: x
  354. 9 g" e, @' m: w6 ]0 z& w
  355. /**
    % r. Q) n' ^+ R5 \" h' i: P3 c
  356.   * @brief  CAN set receive finish callback.
    2 q0 X3 q& \. f8 n. ^- }8 O& p
  357.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.9 H+ f) I- ]2 F
  358.   * @param  [in] Callback: Callback.3 A" E7 R+ ]$ L; V$ V( N
  359.   * @return None.
    / }8 M' {2 g$ ]/ R5 U4 r6 |) k2 V9 M
  360.   */1 G! Q5 {! J( D8 W
  361. void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void))
    # y9 U0 J- h* ]  N0 i  D9 ]" X
  362. {/ {" W3 G) I4 f; w. G; b
  363.   if(CANx == CAN1)
    ( Q9 G! I3 V: `: K
  364.   {
    ! f; t" v- B) C- H$ m- R4 Q
  365.     if(can1InitFlag == true)
    4 u+ i- v, G0 G/ s' m% S7 s+ T9 {
  366.     {0 E, d6 w4 _0 v
  367.       can1ReceiveFinishCallback = (volatile void (*)(void))Callback;9 E) H: l; y; ~/ y5 |
  368.     }- m& E1 C4 C+ X* B$ J
  369.   }2 v0 K0 S0 u1 V4 A6 t. J, h2 |

  370.   B$ }$ Q7 \- `5 [: F/ t5 y
  371. #ifdef STM32F10X_CL
    ' l$ U9 K9 R* }8 d8 H% U0 i% g% ~
  372.   if(CANx == CAN2)
    2 E3 }! {# v/ m$ s2 f& a0 {
  373.   {
    * C% q( K- H( C' R0 _
  374.     if(can2InitFlag == true)
    ' ?0 y3 U  Z5 G5 R- h
  375.     {
    1 l! N4 {- R* ]4 r% a6 m+ y+ N
  376.       can2ReceiveFinishCallback = (volatile void (*)(void))Callback;/ F9 Z3 Z9 u# F# f/ H( i
  377.     }% q  H2 ~& K7 i& ]3 }
  378.   }& [) |% Y+ ]5 k3 b9 z
  379. #endif /* STM32F10X_CL */& l& f/ S+ `" x' }( j
  380. }
    ) \' f2 j: _; C+ _5 K# I

  381. 0 t; T) z* m1 B1 I8 T; w' S
  382. /**
    3 d% b7 _, L, u% R' ]) W% X
  383.   * @brief  CAN set transmit message.
    $ U+ G& a" K8 B! z- O! Z4 x
  384.   * @param  [in] CANx:    Where x can be 1 or 2 to select the CAN peripheral.( o, h3 Y1 c' s1 c- T" {2 G
  385.   * @param  [in] Message: The address of the message to be transmit.& v' Q5 ~* c* W+ J
  386.   * @param  [in] Number:  The number of the message to be transmit.
    0 _5 f$ X2 p( E. D6 }- ~9 A
  387.   * @return The number of message transmit.
    / l( [' K3 {, }6 N! n
  388.   */7 Z3 y( y3 @5 z3 A. n" c+ H& I
  389. uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number)
    " ~5 Y+ _2 p5 o
  390. {
    & g/ j# Y% f) P$ x$ Q3 T. `
  391.   if(CANx == CAN1)
    + Q6 g! s( ~6 C* y( E2 t. ^; u
  392.   {2 K, S! x5 U' s( M) Q  b
  393.     if(can1InitFlag == true)
    * u& N, i3 s! o& _5 M& w9 G
  394.     {" r' K& x/ j! {  t) o' T. \6 G
  395.       uint32_t available = RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);
    ' t  j8 r! j# N4 e& t8 W

  396. 3 D4 {2 U/ ]7 o: a
  397.       if(available > Number)' a/ o& j, \' _. g# k1 n5 V0 Z1 y
  398.       {
    5 _- V) S0 c! @+ y
  399.         Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);
    8 {4 Z/ Q* Y5 C- b
  400.       }- E3 G! J; U: L. X" a7 k6 m) R. W
  401.       else8 ?" K: w/ f, }
  402.       {$ L3 _: s  j( z* E) V* x. q
  403.         Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);
    6 N; [" C  a* _1 v. L: l& n) l
  404.       }
    ' ~# i9 T; z2 ]

  405. ' y% w  S( ^: K2 K+ t/ S
  406.       if(Number > 0)2 ?6 p6 L. b9 ~8 |$ q3 ^3 t$ t
  407.       {
    % d5 m/ x: h. e
  408.         if(can1TransmitFlag == false)& T; N+ U7 ^6 r( \) `4 O6 D+ X/ t: G5 B
  409.         {
    ' B! ^" u; |% `, W
  410.           can1TransmitFlag = true;1 x+ ?2 e0 e2 G9 S3 l* L
  411. , ?5 T) h( a3 _+ i: X
  412.           CanTxMsg canTxMsg = {0};
    : ~* R5 j3 f& [# ~3 O/ f/ i" n
  413.           RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg));
    8 e5 D% O4 K; o
  414.           CAN_Transmit(CAN1, &canTxMsg);: k) J. K( D3 u- x
  415.         }
    - K- V: u( ]5 c, X/ Q
  416.       }
    ; D9 _+ H. n' A5 [; G; q1 B' L2 k

  417. . N- j$ G5 ~- k- d  _3 m
  418.       return Number;( F* [3 T8 l$ o& s- H& ?
  419.     }
    & P* e: X5 Q6 Q: T  |6 Q- e, B/ y" D
  420.   }+ i; @& h3 e; U) W" E1 E# l

  421.   R9 Z2 q2 F; W! L7 E% @
  422. #ifdef STM32F10X_CL
    $ ~# ^3 X' Z2 v3 {
  423.   if(CANx == CAN2)6 h& D: F2 F# r! @$ Z
  424.   {1 T+ n0 L0 p# a( X# K
  425.     if(can2InitFlag == true)) f' X' a% X' z4 C; C( l7 j
  426.     {* Z) k" |8 `$ m, r
  427.       uint32_t available = RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);
      k1 X2 M6 O* O( k8 Y
  428. 5 t/ _5 V* I4 M. W
  429.       if(available > Number)
    . o: j) d% @. z, S. b
  430.       {5 t- ?9 T# R5 r, T+ a' N: B6 G
  431.         Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);- b! d( t& p% \4 d8 M5 g
  432.       }
    2 ^- H( T5 H8 t) n2 h  `+ L
  433.       else/ d3 d( o, \% o7 p1 d! b
  434.       {
      ^9 p6 P& a) w9 l) Z9 O' Z5 A6 M
  435.         Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);1 g9 X. k; P  z" C( r, |
  436.       }* @' _  j. h3 \: q4 Q/ g" P

  437. 8 E7 y+ e* v" Q; C
  438.       if(Number > 0)
    + S6 G1 s  Z, [% r0 f  D+ J
  439.       {% }. S( U. V# S/ P' S5 J
  440.         if(can2TransmitFlag == false)0 D* H; l, T" M" h* P3 i% _
  441.         {# s6 R6 @+ u9 m8 H# U0 b) B
  442.           can2TransmitFlag = true;
    9 C* {8 M  r, i' l6 C" q
  443. " ?' q& v  E/ F
  444.           CanTxMsg canTxMsg = {0};1 B5 r  B2 z' d1 Z+ e
  445.           RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg));+ ]* b' s0 V% a* W
  446.           CAN_Transmit(CAN2, &canTxMsg);
    # T4 z9 Z( F* F+ P2 `
  447.         }
    0 m, }. H% ?* z
  448.       }
    & h/ p  A  d# d

  449. 9 A7 a2 E6 w& @
  450.       return Number;
    " G0 Z7 v% ]1 f$ y
  451.     }
    " u6 y1 s& E% d3 T2 a
  452.   }, V. x2 R- l7 T) ~
  453. #endif /* STM32F10X_CL */
    $ x; |! K& a8 F( W9 w" x# K
  454. 6 @; }3 ^& f6 p  `! z- w4 j7 H
  455.   return 0;
    $ \; S* a, n  R+ I8 p( b( |
  456. }: n- Q' @0 h, m" d( V
  457. 6 _. F% t0 v. w2 Q  G
  458. /**
      u5 H( J1 ]# _5 `( p
  459.   * @brief  CAN get receive message.
    , z2 o9 h* S) o% p
  460.   * @param  [in] CANx:    Where x can be 1 or 2 to select the CAN peripheral.* b) v3 m; m5 n
  461.   * @param  [in] Message: To store the address of the receive message., t' |9 l4 ~1 z- x
  462.   * @param  [in] Number:  To read the number of the received message./ r+ h+ O" f! E. |2 t- l. }
  463.   * @return The number of message obtained.
    : y2 o. `  `# P% o3 j  R+ p9 @
  464.   */
    2 T) ^8 @; O$ C$ {' H! e; h+ p
  465. uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number)
    ' T, G# [9 E0 X3 T- s
  466. {
    - y8 R5 V1 N7 ^2 c& h( E
  467.   if(CANx == CAN1)9 Q( Y! g0 K% o# q/ Q
  468.   {1 R" ~* C7 {% L3 U8 u5 `# |. t
  469.     if(can1InitFlag == true)7 U! j1 ~( G. j4 D0 F# |2 d
  470.     {
    ; S5 ~0 |. \+ m$ h1 [" U" Y0 s
  471.       return RingBuffer_Out(can1RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);
    + b& R: p* H( |/ L8 [+ z
  472.     }2 z! I* u3 z8 a1 ?* B' @
  473.   }
    7 m: ?3 {/ d( b, x. S2 R- R' H1 X

  474. ; x" Y% A; s$ r% I
  475. #ifdef STM32F10X_CL" a2 Y* n- g  I
  476.   if(CANx == CAN2)
    4 C! q1 M$ u8 T+ |3 E2 Q
  477.   {" I7 o) l$ P4 ?+ d( N. v
  478.     if(can2InitFlag == true)
    * l# Z8 C, f$ R: ?  O1 W
  479.     {
    - `# d) w( q. p5 {
  480.       return RingBuffer_Out(can2RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);6 y# D" e' Z4 w7 s
  481.     }
    # D; Q7 q' |% w
  482.   }
    ' ^* M+ M. T# k' [" g
  483. #endif /* STM32F10X_CL */
    3 P. j# L0 c/ _

  484. 0 {6 t( F0 _  A7 V* G4 I7 Y; l5 p1 G4 ]- c% F
  485.   return 0;1 s5 A. j- V% T: u2 |
  486. }
    % U+ S. V3 B, d" I3 O

  487. # Y- E: X* v, f% U
  488. /**) y1 @$ K+ L4 Q+ u3 G1 ~* ^. k
  489.   * @brief  Get the size of the CAN transmit buffer used.# o3 Q( j8 k# Z* \
  490.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    % U  n1 k$ B/ A
  491.   * @return Used the size of the transmit buffer.+ W# M& S# h- S7 n. Z
  492.   */
    . x3 }) t- v$ x$ E  G3 H8 y
  493. uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx)
    6 q" Y# U, Z$ g* v$ E
  494. {7 c2 X+ K- e) ?4 p4 e
  495.   if(CANx == CAN1): l& b5 e1 z; ?4 o2 i. L
  496.   {
    / x8 D3 X0 o7 D# e! g+ A
  497.     if(can1InitFlag == true)
    5 l) b  @# }; H, g
  498.     {
    # s; ?3 ~! u5 D  e
  499.       return RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg);) b' |' _! D$ B8 l" t
  500.     }
    5 T3 Q7 @) {' s. H: F
  501.   }8 p6 l( K! W1 I7 @4 m# k4 F

  502. - v) j! E! G3 G2 n) O
  503. #ifdef STM32F10X_CL& b8 m3 Z1 Z4 N  f
  504.   if(CANx == CAN2)/ g7 |$ l2 I, l2 Q. d  A
  505.   {
    9 G# f: S5 G7 _1 ]
  506.     if(can2InitFlag == true)  b( x% M0 C* H( _- y
  507.     {" z7 l) l- X- D! x+ \$ l. b
  508.       return RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg);
    " f  U" B. |7 f
  509.     }
    6 [2 w. t+ h, `, v/ \
  510.   }5 C. k0 i' F" @
  511. #endif /* STM32F10X_CL */* Y- }: N/ s7 |4 m; O5 g' Y+ X

  512. 5 b/ |' u, w" T! R3 R$ z" X
  513.   return 0;; h( a* x) [( g
  514. }4 s1 S3 V% j- V" B
  515. $ I$ A6 W" f! R7 i5 V4 a
  516. /**
    ) c! G/ l" D/ @6 Z! l, M
  517.   * @brief  Get the size of the CAN receive buffer used.
    3 Z/ U  C5 F0 ^+ z8 ]+ B/ {, e
  518.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.) T' [) Y. f4 X: T
  519.   * @return Used the size of the receive buffer.  m5 o0 J/ m, }; Z. P4 e: l  j
  520.   */2 S$ V# g' a8 O  y9 W
  521. uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx)
    ' R+ m: s2 n& i* |) z+ [) V
  522. {9 u4 n' F$ u0 m. V
  523.   if(CANx == CAN1)+ b- Q% ^/ _, F8 Z  l4 S9 G3 o& C
  524.   {3 h: a$ i) v$ H+ `8 n- h
  525.     if(can1InitFlag == true)
    % b* j6 b' t! H; Y* o
  526.     {  X# p/ R2 Y2 V
  527.       return RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg);6 P" g- J& F! {: q0 g
  528.     }
    % p: T' G% ^9 X# @' O* i' V/ a
  529.   }
    , z" V+ J% z5 C3 a

  530. & Y  a( c& @( ?  w4 e: B
  531. #ifdef STM32F10X_CL$ f9 L$ T1 p& ?% e" ~1 {7 j
  532.   if(CANx == CAN2)7 L1 |* s& K/ Y! m/ _, H5 D  F
  533.   {
    9 ^8 j& b$ F4 e; J$ x/ @6 y
  534.     if(can2InitFlag == true)
    : u+ e0 z7 s% a' H! k2 Z' e3 l) |7 t
  535.     {
    8 p, W( I5 j  P$ O
  536.       return RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg);! D% o& I/ Q7 v- P4 u' [
  537.     }
    . S( n) K5 H, C9 G: E3 N, v
  538.   }
    4 X6 x# s( K& y. H/ F
  539. #endif /* STM32F10X_CL */& ^& c; j' s; |6 c8 M2 u
  540. & p3 o: L7 C; c" J
  541.   return 0;( v8 c& D5 z/ G5 F
  542. }2 K- Y  E7 O: z
  543. / m  X. k* ?4 `+ G& k
  544. /**2 n1 ]& P; R3 I% t. O
  545.   * @brief  Get the size of the CAN transmit buffer unused.
    # H  I  u1 w/ m6 D3 ?8 j( V. E
  546.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    + A; u4 O" }. s; h. `% v; J& v7 _
  547.   * @return Unused the size of the transmit buffer.
    , S& v# e- |, \# O
  548.   */: _3 z: [- I3 `8 |- |
  549. uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx)8 F9 ?* K9 B& Y, ~$ ^
  550. {
    # o. ^3 O5 ^) t; P+ F
  551.   if(CANx == CAN1)
    ( q; a7 U- {* {& t3 |
  552.   {. }; i1 X7 T( t- E4 Z5 Z; |
  553.     if(can1InitFlag == true)/ q9 h1 }3 h! b1 _- L$ Z! x3 n. A2 Q
  554.     {' J; y) W6 t6 |& j: r3 f. J
  555.       return RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);- k4 \8 ]6 y/ p3 ~  L
  556.     }
    " M; J1 c; o: e  z7 e: f
  557.   }
    9 D3 g! J$ E2 `
  558. & t$ C# w, W/ C
  559. #ifdef STM32F10X_CL
    + B7 e& D' R- t. l4 w: o( l' t
  560.   if(CANx == CAN2)/ m5 Y: [$ |! C6 ]- Q3 d- |, Y
  561.   {8 {; U* P2 |" y7 W7 F) z: _9 y
  562.     if(can2InitFlag == true)
    % a" _9 U6 s  B5 |' G
  563.     {& B+ L; G( Q6 j
  564.       return RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);
    3 e! V. h3 ]! A1 e* k# n6 X
  565.     }. b6 K% [  X5 |2 t# _. @4 Y& Q
  566.   }
    1 g7 F1 Q7 n7 j" k5 i" n6 Q
  567. #endif /* STM32F10X_CL */3 r! C5 s! s# s; w, [4 g
  568. 4 i6 n) h- N& T# R9 Q0 s! P0 H
  569.   return 0;
    7 j# ^& D0 k% ^1 P
  570. }
    7 T0 H! n5 W" }8 W+ A1 D. I

  571. " ?5 ?5 z. [6 [6 d- z; U/ r
  572. /**$ `$ D1 k* r. {
  573.   * @brief  Get the size of the CAN receive buffer unused.- R& ?7 i, W. M& F- G2 _
  574.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    - @8 O; e* ], W+ e$ ~" X+ l5 W
  575.   * @return Unused the size of the receive buffer.) L( W# P: X( T1 ]1 x9 y& ]
  576.   */
      u$ j2 d6 h; e
  577. uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx)
    4 X2 q% ^' H& X. \0 v
  578. {
    1 h# ^& P3 }- o
  579.   if(CANx == CAN1)
    , r9 m$ b6 u* Z$ i4 \) h
  580.   {) m* W5 d6 R8 Y  t: P
  581.     if(can1InitFlag == true)
    ( ~( \" W5 K9 K. Q4 O
  582.     {
    8 C5 J) U( ~- a$ T# H0 Y* E" R
  583.       return RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg);
    " Y1 Y/ f. e' v3 s6 b
  584.     }9 H# e( @4 T- G# x8 P0 P
  585.   }
    * P: A3 O; @' K. ~0 @* w
  586. & U# t8 I  k+ h
  587. #ifdef STM32F10X_CL2 @8 ~9 \4 y2 [7 m2 H0 r% _
  588.   if(CANx == CAN2)
    ! M3 n& K$ K5 e+ S) k
  589.   {
    0 v- m& W) m3 D/ d4 U
  590.     if(can2InitFlag == true)5 F6 |5 o" k' z& ~/ Q
  591.     {
    * h# {7 s$ h  Q3 N0 y, Q
  592.       return RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg);
    ; V; c, m' U* z$ c' L! z0 e( K9 p
  593.     }
      G% e: v5 s0 f0 ]( |/ i+ t; _( J
  594.   }5 M+ H, ^1 ~; \: i9 ]$ c
  595. #endif /* STM32F10X_CL */
    7 n9 w; c& v+ |. L! k7 A( U
  596. 1 O+ @  b) V+ q1 R" I
  597.   return 0;
    . n. }# M# L- q, S1 w( t4 ]/ N
  598. }! b0 o' c  r9 p4 O/ b+ E

  599. $ r/ R, G0 s' ]( ^" R6 [
  600. /**: z( V: h% W) }& {, ?9 C
  601.   * @brief  Is the CAN transmit buffer empty?
    0 U5 G5 l; s6 y9 m5 c7 Z
  602.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.6 k- K  V. |5 s% R$ t
  603.   * @retval true:      The transmit buffer is empty.
    ' o3 g$ w+ A2 ], I8 \
  604.   * @retval false:     The transmit buffer is not empty.
    , v1 ]. t; |) T% W; i
  605.   */
    / Z4 G% I8 c# E- r- i. c& Q5 L
  606. bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx)
    : M5 {2 }# g2 x
  607. {
    . G% M+ r. {& v) Y8 b
  608.   if(CANx == CAN1)
    2 `: Y% P* e- Y
  609.   {
    7 m) @& ]: [# S6 A/ Y- c+ X; B
  610.     if(can1InitFlag == true)- l  n7 A9 t- b1 i
  611.     {
    1 ^# h5 |! c( R/ p; h
  612.       return !(RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg));6 \/ S- x( r- ~
  613.     }
    - z: r! b- J, h6 F% o) r! A% ]
  614.   }) _7 Y6 X+ U0 o2 I* r9 V

  615. $ Y1 P) p/ M# G9 D0 X- q! x5 |
  616. #ifdef STM32F10X_CL
    6 U2 ?& c2 R4 H3 H( \' V4 G1 s
  617.   if(CANx == CAN2)
      Q: S5 J! t8 q
  618.   {
    # I, u: h) Z0 i
  619.     if(can2InitFlag == true); U# R' i7 J8 z# N  ~/ F9 Y3 x
  620.     {
    9 I3 ^1 G7 U, i
  621.       return !(RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg));
    - Z5 v5 H1 y9 {
  622.     }
    ( \" N) q* w  ^6 P) O
  623.   }
    & ]0 c4 E& ~0 H- Q8 i( O+ _
  624. #endif /* STM32F10X_CL */. H3 E1 ~4 N; m2 W. I. V

  625. % c( w0 d0 ^- ]+ T+ h
  626.   return false;& @! Y$ d1 b, Y3 d
  627. }
      }" {+ n8 ~# S: c( G5 D

  628. # y) X8 }6 P, q: q
  629. /**
    8 p' `8 {5 X! F
  630.   * @brief  Is the CAN receive buffer empty?- }; Q/ D4 k8 v; u- h
  631.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    / X2 h0 Z' V8 l  ?( d
  632.   * @retval true:      The receive buffer is empty., J" [- D% P, Z3 ^; w
  633.   * @retval false:     The receive buffer is not empty.  w) G, s/ p/ x+ f
  634.   */! ~# P( g# T: F
  635. bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx)
    6 H# ^- `$ {0 j% F9 f4 W1 @5 N
  636. {/ G# I% Y( Y$ f/ e- T
  637.   if(CANx == CAN1)
    9 x9 Z* D: J5 h  T
  638.   {& ~/ Y+ X% ~0 W
  639.     if(can1InitFlag == true)7 i. p- x' H2 P( R/ O2 |( I# B+ z
  640.     {# O# U" O) a% K& c* |/ E6 l& J
  641.       return !(RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg));
    ; V3 Y5 H  j) {( {8 T( }# v& O
  642.     }
    ; }3 G  t; A. h- l
  643.   }( Y7 M+ i- z: Q& E0 V9 j

  644. 6 k: P  ~) }6 K. ~' G3 }6 t
  645. #ifdef STM32F10X_CL  e$ K* z/ B- l6 o0 G
  646.   if(CANx == CAN2)
    ; w! z4 m: e' w$ P0 z' E
  647.   {
    4 J8 j6 P! b2 _% }/ o+ o9 a( c
  648.     if(can2InitFlag == true)
    * d3 q6 h- h6 A
  649.     {
    2 D! d1 B+ S" H, q! |4 Y
  650.       return !(RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg));: k+ O8 A2 N, r; ~
  651.     }
    ' H& k* n! h9 Q/ Z4 a" q0 I$ q- c& C5 u& o  P
  652.   }+ Y7 V9 \; u; b
  653. #endif /* STM32F10X_CL */  E  F6 q* A6 ^0 Y0 g, p

  654. + v0 |1 \" K( w! M& v
  655.   return false;
    8 V9 U# X/ R% N5 e
  656. }
    ) G8 W7 L; w5 p5 V

  657. ! V8 n% y6 g% L; i' r
  658. /**8 L& |( `9 z" E
  659.   * @brief  Is the CAN transmit buffer full?# t/ z7 S* h6 P% v/ x
  660.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    ) d* E; j5 d! \
  661.   * @retval true:      The transmit buffer is full.
    8 N6 T+ D# t. o1 ]
  662.   * @retval false:     The transmit buffer is not full.! P; B+ y+ T/ C  ~6 d& P( C
  663.   */
    , Q4 f6 `* P6 ?; o! w. e; ]
  664. bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx)
    + V, g4 ^0 T2 X/ O
  665. {
    5 E- k- f) m; i
  666.   if(CANx == CAN1)
    $ u* C; ~- A: ]8 e1 ?& b1 L
  667.   {. @4 N' Z8 O1 J8 w
  668.     if(can1InitFlag == true)
      y+ c8 b  p' L; x' Z4 E
  669.     {  T9 S0 i4 f! X& K
  670.       return !(RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg));
    3 y# D. A1 [5 \$ P' N- A
  671.     }# N* o1 a" p7 E+ F/ w0 J; F5 b
  672.   }
    5 Q+ w6 k# X6 z5 g! z

  673. 5 l; X# s' o1 c  F! H' w  R* c% V
  674. #ifdef STM32F10X_CL
    ' @) Z. N* ?: k: ~# N8 z( B
  675.   if(CANx == CAN2)& u9 g  W. n7 i0 O0 a
  676.   {0 n; j, y. H: V1 u
  677.     if(can2InitFlag == true). N$ D* m) h# w( j! X8 i4 Q9 |- H
  678.     {
    ( B6 V! p6 {8 R8 F
  679.       return !(RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg));
    9 m( @7 T' {6 G; ?5 k
  680.     }( O0 I+ H( X- j0 _
  681.   }
    ( \+ G$ U! C6 k, f, O6 U: p3 t4 [
  682. #endif /* STM32F10X_CL */+ h# W' J0 L* d  J" I

  683. - _8 @+ z& g* u+ w: s
  684.   return false;
    2 l  {8 e# a+ w
  685. }
    5 E7 y( ?3 ~6 c' U

  686. " Q  x/ ]' Q: F( h0 i) h8 t
  687. /**
    $ _3 M0 v! f- F1 y8 G) ^4 ]" Z" P
  688.   * @brief  Is the CAN receive buffer full?
    ' x, b- m# M/ d; Z! S: o, r
  689.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.2 Z+ N5 Z6 S8 {4 y
  690.   * @retval true:      The receive buffer is full.
    8 H. _5 `$ t: e6 k/ i/ X
  691.   * @retval false:     The receive buffer is not full./ h; ]! C7 g2 ]
  692.   */" X( t! @: @, C
  693. bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx)6 t# ?! @( }3 N. Y/ {: v$ x
  694. {
    1 u" |# [7 n  n( t, ^" o
  695.   if(CANx == CAN1)
    1 g5 c8 E3 t5 @' k
  696.   {
    + v) ~7 W% c$ m- G5 I
  697.     if(can1InitFlag == true)  t5 k! x- }& P6 Z; S3 B
  698.     {
    8 L3 Y% d% Y5 k' p, k  M
  699.       return !(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg));
    4 S0 B: z8 v2 W
  700.     }! L: u3 N6 f0 D' Q9 m
  701.   }- m, p( g, T) n! n! I; j* J
  702. 8 F) u! k2 C# Q. G7 d( F2 o
  703. #ifdef STM32F10X_CL
    0 D. A' ?3 ^- S# q; w6 o: {
  704.   if(CANx == CAN2)7 `. v1 H+ m% c9 ?6 O% `; {
  705.   {5 V9 ?; f" Q# ~) B' d0 K
  706.     if(can2InitFlag == true)
    $ X7 }4 p+ Y6 \' P! i/ X
  707.     {
    0 L. X0 K3 ^/ T9 L4 c
  708.       return !(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg));
    3 R& r  ^9 I) Y) b9 n
  709.     }* e4 U# N4 k7 r( }- O4 J/ @
  710.   }( T" t/ d0 K5 G& |* T
  711. #endif /* STM32F10X_CL */
    4 E8 f8 u- H" G8 Q
  712. 4 e& H& E6 y# ]0 u
  713.   return false;0 w% }- m* _9 s6 x
  714. }0 A3 n( d( }# ~, b  o

  715. : t; N! @0 r* @& C5 g
  716. /*** t! P, x8 i; `( r1 B) u& E) E
  717.   * @brief  Clear the CAN transmit buffer." q8 s/ t9 {4 Z3 b* u( X$ u6 z
  718.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    # h+ l5 ^# y) e- M# R4 z
  719.   * @return None.
    3 `' ~. \7 w& z; B0 x
  720.   */, ^  N; a6 F; ~  c( i
  721. void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx)* m3 L2 H- b( p+ V% h
  722. {
    + E- _/ k4 I8 P5 r
  723.   if(CANx == CAN1)
    ! }- I8 ^1 r4 ^! t* i, P& q5 a
  724.   {
    3 y- [6 ]( Q  E+ ~+ y
  725.     if(can1InitFlag == true)
    5 h) e" K3 T8 O9 Z% i
  726.     {
    : U( x! ?! n8 W# t& E& q
  727.       RingBuffer_Reset(can1TxBuffer);
    7 a& U+ q& V( L  M6 i/ [" f
  728.     }
    7 Y3 c( e: U# T
  729.   }
    1 B7 S* H% M) G
  730. 0 Q7 v! T2 y( j' D* }$ G
  731. #ifdef STM32F10X_CL
      r( q: B& Y7 A0 a
  732.   if(CANx == CAN2)
    : v. [: L( L$ l6 @2 d1 n
  733.   {
    + K$ b; K* i' m! G: G
  734.     if(can2InitFlag == true)
    $ z0 `5 i1 ?2 M: A
  735.     {) Q: [. K5 z; i/ N
  736.       RingBuffer_Reset(can2TxBuffer);$ k9 W8 s% a; L
  737.     }
    " D: G$ C% f$ d2 E  v+ x. U
  738.   }
    : `' {- B8 r  U: n
  739. #endif /* STM32F10X_CL */( F: a2 ~7 a" |8 D% r
  740. }
    ' N. w5 j* I. R9 ?

  741. $ X4 j$ p' [6 g& l- b
  742. /**
    " G- V8 X* P8 g( L5 V8 E4 t
  743.   * @brief  Clear the CAN receive buffer.
    $ X# F' g, N+ C& E2 {- l4 x
  744.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.6 n: b1 C$ s- H
  745.   * @return None.
    3 a" n# n; e- ^- y9 g" f
  746.   */! n8 S1 h) s& l8 j/ L/ F
  747. void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx)
    # Z' F( |* A* g4 {
  748. {
    7 w0 i% I3 j* y2 A3 V$ [
  749.   if(CANx == CAN1)
    & C. h4 s$ M  W9 \0 w' u- {
  750.   {
    9 j6 l& A5 R8 v) m  r* F4 x
  751.     if(can1InitFlag == true)% `8 Q. r+ [% G5 i# ?( e+ P+ j( ?
  752.     {6 E1 b" O) n# i' Q1 N. }
  753.       RingBuffer_Reset(can1RxBuffer);% c3 V6 ]6 }2 ~- F( X6 a; ?" e
  754.     }
    6 f6 _) I9 E' h: }; O, x& Q
  755.   }
    ) a2 [" f- Q- F5 y! M7 i

  756. % B4 Q( D% ~! ?' g6 c# U
  757. #ifdef STM32F10X_CL9 J4 ~$ t& z. h% b- l/ H6 d% ^. l
  758.   if(CANx == CAN2)3 B3 P7 R7 T( w$ F" m8 y9 U
  759.   {+ s+ x  z+ k& T8 v$ d
  760.     if(can2InitFlag == true)
    6 ~4 [: V6 }8 z2 W7 T9 K
  761.     {
    ( P; Z6 w; q  E: G+ k
  762.       RingBuffer_Reset(can2RxBuffer);) K! p' W- b  \: f
  763.     }
    - Q% e% I1 e( @, J
  764.   }
    ! i( @9 D- e1 s% y- o( P; ]6 F( N
  765. #endif /* STM32F10X_CL */# p: k% Y3 g6 q
  766. }
    / t8 n# @. m3 ?5 [: ^- t1 m
  767. # {$ {, Y. h. {: Z( h" x+ S' S( q
  768. /**
      R( v! `3 A7 ~# v/ V: F" D  H
  769.   * @brief  Is the CAN transmit a message?% b4 U, S/ c4 j" I3 N" ^6 R
  770.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.0 m1 n+ d  E4 J: N+ S
  771.   * @retval true:      Is transmit a message.1 c& B" S# [0 Y
  772.   * @retval false:     Not transmit a message.
    4 Z3 @8 O: D" b/ o9 g  w  k
  773.   */
    0 `2 e; Q6 {' K$ a& X2 _
  774. bool CAN_IsTransmitMessage(CAN_TypeDef *CANx)* a% ~8 h9 ^. S2 d4 O3 b
  775. {7 j$ i; h$ V3 p( S4 U
  776.   if(CANx == CAN1)7 k$ @$ e3 }" N7 B
  777.   {/ f0 J- o( N) B- V4 P  R+ C0 v
  778.     if(can1InitFlag == true)
    # y5 u- D5 Y0 K2 ]4 R, ?
  779.     {
    ! V1 D$ K7 K2 ~8 Z. ~; h
  780.       return can1TransmitFlag;9 n  B7 f$ E8 f/ J- G5 J
  781.     }" y, g4 U" ^0 `. u4 d& Y
  782.   }
    & R4 x7 O! E- {$ }4 J/ J& X

  783. " `+ D3 i2 J( z% R- V
  784. #ifdef STM32F10X_CL
    * J& v* o5 f# D
  785.   if(CANx == CAN2)% D; s) _: {" c& u/ z+ d+ a, T; C
  786.   {
    % `$ e9 h; v, z* a- X
  787.     if(can2InitFlag == true)5 ]& O6 Y# L. a7 {4 k8 j
  788.     {  J* [" n3 O5 q+ D5 K7 s* A  v
  789.       return can2TransmitFlag;# s, F0 u9 P+ q6 h$ _  _! s
  790.     }
      U5 h" e5 g3 {  a
  791.   }
    ' k! }* V( q! {; B
  792. #endif /* STM32F10X_CL */( B/ {- T. Y+ L- n* P/ Z

  793. ) y% q$ q$ b# T  J
  794.   return false;
      j# ^! O/ ^- q$ ^+ R
  795. }  D% W& x) u' T" u" }
  796. 8 F* h0 ]8 I  A( i+ y' i5 {
  797. /**$ f( f  }1 ^! x/ R; P
  798.   * @brief  This function handles CAN1 TX Handler.
    3 t. r/ K! O' ?2 b3 n1 t
  799.   * @param  None.
    : j, J4 ~3 u' G  f& w. ]+ m  M0 G
  800.   * @return None.
      u" K! m- p/ `/ u3 v2 S7 @9 |! D
  801.   */3 d8 t3 D7 {$ y# a7 w, \0 A
  802. #ifdef STM32F10X_CL3 V0 ?* h! K. M& t5 P6 \; s
  803. void CAN1_TX_IRQHandler(void)% L3 |2 A4 H+ n( r
  804. #else" x0 k. W8 ^2 C% O' ^2 N3 a
  805. void USB_HP_CAN1_TX_IRQHandler(void)
    ' k6 K5 y) ^. B8 h; J. B- T. M3 V
  806. #endif /* STM32F10X_CL */
    " Q9 q+ v. s3 n$ c+ j6 J
  807. {1 A1 t. e% q( F- S
  808.   if(CAN_GetITStatus(CAN1, CAN_IT_TME) != RESET)' ]! F$ t4 Z) [. H6 V
  809.   {4 U7 K, R+ d' a/ ~% }$ V* a
  810.     CAN_ClearITPendingBit(CAN1, CAN_IT_TME);
    4 L9 W+ ?/ `# v, t7 R& d
  811. 0 U6 S/ p* m2 L' e% _# i
  812.     CanTxMsg canTxMsg = {0};- X" e7 D2 }$ e. ^
  813.     uint8_t  number   = RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);$ p$ Z% T( m1 w. Y3 k$ @
  814. / e( e2 w) n! r* H) s! y3 K! ?( _
  815.     if(number > 0)/ O, [) ]# Y2 ^" {6 X- h
  816.     {
    ' O4 T9 F( R; q- ]- S( u  w
  817.       CAN_Transmit(CAN1, &canTxMsg);
    : t9 K. d, K& r! m
  818.     }
    ( A7 Y" m% @+ o. T) B7 U4 x
  819.     else
    # T# N4 e) |4 C+ @; L+ X
  820.     {  i  G! L& u. h3 h0 S3 A. S
  821.       can1TransmitFlag = false;; R1 {3 O5 a& @5 u; S7 T
  822. . ^  E3 n4 m, a& I
  823.       if(can1TransmitFinishCallback != 0)/ D& S0 E) x: i- G! H, C
  824.       {* o" S8 B* e* C6 A0 E) w7 E$ u
  825.         can1TransmitFinishCallback();" c# h# c) a& R1 U
  826.       }
    % t  Y! Z  Z1 l$ e. K" J: Y
  827.     }
    4 \. T: h/ ]0 a( p1 Y  o
  828.   }
    / `# [- {5 ?+ a% ?1 @
  829. }
    7 l! v$ I6 X( R% [# c6 Z0 L
  830. : e: U. \+ A& m3 S1 H. E: I) i
  831. /**
    9 ~' m# G7 |1 r. E/ }
  832.   * @brief  This function handles CAN1 RX0 Handler.
    9 Z9 l6 e& q' u- T1 b" B1 \3 ?
  833.   * @param  None.. K: }$ T8 ^/ M9 x
  834.   * @return None.5 \( \' h0 }, L% [$ n
  835.   */1 ~+ C2 O' X3 N
  836. #ifdef STM32F10X_CL
    9 {+ H0 c5 H5 s  X0 L
  837. void CAN1_RX0_IRQHandler(void)
    8 E/ l9 }) Y4 O
  838. #else* R8 i+ `# @8 A& t6 D# S
  839. void USB_LP_CAN1_RX0_IRQHandler(void)
    * Y3 w: z8 F# ^  G( l: z& _) ]
  840. #endif /* STM32F10X_CL *// ~1 c! @" `+ p4 R; _
  841. {  M! G! g- b# n6 \
  842.   if(CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET)) i4 x2 g4 A' {% t
  843.   {4 {  z% H$ i, c; i4 y! f7 f  g- l
  844.     CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0);
    * ?6 q, K) |3 }" f  E
  845. 6 l! n8 E4 R8 L* n
  846.     CanRxMsg canRxMsg = {0};
    % P& m$ O- ]9 H. _6 A: D( J
  847.     CAN_Receive(CAN1, CAN_FIFO0, &canRxMsg);2 o  ~* {  i- x5 u/ h

  848. 2 G/ Q9 N( ?+ P- N
  849.     if(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg) > 0)+ u* E+ q  u: L; `! s% N
  850.     {5 O; l- ]2 H% e; t& ^8 d
  851.       RingBuffer_In(can1RxBuffer, &canRxMsg, sizeof(canRxMsg));
    # f) ^# c0 Z2 g1 q% n/ k( \. i9 P9 Y
  852.     }8 p/ G7 M& Z; W5 c* _' U4 Z
  853. + i3 \' N2 ^: u
  854.     if(can1ReceiveFinishCallback != 0); I) c( ^4 A0 v
  855.     {7 a# i4 G9 J; ~* X  C9 u
  856.       can1ReceiveFinishCallback();9 {+ _& x, w. k) p% \) M
  857.     }  e7 P% @! E  ~  }% M! u
  858.   }
    ! M- O& E2 Q( Q% s! H. w' q
  859. }; y- x1 N7 y% K7 w  ?/ r: ~* }
  860. 2 P; u2 a; K+ x+ J. I. f" d& Q
  861. #ifdef STM32F10X_CL6 H) d2 F" C& x2 Z) w; w+ g
  862. /**2 p! P; {$ ]6 E+ _6 r
  863.   * @brief  This function handles CAN2 TX Handler.& I& M7 A0 N1 Z$ B& i
  864.   * @param  None.1 Z  v! M* R1 g# I; k7 E- @$ g3 J% r
  865.   * @return None.
    3 c! ^4 `/ _& S1 R/ ~( W4 }
  866.   */
    0 H. k" n* s/ o- ]5 ]2 m+ S( R2 [
  867. void CAN2_TX_IRQHandler(void)4 X* s# W$ g  Q; G+ q# x8 {+ V
  868. {
    6 h! n5 `  t- n3 a
  869.   if(CAN_GetITStatus(CAN2, CAN_IT_TME) != RESET)
    4 _: [, L: Z+ e0 }; C
  870.   {
    # I) z7 c# x: |- z' |, P
  871.     CAN_ClearITPendingBit(CAN2, CAN_IT_TME);
    - I, e4 _3 |7 |$ H( R, [. Y" G

  872. 5 e$ @! V5 @# K! d! r
  873.     CanTxMsg canTxMsg = {0};
    . p) A* W& l1 N6 Q1 v
  874.     uint8_t  number   = RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);
    9 M2 E5 S8 I' K5 f6 b4 B% K: A

  875. 9 P9 i* }' G) a- t. l! v/ v8 Z
  876.     if(number > 0)! z) @) ^; F! x/ ~
  877.     {5 A; E; P/ b: A* b
  878.       CAN_Transmit(CAN2, &canTxMsg);: R# M% I7 j0 u7 D6 Z" `6 Y) E- P* d$ }
  879.     }
    8 p, Q3 V5 d: A" R. f, g& O7 U
  880.     else! r( M' |3 v0 p7 g  d- t. i+ o5 W
  881.     {  H8 V' P( x% c/ T6 g& U
  882.       can2TransmitFlag = false;* R. Q) h. l5 c0 z# Z

  883. 5 N7 c0 a; S! ~( Y
  884.       if(can2TransmitFinishCallback != 0): U9 c: r. n+ ~& g
  885.       {
    ; O  y$ e6 q# ~+ H8 n3 @
  886.         can2TransmitFinishCallback();* @7 n9 }4 z# u1 s; r
  887.       }1 H4 w, u& X% V2 D* T$ V1 B
  888.     }
    & L4 Y9 o& [2 t
  889.   }* b" {( @  p3 R- X1 Q9 W- c' j# `( k
  890. }
    0 E: b2 Z% [' H/ H3 E  Y  w
  891. 1 z2 f# |0 {( \! ?7 d
  892. /**
    ' ~2 i' s+ Y. t4 T% ?! T. _
  893.   * @brief  This function handles CAN2 RX0 Handler.
    6 q& s1 K  f3 w( t6 @
  894.   * @param  None.& p% Y3 E+ c) M, {2 l1 o
  895.   * @return None.
    ' R' A) H/ A1 z0 |- U+ }7 S% u& \' u
  896.   */. y* ^4 B! J2 m9 {
  897. void CAN2_RX0_IRQHandler(void)3 b& l! t2 [) H
  898. {7 J, U0 L- S. l7 J& s6 S
  899.   if(CAN_GetITStatus(CAN2, CAN_IT_FMP0) != RESET)
    # B3 v/ e1 w4 m" o/ x6 _6 Z& i1 B
  900.   {
    % e! \1 t" W$ X6 B+ @5 X5 V! O
  901.     CAN_ClearITPendingBit(CAN2, CAN_IT_FMP0);/ W- W# g) v6 ^% m: R, O6 {

  902. ( @- B, \% I) V) |4 ?/ V
  903.     CanRxMsg canRxMsg = {0};4 o( P& @3 _+ U8 e9 v
  904.     CAN_Receive(CAN2, CAN_FIFO0, &canRxMsg);
    3 [$ H; B, y- j- z; u; S2 u

  905. 1 z! o. j# A" I# P2 I7 l7 v
  906.     if(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg) > 0)# H" @; {' R1 n" X
  907.     {
    * N4 ~" i# z* u: q5 ^
  908.       RingBuffer_In(can2RxBuffer, &canRxMsg, sizeof(canRxMsg));* w! r" K6 d3 e
  909.     }" T% A  G: e1 j: F/ y0 j
  910. 4 p% Z3 a. A* G8 ?, B3 z
  911.     if(can2ReceiveFinishCallback != 0)* M  G  v" S7 N% k  |: J1 E& n
  912.     {
    3 I7 L$ g' f, \4 r# H2 i( B
  913.       can2ReceiveFinishCallback();. _1 `% O" C+ X! ~
  914.     }
    ) g9 s8 A' V9 Q" i1 {- _
  915.   }( H! h: h* F! s) z
  916. }1 H, Q3 I6 L- A; d3 \) s0 L4 n
  917. #endif /* STM32F10X_CL */
    ; M, e6 z6 v( f1 ?- g$ r# w: M1 w0 r
复制代码
! g/ A# h: r. J8 _6 J' m
' E. K! O+ d4 k
main.h 文件0 W3 g  P6 h8 m4 `! p2 Q9 s
  1. /**
    0 q; v3 z- @- }1 n. h' I& c0 O
  2.   ******************************************************************************; _* ~" ?' S) I4 i) ]" I% G& f( Y
  3.   * @file    main.h: L  a" U% O) e$ J" T5 E' a
  4.   * @author  XinLi, M: g7 A1 D, j. q& B( q! @
  5.   * @version v1.0
    . z6 R8 p; I0 e; h! E* f/ k
  6.   * @date    24-June-2018
    ) M8 X" O6 n: d/ h- S2 b1 f- C( I
  7.   * @brief   Header file for main.c module.
    % w. S9 {& @- U+ ]/ u& V1 Z
  8.   ******************************************************************************8 S( s) w8 N" d% y3 z2 [
  9.   * @attention
      M6 E$ I) o, A: J# I4 O
  10.   *
    " P" n; s' G& d4 w; L9 R
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>( O  A# S* [" K# z+ c4 Y& G5 z
  12.   *
    ' Q: F7 x& m6 Y) Q5 }
  13.   * This program is free software: you can redistribute it and/or modify
      T! ]2 }! {9 R) u
  14.   * it under the terms of the GNU General Public License as published by
    ! E% r- H2 W0 z% X" }" G
  15.   * the Free Software Foundation, either version 3 of the License, or
    / q# ]; N/ V( g
  16.   * (at your option) any later version.; @6 x$ c) n# e) h4 D
  17.   *' p( @3 x6 N6 Q  s* s1 ]0 F) p
  18.   * This program is distributed in the hope that it will be useful,
    4 w; J0 f) R9 v
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of- ]0 n2 {/ y1 N; i
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    9 N& @( A& Q( O- X
  21.   * GNU General Public License for more details.+ f* `. {2 p: l
  22.   *
    4 `# [4 N  [( T5 o+ i& Y
  23.   * You should have received a copy of the GNU General Public License
    8 S! x# j9 ^+ O# h/ x: n
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>' B" d! G' Q+ R* A5 Q* ^6 m
  25.   *
      M- j  W6 t2 @0 |) u* K
  26.   ******************************************************************************' g5 l$ ]6 Y' k5 o# }/ x% G
  27.   */
    $ U4 y5 t$ H5 N

  28. + Q9 R$ U' `( H6 V9 s/ P
  29. #ifndef __MAIN_H( d# {; I* P  r; E9 ?) I8 t
  30. #define __MAIN_H
    8 w7 v, C* j) c( y  q* |

  31. 9 R3 z+ I" p7 Q6 v% T1 I. H
  32. #ifdef __cplusplus+ Z3 p4 T! G( G( g( X! X2 C3 f
  33. extern "C" {6 v1 E. a& e6 O3 i: j
  34. #endif  ~' [$ M. m" J' t& e/ [4 P
  35. 8 _' v  x0 M6 {* C' ^6 s5 K) `
  36. /* Header includes -----------------------------------------------------------*/
    : R! s- I- Y) z
  37. #include "stm32f10x.h"6 x5 p  k" w; Y, U6 Y: m+ Y9 [& A& z

  38. ' E/ m! _. }# L/ M- r  z" e
  39. /* Macro definitions ---------------------------------------------------------*/4 m3 ]$ {9 T8 P1 T* B
  40. /* Type definitions ----------------------------------------------------------*/; U; i% x  o0 [/ @3 |
  41. /* Variable declarations -----------------------------------------------------*/% k5 e6 e$ p) u" H+ }& N- J# Q
  42. /* Variable definitions ------------------------------------------------------*// O) Q: Z. F! q7 Y- |% C2 h
  43. /* Function declarations -----------------------------------------------------*/
    # h2 G$ H( ~, U5 j
  44. /* Function definitions ------------------------------------------------------*/
    9 P! v2 q  O9 P. a% Q# a1 o

  45. 8 l( K- ~& q. c& X
  46. #ifdef __cplusplus
    - h  K2 {$ v: K- g$ a) _' [1 i
  47. }. l. `/ M0 T, L7 J6 W% @3 V$ T
  48. #endif  K; T; p/ R2 D; m8 U; H

  49. + ~8 H2 O4 i$ }8 D; M# d9 f
  50. #endif /* __MAIN_H */
复制代码
6 f" K: ~# D0 Y/ U

$ e( w& z4 W1 @- p( R: N: Jmain.c 文件
4 Y! h9 Y; R' A) L" p$ E6 ~
  1. /**
    - a0 Z$ |, N8 u3 V5 o
  2.   ******************************************************************************
    " s. s6 P( X9 p& r# p  v
  3.   * @file    main.c, e! `7 {7 }% T# ]' W1 n+ h
  4.   * @author  XinLi
    - H# l8 A# p" S; Y: |
  5.   * @version v1.0
    : X1 }' p; M' X# J- @. j
  6.   * @date    24-June-2018; d4 a. J5 D% \  E1 Y
  7.   * @brief   Main program body.
    1 r4 E4 `& a+ d% C% l* Q0 s7 A7 A
  8.   ******************************************************************************2 s4 v* ]  @# s1 ^$ Q7 D& r+ m
  9.   * @attention# d' ^0 R- [$ p3 X& f
  10.   *! W$ T9 w; V+ Q" ]/ ^0 k! E3 I* m
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    7 e& Y: R( Q0 q* B; K; K  z
  12.   *
    4 ]0 |. J5 j: a5 ^5 H- w
  13.   * This program is free software: you can redistribute it and/or modify, V; D/ S- h% ~' u" G) ~* z& `
  14.   * it under the terms of the GNU General Public License as published by
    * V) f) Z) n: C* \5 l9 H0 e( a
  15.   * the Free Software Foundation, either version 3 of the License, or
    ' |* @" ]& B& |0 k
  16.   * (at your option) any later version.7 q0 A5 L$ H0 V- }* `; c4 c+ |% H
  17.   *! F, }- D- D1 r# B' b
  18.   * This program is distributed in the hope that it will be useful,
    ' `+ t3 w* a+ O7 O$ |
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of4 d3 v4 P) ~  ~4 }$ R
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the! Y3 L) G  D  r1 S; B
  21.   * GNU General Public License for more details.
    + p& J5 g( q  r1 j% F7 i6 X
  22.   *3 @) @! i8 t. Q  q" s7 c
  23.   * You should have received a copy of the GNU General Public License8 A* j( i5 I# x/ F. b6 ]7 B* i1 S
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    * K2 Z9 l5 k: i$ m; v! O" d3 N
  25.   *1 ?. k& X* W, r, I! W
  26.   ******************************************************************************5 v# ~, a1 y+ h9 f
  27.   */
    ) H1 P7 x. }, J% v0 k

  28.   L& r. N( t9 p9 ^# N. ~( J# i
  29. /* Header includes -----------------------------------------------------------*/
    ) t% j/ _2 L* ?
  30. #include "main.h"5 [0 H3 \3 _7 D- ]8 m8 ^
  31. #include "CAN.h"
    1 w! K! N3 c, ^1 a. F! L

  32. . B* ?1 o9 `7 {  y
  33. #ifdef _RTE_/ P" h/ N) ^. b# Z& w+ G( s
  34. #include "RTE_Components.h"9 E0 R" i$ P  @, b8 x* }5 Z! z% _
  35. #endif+ ^4 a; [3 m0 S$ q6 w3 `' @4 k

  36. 2 p+ C; g  T& K. h  G
  37. #ifdef RTE_CMSIS_RTOS2! A0 y! E# s/ `8 H* g6 B; S- f7 i
  38. #include "cmsis_os2.h"
    + [  }# O- _5 o* A; x; e
  39. #endif
    4 k! I3 l- K, F# ~% H  T3 a

  40. % Y5 j1 R1 h+ Q6 o+ K
  41. /* Macro definitions ---------------------------------------------------------*/7 H' O' K6 e6 B( A3 C
  42. /* Type definitions ----------------------------------------------------------*/0 t9 @% y6 V9 w! W5 k
  43. /* Variable declarations -----------------------------------------------------*/
    , l: ~1 Q8 ]( ^: e7 y
  44. /* Variable definitions ------------------------------------------------------*/
    & |" ~5 `  h8 G
  45. static CanTxMsg canTxMsg = {0};
    7 |- j0 g. a7 d
  46. static CanRxMsg canRxMsg = {0};  s4 |7 C( y2 j( |- _- N
  47. % T2 K; @/ H  ?; T/ _2 j
  48. /* Function declarations -----------------------------------------------------*/$ U9 J0 K; _7 }- F1 K0 r, r& M
  49. static void SystemClock_Config(void);/ E2 ?3 g6 C9 {/ j4 I- }

  50. 5 H' C  [/ p, A# P& h
  51. /* Function definitions ------------------------------------------------------*/2 x; x. @- {# [5 u( T5 W

  52. $ S' Q) o6 y3 N( C  f# ?* p6 P& Z
  53. /**/ c9 S8 v1 n: i, ?0 ~/ Q8 [; Q
  54.   * @brief  Main program.
    $ x) U8 L: }& E; K' b
  55.   * @param  None.
    / p. W" U2 u* s$ I1 \$ ]* M& Z+ T, B
  56.   * @return None.
    ; ^+ u4 X0 R' d9 F
  57.   */
    " D2 }# Q! H4 Z6 C" |( _- p5 U
  58. int main(void)8 ~9 K/ o+ \" x% R8 |: z
  59. {3 Q5 l/ F. T$ N9 ?& G& p) g; k" t* b
  60.   /* Configure the system clock to 72 MHz */% T, F/ u; i2 U
  61.   SystemClock_Config();1 q5 z6 h$ x6 B* ?6 \6 K$ E
  62.   SystemCoreClockUpdate();4 z: F# s5 t# S6 X: w5 A$ Z
  63. 6 u+ O& I% o0 b. I$ w
  64.   /* Add your application code here */
    * g. S7 V. R* I$ _/ r
  65.   CAN_Configure(CAN1, CAN_WorkModeLoopBack, CAN_BaudRate250K, 0xAA55, 0x55AA);: m3 y" m# P5 Y& K0 j6 X$ P# I
  66. 2 U* L" D/ ~5 c: M' K
  67. #ifdef RTE_CMSIS_RTOS2
    9 Y) D6 d6 L, K5 l
  68.   /* Initialize CMSIS-RTOS2 */: ?# T- F4 c0 F" d3 r8 y
  69.   osKernelInitialize();3 S- T0 X. L$ B* F5 y8 P7 c

  70. % p: J* |/ f' t. ~5 ]& |3 z9 I/ |0 t
  71.   /* Create thread functions that start executing, 1 A9 h7 k: U1 {6 z& s: ?" H
  72.   Example: osThreadNew(app_main, NULL, NULL); */
    7 F! l/ b. H3 Y9 f

  73. ; U- n! J! ?9 c
  74.   /* Start thread execution */
    " Y) k1 D- `2 F
  75.   osKernelStart();
    / D. l) n5 I9 s+ J( S  U/ Z
  76. #endif
    # o8 P& A- U4 e8 V, A+ j$ X: P* D

  77. 0 E# j& B5 ~" h' u) D
  78.   /* Infinite loop */
    $ W3 p$ W! F7 p+ W7 C
  79.   while(1)
    # ^& Z+ S( |9 x
  80.   {8 K# v# v3 ^( H( m$ @7 ^( D; _
  81.     canTxMsg.StdId = 0xAA55;9 H5 ?/ h$ P* h$ X  F
  82.     canTxMsg.ExtId = 0x55AA;
    1 y4 s$ g7 E2 y: _# H! t( H
  83.     canTxMsg.IDE   = CAN_ID_STD;
    0 y$ \" @6 t4 V* r
  84.     canTxMsg.RTR   = CAN_RTR_DATA;+ Y4 l  F8 ^' ^3 H0 c4 n" k# l# X
  85.     canTxMsg.DLC   = 8;
    7 z3 {0 m. F/ g7 y8 c$ K
  86. ' H' l" [, h. J  X# v! f, G# i
  87.     canTxMsg.Data[0]++;; b6 J0 o) {, K. K+ t( `$ y
  88.     canTxMsg.Data[1]++;0 ^6 i4 g- C+ k
  89.     canTxMsg.Data[2]++;
    9 M8 [( k; I; ~, ]- }
  90.     canTxMsg.Data[3]++;
    ( {+ C9 f* `$ j/ @' k, ]- d- N
  91.     canTxMsg.Data[4]++;: m. O0 D, W0 d& S7 O1 @4 D
  92.     canTxMsg.Data[5]++;- @0 f1 b% D$ C7 Q% d% U* g
  93.     canTxMsg.Data[6]++;
    8 |  A- _1 Q. {! ]6 y) D+ \, a
  94.     canTxMsg.Data[7]++;) \- ^, a) k  A

  95. 2 b9 ]  n# b; y# u/ n$ Y0 g+ w4 [
  96.     CAN_SetTransmitMessage(CAN1, &canTxMsg, 1);
    7 Z3 Z. B4 N. [( A! z; L

  97. ! ?9 q* d3 l+ V* A" G6 V$ O' Q) j
  98.     while(CAN_IsReceiveBufferEmpty(CAN1) == true);7 [: R4 |) @6 O. H0 c2 b! @0 A! B
  99. 8 }$ P  ?# M$ z/ ]
  100.     CAN_GetReceiveMessage(CAN1, &canRxMsg, 1);  \- j8 n( g  D5 Y% S! s% S
  101.   }
    ) ?! e* v, U8 e! k& r7 M
  102. }
    , Z. N( @8 ^, P, R: J" G) U
  103. . A2 T/ Q$ k8 c% N, ~
  104. /**9 C7 W8 L  X% S' f
  105.   * @brief  System Clock Configuration." ]( s/ _$ c" Q5 q9 {# W# B
  106.   *         The system Clock is configured as follow : / Q8 [' I: l. h
  107.   *            System Clock source            = PLL (HSE)7 `9 s1 v3 ?) k0 I6 u
  108.   *            SYSCLK(Hz)                     = 72000000
    4 Q' d) t* `+ B, l  |, L
  109.   *            HCLK(Hz)                       = 720000006 E+ D# l+ b* [7 S% u8 v' O! L: I
  110.   *            AHB Prescaler                  = 1
    ( N  A) p' N: Q5 [+ x
  111.   *            APB1 Prescaler                 = 2
    % |7 x: j9 g$ W! [0 {
  112.   *            APB2 Prescaler                 = 1$ u1 V4 L; I1 F6 T$ ?% M; O
  113.   *            HSE Frequency(Hz)              = 8000000
    ; l+ q- U5 ]$ m9 R( ^* J
  114.   *            HSE PREDIV1                    = 1
    % v0 j8 H0 ]4 M" ]5 D; m: ^, r1 j
  115.   *            PLLMUL                         = 9
    % n! C) @% k) x; r2 s" {) @; |7 U7 @8 a
  116.   *            Flash Latency(WS)              = 2
    0 y( w) \' ?3 k; z9 W! z" ~
  117.   * @param  None.
    # p0 W% T& U% J5 `/ x7 I' a
  118.   * @return None.
    & j1 J( l- @( D. l1 V. ~
  119.   */0 \# J: p* I( L( G
  120. static void SystemClock_Config(void)
    . a2 K, ^  U+ D, b. N
  121. {
    ) \: B$ |& ~+ }+ l3 W
  122.   /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration */
    # E' j5 P% x! j! p9 w4 _
  123.   /* RCC system reset */
    ) u' B& O- i+ @- g
  124.   RCC_DeInit();
    : S$ l$ c* d. ^8 m8 T2 |$ H# g7 Q
  125. # q3 l: H1 o9 U5 J. Q
  126.   /* Enable HSE */9 Z# j; n. ]+ c% V9 I$ q; s
  127.   RCC_HSEConfig(RCC_HSE_ON);, @2 c9 b, e0 ]8 P$ E- W4 E
  128. $ C8 M" }' J+ z5 t1 K! ?, `
  129.   /* Wait till HSE is ready */& y7 q$ C3 F% }; u9 k
  130.   ErrorStatus HSEStartUpStatus = RCC_WaitForHSEStartUp();/ J- x) m& B6 v1 q9 p/ J% b5 j: o& x

  131. . C1 _5 w1 m8 j4 {9 S3 L0 n
  132.   if(HSEStartUpStatus == SUCCESS)
      j" @) ?8 M* K  @
  133.   {$ T: o; `0 f. @
  134.     /* Enable Prefetch Buffer */
    5 q% N0 z' E( F0 N
  135.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
    8 O! T' ^8 C( d; [4 M: Z

  136. * p0 o% G+ j$ K* r6 j0 ]
  137.     /* Flash 2 wait state */% h2 U8 o3 `- K
  138.     FLASH_SetLatency(FLASH_Latency_2);* ]8 A9 \5 P" Z4 \. R

  139. 2 G( _- l6 K$ v* r, [$ u
  140.     /* HCLK = SYSCLK */
    ( s/ \" V+ ]9 C! j* i# d
  141.     RCC_HCLKConfig(RCC_SYSCLK_Div1); 3 t& n' n, n1 {
  142. 2 p# q4 l. s( D8 N" ~
  143.     /* PCLK2 = HCLK */1 d$ |: e( Y% O+ C! v  {
  144.     RCC_PCLK2Config(RCC_HCLK_Div1);
    5 v& c. u' T( r; o! M

  145. 1 H, I* A8 ]3 M, x1 f
  146.     /* PCLK1 = HCLK / 2 */
    1 f% Q7 i: M- d
  147.     RCC_PCLK1Config(RCC_HCLK_Div2);
    + [) V  R. I9 T

  148. 6 W4 Q5 n; J: m. P2 A/ b5 `
  149.     /* Configure PLLs */& J1 g! M* n6 a; p- ~2 T' J3 I" N
  150. #ifdef STM32F10X_CL; i' S# \) k- x
  151.     /* PLL2 configuration: PLL2CLK = (HSE(8MHz) / 2) * 10 = 40MHz */
    , y' p. {" ~; u' s8 n  ?. K/ s. p
  152.     RCC_PREDIV2Config(RCC_PREDIV2_Div2);$ I1 ~. U2 i( l$ R- `
  153.     RCC_PLL2Config(RCC_PLL2Mul_10);: Y' ~- B- @2 h$ G$ c0 Q' N2 \2 y
  154. 2 \& I- W, _$ X. s$ E2 P" [" Z
  155.     /* Enable PLL2 */
    . r) @3 G- A3 ^; s. e9 e. `) t
  156.     RCC_PLL2Cmd(ENABLE);
    ' Q& Y$ a2 Q% U
  157. . O  Q4 I, x. A& f+ C0 q( M
  158.     /* Wait till PLL2 is ready */* K- _7 V, ^4 c/ |1 R
  159.     while(RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET);8 L! I. C2 @, E1 e- b4 Q7 Z7 n

  160. # T" E: t+ M6 s- M# S! y0 j
  161.     /* PLL configuration: PLLCLK = (PLL2(40MHz) / 5) * 9 = 72MHz */
    1 y8 e4 d7 C$ e
  162.     RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div5);& z# |4 ]9 }; ?/ D3 H2 \
  163.     RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);
    & z; a* @/ S) A2 M6 j3 l+ D
  164. #else. N+ k' S' \% f7 b' e% E
  165.     /* PLLCLK = HSE(8MHz) * 9 = 72MHz */
    4 H* F/ p9 A# Y* U) q, H7 v
  166.     RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);# L+ }* ?2 l0 R" e( I6 X
  167. #endif8 t4 @% P+ G2 N$ d( x1 _2 r- G
  168. + b; T' w" i- E( t- C4 l
  169.     /* Enable PLL */( [8 f1 U% j  s! J; {
  170.     RCC_PLLCmd(ENABLE);
    2 J- Z8 _; _# [$ a, ], H

  171. 5 [2 f! g0 q  q2 x% i& m' w. w
  172.     /* Wait till PLL is ready */* m7 [, u: i8 x* {; ]: x/ G3 R- ^
  173.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
    ( v) }9 f0 m; T2 }3 q

  174. * ]! A6 J# D" I8 p! V, F- s, {4 |
  175.     /* Select PLL as system clock source */6 c4 q7 I4 q+ d& I: j
  176.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);" f/ D# V) |5 s% Y/ ]2 }
  177. 1 U0 I7 S% M8 V* L  F+ P
  178.     /* Wait till PLL is used as system clock source */
    % w7 p% n( v* f- @1 d- v
  179.     while(RCC_GetSYSCLKSource() != 0x08);
    ' _. N- W3 O3 |
  180.   }
    - J# p5 \) |+ B2 [) N9 }! ^; `
  181.   else8 A) ^$ O0 g1 }  ^- e3 B3 ^+ Y
  182.   {
    ' @# A- _3 Z( v
  183.     /* Disable HSE */
    0 z$ B3 `0 W( q: |, `7 q: z2 S
  184.     RCC_HSEConfig(RCC_HSE_OFF);
    % R* G, m5 a3 {0 a# o

  185. 3 D  J' P) _) z" B# V# P
  186.     /* Enable HSI */
    3 s  |6 p5 E5 h. l1 H) U
  187.     RCC_HSICmd(ENABLE);
    % W4 h! P0 V" S

  188. $ z. E: X. ?8 V6 l" \* ]
  189.     /* Enable Prefetch Buffer */
    & U: C/ b% _7 l5 Q( V* K5 l4 H
  190.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
    ( q7 \: ~1 V9 F4 Y3 E4 W
  191. ( a8 H2 E% {% t( V
  192.     /* Flash 1 wait state */
    # _9 M" b: X2 o. l/ z2 F( `+ c2 d
  193.     FLASH_SetLatency(FLASH_Latency_1);- e# _/ o" F/ a  z

  194. . T& f! K" S- J) }# L( l
  195.     /* HCLK = SYSCLK */
    5 m- D" u$ y8 X9 K  ]8 H
  196.     RCC_HCLKConfig(RCC_SYSCLK_Div1);
    ( Q, m/ I  B6 E

  197. ' }6 A# X) s+ K# R+ R; {
  198.     /* PCLK2 = HCLK */
    5 [* r+ _+ W" s' V( i
  199.     RCC_PCLK2Config(RCC_HCLK_Div1); 0 m# |1 S) h0 ~# ?0 c* L5 t
  200. ) H" t* N7 ~5 p6 ]1 z( ?/ z. x7 d
  201.     /* PCLK1 = HCLK */2 a9 u! e+ y, ?9 Q
  202.     RCC_PCLK1Config(RCC_HCLK_Div1);
    0 H# ?6 W% [/ F9 `8 M6 f' E

  203. # ?) {) K: s, F2 g! A4 l; j
  204.     /* Configure PLLs */) R3 d& ~2 `- `& b
  205.     /* PLLCLK = HSI(8MHz) / 2 * 9 = 36MHz */
    1 G" {3 D# r0 @& E8 X9 v" R# D
  206.     RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_9);
    7 U2 `8 U; _3 Q( H
  207. - }5 g6 |' X6 `* H2 c# |+ A
  208.     /* Enable PLL */4 ?- f6 a$ ^+ z: l6 j
  209.     RCC_PLLCmd(ENABLE);
    ' ^7 n( ]) W, \+ Y7 u
  210. 7 O7 F5 _7 v( C% u- }
  211.     /* Wait till PLL is ready */4 f. E9 o# }  y! |' o+ m' s
  212.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);8 R4 T+ |" s* u
  213. $ ~$ e4 V0 ~+ o7 b# [
  214.     /* Select PLL as system clock source */
    8 W& V$ t+ f- O4 }, Q* Y! _% I
  215.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);+ E3 k& i6 Q, r, \  O

  216. " N% j% x# w  o
  217.     /* Wait till PLL is used as system clock source */
    / j/ l  V; Q  k9 Y, Z5 ]
  218.     while(RCC_GetSYSCLKSource() != 0x08);
    3 A5 a8 j' r- Q2 G' E, p
  219.   }
    / J& i& g, v  n# F
  220. }1 S" w, ]5 `: W( f

  221. ) M4 p5 o' H# W- Z
  222. #ifdef USE_FULL_ASSERT
    1 L. G6 d& y# T1 ]. H( k
  223. /**1 y. S- ^+ E% K& [
  224.   * @brief  Reports the name of the source file and the source line number
    ' _8 l1 x/ |8 W  c: P; b3 V
  225.   *         where the assert_param error has occurred.5 k9 S( P; P' t4 t0 b
  226.   * @param  file: pointer to the source file name.1 r8 {- s# n$ F" j6 ]
  227.   * @param  line: assert_param error line source number.' S: ?5 F: P# q1 n3 X
  228.   * @return None.: [* Q/ a# f2 o
  229.   */; h" d( _6 J" [, O( J3 g! Z, P+ ]" ?
  230. void assert_failed(uint8_t *file, uint32_t line)
    , W' ?" m' q4 X
  231. {: f. Y( a# K6 ^2 Z& o7 C2 E" ?
  232.   /* User can add his own implementation to report the file name and line number,
    . F+ Y- z8 b3 s
  233.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */0 G' J( b( t3 o6 P+ @
  234. % J* Z2 c! M' }( N7 P$ |5 x% x, C; v
  235.   /* Infinite loop */( j* V+ G5 g! X5 L$ F
  236.   while(1)
    . L& Z: C2 g; V- T
  237.   {
    5 N0 C) c* ~# p; @+ e
  238.   }
    , o5 F4 H- ^* {& P$ A
  239. }
    : h& I" Z( l9 y1 ^
  240. #endif
复制代码

. e9 X2 [/ f8 w; D3,注意
* r0 j5 y' i' Z8 G! M! E( H+ d/ t1 ?7 `' O. u' Z$ Q$ _- h
CAN 消息发送缓冲区和接收缓冲区的大小,可以根据应用的需求进行修改,缓冲区使用的是堆内存,需要根据缓冲区大小和应用程序中堆内存使用情况进行配置。( L1 [2 ]6 @; l) C

) y& [' w8 v! h# W5 `
- {# @/ D3 a" i" q1 a$ S' K+ b3 }' H0 N# ?
收藏 评论0 发布时间:2021-11-26 17:00

举报

0个回答

所属标签

相似技术帖

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