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

【经验分享】STM32F1(CAN)

[复制链接]
STMCU小助手 发布时间:2021-11-26 17:00
1,开发环境
* c+ J3 m, x9 w# H! L" N
6 e9 u# k( `8 ?- Y2 [& j' j$ w% Y* j1,固件库:STM32F10x_StdPeriph_Lib_V3.5.0
9 Q; K4 J( J( s# \* }6 [
/ E1 \: g! a! h! ]0 s5 d2,编译器:ARMCC V5.06
4 s5 {4 f' N$ H$ F0 s  Q; b+ ?* Q8 o. n: H5 S; a3 ^1 M
3,IDE:Keil uVision54 E  H& O1 _1 c4 S+ i  w

/ e1 \* g" t" E  }+ @$ T, t% ~4,操作系统:Windows 10 专业版
- q) _" Z6 u: Q7 @4 D. L. d/ G
* @3 R( u& u9 X8 g8 V
/ h' x6 @% R2 U8 e/ |2,程序源码/ q9 q5 `4 }; f( Z  ^6 h2 q) @

( c: D- Q0 ~" @RingBuffer.h 文件
5 N: h: _! D* a: c8 u9 [
  1. /**
    ! A; m7 y' Z! ^7 p* y
  2.   ******************************************************************************
    ; d5 ?, {# j+ ]( f
  3.   * @file    RingBuffer.h' n5 J* f+ h" |. s8 S2 C& R/ \
  4.   * @author  XinLi4 `/ i/ ]/ |2 F! T, P( U
  5.   * @version v1.13 E( y' p( A9 P  ]" K! s
  6.   * @date    15-January-2018! ^) `! ?. R- V# B. I4 ]1 \8 F: V
  7.   * @brief   Header file for RingBuffer.c module.3 ?" o" N, [7 r% ^8 L% i
  8.   ******************************************************************************
    0 [1 d' ^+ y2 U" {
  9.   * @attention" \0 z2 Y. L3 L
  10.   *
    ! O1 R# x- e: f5 u
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    + U* d  ^  t( d% @" T; {9 q
  12.   *
    0 `* E; i2 ^7 y0 }) w# x1 \& t
  13.   * This program is free software: you can redistribute it and/or modify
    . E0 a: U2 ^6 a) i+ d
  14.   * it under the terms of the GNU General Public License as published by- a" J5 C* a( K, [
  15.   * the Free Software Foundation, either version 3 of the License, or# |  Q! N9 ^* e( K: ~8 b
  16.   * (at your option) any later version.
    7 I: P( M+ C: V/ d3 r& v
  17.   *) P, @- ~) |* M; }2 c3 ^- c$ A: y
  18.   * This program is distributed in the hope that it will be useful,
    5 ?0 p7 M" Q# y1 }: Q0 k7 f/ ?
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    . J6 z% \2 S) E
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    * L- s9 M- T# i% L
  21.   * GNU General Public License for more details.
    - V0 m  d5 ^, ^! E8 |0 Q
  22.   *$ O* J: [9 m; p! _' {- t
  23.   * You should have received a copy of the GNU General Public License
    5 w. Z. `5 ~9 Y! ?' z4 D
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    1 h* k3 O! \3 V3 W: O5 }
  25.   *# X  I9 |( R3 X3 B7 u! }4 A: @
  26.   ******************************************************************************
    $ f# E( g9 v/ `* ]0 C8 B& U8 j
  27.   */
    6 U: g5 h3 f0 U0 ~6 K2 |

  28. ) r; q5 Z' ~! q. m9 m
  29. #ifndef __RINGBUFFER_H
    4 [' h8 t& n9 b
  30. #define __RINGBUFFER_H! R; Y( u7 p9 v
  31. 6 |: d! C; N' }! p, o
  32. #ifdef __cplusplus* z* C6 z2 U0 `+ r+ q+ @: d; d  K4 A
  33. extern "C" {
    , {$ q6 h+ k* A) r
  34. #endif5 y. }4 q+ ?8 n

  35. 3 Z* U; l! }5 m+ D  v- B
  36. /* Header includes -----------------------------------------------------------*/7 p! b! o. @) i+ {9 v: ?* a
  37. #include <stdint.h>
    # \3 k' C. ?/ ~/ G' z- e; O( M
  38. #include <stdbool.h>! _6 S" O& v0 X  t7 w9 o# d
  39. #include <stdlib.h>* B8 w0 S% B  L3 w' }2 c# w0 f% S
  40. ( P5 @" \: ?" B' Q
  41. /* Macro definitions ---------------------------------------------------------*/! b/ W! @8 W- S' `, x6 N9 g; P- L
  42. #define RING_BUFFER_MALLOC(size)  malloc(size)1 ~/ W( P3 T0 r8 B$ r( S
  43. #define RING_BUFFER_FREE(block)   free(block)
    : V8 }. T+ i  ?% W/ h8 H0 E

  44. 3 k4 o/ t2 m) Y4 o" K
  45. /* Type definitions ----------------------------------------------------------*/
    2 R: k8 P/ A& q# Y0 k
  46. typedef struct8 I5 u; O# C$ ^) F; ]0 x6 Y
  47. {
    + O4 ^( N: F5 p: k2 {
  48.   uint8_t *buffer;- h' h4 [1 H$ S7 K& A* N( ^* ^
  49.   uint32_t size;
      L/ `7 V* X) M' h9 K) K
  50.   uint32_t in;6 [: h1 S" y$ F5 e* e
  51.   uint32_t out;
    - q4 D4 n8 i9 f+ O( w0 {9 |
  52. }RingBuffer;
    : w1 J. m- b0 W9 t. s; a+ V

  53. ( m. u4 _( @  V0 W  |# V( u7 k
  54. /* Variable declarations -----------------------------------------------------*/
    , m) o- _0 w$ B/ w
  55. /* Variable definitions ------------------------------------------------------*/
    $ B& C. j3 ^! F" Q3 }
  56. /* Function declarations -----------------------------------------------------*/1 ?3 s/ V$ A' C" O9 ?: g
  57. RingBuffer *RingBuffer_Malloc(uint32_t size);
    # h% A  B# L8 e
  58. void RingBuffer_Free(RingBuffer *fifo);
    & o9 J. |3 }8 v$ b2 a2 B
  59. 2 O5 M7 r# T4 r: Z" C4 Z- p! I
  60. uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len);- t/ j6 I3 H4 {0 A4 v6 I0 k
  61. uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len);- g- z' @- X: m9 i4 Y
  62. 5 J. ~' e! S- I
  63. /* Function definitions ------------------------------------------------------*/
    ; E9 m+ V2 U, l* q5 Z3 Z

  64. : V2 J) ]2 w; j, `" ^
  65. /**6 J4 \7 m+ V6 q) `8 }
  66.   * @brief  Removes the entire FIFO contents.- D4 r7 H6 [5 U% w
  67.   * @param  [in] fifo: The fifo to be emptied.- I3 y& J: U) V, y1 M6 T' S0 @
  68.   * @return None.
    " t6 A$ K, ]9 k/ G# ~# G
  69.   */" d) Z! X8 ^! q7 n4 g- m+ r
  70. static inline void RingBuffer_Reset(RingBuffer *fifo)
    # w- Y, J& O' t* W6 {
  71. {
    ( J9 k) B& \* E" y' D- q
  72.   fifo->in = fifo->out = 0;
      A1 E. b* s( A* F$ N
  73. }$ x8 X& f$ L2 o0 K' p* e
  74. ( A' _3 g: e3 U. J, J$ t9 K8 j
  75. /**$ S) l" [/ P# f/ Y9 M( z. g
  76.   * @brief  Returns the size of the FIFO in bytes.4 ?. O/ D1 m& a
  77.   * @param  [in] fifo: The fifo to be used.& c- {/ P6 P/ P1 ~' t
  78.   * @return The size of the FIFO.
    + \* n6 F  Q; y" g0 y+ c' H
  79.   */
    ' M9 S, E. x, D2 U
  80. static inline uint32_t RingBuffer_Size(RingBuffer *fifo)8 |# X- Y. F- ~8 X" B" y) k
  81. {
    & B. e% s2 U: E
  82.   return fifo->size;2 i3 Q& f$ J/ j+ y
  83. }
    0 L  D2 K7 u" z2 k. P
  84. 4 Q) _% o9 V" S/ M+ o6 G% M
  85. /**/ y, T. `0 E( g
  86.   * @brief  Returns the number of used bytes in the FIFO.
    , L$ @6 e) ^4 K* e6 s3 E
  87.   * @param  [in] fifo: The fifo to be used.
    : p' H# Y6 H* h3 i' d' a
  88.   * @return The number of used bytes.
    2 b) Y9 r/ l: L' b; E, R. r- C( M4 t
  89.   */# Z& Y7 i2 s1 \4 M4 t
  90. static inline uint32_t RingBuffer_Len(RingBuffer *fifo)
    8 n) n; ~2 s: L; D! Y% Y, f- v
  91. {
    * |; M! T* v0 L. q, X2 E' h
  92.   return fifo->in - fifo->out;
    / F- T, n# x, P* q7 O
  93. }
    " P. Q% k+ Y+ r3 k& V
  94. - d1 N/ g; o$ \
  95. /**, L/ D* Z( ~6 P, X+ ]
  96.   * @brief  Returns the number of bytes available in the FIFO.
    , e) j2 ]2 y* I6 I3 H! T) r
  97.   * @param  [in] fifo: The fifo to be used.
    % {+ p! b# w( e0 v" L
  98.   * @return The number of bytes available.
    / N7 s( n+ g7 r. ~
  99.   */' g# O- z& X" l( j4 N& g, k! I
  100. static inline uint32_t RingBuffer_Avail(RingBuffer *fifo)6 A% k3 P) P2 M1 N( Y' J/ j& `
  101. {3 i, F+ V5 |1 H) q5 ~
  102.   return RingBuffer_Size(fifo) - RingBuffer_Len(fifo);* C! ^, {" O, H% n4 `/ k6 o
  103. }6 X: d& C7 U9 u
  104. 9 x- J4 g3 x, g: ]
  105. /**
    1 _$ b$ ^3 J5 Z( N% J" z
  106.   * @brief  Is the FIFO empty?
    ! e# }4 \5 ?/ f8 ]
  107.   * @param  [in] fifo: The fifo to be used.
    9 m9 I, y/ f) S$ l5 w0 J
  108.   * @retval true:      Yes.
    - k! U- t# B' i( u0 f4 x) ~3 F. ?+ d
  109.   * @retval false:     No.
      ?4 P5 c  @2 j9 H1 S: t
  110.   */
    " [! c1 i- V" Q  \1 F/ g
  111. static inline bool RingBuffer_IsEmpty(RingBuffer *fifo)0 ?; E2 P/ F3 H8 B
  112. {" s0 r: F/ T3 `5 X0 r" j
  113.   return RingBuffer_Len(fifo) == 0;
    * H4 q7 W) q3 _6 Y- A7 b1 _
  114. }
    6 t8 t/ O# q- i+ q  A# k2 B

  115. 5 ~# s  q! d3 \4 u: C
  116. /**
    , c5 Y7 d9 Y, e& I
  117.   * @brief  Is the FIFO full?6 ?- I  M, m* v6 G( X' e
  118.   * @param  [in] fifo: The fifo to be used.! l2 G# u8 u$ b" H. ^4 ^& k: J
  119.   * @retval true:      Yes.
    + r9 d; C# |( A: {" ?
  120.   * @retval false:     No.
    + s* t0 X8 p( c2 O3 r4 x2 {" B4 r
  121.   */
    % K4 g" N+ O4 m5 m/ s; j" i
  122. static inline bool RingBuffer_IsFull(RingBuffer *fifo)
    1 t* R  o" J( P/ G& b
  123. {* `* |" |; a8 n! C' x6 N3 H
  124.   return RingBuffer_Avail(fifo) == 0;
    * l2 }6 k/ T! D
  125. }; s3 q3 F9 U7 Z. y( ~8 z
  126. 4 f+ T9 X9 L% L& o3 f% c# q
  127. #ifdef __cplusplus
    * [) W6 k4 ^( q7 M) a1 g+ K4 l
  128. }7 S9 J# f. v" H6 S) j5 P
  129. #endif+ a4 D5 ]% V9 c( W; L5 D

  130. ( ^& T4 P: U7 J5 D1 F' d7 R
  131. #endif /* __RINGBUFFER_H */2 `1 v3 L+ r0 d1 r3 S
复制代码

. {$ Q9 z5 y0 Y: r' G' {5 e. q' T# _/ V$ I9 N# h6 |
RingBuffer.c 文件) C1 x4 k( k7 z3 D8 i! I
  1. <div>/**- Q9 Z1 _& H% W5 A! D
  2.   ******************************************************************************
    4 X) ?" |" b, H% H
  3.   * @file    RingBuffer.c
    1 N0 j! x% p% ]/ N' f9 q
  4.   * @author  XinLi/ O1 s6 Q' E* k7 Q
  5.   * @version v1.1" F' Q! |; j0 R9 l: I
  6.   * @date    15-January-2018
    2 v7 S9 [' h1 F
  7.   * @brief   Ring buffer module source file.
    0 b6 Z  U) G: w
  8.   ******************************************************************************
    9 H. Y; B: d, n
  9.   * @attention
    , {, H" R* P' l4 O8 F3 h5 X$ `1 d
  10.   *
    * o3 l2 [& m$ R5 ~3 T
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>0 z* J2 q$ M2 ]! F5 ^& v
  12.   *
    5 g# v2 K6 c' v- w
  13.   * This program is free software: you can redistribute it and/or modify. o6 y, }$ q' ^; V1 c, m3 C7 j, [
  14.   * it under the terms of the GNU General Public License as published by: l/ j2 i. a: Y  f& q1 h3 p
  15.   * the Free Software Foundation, either version 3 of the License, or: S0 ]: F4 Q- Z3 J  q. g3 n
  16.   * (at your option) any later version.. I' q* B% \5 \) L) G
  17.   *( b( [3 d( m6 j9 D% k- E, H
  18.   * This program is distributed in the hope that it will be useful,
    0 ?) L  |# x, ^; I. v) C
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of* D! h) A( f; l& ?) C) L
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the0 d' A" S! ~: M
  21.   * GNU General Public License for more details.
    - f) E7 s9 S- H2 J
  22.   *$ x" L7 v$ t" _2 Q1 P
  23.   * You should have received a copy of the GNU General Public License( f6 e  P; A% A0 q/ n5 m
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>9 K7 B: R, `+ d2 @7 n7 m' C9 `# h& g
  25.   *
    # Q+ Q) ?- `/ E' v1 D6 W7 l" t0 h
  26.   ******************************************************************************
    % ~  ~: V, d1 y# l3 H5 |
  27.   */4 N, U' q8 ~7 X* q2 i
  28. , G! {) [$ V& ]2 }$ ~: z
  29. /* Header includes -----------------------------------------------------------*/
    $ S) E. C' r: ^% z3 Z# Q( ~! v7 ^
  30. #include "RingBuffer.h"
    ! d1 ]' S0 G* D3 M- |" I
  31. #include <string.h>
    ) H7 u8 n0 T( F
  32. & I% g: g/ Y6 {/ g; _; d- G0 V4 e
  33. /* Macro definitions ---------------------------------------------------------*/
    1 s/ V5 |# G% z' }4 N3 F: a8 D, N
  34. #define min(a, b)  (((a) < (b)) ? (a) : (b))
    ( o! d; F2 f' g) U
  35. " ~8 V4 v2 F% u, @8 j
  36. /* Type definitions ----------------------------------------------------------*/
    + Y4 t6 ~0 b$ p9 R& I* r
  37. /* Variable declarations -----------------------------------------------------*/
    ) P( k; s0 d# J
  38. /* Variable definitions ------------------------------------------------------*/5 e+ }* g( m" x1 y+ X' ]
  39. /* Function declarations -----------------------------------------------------*/
    2 q1 r: j4 f1 H) j5 m
  40. static bool is_power_of_2(uint32_t x);
    8 b1 I. c6 {+ S* v( H* c
  41. static uint32_t roundup_pow_of_two(uint32_t x);
    8 r/ ?5 b6 S! w; n' W' _; Q( ^# [
  42. 5 j0 o% D; l  i# M6 H
  43. /* Function definitions ------------------------------------------------------*/
    + H" p8 Y# ?. V4 Q% K
  44. . w4 S1 ]! Y: `8 l- d1 s
  45. /**; ~8 f! t% D% b  i# O3 x0 H$ T
  46.   * @brief  Allocates a new FIFO and its internal buffer.8 T) b7 T- R: `3 ]3 i1 o
  47.   * @param  [in] size: The size of the internal buffer to be allocated.
    . c& x3 _+ l! h/ [
  48.   * @note   The size will be rounded-up to a power of 2.& E! I8 @8 ?# c+ @- \( I1 @
  49.   * @return RingBuffer pointer.- i3 s! i$ U9 z$ h6 l' a% X, @* _
  50.   */7 d/ f1 _+ e( M/ x# k# e- O
  51. RingBuffer *RingBuffer_Malloc(uint32_t size)
    & f. w/ x* u2 J( A
  52. {
    $ {) F& `+ D6 f+ f+ ^$ }
  53.   RingBuffer *fifo = RING_BUFFER_MALLOC(sizeof(RingBuffer));
    3 e; n" R5 A" c2 [; n: m4 B

  54. 4 f3 G$ c, S5 J$ q( V, p
  55.   if(fifo != NULL)3 Z$ K1 a- Z7 t; o  \
  56.   {' |- q5 A# `, B% K% ~0 k
  57.     if(is_power_of_2(size) != true)
    " H3 [- C! [1 f, k
  58.     {
    " T1 p2 ^+ Q, I+ W7 N2 E& ?" p
  59.       if(size > 0x80000000UL)
    , `/ \; f+ J0 u8 n4 ^& v
  60.       {
    ) w. V. Q1 o& i# C
  61.         RING_BUFFER_FREE(fifo);
    ! F/ Z: T* y+ H' \
  62.         return NULL;, c' l6 {; z9 f8 Y6 _+ q
  63.       }1 M( }' A  n* S' l2 u$ F5 e
  64.   o- O% o' Q7 h1 R* z
  65.       size = roundup_pow_of_two(size);3 @9 q& E. {+ D% ~5 g
  66.     }
    % h$ H$ R6 C4 d+ Q) K; F
  67. # ]2 @- l$ n( p& @0 P, Y5 T
  68.     fifo->buffer = RING_BUFFER_MALLOC(size);
    1 t; B# y# O& A

  69. ) s! I# ^% W& P/ c1 O2 n1 P, {- V6 ^% T
  70.     if(fifo->buffer == NULL)
    : ], {, ]3 Z0 }$ [4 ]
  71.     {
    ) O6 s, h$ k6 ?0 h5 i+ J/ n6 v8 @
  72.       RING_BUFFER_FREE(fifo);/ M9 `3 ?* h7 a" ~3 U% A! `, i, p
  73.       return NULL;
    ( p/ i, C+ m6 r3 S% W8 _: {& O) V
  74.     }% [9 V8 ]3 y4 F" T3 r; G$ r: v

  75. + U4 T3 {9 Z2 A, y+ f# P
  76.     fifo->size = size;# G. m, @( k0 b$ [( z- A( J
  77.     fifo->in = fifo->out = 0;
    7 A( j6 j6 [, z5 ?
  78.   }
    ! b( ~8 R; |! b( l- R" `% ^9 Z
  79. ( y3 T* x$ X6 R* i+ E
  80.   return fifo;$ x* e& B% `% d% E' d. L
  81. }, ]5 Y; O5 ~: E

  82. " t! Z/ F( _* X0 v; b
  83. /**  ~- i+ A! e5 k8 s
  84.   * @brief  Frees the FIFO.0 h: M5 R7 q" S4 f2 b6 Y
  85.   * @param  [in] fifo: The fifo to be freed.
    " `1 b) l9 ^+ w; ~  m$ u+ p, i7 D
  86.   * @return None.
    8 `2 k9 l, k5 S6 z% C" D
  87.   */. D" ~* `5 X( z+ U) t
  88. void RingBuffer_Free(RingBuffer *fifo), r8 B  u& k- m# p- }/ S
  89. {
    5 O) A* I) N8 o4 U% g
  90.   RING_BUFFER_FREE(fifo->buffer);
    " \+ ^( T$ W0 O$ W- y: G1 t
  91.   RING_BUFFER_FREE(fifo);
    " ^9 O2 D* j. |9 L- g5 F/ z( Y0 r0 |
  92. }, I# M% x) B2 |+ d

  93. & _, U& \# a; w+ f5 |0 t  b
  94. /**
    * x3 C8 q. ?/ I) V
  95.   * @brief  Puts some data into the FIFO.! h* w" m) v! ]% H2 l& }0 F
  96.   * @param  [in] fifo: The fifo to be used.% R3 U: A- k4 [
  97.   * @param  [in] in:   The data to be added.
    ( w3 ?  h5 a, c3 o$ x! p
  98.   * @param  [in] len:  The length of the data to be added.
    8 @4 `2 R" `" N( v2 _) T1 l. u
  99.   * @return The number of bytes copied.
    1 \7 \3 G  i4 ]5 |
  100.   * @note   This function copies at most @len bytes from the @in into
    3 ?* w: D, i6 r1 ?3 K
  101.   *         the FIFO depending on the free space, and returns the number* G  |- r* e0 {8 Q/ j
  102.   *         of bytes copied.
    8 W" \% f8 P8 ~9 C" A1 S
  103.   */6 c) Q' j) f3 |& M
  104. uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len)4 s2 y9 {1 q& Q  J
  105. {9 [, C. V. `4 E) r) ^, s
  106.   len = min(len, RingBuffer_Avail(fifo));
    5 D% }# y& ~5 B& j/ F

  107.   B) S$ ]' E2 _! ^% J8 b
  108.   /* First put the data starting from fifo->in to buffer end. */
    $ U7 u- j- b9 s- U
  109.   uint32_t l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));' E+ g  s2 a- \7 J  n* ~
  110.   memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), in, l);0 r% \- p" s2 Z1 t( V! ?
  111.   ?7 Z. X" Y; X4 j+ Y3 x. }* A) T
  112.   /* Then put the rest (if any) at the beginning of the buffer. */$ R' B5 H# T* L. X' m6 w7 l
  113.   memcpy(fifo->buffer, (uint8_t *)in + l, len - l);
    - D, P8 l& V; c1 }4 @8 u. K! a( E

  114. ; A! j& k, N! Y& }& U( Y( n
  115.   fifo->in += len;' A8 t( x7 v- ^) R/ o( \
  116. 5 q# M& A( r: E# `& J
  117.   return len;
    . L, V3 f" G+ u! k% q
  118. }
    7 F& x5 H6 g" \' ?2 O6 r0 u4 D

  119. , T% B, r5 n9 r' p/ }9 @
  120. /**, @8 r7 O# s1 r5 o# d) X" ~% ]
  121.   * @brief  Gets some data from the FIFO.8 i+ I2 m, J5 S# l- d4 O
  122.   * @param  [in] fifo: The fifo to be used.1 _6 _' H' _3 t
  123.   * @param  [in] out:  Where the data must be copied.
    ; @1 L8 {! b6 n1 p! X9 f
  124.   * @param  [in] len:  The size of the destination buffer.# ?+ b3 c9 T# Y* |5 `) i
  125.   * @return The number of copied bytes.
    ) v, {0 j9 y/ s* s. f6 g; S9 z7 d
  126.   * @note   This function copies at most @len bytes from the FIFO into4 X2 O, _9 |. f
  127.   *         the @out and returns the number of copied bytes.# h" `( L. S  O/ o( Z! i- P
  128.   */
    - y8 S9 a! K  C1 [! j
  129. uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len)
    ! Y2 j2 P3 b: p7 O2 ?2 i) {
  130. {
    " T$ W. @" [  C( }
  131.   len = min(len, RingBuffer_Len(fifo));) k* ?: w% h# T2 g* M/ d3 u9 m
  132. - p! l7 J$ z4 m, I- l8 r3 c2 G* e
  133.   /* First get the data from fifo->out until the end of the buffer. */
    ; t# E" }# a. _) Y
  134.   uint32_t l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));
    & B7 v5 [" n3 O  d( ?7 @5 @+ P- v
  135.   memcpy(out, fifo->buffer + (fifo->out & (fifo->size - 1)), l);
    7 A3 ?' _  a  _' _4 d) Y* a

  136. / O8 c: b) y) w% h; T
  137.   /* Then get the rest (if any) from the beginning of the buffer. */9 \- o* p: H5 {8 k7 v3 D( ^/ L
  138.   memcpy((uint8_t *)out + l, fifo->buffer, len - l);/ t) G; u6 `- x+ v) Q3 s) I. }. Q

  139. - }4 V: E: ^& G" `& @
  140.   fifo->out += len;0 O: \" w5 Y8 b! z( `

  141. $ Y/ T: [5 @7 F- H' K1 F6 U
  142.   return len;
    . |: |& Z; s) p
  143. }8 c" n6 O: T; z; g6 m
  144. # j& v0 i  f* v, ?
  145. /*** Z; x- W% n! a7 e: U  f
  146.   * @brief  Determine whether some value is a power of two.9 F/ I2 N4 p* f
  147.   * @param  [in] x: The number to be confirmed.4 u2 ~7 b7 ?& \7 o* R, T/ C
  148.   * @retval true:   Yes.
    - I/ K- u3 {( @' ?
  149.   * @retval false:  No.# `  X, l# Z1 T+ `# E$ ~9 y1 T5 U
  150.   * @note   Where zero is not considered a power of two.
    ( v+ N6 F, [: ~% f& x2 y* q
  151.   */% j, r# @  c; E% Q; x2 q6 I
  152. static bool is_power_of_2(uint32_t x)
    " j& t! F% |( W7 _" O  ~% K2 o
  153. {* u+ S6 g) b  X* B1 G
  154.   return (x != 0) && ((x & (x - 1)) == 0);5 \1 k7 h7 r/ W6 Y5 r  j1 G" l/ `
  155. }6 E1 }; W& ~7 X. H" T, M
  156. ( ?, ~  W% |, G5 z; |. ?- U) O
  157. /**
    " S6 O/ g: c. S4 ?4 ~
  158.   * @brief  Round the given value up to nearest power of two.
    - z8 h2 e6 u! h! Z
  159.   * @param  [in] x: The number to be converted.) j, o' F+ v1 r! Y$ z; P
  160.   * @return The power of two.
    3 y) d( G+ L2 N: b# {+ S
  161.   */
    : P; I: o" \2 p; U7 ?9 ~7 Q
  162. static uint32_t roundup_pow_of_two(uint32_t x)
    ( E! y" N; |; z! A: m
  163. {
    ; f* W4 ~# T2 G
  164.   uint32_t b = 0;
    3 Q6 y% N  n: B) C: F( v4 R5 q$ ~8 ~

  165. + [. l  O, X; E+ @; ~& l( A3 }* D4 }
  166.   for(int i = 0; i < 32; i++): M: Z# W8 r7 e+ m8 n% A
  167.   {1 b1 Y% I, w* k! s0 i3 @/ `8 P
  168.     b = 1UL << i;5 b$ F4 {. s% }2 j  u

  169. 9 j3 E4 `7 v1 r& L
  170.     if(x <= b); n& g5 G7 c) n- B0 c2 e
  171.     {
    3 y7 a4 t: W9 p) v) Z* ?, e
  172.       break;
    ( U; r6 @9 B" E2 `
  173.     }0 T: r8 M! R4 C
  174.   }4 Q/ b; M4 z+ b

  175. ) ~. Q6 t+ S" v* t) N- \
  176.   return b;  l3 Z. K0 y. [6 ^
  177. }</div><div></div>
复制代码
- _  [' h! P2 ?# \  M! \2 t) D

) g- b" v5 ?- ZCAN.h 文件. L/ T7 p! R% }2 i) \
  1. /**. W5 T5 a1 \' ^2 I0 r( e& B  p/ x
  2.   ******************************************************************************
    ; G3 a* j8 q% Q
  3.   * @file    CAN.h
    9 E" f3 k6 Z& [# t
  4.   * @author  XinLi: R: \" v5 D* @6 ]# C
  5.   * @version v1.0
    & w2 G6 u2 I5 L/ z4 Q% ^+ K
  6.   * @date    24-June-2018
    # Q9 l/ N6 v% ?& t
  7.   * @brief   Header file for CAN.c module.
    # z/ s& J4 y/ C$ W
  8.   ******************************************************************************
    ( o/ J* [) C' n' M8 [: x3 L* `
  9.   * @attention
    ' I  F$ E; g" [& O# L
  10.   *) h& K- R) ~# U$ d3 O# w
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    : k' M/ O4 @7 h
  12.   *3 k( C9 \+ M. L( ~5 z3 }
  13.   * This program is free software: you can redistribute it and/or modify; k2 V/ M) B3 N0 m) a0 p
  14.   * it under the terms of the GNU General Public License as published by# v2 Y. k, g& B) L
  15.   * the Free Software Foundation, either version 3 of the License, or- {# S2 w) f) \% E8 d
  16.   * (at your option) any later version.
    ! s& H6 @# u6 p  d
  17.   *6 T+ S  x% W1 m$ s" J
  18.   * This program is distributed in the hope that it will be useful,  k8 T; R9 h9 |5 T
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of  o) U3 {: P- @2 k; v8 V
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    " ~$ v6 w! y, p/ Y: F1 v: p1 J
  21.   * GNU General Public License for more details.5 Z: u7 u" A+ T
  22.   *) o. _8 e% U' E4 G3 k
  23.   * You should have received a copy of the GNU General Public License
    4 T1 ?/ X7 B" ]2 T( T- ~. o
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>1 u1 g+ y  c$ W; q. u( m
  25.   *
    ; W: J  M* @, o& y* j, P
  26.   ******************************************************************************  ^6 }* e5 R& t6 N' W
  27.   */
    5 V9 e2 G7 m" |# z3 Y& q1 g* {
  28. 7 X+ B$ K( y: @( D/ [/ D
  29. #ifndef __CAN_H( T& s" {, t) M8 j1 F# Z8 m" {
  30. #define __CAN_H# t& T0 i  Y" B- b; z3 a$ j/ a

  31. 6 R! h( \' N3 f: L7 ^2 }+ y
  32. #ifdef __cplusplus
    6 J8 o$ @( u6 B7 B* g6 ~1 [+ Z, G
  33. extern "C" {9 M+ X5 O# p, b7 W, o; C
  34. #endif) U$ _( j' {( _+ G" K

  35. 9 i; _/ {" r8 C- i4 L, i% X
  36. /* Header includes -----------------------------------------------------------*/5 A" {* u3 _3 i0 v( o8 z8 z+ `
  37. #include "stm32f10x.h"
    9 h$ j8 b+ t3 B( o7 j
  38. #include <stdbool.h>) g( N: j; M( A& q4 f
  39. , S) S4 T. j) L8 X% U# a4 T
  40. /* Macro definitions ---------------------------------------------------------*/
    $ n( Y9 ^! Z. L# {( A6 x7 F# }; M
  41. ; N) |% Y) `1 S& }
  42. /******************************* CAN1 Configure *******************************/
    ' n; e+ m2 C' E7 v/ C" A- G
  43. #define CAN1_TX_BUFFER_SIZE        (16)+ \5 l) e1 w3 F  z& n- \" O. W, k" @
  44. #define CAN1_RX_BUFFER_SIZE        (16). |5 O: Z( N5 k  I. S, P# g$ w$ T

  45. % m# m  q2 c: [; e! Y
  46. #define CAN1_TX_GPIO_CLOCK         RCC_APB2Periph_GPIOB
    # G: r9 m. K# C7 X' n) j
  47. #define CAN1_RX_GPIO_CLOCK         RCC_APB2Periph_GPIOB
    ( b6 i3 z* i3 K' e1 d" x
  48. ' A( @3 T6 L- O& `
  49. #define CAN1_TX_GPIO_PORT          GPIOB
    ( p9 y0 L2 c8 G4 }6 |% K5 u, L
  50. #define CAN1_RX_GPIO_PORT          GPIOB
    . f! _  r! U0 e0 n/ z
  51. 3 \' r( {7 [, d$ i
  52. #define CAN1_TX_GPIO_PIN           GPIO_Pin_92 `* G8 u& m! Q
  53. #define CAN1_RX_GPIO_PIN           GPIO_Pin_8; V! e+ X7 b+ }7 @) ^
  54. & w1 k& w$ b( S, `
  55. #define CAN1_IRQ_PREEMPT_PRIORITY  (0)
      u( P- F( Y1 v6 x# }
  56. #define CAN1_IRQ_SUB_PRIORITY      (0)
    # O* u: t+ U# G8 d* g7 |- A- @

  57. ( X9 i2 r4 z( \3 n* ]+ W
  58. #define CAN1_PORT_REMAP()          GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE)
    1 E$ N( c: E( v1 u/ K  x1 n$ e- R
  59. /******************************************************************************/
    5 ~, }% l* L! Y

  60. ! B( @) p) ?, h
  61. #ifdef STM32F10X_CL
    # K  u2 k, W4 i( t
  62. /******************************* CAN2 Configure *******************************/, g, b) l2 k5 L" R0 t( M2 c
  63. #define CAN2_TX_BUFFER_SIZE        (16)
    8 K$ x% E8 Q2 o2 J: a
  64. #define CAN2_RX_BUFFER_SIZE        (16)
    : h9 L" d& N( C' T" ~

  65. $ n& \! p! X7 f0 q4 e0 ~- T
  66. #define CAN2_TX_GPIO_CLOCK         RCC_APB2Periph_GPIOB
    5 y  E, ^9 F) F9 a* i- ^$ s
  67. #define CAN2_RX_GPIO_CLOCK         RCC_APB2Periph_GPIOB- G2 r6 X1 s2 t1 p9 w3 d8 W

  68. , o3 [4 C3 G. T6 P" z
  69. #define CAN2_TX_GPIO_PORT          GPIOB
    ) J, t) ?8 s' {5 Y) D6 P# I+ u
  70. #define CAN2_RX_GPIO_PORT          GPIOB( c( j/ H; o7 N1 F" x4 ^

  71. 5 c9 ]! h. o3 I' f0 X, a5 ]& e
  72. #define CAN2_TX_GPIO_PIN           GPIO_Pin_13
    * ]0 [( f% d- O0 V1 Y1 K
  73. #define CAN2_RX_GPIO_PIN           GPIO_Pin_12
    0 C" Y. m% [$ w' T, n
  74. . i& E. i7 U# p
  75. #define CAN2_IRQ_PREEMPT_PRIORITY  (0)1 k( G+ l" l; ~
  76. #define CAN2_IRQ_SUB_PRIORITY      (0)! K# o8 V  b3 m7 G! S6 m2 r
  77. ( s: N# r1 O" d
  78. #define CAN2_PORT_REMAP()          GPIO_PinRemapConfig(GPIO_Remap_CAN2 , DISABLE)
    4 s+ R- [% [4 u6 }2 s, z
  79. /******************************************************************************/
    & x# d2 s2 S0 Z* n2 U
  80. #endif /* STM32F10X_CL */3 M& o7 W' Z  e

  81. ; a$ L0 U! [0 E$ z
  82. /* Type definitions ----------------------------------------------------------*/# A+ p% d% v/ u2 z; g/ K# D
  83. typedef enum9 e  q" c: `' `; ~( E+ t/ ?' p9 n
  84. {
      S. _0 r& H8 O% f
  85.   CAN_WorkModeNormal   = CAN_Mode_Normal,
    % `  p% i- r3 w8 |- |5 ^
  86.   CAN_WorkModeLoopBack = CAN_Mode_LoopBack
    9 D. a3 H9 u* F: ^) N+ X& L; }) _
  87. }CAN_WorkMode;
      G& j) M: n( ?( O. O8 R
  88. : d, d1 P7 Y  V/ j
  89. typedef enum
    / i- W; e9 M6 M8 _' Y/ t( _- D
  90. {& O4 V7 ?2 J, H
  91.   CAN_BaudRate1000K = 6,. E5 C" R0 `! W9 K% ]
  92.   CAN_BaudRate500K  = 12,
    ) T5 ^( ?6 k- ~; ~
  93.   CAN_BaudRate250K  = 24,
    ; y9 }3 N" K& V
  94.   CAN_BaudRate125K  = 48,6 z; U1 F) a  I, e
  95.   CAN_BaudRate100K  = 60,
    % N! \; V/ x# D
  96.   CAN_BaudRate50K   = 120,% v1 e; b1 u# J/ y5 {
  97.   CAN_BaudRate20K   = 300,5 H$ ~% n7 `6 W' a3 B- ^0 m
  98.   CAN_BaudRate10K   = 6007 ]9 ]" K- i# t' y/ ?
  99. }CAN_BaudRate;, T/ y* n5 o2 v( G/ u& G; p' I
  100. 8 F# E! ^3 Y8 j, J
  101. /* Variable declarations -----------------------------------------------------*/
    . L" U0 b+ R+ D" ?& v3 t
  102. /* Variable definitions ------------------------------------------------------*/2 C0 O3 T, ]1 ^( _* P. ^
  103. /* Function declarations -----------------------------------------------------*/
    , }7 w9 V$ `$ y. _
  104. void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId);
    0 B7 }, X* M# G& _
  105. void CAN_Unconfigure(CAN_TypeDef *CANx);: j% W0 X* d+ H/ Y" W1 ~. d$ C

  106. 8 k  @, |1 Y' A/ n6 d! d% A' W
  107. void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));& }: R$ }0 E. n
  108. void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));
    $ D4 s3 p, q1 b5 y0 P* i# W$ Q
  109. : [- k2 X: I1 H; _# n9 z2 ~
  110. uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number);
    - f# y# |( d( E- a! F" s' V9 d* Y1 C
  111. uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number);
    2 K% H+ o4 l6 j; c
  112. ( P, S. i) H' {' s) b
  113. uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx);
    + j: O. _7 s2 e- {
  114. uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx);5 H) z7 a( d) q, t9 {3 h
  115. uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx);! K2 m, P1 N/ p
  116. uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx);; o2 n/ M+ M; A2 i0 q4 s2 l$ Y) _

  117. % t' O; A- ~6 p
  118. bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx);, r6 ^9 A0 v) c; |
  119. bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx);8 l' L: [0 a5 X% t" S
  120. bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx);
    & @% ^) b. U4 {) i
  121. bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx);
    / D1 {" m2 r- s# _, A5 r0 x; [
  122. 6 Z; f6 c7 D4 [! j3 w. l( ]: w
  123. void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx);
    ( z. H' O6 b' W2 W- U8 Z
  124. void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx);
    # J0 X9 e! g8 H6 t+ R8 y' A

  125. 7 P! v( ^, X( d# e$ C1 u
  126. bool CAN_IsTransmitMessage(CAN_TypeDef *CANx);7 Q3 s- V+ Z4 L" A- Y2 y

  127. ( ?6 v' ]$ R3 B, v  |- F
  128. /* Function definitions ------------------------------------------------------*/
    0 G8 U+ r1 o3 a* g

  129. 5 h5 T! F' g9 z) t- M; Z
  130. #ifdef __cplusplus: W2 E/ l4 N3 }8 v/ b9 I+ Q( j
  131. }
    ' y* H& s  @5 u  C8 x
  132. #endif, U, \0 ]2 u# ~7 o4 B4 R' p
  133. ' z7 D1 y; e6 i9 h( E
  134. #endif /* __CAN_H */
    + \: S* B$ n: {, Q* e7 Y
复制代码

! \- F- N: z( G. p3 @7 W4 T& [% g$ |( Q# N% [& J

* o( U" ~3 Q' \CAN.c 文件
; d: q& U% c' @7 R1 `* f
8 ?, u  O- \- H8 k5 r3 H
  1. /**
    ) |# M. S; g; ]% z6 E+ v- t" ~2 d
  2.   ******************************************************************************7 A! z7 ~' U; Z
  3.   * @file    CAN.c
    6 O" V( Z7 h, o
  4.   * @author  XinLi
      z$ g4 B0 E: R/ ]  e; I$ Y
  5.   * @version v1.0
    5 J- V, S8 v9 _" S7 Y, X: r9 c/ \( u
  6.   * @date    24-June-2018" |5 W: h' B5 Y0 `
  7.   * @brief   CAN module driver.
    # {+ c5 Z( x, w2 t+ N$ F
  8.   ******************************************************************************$ i( d! c$ Z( x1 T' ^% |% [" x
  9.   * @attention$ A4 \8 @# b4 g  a9 I
  10.   *' g  b& i6 {  F
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    % {* }1 s, t" T
  12.   *- Q4 `5 h% b& |5 P. ~7 W
  13.   * This program is free software: you can redistribute it and/or modify" y; a5 j$ _0 T& P
  14.   * it under the terms of the GNU General Public License as published by
    2 t+ n) S! v. s8 q0 M
  15.   * the Free Software Foundation, either version 3 of the License, or+ U& ~: o/ y0 p- ^' n! T
  16.   * (at your option) any later version.
    $ B) Q  _1 L( b9 c
  17.   *
    - m2 Q) }: e( E, D) r  F+ d  K
  18.   * This program is distributed in the hope that it will be useful,
    9 Z( o& c& z, w! o9 u. _
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    $ a, g) M4 K/ d( v$ K9 N$ b+ G) s
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the, e& u# x; v/ }% n
  21.   * GNU General Public License for more details.  ^" n: C! |3 r3 Y" V" s
  22.   *
    ( O8 \5 M' f* ?& ~- [, D+ R5 V7 P
  23.   * You should have received a copy of the GNU General Public License: Q) v! x3 V& Z" s/ ]# `
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    6 C) t- r* n, F. L
  25.   *
    3 I/ M# w$ S' N+ V) E
  26.   ******************************************************************************) @9 E. h4 [7 ]4 \( h
  27.   */
    ; y' F8 d+ E1 W5 V: p4 ^9 y4 M8 n
  28. : Q* g* `1 N/ Q/ o
  29. /* Header includes -----------------------------------------------------------*/) |; l: ~2 U5 T* r" Z  U
  30. #include "CAN.h"
    + O% Z. J& U- C  T5 _
  31. #include "RingBuffer.h"
    ) O* H* e! p+ C

  32. # T5 j# v* o) v8 U1 f/ B8 i1 T( t
  33. /* Macro definitions ---------------------------------------------------------*/' C% ~1 U6 w; a& M/ q2 B# `$ y; s
  34. /* Type definitions ----------------------------------------------------------*/
    1 S# U! @  [7 Z( a
  35. /* Variable declarations -----------------------------------------------------*/
    0 \; X/ J! ^1 c
  36. static volatile bool can1InitFlag     = false;
    / o3 M6 y0 J; i& ~7 N6 a3 @% O
  37. static volatile bool can1TransmitFlag = false;1 z3 R% H6 Q3 c- ~, \

  38. . y0 j- V" r5 b* n
  39. static volatile void (*can1TransmitFinishCallback)(void) = 0;
    ; U9 A1 U) y) V2 P# t1 _
  40. static volatile void (*can1ReceiveFinishCallback)(void)  = 0;" }% `, G- W4 B0 H" w% c' [& f
  41. 2 z% a( I% f4 A5 {
  42. static RingBuffer *can1TxBuffer = 0;
    6 l* U6 G" `7 w/ D7 |
  43. static RingBuffer *can1RxBuffer = 0;
    0 c  f9 x/ t- Z! f; N1 I) C# @

  44. . C6 z0 v+ i3 y6 n
  45. #ifdef STM32F10X_CL7 l9 f( b2 j! L" b
  46. static volatile bool can2InitFlag     = false;/ S8 o5 p/ l% Z7 V  t9 d
  47. static volatile bool can2TransmitFlag = false;4 p, T9 l7 e+ c* k! f, M6 z& H

  48. " ~! G+ \' t3 |& b) I/ _+ N
  49. static volatile void (*can2TransmitFinishCallback)(void) = 0;3 ?" y  z8 G: X: Z9 i
  50. static volatile void (*can2ReceiveFinishCallback)(void)  = 0;/ W. I+ S' v* U( l

  51. + f& m, d" l1 |8 b" @3 s' R
  52. static RingBuffer *can2TxBuffer = 0;
    4 Q9 Q0 ?8 }1 \/ W
  53. static RingBuffer *can2RxBuffer = 0;; f1 r8 ^+ ]4 l. D  ^; x
  54. #endif /* STM32F10X_CL */2 B& @$ K, n$ a4 |4 \& b- ^2 Q& S
  55. ' S6 M' Z% G$ V5 j# N9 X* n
  56. /* Variable definitions ------------------------------------------------------*/4 S: c2 j6 R1 h7 h$ Q' k2 J
  57. /* Function declarations -----------------------------------------------------*/
    - |* q1 \. F8 g
  58. /* Function definitions ------------------------------------------------------*/' U+ \" }5 k" D! m

  59. ; O9 c7 q8 M4 \/ o3 y. f% [
  60. /**# m# J, R# }6 ?8 q* `" Q' E* H
  61.   * @brief  CAN configure.6 ?5 a! \  L5 U4 v
  62.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.5 W! }- a' b3 N" D
  63.   * @param  [in] WorkMode: Work mode.8 Z, v5 G* M/ }5 P( w) ?
  64.   * @param  [in] BaudRate: Communication baud rate.
    4 R: v' W  F- [# r$ D4 \1 o
  65.   * @param  [in] StdId:    Filter standard frame ID.
    8 G% w6 j' Q+ o  B: j1 S% R
  66.   * @param  [in] ExtId:    Filter extended frame ID.
    ; G3 }( O7 Q9 P5 v0 A2 I+ Q
  67.   * @return None.
    9 L* F. G9 W5 v3 P  h; I/ Y
  68.   */* {" J8 H+ J, l* w# I
  69. void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId)
    ) n. }/ r" X( s1 J9 f) c% j- z: y
  70. {
    ! O) U: H" X( S' _6 A
  71.   GPIO_InitTypeDef      GPIO_InitStructure      = {0};
    5 _6 m! S: N2 O5 V
  72.   CAN_InitTypeDef       CAN_InitStructure       = {0};2 {7 P  W& ^6 K4 [) s3 F+ t  x
  73.   CAN_FilterInitTypeDef CAN_FilterInitStructure = {0};/ d! i$ @% [& V4 {8 @
  74.   NVIC_InitTypeDef      NVIC_InitStructure      = {0};
    7 e( d5 h) S  S$ v; t; o: m! n3 @
  75. 5 i6 q! V& N; m
  76.   if(CANx == CAN1)
    * a" x1 j/ m2 W2 }
  77.   {
    6 u' O" w6 ^3 z5 k, O
  78.     if(can1InitFlag == false), e8 j9 `* u4 X
  79.     {
    ( C+ r! G& W: u9 s6 z; T
  80.       can1InitFlag = true;
    % \& M' \- E( y  [5 G' P
  81. 6 y- `! b* I. @$ a3 V8 n; B
  82.       can1TransmitFlag = false;
    " \* O" q0 a. N- Z9 O7 h+ ^
  83. ; o! e# g# u' P4 s6 o# D% I" ]
  84.       can1TransmitFinishCallback = 0;
    5 x* V" _$ g7 l+ O- Z/ P
  85.       can1ReceiveFinishCallback  = 0;' l/ p' Z2 A3 y5 M) |7 d4 R) T
  86. ! {$ d& M8 ~3 E  Z) V5 M( C& g
  87.       can1TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN1_TX_BUFFER_SIZE);; I) r& t  ?+ j3 k! H/ }
  88.       can1RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN1_RX_BUFFER_SIZE);2 _4 B4 a1 E1 Q, T

  89. ' @( k8 f% M- y2 Q1 C9 P9 o4 n7 \
  90. #ifdef STM32F10X_CL
    4 ^, ^3 u! L% B/ s- C4 D0 ]& d/ [
  91.       if(can2InitFlag == false)
    ; _" C8 W! c/ A5 x4 ^
  92. #endif /* STM32F10X_CL */  E8 E4 G0 z) f( R9 g7 o2 ?
  93.       {
    2 z+ k( L7 F" }! M8 J( N9 y
  94.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
    8 g$ i0 T* h/ V! u% l" ]2 ?# \% b
  95.       }! \' B/ h1 W: u0 ?& P, [2 s

  96. 1 T9 X/ J9 a0 J
  97.       RCC_APB2PeriphClockCmd(CAN1_TX_GPIO_CLOCK | CAN1_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);% s9 @1 y- Y( k, d

  98. 9 [9 n6 t* O' _
  99.       GPIO_InitStructure.GPIO_Pin   = CAN1_TX_GPIO_PIN;
    3 Q" J- o% g1 s7 P- f* X
  100.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;4 y& n3 x6 v: E' ]
  101.       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    + m9 u* W! g- m4 O( \  ^( ]
  102.       GPIO_Init(CAN1_TX_GPIO_PORT, &GPIO_InitStructure);8 w+ g% i+ J( S& R  f! m4 D  c
  103. ! c$ d. L! N4 s, t' u- v( P
  104.       GPIO_InitStructure.GPIO_Pin   = CAN1_RX_GPIO_PIN;, Z6 K" X8 e$ y8 W$ a8 r
  105.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;. W# O, {( C/ Q, M" H6 r
  106.       GPIO_Init(CAN1_RX_GPIO_PORT, &GPIO_InitStructure);
    ; W( e5 P  k1 A% F! D

  107. . d, k; j6 K1 {+ V9 z  t/ f
  108.       CAN1_PORT_REMAP();& D8 ]. P* L0 r( U# [* A+ s. o$ e
  109. ' h9 Q0 N7 k: O5 ]* A( f7 p
  110.       CAN_InitStructure.CAN_Prescaler = BaudRate;0 Z, {" ?8 ~; T5 z3 ?. `! f/ V0 \) @
  111.       CAN_InitStructure.CAN_Mode      = WorkMode;' W: V2 O: k8 _) r
  112.       CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;# k5 Y% W5 I; A6 l; D1 Z; Y
  113.       CAN_InitStructure.CAN_BS1       = CAN_BS1_3tq;
    ( @7 i; u: y$ C- I
  114.       CAN_InitStructure.CAN_BS2       = CAN_BS2_2tq;
    + @. Q$ Q# K" w
  115.       CAN_InitStructure.CAN_TTCM      = DISABLE;
    / v1 m5 T6 b9 o4 a: B9 f, ]
  116.       CAN_InitStructure.CAN_ABOM      = ENABLE;! r% {4 h0 h* G, U/ K( W* W
  117.       CAN_InitStructure.CAN_AWUM      = DISABLE;  r4 s9 K1 W, c  [
  118.       CAN_InitStructure.CAN_NART      = ENABLE;" G9 R/ a& r4 K
  119.       CAN_InitStructure.CAN_RFLM      = DISABLE;
    7 J5 H2 n6 `# R
  120.       CAN_InitStructure.CAN_TXFP      = ENABLE;0 H- _0 O1 w! V. F/ H( n/ b6 J' [

  121.   y" w% R( K* W
  122.       CAN_DeInit(CAN1);
    # P2 b* ?( N" T, g4 L
  123.       CAN_Init(CAN1, &CAN_InitStructure);- X3 [5 {1 y+ C  g

  124. , M  G3 X7 w' z: F1 ]
  125.       CAN_FilterInitStructure.CAN_FilterIdHigh         = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);. Y# i8 j/ }# a) ~( |
  126.       CAN_FilterInitStructure.CAN_FilterIdLow          = (uint16_t)(((StdId<<18)|ExtId)<<3);* H/ h3 T8 \% R
  127.       CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;6 X& i; ?3 @; `% i1 l
  128.       CAN_FilterInitStructure.CAN_FilterMaskIdLow      = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;
    2 T. `7 n2 b; T
  129.       CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;, b+ x& G* o  J4 ]
  130.       CAN_FilterInitStructure.CAN_FilterNumber         = 0;
    * P$ f% H2 d, w# _9 c
  131.       CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask;
    3 B9 M' F+ u! J5 I5 R' {
  132.       CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit;
    5 k7 C! ~, z9 i. p9 P0 _
  133.       CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;+ P; a. n3 y* b( O8 L3 i
  134.       CAN_FilterInit(&CAN_FilterInitStructure);
    1 j4 T' ?6 d- c* u! `7 i

  135. ) h. r. d$ |( ~7 S7 h: Z) m
  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 |9 a/ O- C7 j! s8 z) n
  137.                          CAN_IT_WKU | CAN_IT_SLK  |CAN_IT_EWG | CAN_IT_EPV  | CAN_IT_BOF  | CAN_IT_LEC | CAN_IT_ERR, DISABLE);+ @7 p' `: e$ _3 D" ^6 z
  138.       CAN_ITConfig(CAN1, CAN_IT_TME | CAN_IT_FMP0, ENABLE);
    / N2 e0 ]6 I; z$ q. I3 D$ V
  139. # z; b% G  v8 e" B7 U
  140. #ifdef STM32F10X_CL2 J7 i( y& E# }' s* `4 l# P
  141.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_TX_IRQn;
    & E0 P6 W; y% c5 X
  142. #else( w$ u: {( i% ]" A0 I% Q, i
  143.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_HP_CAN1_TX_IRQn;* u7 ]) s  b, l9 ?2 W3 S# H
  144. #endif /* STM32F10X_CL */; i6 m$ s* W) o. G. q

  145. 0 M- D* g  l. a2 z. I0 H$ H
  146.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;+ W. v4 _' W; a" D6 W5 b  W% k1 {
  147.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN1_IRQ_SUB_PRIORITY;$ X( t; R2 C- a% `1 t/ G) j
  148.       NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;# z% g) f# d& d
  149.       NVIC_Init(&NVIC_InitStructure);0 H/ O/ g+ Y: ?, y$ c
  150. 8 X& y6 Y5 b8 C/ M( [: G/ R
  151. #ifdef STM32F10X_CL; |+ P% D# M) L% d; P
  152.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_RX0_IRQn;9 w/ G' {7 p4 ?+ f# f& ]. C
  153. #else
    9 O0 c1 t: W+ ?2 ~9 s/ |- S6 H
  154.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_LP_CAN1_RX0_IRQn;
    & V% v1 t2 [/ X% r; u1 @# h
  155. #endif /* STM32F10X_CL */
    3 G5 h7 a% \$ F# Q) y
  156. : h. u9 @) @6 W9 a7 G, ~1 ?
  157.       NVIC_Init(&NVIC_InitStructure);
    7 s4 R9 v% ^! U- s& E1 H& o
  158.     }
    0 }% n$ g# L4 o$ I* S
  159.   }
    9 c* e2 ~2 a4 ?- r3 g# c
  160. " H' H# B  K7 n( h3 D4 {
  161. #ifdef STM32F10X_CL* g7 |" M+ h/ f0 j* @5 d1 l
  162.   if(CANx == CAN2)
    / {( c& j. z% ~* F2 N3 {" e. Y
  163.   {9 @. ?2 ?* ~$ M% z
  164.     if(can2InitFlag == false)
    + R- D4 h1 |; w
  165.     {
    0 o% W7 D, `2 y3 _' y( v4 g
  166.       can2InitFlag = true;1 y% u' a% C) l% E2 S

  167. ' }1 y3 ~8 y, W
  168.       can2TransmitFlag = false;$ ?. l) h: i# n' G1 n5 ?
  169. ) F7 D, l, [! V3 J" ?) b) i$ G
  170.       can2TransmitFinishCallback = 0;  E& H; p) K0 H" k: i3 d
  171.       can2ReceiveFinishCallback  = 0;
    ) X) D# J/ x9 P& A0 m. _* I- |

  172. ! `) P+ k1 Z3 p  `  K: _9 k2 b" M6 `  N9 I
  173.       can2TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN2_TX_BUFFER_SIZE);
    , a  D( s. a) ~( D7 }
  174.       can2RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN2_RX_BUFFER_SIZE);, v2 E: {# h$ N9 I
  175. & |  O! A! a0 y0 b* C
  176.       if(can1InitFlag == false)& _- A* `1 ~- b  }) x) H- G4 H
  177.       {
    . M6 _0 p- Y2 `# ~
  178.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);( Q$ z) ^7 z2 T: D% `
  179.       }  g/ ^! V1 E  [; R4 C$ h
  180. ( T# V, r4 g) W+ }
  181.       RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);
    # }" d- x5 r( z: y1 ?- b# B
  182.       RCC_APB2PeriphClockCmd(CAN2_TX_GPIO_CLOCK | CAN2_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);
    6 \6 V; _8 N4 l: @

  183. 1 D. k' o+ l3 O2 Y: q2 e8 \7 R
  184.       GPIO_InitStructure.GPIO_Pin   = CAN2_TX_GPIO_PIN;  p6 y! p  s3 ^) S4 H+ `( z6 U
  185.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    2 b  R) j9 u0 M* g$ ^% s" b9 T
  186.       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    * c; V$ q) w- U' O. k0 w& |, @& k
  187.       GPIO_Init(CAN2_TX_GPIO_PORT, &GPIO_InitStructure);
    0 }: h* d7 G6 M, D) D4 p  u. I

  188. - z* O8 c2 h' E+ b5 D7 b. m5 ~5 g
  189.       GPIO_InitStructure.GPIO_Pin   = CAN2_RX_GPIO_PIN;
    - {; X# A/ l9 w6 V
  190.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;7 P! I3 D8 M% @& Y. O6 I+ R/ _3 K
  191.       GPIO_Init(CAN2_RX_GPIO_PORT, &GPIO_InitStructure);
    * M* d5 n+ h7 ^1 a

  192. + m. N; |/ b2 B" Y" }' T8 J% O
  193.       CAN2_PORT_REMAP();/ k! z! w$ l, X; O" {5 I3 t$ p" P

  194. - |  `9 |5 F  Y2 A+ `# m
  195.       CAN_InitStructure.CAN_Prescaler = BaudRate;
    2 R3 s- }) J; S# Q' A; c" c5 p! ?
  196.       CAN_InitStructure.CAN_Mode      = WorkMode;
    1 S% v, T5 R- x# A3 Q7 H
  197.       CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;8 H8 f- e; B7 @! O" h9 ^+ |# P; S
  198.       CAN_InitStructure.CAN_BS1       = CAN_BS1_3tq;
    0 n7 R8 L2 o  p
  199.       CAN_InitStructure.CAN_BS2       = CAN_BS2_2tq;4 n4 S6 X( Z7 ?' l% v6 ]7 b# ~  l8 l
  200.       CAN_InitStructure.CAN_TTCM      = DISABLE;- N" L# M1 {; ?! o6 w
  201.       CAN_InitStructure.CAN_ABOM      = ENABLE;; d: {) @* n; l' p: K
  202.       CAN_InitStructure.CAN_AWUM      = DISABLE;1 f* A5 b3 |6 k$ T5 E( w
  203.       CAN_InitStructure.CAN_NART      = ENABLE;
    ! S- ?/ m" j* G
  204.       CAN_InitStructure.CAN_RFLM      = DISABLE;
    : j( t/ O2 t) `5 N
  205.       CAN_InitStructure.CAN_TXFP      = ENABLE;$ q! ?' T4 ~- {  Q5 y
  206. / D7 v% W2 x! K- s. R8 h) T8 q* O" \
  207.       CAN_DeInit(CAN2);
    ) J0 n+ j! x8 _9 Q0 C( j& u, Q
  208.       CAN_Init(CAN2, &CAN_InitStructure);
    , U: N6 W( U$ n7 o# s* x3 M1 W& g5 t
  209. - w5 q; a. ^3 M4 h% c2 G
  210.       CAN_FilterInitStructure.CAN_FilterIdHigh         = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);+ Z) C3 ^2 p' }
  211.       CAN_FilterInitStructure.CAN_FilterIdLow          = (uint16_t)(((StdId<<18)|ExtId)<<3);
    - K: u# }* x2 ?5 r+ ?/ k
  212.       CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;( s4 x5 E4 ^+ J/ [& w% o$ x- C
  213.       CAN_FilterInitStructure.CAN_FilterMaskIdLow      = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;
    - v0 @5 @' I+ J& @+ A0 [+ o( \
  214.       CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;0 S7 M, q: O5 D
  215.       CAN_FilterInitStructure.CAN_FilterNumber         = 14;
    - _2 f8 {- D5 Z3 b3 Y
  216.       CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask;2 i1 f9 a, `/ B- p, Y  h
  217.       CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit;
    0 T+ u* O5 O2 E, t  q2 B
  218.       CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;  w+ v, W: G4 Z+ E
  219.       CAN_FilterInit(&CAN_FilterInitStructure);
    7 H* m+ @4 e" |' m
  220. 4 Y/ `; R% T$ n) D4 \3 x
  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 |
    ( u$ d2 P+ E5 @$ j6 G0 M' H* y
  222.                          CAN_IT_WKU | CAN_IT_SLK  |CAN_IT_EWG | CAN_IT_EPV  | CAN_IT_BOF  | CAN_IT_LEC | CAN_IT_ERR, DISABLE);
    $ V9 g5 {# l+ N# a3 u" ?' u
  223.       CAN_ITConfig(CAN2, CAN_IT_TME | CAN_IT_FMP0, ENABLE);6 |2 W: y+ S' C1 g+ Y; P
  224. : Z& j) ^2 h/ l
  225.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_TX_IRQn;
    ) D0 r. m% J9 [% R6 ?. a, v- T
  226.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;
    4 G, k" f  H: r7 g1 o
  227.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN2_IRQ_SUB_PRIORITY;
    ' E; O7 u. d: k, S: P
  228.       NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;- ~& u; h$ d' ^
  229.       NVIC_Init(&NVIC_InitStructure);
    - t7 S' G. V( Z, q

  230. % x2 o2 X; g- C  v
  231.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_RX0_IRQn;
    ' [. g+ ^+ U1 P  u. i" d+ i
  232.       NVIC_Init(&NVIC_InitStructure);8 Q* ]5 S* {" C0 m( U
  233.     }. ~  y) z5 z) }) q+ r$ \! p2 D
  234.   }
    ; N7 r0 u' B+ D$ n" v( v
  235. #endif /* STM32F10X_CL */" s% k3 C( I9 D" o  P) A4 _
  236. }
    : X" o1 ]8 |! }+ ]3 f" ]
  237. 1 m, ^' _* ^% A9 |1 U7 ~1 r
  238. /**
    ( `# b* y' o9 ^0 G$ b) Q
  239.   * @brief  CAN unconfigure.
    6 a5 K, D/ m. }! C
  240.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    6 Y# N) S  H) S8 Q" x! Q2 r( {& ~6 [
  241.   * @return None.) r# E. k6 G5 n. d5 [
  242.   */
      }5 v+ B8 a5 `. W
  243. void CAN_Unconfigure(CAN_TypeDef *CANx)
    7 v  g9 H; U2 p9 U7 `' K
  244. {
    5 o! l6 k; K5 H$ U) W; }0 Z) j! G
  245.   NVIC_InitTypeDef NVIC_InitStructure = {0};
    ' Z) I2 ^7 H' A+ N. Y6 a

  246. 4 S( A& \. J- @" X
  247.   if(CANx == CAN1); o% S: }1 A! H5 `# a
  248.   {
    - T7 y0 F- t. E
  249.     if(can1InitFlag == true)9 d$ l" J6 R1 b) k4 }! p
  250.     {; ~, l6 |+ Y" d, L. U
  251.       can1InitFlag = false;
    ' M- \! P4 o& Q  c
  252. ( B2 A& W) |5 h8 |1 I9 P- D' o
  253. #ifdef STM32F10X_CL7 d7 K3 P: E' B! f/ x
  254.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_TX_IRQn;
    1 j7 V) T) X- V( \
  255. #else
    0 U/ l4 q( `& W8 [  s
  256.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_HP_CAN1_TX_IRQn;
    * A. Z) q* x& a1 p% M
  257. #endif /* STM32F10X_CL */: B$ a  ?: o* A* n
  258. , F' y4 K' ?% f- l) C
  259.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;0 A1 ~* k! W2 I7 e5 X% }
  260.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN1_IRQ_SUB_PRIORITY;
    1 m) R. B! f: `% J3 f4 {
  261.       NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;
    . M0 K0 x" ~- k, z
  262.       NVIC_Init(&NVIC_InitStructure);
    ; O# |8 J6 }+ w- o3 {5 S( z& u# Z
  263. 4 z1 u3 K$ v7 r9 o! ]) A
  264. #ifdef STM32F10X_CL
    : n! v, N& q9 ~, [4 D8 q
  265.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_RX0_IRQn;( i& s- S2 v5 _! D' ]9 R7 h
  266. #else8 H6 L$ |8 Q! V
  267.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_LP_CAN1_RX0_IRQn;  k& I3 W5 O# K: k2 J
  268. #endif /* STM32F10X_CL */
    ) i) W* v# j. q$ T4 k4 R/ Q
  269. ; l  _! F" f* N2 \, ]  n* L. z3 ~
  270.       NVIC_Init(&NVIC_InitStructure);
    . h/ {9 e8 k6 R

  271. # ]6 d, M* s1 M0 S7 C4 L1 P
  272.       CAN_DeInit(CAN1);
    ; W9 U; Z- `$ n$ d  {
  273. 5 b6 }! i% n: l; q$ L7 q
  274. #ifdef STM32F10X_CL
    # p; t" X: O( p( y. t0 u2 ]
  275.       if(can2InitFlag == false)
    7 s5 n+ f+ ~) z* q% x9 d; q6 Y: |
  276. #endif /* STM32F10X_CL */
    " Q  P0 L% w! v9 E4 L
  277.       {7 J1 B9 j9 w( W& o1 }
  278.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);6 x! ?7 N7 ]% J; z7 S* b" ]" z1 [
  279.       }
    ( |) v9 Z" y2 p7 S

  280. 4 J2 p: O( d6 a7 X% D' O
  281.       can1TransmitFlag = false;1 d! S# D- |) ^# b$ |
  282. $ i) v6 H% h6 \* ?0 l: K
  283.       can1TransmitFinishCallback = 0;/ V5 B: F; ^: Z" U7 z4 U$ f
  284.       can1ReceiveFinishCallback  = 0;
    $ K! c! h, R9 j; g2 S

  285. + \9 J, T6 Y) i) Q
  286.       RingBuffer_Free(can1TxBuffer);2 f  L6 _7 @/ w9 ?$ M' s
  287.       RingBuffer_Free(can1RxBuffer);. U2 `; S( C# I. n
  288.     }: |0 Y6 t6 M7 X1 s9 P" v
  289.   }% C2 c5 ]5 d8 u1 O
  290. 9 D% @  B2 W- g7 a; j+ @* G" {" P2 a
  291. #ifdef STM32F10X_CL, Z( v; Z. H( \+ {
  292.   if(CANx == CAN2)3 X% q; M* t3 f- X1 k; i
  293.   {
    ' l: i- w0 J: y# j3 |
  294.     if(can2InitFlag == true)
    : y/ p- c/ [6 U
  295.     {  Y2 q/ H7 G5 Y/ G2 M* V
  296.       can2InitFlag = false;
    ! f7 ^( r6 Q% J# n( f

  297. , B9 f- x) z$ y/ U
  298.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_TX_IRQn;
    " Z* r8 q7 l$ H0 ]# m- o6 N
  299.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;8 X# L4 G& u& K
  300.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN2_IRQ_SUB_PRIORITY;) O0 V+ h1 i$ r/ G9 |3 j3 }
  301.       NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;$ M  J* R9 |! u+ e8 D' L. d( X
  302.       NVIC_Init(&NVIC_InitStructure);
    $ C( o3 l- j3 I9 O9 G) p/ y

  303. 5 _9 V, s! Z: K
  304.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_RX0_IRQn;/ d. G* @7 G( K# c5 @( a/ I
  305.       NVIC_Init(&NVIC_InitStructure);
    ; q" ]. W5 ?8 C0 I
  306. 3 K! p2 E7 r2 y6 d3 b. Y; T
  307.       CAN_DeInit(CAN2);
    ! x3 U# |3 [& u4 z
  308.   X4 [1 l/ b6 H& |* {5 e
  309.       if(can1InitFlag == false)
      }0 F9 W. i! z
  310.       {
    2 @' V* m5 }9 W" T7 t
  311.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);
    : u* k3 Q: g1 o+ ]3 x0 [
  312.       }
    ' J$ J6 L1 A+ G* q" a) K6 L7 C
  313. 8 K+ _7 h% |+ o+ `7 }
  314.       RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, DISABLE);
    % x& L7 L: D- y% Z5 H
  315. ( W, c5 ]1 b, }4 Y  V7 I- g/ ]
  316.       can2TransmitFlag = false;
    # Q! R/ g3 z- F, V

  317. 7 c5 Q5 D1 b7 L9 r0 H/ x
  318.       can2TransmitFinishCallback = 0;
    1 M- s# N% E( a: x
  319.       can2ReceiveFinishCallback  = 0;( O& n  N4 X# s- W0 `8 v

  320. ) J6 \; Y1 F) ~1 k5 n- m; `2 ?+ E
  321.       RingBuffer_Free(can2TxBuffer);; c2 q) R& }0 h3 t" x3 l1 i
  322.       RingBuffer_Free(can2RxBuffer);
    6 {- T. R% D1 S( _8 k- v- _- H1 d
  323.     }: R0 E8 ]% t# U
  324.   }( M0 ?4 R) C. U7 i* t6 q
  325. #endif /* STM32F10X_CL */
    1 }. D) R/ H0 a6 z  Q
  326. }5 W+ x3 m& l1 H5 t# G+ U

  327. 7 Y" G3 ~& \, a' l) V
  328. /**+ a) F# O: i: e1 L/ n. D
  329.   * @brief  CAN set transmit finish callback.
    . H9 d1 E8 v/ F; x; O
  330.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.
    8 M7 ^& ^. E4 c7 T
  331.   * @param  [in] Callback: Callback.5 \( g7 F+ D. B' G
  332.   * @return None.9 e5 L$ \2 |! L4 Q- O1 b
  333.   */
    + X3 d) @# u- \. Y" L" x
  334. void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void))
      z% d  Q9 [6 _/ B* ~
  335. {
    . u+ G+ g$ |6 |9 v# a& ]
  336.   if(CANx == CAN1)+ M+ P8 w2 Z: D8 {; `* G" v* w
  337.   {# v2 T; k  W1 g; @- k
  338.     if(can1InitFlag == true)
    : u" b: ?# ?% R7 S+ |) p9 U8 u
  339.     {2 C* `2 \5 Y9 |' ?- L
  340.       can1TransmitFinishCallback = (volatile void (*)(void))Callback;
    . h0 i" h( M# w) y
  341.     }3 @, C9 U/ N7 u- [) z) n
  342.   }% z0 e& `* a! r( c) \! g% d8 B. w

  343. ( {  L$ J) T% T% E2 r* v
  344. #ifdef STM32F10X_CL, f( ~) ^) G9 t, R) C& g, d
  345.   if(CANx == CAN2)/ S5 |7 G% \0 S9 [. `$ M
  346.   {4 t  C0 G, e2 n: t
  347.     if(can2InitFlag == true)
    , C# Z+ @* X; {+ u/ P* G
  348.     {
    1 V5 n( u- Z$ V+ X2 k
  349.       can2TransmitFinishCallback = (volatile void (*)(void))Callback;
    : E; s" i7 b7 m& I
  350.     }3 F) j+ U5 E+ [. f0 {4 b/ K
  351.   }
    5 |( L( ^2 [9 T1 ^
  352. #endif /* STM32F10X_CL */
    9 z" K; l8 |2 U) B
  353. }; O/ k" _' O0 ]5 v% {, p
  354. ' ~! L; ]% n. R3 x
  355. /**- l7 X: Y6 ]* k0 v0 @5 T' Q, b
  356.   * @brief  CAN set receive finish callback.
    0 s: m, i$ Z1 D* ]! Q
  357.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.
    * }8 ~. I+ e( m# e- ]2 W& |. Y
  358.   * @param  [in] Callback: Callback.
    ) {6 ~; b. U  Q
  359.   * @return None.3 N5 U# K5 n* g5 G1 ]6 ]$ I, `0 W1 u
  360.   */' @% v$ z& _1 f. h
  361. void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void))+ E. C4 @. a5 f
  362. {- {) i, r! i7 L2 n
  363.   if(CANx == CAN1)2 Z2 E3 A) N6 I5 n
  364.   {6 {, M  s: l; p7 v& f" p" K1 c
  365.     if(can1InitFlag == true)
    - z8 p$ X7 l, z+ a
  366.     {
    + y* s. n) v7 b: z# r- V/ Y$ q0 @4 b
  367.       can1ReceiveFinishCallback = (volatile void (*)(void))Callback;
    1 _4 O3 [  h( {
  368.     }& H7 {1 j* K9 g( A: m& C0 `
  369.   }
    . c$ _5 |/ x7 Q) i

  370. , j+ N% a5 K3 F/ y
  371. #ifdef STM32F10X_CL
    4 Z4 P) F2 j" n  W/ r' b  M
  372.   if(CANx == CAN2)
    6 ]1 c" I1 Y7 o4 ?; R8 P# a
  373.   {6 W- X6 @$ O5 q# I; c  o
  374.     if(can2InitFlag == true)( U+ Y4 t$ }( t- d3 A
  375.     {
    " ^7 H3 N" X/ M* p. f2 b5 j
  376.       can2ReceiveFinishCallback = (volatile void (*)(void))Callback;+ C4 g- Z( q8 R5 Y4 Y( Y5 i- {
  377.     }# \" |4 p& |7 F; f" z& F! W
  378.   }2 L7 [7 ]& D6 b6 X( Y1 Q
  379. #endif /* STM32F10X_CL */
    7 G' u/ }. C/ W5 h: N. _
  380. }
    : U0 Z0 p( f. H

  381. - y3 I% r* |1 O( X) Q# [9 y# L% M
  382. /**2 I9 @1 R9 j& Y; \  R
  383.   * @brief  CAN set transmit message.
    + }$ m) J; l' b* `0 w  K6 n. s
  384.   * @param  [in] CANx:    Where x can be 1 or 2 to select the CAN peripheral.
    : u( T. B8 W: m" x
  385.   * @param  [in] Message: The address of the message to be transmit.) i  M1 k% i5 K) N# k! C. S5 l
  386.   * @param  [in] Number:  The number of the message to be transmit.
    , [* U2 i5 k; N  N2 s- }
  387.   * @return The number of message transmit.* k; @4 M( X" c" Y2 e. \: O% b* ]
  388.   */9 b4 A: y$ i* ~: i3 V# ?
  389. uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number)& Q- N  \) U  @) h# j( K( M* V/ o
  390. {' B+ @4 l" U' u9 \' S, V
  391.   if(CANx == CAN1)4 e6 K6 A8 Z( v2 B0 T' E
  392.   {) m+ P$ t0 Z! I% Y* ?8 f' |. @
  393.     if(can1InitFlag == true)8 l' X: T% ~9 H  i2 c2 |: o
  394.     {" {) R5 p( j8 |: Z
  395.       uint32_t available = RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);
    0 s# ?/ G- V4 `% t

  396. & M8 J9 N" j) G! X  g7 l- O. v
  397.       if(available > Number). H+ @* x' ^% j6 w0 m
  398.       {
    ; _: A" F' D! [- d
  399.         Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);! i0 ]0 \3 }7 ^# [$ K' x
  400.       }
    " K& h" G4 j, ^4 i0 K! P
  401.       else
    0 g/ w. c: {8 m& r0 ^( `: U
  402.       {
      g2 h: I  U5 ^& j! i
  403.         Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);; Q: u4 u( b7 b
  404.       }! a% B) g& x3 m* X+ Y* I, g
  405. % o8 v" B. k& a) ]) ]4 ?( k9 y
  406.       if(Number > 0)6 S' ?  Q: X2 I2 m
  407.       {
    ( k) k2 D9 M5 e
  408.         if(can1TransmitFlag == false)
    0 h; n6 v3 G* t! ]# _( T
  409.         {6 }" i( B( t$ J$ z
  410.           can1TransmitFlag = true;
    ( I% b3 E( r2 U! ]' V
  411. ( I& @7 H" C7 S' Q$ A
  412.           CanTxMsg canTxMsg = {0};  v8 g. [, [0 u% |
  413.           RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg));  C/ f; P. t# k, |. d, P
  414.           CAN_Transmit(CAN1, &canTxMsg);
    6 w4 |: v$ ?0 b: J
  415.         }4 h9 {# v5 n5 H& r. B6 ?& E
  416.       }8 v7 v. W: h; [, P+ V3 d2 ]1 ~# s

  417. ( @3 `  q& ?/ a% V6 d+ j! h4 p
  418.       return Number;1 s5 f. g" d' y  O$ l/ o1 s8 D
  419.     }' Y8 K! J  t6 X* e  G& Y. ~) w
  420.   }
    . `) v4 ^! p$ L5 v+ L% v9 j

  421. . E% }) D* K4 e/ x! ~6 S% f1 b6 M
  422. #ifdef STM32F10X_CL
    ; M  o1 D3 ?% j" P" q5 q7 y
  423.   if(CANx == CAN2)
    9 {1 |* }, e: Q
  424.   {
    ! P9 \4 ^8 D8 {& Q5 D7 q4 W/ T2 g
  425.     if(can2InitFlag == true)/ ~3 M" m$ I9 y' i/ X: b
  426.     {1 }4 k7 y5 j! g( E% R! t
  427.       uint32_t available = RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);
    9 x. l' a- F  ~1 h
  428. ! c" a( o6 Z& {
  429.       if(available > Number)
      N% n7 f, b: [( ^! A1 d
  430.       {
    % j: o9 `, z6 @+ D- V7 }# Q7 y
  431.         Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);
    4 C* l% {# u" Q8 X6 V
  432.       }! q3 |  ~3 {7 c  g2 X: N  U% G
  433.       else
    & t* M+ h" e+ U- C/ P
  434.       {: G4 K/ d4 B7 V) h" f* V  g4 \
  435.         Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);
    % S4 A) e  o) W) J
  436.       }0 C/ T; E4 \5 X& t, T$ ^- s
  437. 6 ]5 G, o3 g' Y
  438.       if(Number > 0), D! x5 p5 M# i
  439.       {* i2 X  F4 n% N
  440.         if(can2TransmitFlag == false)
    8 d. s. I: V7 p' g1 ?9 U. D  n
  441.         {9 n) z) a+ z$ @. H2 J; }
  442.           can2TransmitFlag = true;
    ( a5 m2 N. Q) y; _% ?# j
  443. % n# I6 N% J5 }8 b
  444.           CanTxMsg canTxMsg = {0};
    8 U0 G" `1 x) E/ p" Q
  445.           RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg));$ E2 W) ~3 U: F
  446.           CAN_Transmit(CAN2, &canTxMsg);
    - W9 T7 ]! b+ A% q. Q
  447.         }
    $ |$ k3 x" n8 H
  448.       }
    4 |: D9 `7 c- o' d6 o' ]9 Z

  449. 3 O1 }5 x! ^' ^  ]! q; {3 V9 y2 Q* t
  450.       return Number;+ X: j6 f/ r( M4 a0 Y% f2 k
  451.     }( b$ j2 Q/ I( n
  452.   }
      Q8 t' ~1 _# c% p
  453. #endif /* STM32F10X_CL */
    6 q( Z6 t5 `8 R9 Y# Y  Z' k- M

  454. & b9 J/ j, D' F
  455.   return 0;
    , k: f5 T4 x: E
  456. }, S/ e9 d8 l+ j: [9 A- Q
  457. * ^+ M- p! ^' P+ g6 v7 f9 `. x
  458. /**
    / @7 T$ S. e5 q5 M0 g# _
  459.   * @brief  CAN get receive message.
    - C$ {3 `! L* J' w
  460.   * @param  [in] CANx:    Where x can be 1 or 2 to select the CAN peripheral.' A! U  H7 _7 Q5 R  I$ l& @- K
  461.   * @param  [in] Message: To store the address of the receive message.
    % a) m3 w. C3 S2 q/ k7 l9 f
  462.   * @param  [in] Number:  To read the number of the received message.
    - i- ^& Z* a* {/ Z+ ]% @  d
  463.   * @return The number of message obtained.: }7 D. u9 N/ p% C4 g, z+ F3 P  O  [
  464.   */
    4 z! W+ k+ s: W5 ^5 P& P6 j# f" J9 a
  465. uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number)* y5 k0 U2 q0 t2 V$ z
  466. {* w3 {5 N- g9 D1 H: M2 Z
  467.   if(CANx == CAN1)
    , f# g# @! X. M5 u
  468.   {
    * D/ |+ Y( W. Z4 D& R
  469.     if(can1InitFlag == true)8 P' h% _8 V; y! C8 W/ Z& c
  470.     {
    + B5 e6 l) E7 Q
  471.       return RingBuffer_Out(can1RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);
    7 G& w- K8 m  h5 m
  472.     }8 B1 d6 V5 F  Y& c/ U* }
  473.   }
    4 Q3 e( o9 c; o# d; L; e! O& U  P5 s

  474. % P+ \) k+ S/ }) H8 V6 ~% `
  475. #ifdef STM32F10X_CL
    : Q+ c' s) g, e7 _" U; ]
  476.   if(CANx == CAN2)
    " q- ], o$ d  P) e2 e* q6 {2 j
  477.   {
    6 U+ Z' i* @9 W" o2 e) u
  478.     if(can2InitFlag == true)
    8 |4 T4 Y% _( \& I" l
  479.     {9 P1 c$ l- c- @7 f8 q) ]; N  b
  480.       return RingBuffer_Out(can2RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);
    * a3 l) i3 j3 D
  481.     }
    ( r! k+ l$ V( @6 {% O" v
  482.   }
    : n% M, s2 Z, t3 K2 ^% ]
  483. #endif /* STM32F10X_CL */# w" K: r7 r; |  M/ A5 u/ b
  484. 9 e) X1 C' ]+ q
  485.   return 0;
    / I: v. v9 U; {6 k! q
  486. }! A( Z. G) z; A% Q, z! [6 E
  487. 0 C& r; i% `9 S( L7 c9 l/ J8 ^
  488. /*** \4 A3 K6 N" S; D- `: E
  489.   * @brief  Get the size of the CAN transmit buffer used.
    . ]9 n! b) v8 p
  490.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    ) p5 d# _" }& W" c
  491.   * @return Used the size of the transmit buffer.
    3 J- L" e: ?- T
  492.   */
    : b: i6 ?/ k# Y
  493. uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx)% {- n1 h$ D5 Y) \) U
  494. {
    8 b) _, U. ?5 i  d
  495.   if(CANx == CAN1). O' G: A2 T( q* z8 t- {
  496.   {' a6 J* J% _0 p+ z, V/ E" v
  497.     if(can1InitFlag == true)) l% k( a; z) _. l4 N$ v
  498.     {# s" y. ~+ e& d
  499.       return RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg);
    / q/ q3 i, o: l. P" @5 \
  500.     }3 E+ x( x( x7 m0 d8 s3 G- w$ [
  501.   }
    , `& l! o7 t( K, f- ?2 L/ ~  X

  502. 1 T" a. q6 J! H
  503. #ifdef STM32F10X_CL: b3 B; K! w8 Y4 M4 w+ `' u
  504.   if(CANx == CAN2)
    ( ?, u' ]+ m" _0 |) _
  505.   {0 @2 u' _) o' [- F, p
  506.     if(can2InitFlag == true)- {7 \6 k" w- v) a' y
  507.     {: h4 `2 K1 b8 [& J1 H8 X& a
  508.       return RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg);
    9 r: r, k3 A) T: o$ Z# c1 w" i# P
  509.     }
    9 t; F& ~" R1 [) B: C
  510.   }
    ! t# g- L  w% V
  511. #endif /* STM32F10X_CL */6 d, Q  {0 j6 Q  P2 ~

  512. ( [* ]8 l+ L' n. d4 z# {6 }
  513.   return 0;
    , x3 |5 D" @; J
  514. }
    + G4 \. @, n: I* t& [
  515. 2 z& y. x2 f) z
  516. /**
    . O1 [0 f% Q) i. O+ M
  517.   * @brief  Get the size of the CAN receive buffer used.# G+ |0 z0 H, A7 g2 K6 s( j
  518.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral., V' |1 m9 E/ @+ q, j; l
  519.   * @return Used the size of the receive buffer./ ~' ^  U+ N6 o& N' S' k
  520.   */3 a: m+ c& C$ a. r6 T. v
  521. uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx)
    " H3 r# G6 [  ?+ p
  522. {
    ( ]& ?0 o, c, @5 d. f! ^
  523.   if(CANx == CAN1)
    " P' ]$ H0 Q' V+ e' ~' y
  524.   {: l/ j/ L5 e1 j9 N
  525.     if(can1InitFlag == true). }8 d+ H# e! _$ Y( |) [! \
  526.     {5 v. Y; w- Y# p
  527.       return RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg);
      R) ?( R4 L3 J& T" p
  528.     }
    $ J/ P- y7 `5 `  S! `
  529.   }+ Z" b* c% P7 C& I$ ~- O( ?

  530. . J' b: |; I. k
  531. #ifdef STM32F10X_CL, N( @. M/ W; i
  532.   if(CANx == CAN2)
    ! D/ a; ~( D' S& k9 y( ~- ?
  533.   {
    / Z: v% y8 W, h$ C; q
  534.     if(can2InitFlag == true); K$ R$ W+ ~1 r0 g9 r2 x4 W7 }
  535.     {! V0 i8 q/ Z- J% u5 j2 l& y
  536.       return RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg);2 V5 U7 w7 H! Y' d  u( }
  537.     }
    7 p0 H, k3 o2 u
  538.   }7 J. y, X' @' u
  539. #endif /* STM32F10X_CL */
    3 x5 S; `2 k% B' C* r

  540. 4 C! P- W" Q- Q
  541.   return 0;7 u5 t* U" p/ {* E8 c" Z. `
  542. }: S1 F9 W3 n! [5 l
  543. - h# U5 E  U( q- [& i5 }( o# g
  544. /**0 H  U, B5 t' Z" S$ Z
  545.   * @brief  Get the size of the CAN transmit buffer unused.
    ' w1 ]: ~) W( K1 Y9 E% B
  546.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.* r# E, ?5 o8 q- M/ f8 H9 m
  547.   * @return Unused the size of the transmit buffer.
    ' _& ]: I6 F  a; F! i8 T9 D
  548.   */
    % J2 W8 R( m9 ^  |; Y+ P4 p
  549. uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx)
    6 n. K% K/ g3 c+ h! Z4 F. f3 g
  550. {) t$ C( R; @: p5 |
  551.   if(CANx == CAN1)& D" s6 h% ?1 t* ^2 ?- C- s
  552.   {
    / R% y, D' \. j7 f; _1 M0 p4 X
  553.     if(can1InitFlag == true)
    & s$ R5 c6 I- b% u2 R/ w2 r
  554.     {1 @$ B4 ~: m# ?( p
  555.       return RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);" Z  t6 f/ P/ ~
  556.     }3 z- t5 \- p: B* H
  557.   }
    $ J- Y9 z. H+ \8 E/ B9 S" @# F" w* e: f
  558. $ B1 j( J# C2 n" P
  559. #ifdef STM32F10X_CL, R6 T% `) c( m1 |# y: h
  560.   if(CANx == CAN2)/ Q: e) r4 I- ~7 {) e2 s
  561.   {+ O. T4 }4 g! g( r- o
  562.     if(can2InitFlag == true)- J$ x+ }, M, `8 V
  563.     {: j7 _0 W7 _  N  a- x! Z9 a4 A
  564.       return RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);, _9 n4 g! g4 v5 _
  565.     }
    2 ~# o8 _  D! ?! @7 F7 H
  566.   }9 S/ m: n3 e# c8 ~
  567. #endif /* STM32F10X_CL */8 [# Z, k# Z/ [5 y! C9 [. p6 Q
  568. $ s9 d4 T& N6 L* v/ m
  569.   return 0;
    7 m9 e$ X0 R# m4 M, B
  570. }4 b* O- _: }: i; Q
  571. # u8 S% B) ?# H8 C! Z' a
  572. /**
    ) \0 b# y8 k1 f" m  P8 H
  573.   * @brief  Get the size of the CAN receive buffer unused.
    ; V( i, u5 W4 Z6 b1 V: I
  574.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.  r4 ^8 i) S# ]1 h$ Q4 K0 a
  575.   * @return Unused the size of the receive buffer.
    6 W$ T* `4 a7 j* c8 a* H  z9 Y/ ~0 W
  576.   */7 d' ?) I( F  o1 A
  577. uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx)
    % X2 z+ O; U" ^
  578. {9 Q; H/ e2 ]6 e1 Z; c
  579.   if(CANx == CAN1)4 N% W% J. J; X, y" s. C
  580.   {
    1 f$ O: j! }' S( [3 U' V
  581.     if(can1InitFlag == true)
    4 i3 l0 C$ W- Z8 b
  582.     {" L( Z! d7 i( e' t7 V" G  `0 w
  583.       return RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg);
    ' m- r8 f# n8 W7 c. \% X# c& e) u( s# z
  584.     }) Q# G4 n6 o" Q7 x
  585.   }: {3 h/ R8 m/ v5 E* |

  586. 4 t! I" T3 z, }$ ?. G/ n8 _2 ?1 c- n
  587. #ifdef STM32F10X_CL
    7 x2 f+ E+ g4 T8 X( f) h, ?
  588.   if(CANx == CAN2)- Y. V" x& B0 {6 G
  589.   {
    1 p2 h" D1 ]. G6 y; c
  590.     if(can2InitFlag == true)7 F, {+ c' o( I/ A
  591.     {
    6 h* L% Q, Z/ \6 N$ Z9 L
  592.       return RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg);4 W- ~, W7 V7 q. U1 {3 b
  593.     }+ b& U7 M2 j$ d
  594.   }( c% j" {* S' `  e$ q  Y$ W( n
  595. #endif /* STM32F10X_CL */" q9 x3 H) W" d& c! y$ R5 q" b
  596. " k0 A# X. O" H  ^5 ]% X
  597.   return 0;+ p1 [: U& ^3 ^/ a3 v9 K
  598. }
    * N1 Z# ~  K6 t  u3 \
  599.   H- P6 V, m1 k; h* d0 K' O, b6 [7 i& S
  600. /**
    3 _1 Z6 \% K) m# z  Q) B" c) V
  601.   * @brief  Is the CAN transmit buffer empty?! r3 Y+ Q9 S1 f- M6 x) N+ f0 q
  602.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.* N3 Z: T$ {4 e0 {, D8 g* v$ H
  603.   * @retval true:      The transmit buffer is empty.1 ^; u* b! y1 h5 ^8 U" y
  604.   * @retval false:     The transmit buffer is not empty.
    3 u+ B1 _* S7 N$ ~8 J; a& j
  605.   */: w) }/ P4 p2 d) ^/ R  O( `
  606. bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx)$ e- Z9 g, }; Z" `* H* r2 R, L% f9 p
  607. {* G" g6 m: c5 h! ]( }" \# V$ Z
  608.   if(CANx == CAN1)2 a$ ]- g. i" e' S$ d
  609.   {6 P8 E0 B- F, T% h
  610.     if(can1InitFlag == true)+ V/ R! T. H# j/ }( {* o4 m
  611.     {
    5 g8 ]" a$ N" I4 T7 t8 R3 ^
  612.       return !(RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg));( F, s7 Z3 b) n/ ^- @5 d: n8 e
  613.     }
    2 d9 B% `1 a& m  `. F
  614.   }
    7 ?7 s. u: n9 x+ y& K0 l

  615. 1 m: d8 v1 X# _4 J
  616. #ifdef STM32F10X_CL
    5 H1 H" l$ k3 }8 S  X' y* b( ~9 U& H
  617.   if(CANx == CAN2)
    $ @& s" N: H+ n! u; c
  618.   {
    * n$ x# B( f- j, g+ [2 v# b
  619.     if(can2InitFlag == true)/ r" S+ r* R- P3 E6 U( R- z9 h, T
  620.     {& p: `8 x4 o' `7 P, I+ U4 X9 @% ^
  621.       return !(RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg));
    8 }) t$ Q9 @! c6 ^. B
  622.     }
    ' p, S) u5 o3 F" o0 C, e( {
  623.   }
    ! t5 u+ `  G: D; O2 K( M$ n+ h
  624. #endif /* STM32F10X_CL */$ H9 K4 G, Q; }  E4 D! S

  625. . V9 b6 B, T2 V: K
  626.   return false;& ?, V* P3 B4 q6 X  T7 }
  627. }
    ' C' f% m' b9 e' t* O7 ^' P
  628. ) n1 A0 O+ H& `5 n' P2 G' P$ X
  629. /**6 }0 T* B2 C% `( W# c$ _
  630.   * @brief  Is the CAN receive buffer empty?& |8 Z' p, a0 k; u
  631.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.. ^; I1 P, Z0 R; s; c8 c* ^' H2 Z
  632.   * @retval true:      The receive buffer is empty.9 G8 X% S6 A% x" O' K
  633.   * @retval false:     The receive buffer is not empty.! e6 _1 H& A2 a+ P2 A- a
  634.   */# G5 \/ M( t8 ?, s3 ~
  635. bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx)3 T% f% K: o- F; @, Z$ w
  636. {+ z; @  }" ]% a1 d# Y6 Z* z8 l- Y
  637.   if(CANx == CAN1)
    + \8 X3 g; t* P4 i* z
  638.   {4 D9 w; O3 L. l) S
  639.     if(can1InitFlag == true)0 n/ E( c! R1 D' J4 U. D0 Y/ B2 F' E
  640.     {
    4 \; z2 Y/ a6 V( E) N# u8 ?9 I
  641.       return !(RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg));
    + k: N! j$ a- ]* s3 v5 l
  642.     }
    & Y/ T. n- t( Q+ }
  643.   }
    ( }/ H  T. Z6 P) j2 V: p: Y
  644. - W7 @% [9 O- \8 {
  645. #ifdef STM32F10X_CL
    * g. w3 ^& g1 n& s
  646.   if(CANx == CAN2)
    7 {+ j: d) r4 [# ?
  647.   {, {+ Z6 m$ X- R8 S% y' [6 H
  648.     if(can2InitFlag == true)
    # ]+ ?1 `. s- _1 D
  649.     {1 Q3 t* R5 c- d5 y" w  `+ U4 G
  650.       return !(RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg));
    , i2 \! T- T- Z' q& f) v: G2 e+ x
  651.     }% |: Y2 u2 Z4 w
  652.   }
    * c: w$ J4 w1 s1 I
  653. #endif /* STM32F10X_CL */" @4 U, W( _. \2 O

  654. ' M% f* Y0 M9 M& ^+ I1 G
  655.   return false;
    4 N1 w/ E/ s3 w# r) u6 {
  656. }& o0 Z7 {* x% |7 r( P
  657. 9 u% g, ?; P- O! A4 m
  658. /**
    / x8 I) Y5 Q5 a( s
  659.   * @brief  Is the CAN transmit buffer full?
    - Q. e  {) V0 `/ b' R
  660.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    9 \7 I+ m7 ?/ A5 f8 k! m( D) a% b5 m
  661.   * @retval true:      The transmit buffer is full.0 z! F3 Z% c: s. Y
  662.   * @retval false:     The transmit buffer is not full.4 v3 N, G& ?# @- m' Y  U
  663.   */
    1 J! \* U1 y/ @1 m9 \% u7 }* ?
  664. bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx)" v2 \- l/ [2 Z& M$ S0 J
  665. {0 e* ^" C3 V& B1 U$ w9 @2 J; H
  666.   if(CANx == CAN1)' N/ b1 d  i1 v. U- Q1 I
  667.   {3 U" \# R( q& z( t( N
  668.     if(can1InitFlag == true)
    " T1 [1 f6 E8 Y# I0 p
  669.     {/ B/ E2 C2 V$ e+ A+ G* V
  670.       return !(RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg));. [+ p# v( Q2 i# w4 x
  671.     }
    ) r; i4 h6 P  r
  672.   }
    8 Z% m( Y1 Q% y! K, e4 Y! l
  673. & D, [- g( x& h  U; [% c
  674. #ifdef STM32F10X_CL
    ' [% h% U0 A4 i9 |5 p
  675.   if(CANx == CAN2)
    * w2 V" N/ h$ q" k* s
  676.   {9 _# D, ~, l5 w" ]! T0 L
  677.     if(can2InitFlag == true)
    6 Z1 I% C& N9 L3 ^. c+ Q0 t5 u
  678.     {' ?$ m8 c. {) \5 p0 \+ e
  679.       return !(RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg));2 v, x; }- U- U% e* C
  680.     }
    1 L+ p3 A+ \, `1 A$ ~: C
  681.   }& D9 m' K# \; d$ \$ J; x
  682. #endif /* STM32F10X_CL */
    ' t- N+ d' W% G) ^. n1 t
  683.   u; A3 s: |9 E6 d$ J" R8 m
  684.   return false;, J: J  j3 M* @3 L" R( ?  O  T
  685. }
    3 Y8 Q- E' N: X; \: Q

  686. 5 D$ e9 f* @8 J
  687. /**% Z, S" v$ B0 k! g/ j, S
  688.   * @brief  Is the CAN receive buffer full?
    0 v% ^8 N, w6 w
  689.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.2 E2 Q- R: _( i: Y, ]1 _+ |
  690.   * @retval true:      The receive buffer is full.8 k: g5 ?. @4 g! [+ q3 s$ A; O; @
  691.   * @retval false:     The receive buffer is not full.
    ) a& \8 ^9 I9 x
  692.   */6 A. ?4 U+ }) L8 a% c& C
  693. bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx)* L3 Y* m+ J; y8 Y' b! a8 a! P* O
  694. {6 H7 }$ g, F% m: D
  695.   if(CANx == CAN1)
    ( t0 I2 m! q& I) Q
  696.   {  a3 M. S7 ]: b* Q+ ^1 ?; D+ {
  697.     if(can1InitFlag == true)
    2 U1 ?! q7 K+ m/ I5 _
  698.     {' ^9 T8 C$ D6 m, k4 X) q4 p- \
  699.       return !(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg));
    " N  X. {9 n+ }/ L* _
  700.     }8 C" B3 K+ A" V
  701.   }, s* \5 G: Q$ K5 m" y5 d! N

  702. ! b7 c* b  O( Y7 j  S% K& S" g
  703. #ifdef STM32F10X_CL% a( C# O. B* K+ u. k+ ~
  704.   if(CANx == CAN2)* g; N. {1 b" ~$ C
  705.   {# `# J0 E: i. A3 i
  706.     if(can2InitFlag == true)
    ' Q" P" s+ G0 q' `: f. A
  707.     {/ V. b( [. B8 y/ g- @/ o) P: p
  708.       return !(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg));
    ) j7 W* M9 @5 s9 P
  709.     }* i0 u, y" N8 D# }
  710.   }5 F( m0 J, W/ e
  711. #endif /* STM32F10X_CL */6 V6 Z$ g1 ]3 S. C. X4 H) H# W
  712. * {2 N7 @) A; r  i5 \
  713.   return false;
    : ~" V; Z$ _( n" \: n( Q5 u; b
  714. }% h* u( S; Q) _" u& M' s7 X: [

  715. # F& r1 I- C% t4 S7 L' I  K0 L
  716. /**. r+ R: k) E: q9 M! X/ q: |
  717.   * @brief  Clear the CAN transmit buffer.) e  h% ^" A5 V! d
  718.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.7 h$ a% J6 w0 |. V# ]; T/ G
  719.   * @return None.
    9 m, Y( W6 c( D5 D9 @- w* D
  720.   */9 {* Z  f* U4 P
  721. void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx)
    + ?& t3 s* h- q# a$ k
  722. {" t- q% h, ?7 x: q7 c3 ^: L6 s
  723.   if(CANx == CAN1)
    1 x1 K; ^, G( N
  724.   {& G; I7 s9 o6 N2 Q8 ]
  725.     if(can1InitFlag == true)# o0 {2 N, K; K2 L/ y
  726.     {
    , o' d9 r; y5 j% t
  727.       RingBuffer_Reset(can1TxBuffer);
    4 d5 y- u, k- J. X) p5 A4 R  U
  728.     }+ I. m  \! l& p$ s. A
  729.   }' t4 I: j/ G) f; K# ], Z4 h

  730. ! a$ ~, N- C2 b! S( |9 ^
  731. #ifdef STM32F10X_CL3 }) G0 R8 q6 p& E- [- [0 f
  732.   if(CANx == CAN2)
    - K6 U0 i1 T+ R! d; Q8 ]
  733.   {+ M, O+ x4 ^+ E+ r5 `
  734.     if(can2InitFlag == true)
    : D0 {% ?; B% m% A
  735.     {* N5 ~, R4 y- _
  736.       RingBuffer_Reset(can2TxBuffer);' P# I7 s' X# @" I0 |
  737.     }( ?. @6 M; g) t1 ~
  738.   }& ~9 k; I, [- c! k, v) D5 @1 f
  739. #endif /* STM32F10X_CL */3 t; O. x; E* H# R% e# V; u% M
  740. }- R2 |1 `, ~, N0 g
  741. , i" _0 R9 A! m  i: k
  742. /**
    ( ~% _& P9 ]1 @* y$ B: F$ L: @
  743.   * @brief  Clear the CAN receive buffer.7 g" S) ?* ?: ]
  744.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    2 Y' c: s% k: h* ~& `' ~
  745.   * @return None.) M5 h# B/ l+ \( I' M# ~$ A; T
  746.   */8 m" E7 P4 ?( o2 P# W
  747. void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx)2 P1 H  w$ c  ?2 b
  748. {
    6 _8 o2 h5 z6 Q2 m) ~3 G6 G
  749.   if(CANx == CAN1)! e( d5 G! L" }9 [
  750.   {& \! W8 W# H' r8 B- ?# C
  751.     if(can1InitFlag == true)) [7 X7 E3 R: I( H, b* T" P  {# K2 ?
  752.     {
    ! _7 C* k2 z- l/ h) @7 r. h+ I4 ]
  753.       RingBuffer_Reset(can1RxBuffer);; ~5 Z6 ^9 C% {4 Q- u0 u3 p$ ]: `
  754.     }
    4 J8 ?$ ^3 ~" i4 j0 m1 Q
  755.   }
    6 W/ Q, }7 u" u' Y0 q

  756. ' ?5 C8 t, M* K8 f
  757. #ifdef STM32F10X_CL
    / A& |) t+ t8 n  g3 o
  758.   if(CANx == CAN2)
    + i7 `8 r9 Z3 i/ H% ^- q7 z
  759.   {
    5 P) I2 p* Z( j3 M- p3 p) U
  760.     if(can2InitFlag == true)0 n6 ]. Z% j7 S- S5 ?( [- V
  761.     {
    * p# ^# A; N/ B6 L1 F5 v9 s
  762.       RingBuffer_Reset(can2RxBuffer);
      [- d/ o+ L5 p0 ]2 y
  763.     }/ g. k& f2 q6 {  Y% ?" J
  764.   }! c* o: m. \8 a% M( T3 f* r
  765. #endif /* STM32F10X_CL */( x) Q! r. n  e
  766. }9 W# f9 D( l1 C5 m4 Q% ^

  767. 3 U+ T# U) j5 W' ~% c$ m
  768. /**
    $ L& @$ |4 P5 G& o
  769.   * @brief  Is the CAN transmit a message?
    4 z' I! g5 j2 C1 o& E. f# c( z
  770.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    ) b( L+ x( C9 |" m' A
  771.   * @retval true:      Is transmit a message.
    . ]$ {4 _7 T+ G  {; u
  772.   * @retval false:     Not transmit a message.. n1 K' f2 ^; w: p& f
  773.   */4 t+ I: X. C* v. F
  774. bool CAN_IsTransmitMessage(CAN_TypeDef *CANx)5 y6 s: u8 U; @4 U1 S
  775. {
    % q% k, {) A  D4 B& [
  776.   if(CANx == CAN1)
    / \: G; e$ W* ?! Q* D. J
  777.   {8 X/ L: R+ \; N+ C
  778.     if(can1InitFlag == true)# T+ j7 ~2 J7 y
  779.     {
    % L( v: o, z/ a
  780.       return can1TransmitFlag;
    / t9 ^9 I2 H  N6 w3 h" O
  781.     }
    ) H4 `, Q  a0 G- ^1 ^+ l# u2 \
  782.   }( w3 n. i" n8 `( }# V& r& H; z

  783.   f% h) N. f. w/ Y- \5 ?7 d
  784. #ifdef STM32F10X_CL
    ; Q2 ^" Q' E- G
  785.   if(CANx == CAN2)
    ( r/ L, ?7 }9 k1 ]  f
  786.   {8 d8 F) p, N8 w0 m# a8 b9 U1 v9 D' X1 e
  787.     if(can2InitFlag == true)
    * B' q& G3 k- g" W8 b' \. {* w
  788.     {8 [- _/ G2 d7 M" }& R  C
  789.       return can2TransmitFlag;1 o  T& x- Q; C6 j1 D! o
  790.     }
    * f' P2 n4 b* \7 N& O
  791.   }! Y2 t7 U7 w7 l0 b" b& j6 V
  792. #endif /* STM32F10X_CL */
    , w% {. n) U5 ]; O' U8 R

  793. ) `7 d* l4 _) o  h6 O' y
  794.   return false;" f7 x5 ?+ Y% k5 ~0 z% @
  795. }$ s$ C  Q- Z# w4 {1 ?# e& G1 I- Y/ n. \

  796. 9 P7 D$ s0 q4 }/ w
  797. /**" d5 L/ h8 j2 x  A+ `+ E7 D. y
  798.   * @brief  This function handles CAN1 TX Handler.' X3 O9 @3 [5 j; a- _
  799.   * @param  None.6 k& t  _0 ^% U+ m/ p* K) Q9 @, @
  800.   * @return None.
    1 W: @/ f+ R" j1 \, D
  801.   */
    / W6 q  m& r- f  \& z: x7 f
  802. #ifdef STM32F10X_CL" H0 v( i/ p3 d
  803. void CAN1_TX_IRQHandler(void)
    9 H: E9 Z7 R* L' s, `0 |+ r
  804. #else  C* i0 D2 p0 _) Z1 M0 e# c5 M
  805. void USB_HP_CAN1_TX_IRQHandler(void), T* C9 f5 x3 E# k
  806. #endif /* STM32F10X_CL */) p& M; p: R( w; n2 @: F3 p
  807. {$ e9 Y/ Z' b: f; ~" r7 I
  808.   if(CAN_GetITStatus(CAN1, CAN_IT_TME) != RESET)
    ; F* q/ ?# e4 }3 C4 u
  809.   {
    8 A5 v7 ^8 P# Y: ?% a
  810.     CAN_ClearITPendingBit(CAN1, CAN_IT_TME);( z8 f6 p. g  A3 x. A

  811. - U- i) N7 J) M) a5 i
  812.     CanTxMsg canTxMsg = {0};
    2 J9 ]; y9 n( t7 A. J
  813.     uint8_t  number   = RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);3 N- F( L7 `+ Y3 B# e

  814. " Q9 y( y) S, E$ r) ]: \" a. ?
  815.     if(number > 0)
    ) f9 q, p! d) {$ s: e
  816.     {! k) s- }% s8 m. N) y, p
  817.       CAN_Transmit(CAN1, &canTxMsg);
    7 z: `% v6 c5 D7 o4 f6 o9 Z
  818.     }# ]0 y: ^# a+ \; o/ I; y, V* I; A) K
  819.     else" b% W9 ^% P# W- u- M( G
  820.     {3 Q, D! f0 _7 [- n* C5 P
  821.       can1TransmitFlag = false;  x5 l5 J& v6 c: m

  822. , ~! }7 P" Q! a9 L6 ~
  823.       if(can1TransmitFinishCallback != 0)
    ; O& w  C( }' J2 e& b
  824.       {! I3 E8 b6 H/ j
  825.         can1TransmitFinishCallback();
    7 ~+ ], p% M# p! z: @5 w
  826.       }
    ' p0 l# O2 \8 M3 C
  827.     }( U6 n) S1 _5 n$ d$ M' \0 }4 Q3 B
  828.   }* r5 Y$ J/ x+ H* ^6 K$ J' o
  829. }2 y, d$ @/ l4 f, [" U3 e+ i5 `
  830. * Y8 g3 s1 a& D- m( I4 Q9 d4 m
  831. /**$ ~, `. ^- r) G
  832.   * @brief  This function handles CAN1 RX0 Handler.
      F! R* k4 g$ x/ i
  833.   * @param  None.! I+ h! y2 e7 ]
  834.   * @return None.
    " f; l! A) b+ m4 ?$ W5 S8 y
  835.   */
    8 |- E! n) |/ C! V
  836. #ifdef STM32F10X_CL7 c; k6 u/ s2 r9 N( ^
  837. void CAN1_RX0_IRQHandler(void)
    / m; O. q7 Z+ h! M, {
  838. #else
    % n0 {' y- C: j8 q) {8 T& b, u
  839. void USB_LP_CAN1_RX0_IRQHandler(void)* V" ^9 z, C. |0 M: I
  840. #endif /* STM32F10X_CL */; z/ i$ Z5 ~; T! _% A. p
  841. {/ F& ]0 S" h) W. u3 ^
  842.   if(CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET)0 k' W8 K" X- o
  843.   {
    $ F3 C# V  T7 V* \
  844.     CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0);
    ; q( |( \! c" X0 K! x' p7 u
  845. 7 t; L- s% z7 c  f$ w
  846.     CanRxMsg canRxMsg = {0};
    1 y+ L1 H0 H- g/ K  e6 e$ p
  847.     CAN_Receive(CAN1, CAN_FIFO0, &canRxMsg);$ E7 h; w0 B' [$ ~6 F

  848. 6 \% V7 K" @. P
  849.     if(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg) > 0)
    : [$ m6 I- Y8 o
  850.     {
    & {8 h/ S6 H" h7 M$ \
  851.       RingBuffer_In(can1RxBuffer, &canRxMsg, sizeof(canRxMsg));
      Y8 O2 M  P9 R
  852.     }
    & L2 D9 e* P# l6 W; v1 g  [
  853. 3 Z4 l4 j$ S' M* Y8 L# _
  854.     if(can1ReceiveFinishCallback != 0)
    & @0 Z( J7 J/ b
  855.     {: u# v! K, t* ^+ \. r& ~
  856.       can1ReceiveFinishCallback();
    : a) w7 X  Q+ Q, L% ~2 H1 h. y
  857.     }
    " o% S2 k5 n0 ~9 }5 l- q
  858.   }
    2 q; H5 Y! g) ~3 W
  859. }5 C0 o$ q8 @1 i7 P0 e& X: D4 `6 ]

  860. ( B' `2 k/ s! ~) p+ N
  861. #ifdef STM32F10X_CL
    $ c% |- P' B" S5 B0 y2 [
  862. /**  A5 m+ w# v% X# [
  863.   * @brief  This function handles CAN2 TX Handler.
    # m( i1 O! g/ J
  864.   * @param  None.* @8 \7 G5 W4 {
  865.   * @return None.; l' p9 M, a7 k$ E4 V* c) }( N
  866.   */
    ( k7 E$ Z7 j" u1 R; g  P, `$ b; x
  867. void CAN2_TX_IRQHandler(void)
    6 I+ ~% J+ U. B: s; G3 O& c; x4 M
  868. {
      d5 t" Z, e2 I3 A
  869.   if(CAN_GetITStatus(CAN2, CAN_IT_TME) != RESET)0 o/ x! I; K; C3 M! d
  870.   {
    4 K8 S, D7 A  r/ E# ?
  871.     CAN_ClearITPendingBit(CAN2, CAN_IT_TME);
    ( r' j! [) [  r; {
  872. 6 d) p0 o" P; t. p! A" i, g, }
  873.     CanTxMsg canTxMsg = {0};
    / U  F- B( P) j! |
  874.     uint8_t  number   = RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);+ _; J$ _) E" @' b* u- H- z! a9 @
  875. 3 r! ~3 |& ?0 D( s
  876.     if(number > 0)5 B3 Q4 e4 i0 t! \2 t) |) w
  877.     {
    + x& ]7 @8 k4 {
  878.       CAN_Transmit(CAN2, &canTxMsg);
    6 t- k1 U# N# |2 g( F
  879.     }
    + U* O! H4 b3 N& N8 D& i! G8 a& P
  880.     else
    ) e5 f' Y: {2 w& P( s+ `
  881.     {
    & |, F2 ~) u7 k% f* l! w( t7 k
  882.       can2TransmitFlag = false;/ \2 _7 o9 V0 a" F$ G
  883. 1 T/ E% L' J% r0 m% |: W% \
  884.       if(can2TransmitFinishCallback != 0)
    7 U5 _2 m' A3 N) |; U# l
  885.       {5 }  n4 |! d4 ?; b
  886.         can2TransmitFinishCallback();
    3 Z7 o: y! \/ ]' e6 ]# t
  887.       }; U7 z2 C. f7 H; q
  888.     }- {% j+ E' [1 @  G5 Z
  889.   }0 @, V3 c$ \* w
  890. }
    " Y) Y. C3 ?3 O9 v$ L
  891. ' {9 A, s* C/ Y* w+ X7 l3 f' L* d4 ?
  892. /**( p' X6 N  ]  l, g4 D& [' M$ [2 I5 T% l
  893.   * @brief  This function handles CAN2 RX0 Handler.
    4 e$ P; q; ?1 Y& B1 [. l
  894.   * @param  None.
    7 [8 V: T) A' i4 a9 ]6 o2 P2 L
  895.   * @return None.
    / C& l) ]- M: D3 N/ H
  896.   */
    , k! w; ~0 N7 `; ]9 [
  897. void CAN2_RX0_IRQHandler(void)
      e8 E1 h6 s4 A' F9 [) O/ O
  898. {) K- b  D0 o: c; O0 m3 e" d
  899.   if(CAN_GetITStatus(CAN2, CAN_IT_FMP0) != RESET)+ H; q  n5 a/ `; L& r  Z
  900.   {' Q, g9 k, r6 b& L
  901.     CAN_ClearITPendingBit(CAN2, CAN_IT_FMP0);8 Q" W, a/ T9 o, b" z$ M3 R

  902. & O9 P) Q+ a- ?$ t5 V% w
  903.     CanRxMsg canRxMsg = {0};
    % o' J( j* `& t; N* M8 m0 R
  904.     CAN_Receive(CAN2, CAN_FIFO0, &canRxMsg);9 e/ Q8 C  B$ F: y2 R, k6 l

  905. . ~* x/ a% P5 t- g! @4 f
  906.     if(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg) > 0)
    & O7 R: w1 z9 @5 |
  907.     {3 [( E9 o  V5 s: M; S) b" i9 u
  908.       RingBuffer_In(can2RxBuffer, &canRxMsg, sizeof(canRxMsg));
    7 \" N" k# u+ n  v$ M3 h
  909.     }$ [- ~  x7 ]2 u1 j6 |1 X
  910. 3 ?$ F- d9 b! S2 O, d. j5 {. U
  911.     if(can2ReceiveFinishCallback != 0)' J8 c- y, `' m# h% i" ?
  912.     {+ N& _: f- F( M1 Z
  913.       can2ReceiveFinishCallback();
    ( x2 J% w! P+ ~# n0 T6 |% U  F
  914.     }( ~  p8 j. M9 N+ I
  915.   }
    $ N  j; A: T$ w5 E
  916. }8 c  @# g# m' A# k
  917. #endif /* STM32F10X_CL */& T5 C  D2 R/ v" J0 A! S
复制代码
" i* W# U% [; ^* ^  q( w" {7 f6 g
6 ?  e- L, Q/ u% N' A5 a& w' e
main.h 文件
5 M. S0 u2 M5 x; b* C
  1. /**
    ! d. c* h% y1 i0 P" l4 R
  2.   ******************************************************************************2 |# u, g1 l9 J+ H5 }
  3.   * @file    main.h4 d* Y: K" {! H, {7 Q( q
  4.   * @author  XinLi
    & L1 G- k% M1 u$ ]$ v9 s, R: n
  5.   * @version v1.0! _1 D5 c& Q7 {( t! G, C- @
  6.   * @date    24-June-2018/ Y4 n! m- y9 _* V8 u/ Y! e+ @1 b
  7.   * @brief   Header file for main.c module.
    7 c9 ~# i$ |5 u
  8.   ******************************************************************************
    + M2 O) {! R% N
  9.   * @attention5 Q. W: o: i8 ]& E# r2 h
  10.   *) \3 T, `- i2 L2 [- U
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    ( b) V( o! P- p2 E1 ?
  12.   *
    * V% l3 |+ P. O! v/ R; \/ D* X
  13.   * This program is free software: you can redistribute it and/or modify
    % F! D) C0 B( `6 I5 A  f
  14.   * it under the terms of the GNU General Public License as published by$ {; A" ~+ U" ]* k" L
  15.   * the Free Software Foundation, either version 3 of the License, or* f( O3 f. v! g: K6 t" M
  16.   * (at your option) any later version.
    ( V3 W( U' a) O. R1 Q
  17.   *3 V% `8 \6 N! b3 d) M
  18.   * This program is distributed in the hope that it will be useful,
    ; d8 l3 J. B1 O- B! q$ \
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of& P- {  U6 e: A+ }* s* `+ K
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the" N9 b. A7 p; s
  21.   * GNU General Public License for more details.4 H  W& P- o* ^3 T8 O# m
  22.   *
    0 A1 r( v' s* Y; j, d& Y9 Q
  23.   * You should have received a copy of the GNU General Public License
    7 `! S0 W' g/ W" k* Z
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>  K1 p( `# i) q* z0 s' _7 Y+ Q0 c7 B
  25.   *
    5 ^, ]2 n' ?2 }9 F, C6 f
  26.   ******************************************************************************
    ( T" c8 ?: H1 n: T4 S
  27.   */6 a$ Q. I4 V! P" K+ p5 O0 o% h6 F

  28. ; {. Z& s6 e, Q' q8 `
  29. #ifndef __MAIN_H
    , B' h6 T9 ]% \% G5 d, f
  30. #define __MAIN_H  r0 {0 r7 c6 P8 j% k# l) A6 h
  31. - X# [( A5 I$ E# S" L/ A, h
  32. #ifdef __cplusplus
    9 C: _  W$ c; v
  33. extern "C" {
    + D% c) G$ K$ k/ \
  34. #endif
    + r+ f4 L: y6 {( _* T6 @1 ~. S
  35. $ Y( a) S& t1 B2 p& C$ l
  36. /* Header includes -----------------------------------------------------------*/
    3 k" D& X% A; [6 u' R( T* M' ?
  37. #include "stm32f10x.h"7 \* M7 c# e0 g1 f+ U
  38. . U3 f9 M* s' B% _- f  p
  39. /* Macro definitions ---------------------------------------------------------*/; y$ c5 A$ g: b2 n4 x6 r( x' {
  40. /* Type definitions ----------------------------------------------------------*/
    : x# N8 o+ n% Z, B
  41. /* Variable declarations -----------------------------------------------------*/: _! c' s  [  Z
  42. /* Variable definitions ------------------------------------------------------*/
    ' o, S; s- Q# ]! n$ n& n  J2 ^( `3 \
  43. /* Function declarations -----------------------------------------------------*/7 I8 ?2 D. P4 ^: x9 e6 \9 ]- U
  44. /* Function definitions ------------------------------------------------------*/3 `& d; O; G% n9 _! r2 E

  45. 4 [. C. P) N- r; \! c
  46. #ifdef __cplusplus' E0 f1 l3 {6 k+ i
  47. }
    ! }, q' i% z& w" a
  48. #endif# r3 L' l5 P2 `2 P
  49. - S7 `$ b5 z# u" L2 g# i! h
  50. #endif /* __MAIN_H */
复制代码
$ U3 a  Y" s' u4 R- |) _0 z
6 m: i+ p  {3 R  z0 B5 \
main.c 文件
- S  Q5 [% H6 `. j8 @
  1. /**
    5 Z* M) B) l' r2 H# T% d- L
  2.   ******************************************************************************9 `+ [5 O0 M; C2 j) H
  3.   * @file    main.c
    + |2 @( U4 J* ?- g' u$ p& G
  4.   * @author  XinLi3 o; s, H, X8 M* ~! l3 m- ~6 K
  5.   * @version v1.0
    . u8 z+ p; }$ d: Z5 ?
  6.   * @date    24-June-2018
    & y- H& {7 T8 l3 {, M
  7.   * @brief   Main program body.* @5 x+ g  h$ B8 |! u( N/ M
  8.   ******************************************************************************- B% X/ f( T. f( b0 W. A. B
  9.   * @attention
    , }4 i; u# b- a, P1 R
  10.   *
    - L7 a( v% W5 P+ f/ ^
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>, X& F  ?, ^0 M/ B& J4 D$ l
  12.   *
    8 B# A, E8 h' z8 [
  13.   * This program is free software: you can redistribute it and/or modify
    - x; O' v9 \* D# ~4 K
  14.   * it under the terms of the GNU General Public License as published by
    . H# Q( O5 U7 q9 F' t' Z% G
  15.   * the Free Software Foundation, either version 3 of the License, or+ v9 }3 _$ F' o0 X
  16.   * (at your option) any later version.
    * x; G2 P' u  ^; S1 I5 ]
  17.   *4 z8 {* N7 @+ R0 u& X: ?
  18.   * This program is distributed in the hope that it will be useful,) |- e4 x; f) z+ H7 R; }
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    $ ^) o( P2 Z/ d& \5 U
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the. C+ X. q# n- Q9 e0 W+ N
  21.   * GNU General Public License for more details.  d6 ^- _3 M! z
  22.   *
    ! T4 [$ T7 Y! u* h
  23.   * You should have received a copy of the GNU General Public License  E& T( I5 W. }+ o  h
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    ) Q8 k5 W, u7 s$ y; D, o
  25.   *
    7 F, V1 v2 j0 \: G9 y
  26.   ******************************************************************************: ]$ g. z8 D+ v% M4 q7 w9 A% T
  27.   */9 m5 I* a5 i! f& E
  28. 4 p' E! w4 P. n" S) i- x
  29. /* Header includes -----------------------------------------------------------*/# h; K' v7 D9 L5 @
  30. #include "main.h"
    2 |: p% o$ {# L" o! I
  31. #include "CAN.h"1 m+ @/ B2 P  I

  32. + K5 m/ a! o) d& c( C
  33. #ifdef _RTE_
    ; _. f" ^1 y7 [6 P( ^
  34. #include "RTE_Components.h"
    4 ]' ~& I: t; A. c! F
  35. #endif" ]" ~' X& i1 l# A

  36. ! y4 K, w& d/ J( ^& Y0 L8 C
  37. #ifdef RTE_CMSIS_RTOS2
    $ V5 g  ?  ]- W- {) h: W
  38. #include "cmsis_os2.h"! M' L( b/ G+ j& j. v# A8 l) G9 ]
  39. #endif
      n3 c1 Y* u& }& t5 \! A

  40. : v; s0 L$ t1 K# v
  41. /* Macro definitions ---------------------------------------------------------*/; H0 ?" I! l9 l% f, K
  42. /* Type definitions ----------------------------------------------------------*/1 F" R2 y% @2 ]+ P. ~
  43. /* Variable declarations -----------------------------------------------------*/
    & [: `1 W6 v1 v! V
  44. /* Variable definitions ------------------------------------------------------*/
    # a' f- ~  b: {; E9 v
  45. static CanTxMsg canTxMsg = {0};
    ( X1 ~7 V8 R0 T' S: a1 x1 v1 r
  46. static CanRxMsg canRxMsg = {0};
    # w' |- d) p- i1 ]% Y- \+ z

  47. ' E( W: T) B; N1 w' x
  48. /* Function declarations -----------------------------------------------------*/! y, m' \! E! o5 _( m
  49. static void SystemClock_Config(void);
    * E& h6 ^5 i0 d+ m0 i
  50. 3 q$ K( O1 `2 ^  C5 R
  51. /* Function definitions ------------------------------------------------------*/
    1 ^8 `9 B& J) P* L! f

  52. 3 ]- {" Y" g: R
  53. /**
    ' y, V/ N$ U8 x0 K+ @
  54.   * @brief  Main program.
    % J- l( K' j' r: q4 v9 H
  55.   * @param  None.
    , A' J+ p4 u. {4 {- g$ E. u
  56.   * @return None.( J8 n, c! y# ^; F- ^. c
  57.   */
    2 K* Q( Y0 f9 ?
  58. int main(void)4 W! r  {9 _6 D4 w9 a
  59. {
    & {, C4 m& b8 F3 m# L* z! X4 v! U
  60.   /* Configure the system clock to 72 MHz */: {, t7 D! D& Z  x# o
  61.   SystemClock_Config();9 L" w# q3 r4 J& x1 B3 Q) h
  62.   SystemCoreClockUpdate();
    3 m9 F+ g0 ]2 M% g
  63. % ~3 G6 C1 Y2 M; }
  64.   /* Add your application code here */
    ; I2 s+ Y3 d8 Q* O
  65.   CAN_Configure(CAN1, CAN_WorkModeLoopBack, CAN_BaudRate250K, 0xAA55, 0x55AA);3 Q- v* L. _- N; T" z5 Z) @
  66. 4 N! y, i- f2 {. H" M$ i/ }
  67. #ifdef RTE_CMSIS_RTOS25 Z2 |$ L' A  c1 r# _# C0 B5 `+ Z
  68.   /* Initialize CMSIS-RTOS2 */- F- b' S# W& P* ?" r( L" ?$ {0 E9 r+ X
  69.   osKernelInitialize();! e7 F, s' K4 @( `" H4 f
  70. ' g& A& `6 g0 G" R; {( |/ r
  71.   /* Create thread functions that start executing, $ x" _/ z! Q- O* P. j( N5 }; g
  72.   Example: osThreadNew(app_main, NULL, NULL); */
    - Z3 S8 q! O  a! Y

  73. 0 }# a% F0 B6 p7 ~* y4 P
  74.   /* Start thread execution */
      W( }0 q' w4 W! b5 S4 A
  75.   osKernelStart();4 X7 Q- T& k. c* d, B0 d2 y7 c' x
  76. #endif
    . @2 K$ j  W: o: u
  77. $ z2 U6 ~5 I! C; L5 f1 ]
  78.   /* Infinite loop */9 s- F9 ~+ n0 y3 m0 b* |
  79.   while(1)
      J* t- {1 D- \/ Z6 Q
  80.   {
    ; ~' v% Y* _4 |5 g
  81.     canTxMsg.StdId = 0xAA55;- W- R$ ]& x" U: [5 _6 N5 @7 w: C
  82.     canTxMsg.ExtId = 0x55AA;
    " w) L) C4 W( w+ i: q' s' ~
  83.     canTxMsg.IDE   = CAN_ID_STD;$ h- ^& C: `3 U3 v1 F
  84.     canTxMsg.RTR   = CAN_RTR_DATA;6 y, O( O( \8 k9 |7 }6 {/ P
  85.     canTxMsg.DLC   = 8;$ Z. |& ]& _9 A! S7 [+ \, S9 m7 N& _

  86. - h" F4 r; s  y9 \3 `3 m( ^
  87.     canTxMsg.Data[0]++;
    - p2 Z% d4 T; q0 O: r- l
  88.     canTxMsg.Data[1]++;
    # j. S, i0 E! `$ l' S9 ?: ~
  89.     canTxMsg.Data[2]++;# z+ y% ?* l& Q
  90.     canTxMsg.Data[3]++;1 i/ i  g* k6 n
  91.     canTxMsg.Data[4]++;
    2 C" w7 h: R9 _1 v! C3 d8 ?
  92.     canTxMsg.Data[5]++;
    / X4 N9 H/ v5 p* `9 C, [
  93.     canTxMsg.Data[6]++;
    ; @3 A9 U, |; Y- W7 u1 z
  94.     canTxMsg.Data[7]++;
    5 c! H5 {7 U2 |9 G

  95. % i) ^, u/ l% J$ _- q4 Y
  96.     CAN_SetTransmitMessage(CAN1, &canTxMsg, 1);
    0 H: J& h5 o7 P5 U
  97. ) f  j& \6 U- Y  T' X1 a0 T" D% |' X6 o
  98.     while(CAN_IsReceiveBufferEmpty(CAN1) == true);. k) X( j) z# |7 U( i* q- k
  99. : }2 K2 L: R7 M7 c8 ?, f
  100.     CAN_GetReceiveMessage(CAN1, &canRxMsg, 1);
    , a% v' R: k$ i2 n, V
  101.   }
    $ i+ A& v, H: ?0 c9 E4 P9 Z; u6 |
  102. }
    : z" H$ N, ]( v7 p

  103. 7 T4 o* ^' s5 g2 k3 ?
  104. /**
    . ]- \: T. k6 b5 i5 O
  105.   * @brief  System Clock Configuration.
    / u5 k4 d. n3 J( m/ q2 i3 j
  106.   *         The system Clock is configured as follow :
    ) ~6 s2 R% L/ F: Y8 F4 I1 w4 _* W
  107.   *            System Clock source            = PLL (HSE)
    6 n( T. |: g% p5 Z' s- a
  108.   *            SYSCLK(Hz)                     = 72000000
    1 y  _# X, h& g6 F- o( C
  109.   *            HCLK(Hz)                       = 72000000
    4 Q/ A. y- z( l7 ~. `
  110.   *            AHB Prescaler                  = 1
    : Q' A( U, h* Z; C$ k
  111.   *            APB1 Prescaler                 = 2# a  W0 r& ]. V; K! M
  112.   *            APB2 Prescaler                 = 1( n$ ?2 U* F! X& x& {% b5 |
  113.   *            HSE Frequency(Hz)              = 8000000
    " B' J4 M8 O, P; _3 k) N
  114.   *            HSE PREDIV1                    = 1
    $ }" d0 e9 p7 \7 C/ O4 s4 F
  115.   *            PLLMUL                         = 9
    ; s, S8 V, Q* O5 a7 b/ \- y
  116.   *            Flash Latency(WS)              = 29 F& |! b3 c: f# I: _8 I
  117.   * @param  None.3 a# p9 u4 v2 w  G
  118.   * @return None.
    1 |0 h3 `) S9 {6 z; V* i  Q
  119.   */. Z$ e7 b* E4 b, Z  T3 N
  120. static void SystemClock_Config(void)' Q( k( S9 h; e1 D7 P
  121. {
    / E  ^8 H* U7 J
  122.   /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration */
    4 \: I1 {2 {2 x3 A
  123.   /* RCC system reset */" s" c2 U1 s+ F$ r0 A0 N2 s
  124.   RCC_DeInit();
    + p0 \& v8 }; Q- o
  125. ( F" |) L8 G( w, f
  126.   /* Enable HSE */
    * z  X1 I3 ?$ s
  127.   RCC_HSEConfig(RCC_HSE_ON);
    ( T+ Y% P$ w) x, y
  128. 5 K% x% R6 K& N3 S6 D2 z
  129.   /* Wait till HSE is ready */
    4 J1 T0 t# h+ n. T! m7 O& x
  130.   ErrorStatus HSEStartUpStatus = RCC_WaitForHSEStartUp();8 s! d$ |9 ?: f/ ?) Z+ E

  131. # J& G; s6 L: Y. {& Q; A0 \0 [/ R
  132.   if(HSEStartUpStatus == SUCCESS)
    1 ]1 X: T% H" y* @% L5 F8 g& P3 U
  133.   {5 e5 h1 r/ ~; D) `& _- Y, A( t6 p
  134.     /* Enable Prefetch Buffer */2 X$ Y5 e$ m2 x  O
  135.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);" N/ p7 s& d( o& e
  136. * L# U# u7 |  c' H' O( \' b7 l) t
  137.     /* Flash 2 wait state */
    8 t+ W! T, l; ~
  138.     FLASH_SetLatency(FLASH_Latency_2);% V7 g: {0 r/ f+ c5 w
  139. ) q1 y' b. e6 i7 p% H2 d0 Y- l% q
  140.     /* HCLK = SYSCLK */6 b! j1 k$ R9 u; x% G
  141.     RCC_HCLKConfig(RCC_SYSCLK_Div1); & w5 T. B1 v% J, x8 H$ L

  142. ; J, }, S. O0 T/ V7 t
  143.     /* PCLK2 = HCLK */' t! r" R) C$ A4 u8 t: g$ W
  144.     RCC_PCLK2Config(RCC_HCLK_Div1);
    ) n5 `3 Q; V: M( A! K

  145. , X! h, o' p4 I9 f6 W" H4 A
  146.     /* PCLK1 = HCLK / 2 */
    : X' r9 w/ T* m* p2 Y; {9 ?
  147.     RCC_PCLK1Config(RCC_HCLK_Div2);
    1 x( Q% g+ E1 P( b4 z

  148. * t. B) }% E2 C3 \& k
  149.     /* Configure PLLs */' w- K; V, `9 ]' ~
  150. #ifdef STM32F10X_CL
    0 H2 j& J! A8 b( ^
  151.     /* PLL2 configuration: PLL2CLK = (HSE(8MHz) / 2) * 10 = 40MHz */: W$ V  ~. U2 f' D0 e( `
  152.     RCC_PREDIV2Config(RCC_PREDIV2_Div2);5 w: Y  c# b* S" u+ ], C; t  i0 a& i
  153.     RCC_PLL2Config(RCC_PLL2Mul_10);* u9 E( ^/ u& L" |- |$ i
  154. ' \3 }5 P/ w* C) O" F! i. h2 S
  155.     /* Enable PLL2 */
    ; B, N7 a6 b+ v. @9 Z& P
  156.     RCC_PLL2Cmd(ENABLE);
    1 r$ I: ^& P' V! E
  157. + V. L5 K% i  ?" c4 a7 R1 a
  158.     /* Wait till PLL2 is ready *// l" x* `# ^0 |% p6 D5 }
  159.     while(RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET);1 H. O& @9 h  X% e' k3 M, {2 R

  160. 1 [/ |) ]: z- s4 k; R& z2 |
  161.     /* PLL configuration: PLLCLK = (PLL2(40MHz) / 5) * 9 = 72MHz *// I0 Q5 `% P& k9 u- o7 |
  162.     RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div5);2 X, U+ s& c' @. |% E2 K/ W
  163.     RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);
    * k6 g7 g% K+ n
  164. #else
    * H+ J5 O  b( I0 Z
  165.     /* PLLCLK = HSE(8MHz) * 9 = 72MHz */$ b, b! D7 O0 r7 T  l8 e
  166.     RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
    / P; O' _( h6 v$ a( g7 M# c% d  J9 \
  167. #endif
    5 _- ?. s/ I% Z% l7 J* b: U
  168. - Y2 v7 F. |! N  Y7 M% s
  169.     /* Enable PLL */2 j; \$ ^' T) E& F3 ?
  170.     RCC_PLLCmd(ENABLE);! ]( E! v# b- A& t3 s1 L) J7 C
  171. " @' H% J9 l+ o( B
  172.     /* Wait till PLL is ready */: ?- i( @. X4 s2 P1 }- k6 e, L
  173.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
    , q/ p& W% r4 J1 U! p
  174. : H5 x7 t% R0 d" v7 y; S7 h
  175.     /* Select PLL as system clock source */
    . K0 i2 Q1 {5 a/ ^
  176.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);* u# P% s) ], v( O1 `& B' S
  177. ( G/ P9 k" b2 T- S! n: ]
  178.     /* Wait till PLL is used as system clock source */
    * p$ x0 L( n# n
  179.     while(RCC_GetSYSCLKSource() != 0x08);. Q8 S. G8 Z' k6 O3 v  u( A
  180.   }
    % c2 L0 V" C* j& ?0 l
  181.   else4 R+ `( {* N0 ?2 I0 W# X
  182.   {
    ' m3 w# U3 m$ c  R' r$ i+ D1 y
  183.     /* Disable HSE */% C  M0 g; H0 e4 Y
  184.     RCC_HSEConfig(RCC_HSE_OFF);
    2 D" u; P. [8 h' [7 w, X/ N

  185. 5 \; w8 @1 U0 u9 x  A9 h$ {2 w
  186.     /* Enable HSI */
    # y# @) Z' }4 x& y
  187.     RCC_HSICmd(ENABLE);
    . F# N+ r0 ^- L2 x- H- @0 v" Z0 k
  188. . k# }) G9 i9 |1 l2 m* s0 c( n
  189.     /* Enable Prefetch Buffer */% y7 i8 b$ _  }: V* \, ^  O0 ]
  190.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
    1 X% V- u  e5 w9 L

  191. " g$ ^9 f& e& ]- G9 I
  192.     /* Flash 1 wait state */
    2 D& l% J0 C- N( M
  193.     FLASH_SetLatency(FLASH_Latency_1);; a0 c! x- ?$ X" ^! Q4 E' s

  194. # R) ^7 j8 p3 ^0 {0 D2 e( x3 k
  195.     /* HCLK = SYSCLK */5 j4 Z$ }/ ]) m1 t+ E1 Z
  196.     RCC_HCLKConfig(RCC_SYSCLK_Div1); # W1 g2 J3 H# b2 `2 E4 r2 Y

  197. / {, h; C$ Z) u& B7 B
  198.     /* PCLK2 = HCLK */
    . _8 k/ n4 X( e% z- z: }( }( A
  199.     RCC_PCLK2Config(RCC_HCLK_Div1); ! n! `' `' \! K6 X% O2 [

  200. : E$ a! _2 E" j3 T
  201.     /* PCLK1 = HCLK */2 k% E: D' q1 O9 {5 j$ e/ T
  202.     RCC_PCLK1Config(RCC_HCLK_Div1);' D5 T! K5 A: {' v

  203. ) f9 V0 I1 A: Q5 g& K; H( e
  204.     /* Configure PLLs */
    7 W2 B& ]$ W  }& j
  205.     /* PLLCLK = HSI(8MHz) / 2 * 9 = 36MHz */
    ) f  L  N2 ~6 E2 V" \+ Q
  206.     RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_9);1 B9 j2 c$ M& K
  207. 6 I1 e4 E4 j6 N4 w! y! ]% ^
  208.     /* Enable PLL */2 L. \1 @) P7 L( W% O+ d
  209.     RCC_PLLCmd(ENABLE);. C( a) w( F* b
  210. 9 Y* U9 [) Z% i
  211.     /* Wait till PLL is ready */
    , g; D+ @7 P' S! Z+ {  g
  212.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
    3 R- r3 X- V! S9 g" T( [6 \
  213. 7 P8 `  ]  b) M# W6 Q- x
  214.     /* Select PLL as system clock source */
    , |& b# g. N, _4 o
  215.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);0 ]( d" V4 D5 P; S3 H9 A# Q

  216. ( b% l' F* V% p$ T, t
  217.     /* Wait till PLL is used as system clock source */3 r" Z! f. A. e8 q% D( b% ]
  218.     while(RCC_GetSYSCLKSource() != 0x08);
    . j/ b0 K$ }  ?. z4 S& R- s2 x' D
  219.   }
    ; k4 {1 ~4 m& @# O, V& h
  220. }: ~/ `9 @: j  n' P" f1 O

  221. 2 ~/ r, D% S9 h* R
  222. #ifdef USE_FULL_ASSERT$ j, `1 ^/ j9 x6 O
  223. /**1 |$ t- Z& p8 Z; R% W5 E6 v
  224.   * @brief  Reports the name of the source file and the source line number
    # M6 h. ?  h: \* o; A/ Q; q0 o
  225.   *         where the assert_param error has occurred.
    2 S( _" s4 l# s
  226.   * @param  file: pointer to the source file name.
    ' m* O1 Q  `; H) [9 ~' K
  227.   * @param  line: assert_param error line source number./ E5 U  G( @  I# U$ s) U
  228.   * @return None.
    ; p$ n" ~3 J9 a4 O
  229.   */
    ' W4 L% h  I0 u- H8 j" w9 `
  230. void assert_failed(uint8_t *file, uint32_t line)# _1 C5 [2 W5 `+ F
  231. {
    * Y' H, {) i$ i* d4 c
  232.   /* User can add his own implementation to report the file name and line number,
    4 }" N: d4 C  z
  233.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */( o* _2 ^# \$ D6 |
  234. 3 o% k5 O8 q; J  J' p4 f  Z
  235.   /* Infinite loop */1 P" m; k5 L. [7 ]; |
  236.   while(1)
    - w% Q$ i( n6 W
  237.   {6 ^! V8 G+ [4 m$ p
  238.   }
    * b& O, l0 F4 K+ I; _& ?
  239. }
    3 |/ Z. W$ ?0 K) G6 z
  240. #endif
复制代码
8 }" J# \! d7 ~* Q- @
3,注意6 l3 m" D9 J; d$ V& d* \+ ^9 a' r4 o

( v; t1 j* a8 k; J. w- NCAN 消息发送缓冲区和接收缓冲区的大小,可以根据应用的需求进行修改,缓冲区使用的是堆内存,需要根据缓冲区大小和应用程序中堆内存使用情况进行配置。
2 T& S2 D1 _1 J( `# s  l, W) s
, j8 J: @0 d( p
" a2 F/ u4 r& ~  [9 T9 }4 ^
. \# U# J0 q- c0 D5 y; ?6 o
收藏 评论0 发布时间:2021-11-26 17:00

举报

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