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

【经验分享】STM32F1(CAN)

[复制链接]
STMCU小助手 发布时间:2021-11-26 17:00
1,开发环境
2 `+ ~9 ]- l! g2 k9 `  ^8 o2 n4 c, l, k, o2 a2 f- b
1,固件库:STM32F10x_StdPeriph_Lib_V3.5.0
, {# c# }# M& q4 g; G3 e  W7 n" N2 O, i, D3 ]
2,编译器:ARMCC V5.06
2 b* \' U9 f& e7 n& G0 x! ^
+ q  y1 N9 E5 O; {5 J& P3,IDE:Keil uVision5
2 E/ P% P7 I* q% \  S/ D$ }# }4 w/ U! n8 w( Z
4,操作系统:Windows 10 专业版
3 h: T  I0 y, j* @: _9 J( u: N5 _8 Q2 B* `8 i

6 n( h, Y# q. c0 m$ Q& U2,程序源码
, d/ D; `, q* [; E7 K  k& S+ N; d) B% ]* l. l& L' t' S
RingBuffer.h 文件
# W) n8 ^7 i) }; S
  1. /**  ~" H! z) H! R
  2.   ******************************************************************************
    * @. H3 [) K, w: `: p
  3.   * @file    RingBuffer.h* U0 y" k/ F) @1 I
  4.   * @author  XinLi6 |( K, y$ g' H5 }5 U; [. F4 c% ^
  5.   * @version v1.16 E# p" p" T' w1 ^0 S9 Y
  6.   * @date    15-January-2018; X4 E* U2 R9 Y  O; ~$ o/ M
  7.   * @brief   Header file for RingBuffer.c module.' L$ y8 s6 `! s' j
  8.   ******************************************************************************6 F2 ~1 m6 m9 n. P0 A
  9.   * @attention+ Z  @8 H) k# k, E6 F
  10.   *
    6 P% j5 S2 I+ u% V8 U
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>% q4 o2 p4 B; i- N/ k1 A5 p6 w5 E3 O
  12.   *7 q* y4 @5 o. ~4 l. N
  13.   * This program is free software: you can redistribute it and/or modify
    ) ~6 I: _, P* K" c9 Q  O* i
  14.   * it under the terms of the GNU General Public License as published by
    : c6 F- X% {* \6 `
  15.   * the Free Software Foundation, either version 3 of the License, or
    $ C: T" V9 i: i9 w$ }
  16.   * (at your option) any later version.
    4 ^5 ^+ ~! Q9 T
  17.   *( F) S( G$ s) N1 Q8 G9 P7 A  l) {
  18.   * This program is distributed in the hope that it will be useful,
    ) [3 C8 j2 T) Z; T
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    + P* f( c! Z6 a/ H/ ?
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the1 Q6 i& O  |4 Z3 \6 G2 J/ j5 S
  21.   * GNU General Public License for more details.
    # X: t' m/ k9 }
  22.   *. B0 ?2 B4 X+ N7 M' q0 S  P
  23.   * You should have received a copy of the GNU General Public License+ V8 w; I- i) w$ t/ n3 J
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    # z2 M0 G! g! Y8 u  V: o* W+ O
  25.   *
    2 h4 s( _% R2 s8 T# L. z* Z
  26.   ******************************************************************************' Z3 q9 c0 Y" W' y* a' s7 D/ P
  27.   */
    9 u. k" e$ X; D+ {* }+ T

  28. ; F  |7 P( s0 z: S- k$ r
  29. #ifndef __RINGBUFFER_H/ L( p! B2 d6 T  i4 ?8 s" H4 c( M
  30. #define __RINGBUFFER_H. s5 Y* d6 y/ W9 l3 X+ m6 R3 o
  31. $ c9 r6 k. \' @% z* `5 C. o+ Z& ?
  32. #ifdef __cplusplus4 q( Q$ o! Z. N5 }' \) W5 k/ M4 J
  33. extern "C" {
    & \, p9 y! E8 e
  34. #endif1 W  @0 V% p, [

  35. 1 m, D/ C) C- |6 ^/ P8 _8 e
  36. /* Header includes -----------------------------------------------------------*/7 K/ F6 w3 E: @- a4 O
  37. #include <stdint.h>0 f) K/ m* W' k! M- O+ {  P
  38. #include <stdbool.h>
    # e/ R; x. C% b6 P7 ]& _
  39. #include <stdlib.h>  l. U; N& X1 C; Y

  40.   F8 I8 d) n1 C3 v( d: z
  41. /* Macro definitions ---------------------------------------------------------*/% F& T/ f+ g, d# G  z- Z
  42. #define RING_BUFFER_MALLOC(size)  malloc(size)
    & m  H8 K" Z3 B/ ]) k1 Y
  43. #define RING_BUFFER_FREE(block)   free(block)0 J6 ~# c3 Q! K) V7 H/ S# Q( b

  44. . n" E0 x8 ]) f
  45. /* Type definitions ----------------------------------------------------------*/
      ^9 p8 B3 ~( k$ O0 r9 U+ J
  46. typedef struct
    4 p; T% \. k/ d; I
  47. {
    : `8 n& M& `8 P8 U- [, X( l
  48.   uint8_t *buffer;
    & }8 j/ ~- ?3 C
  49.   uint32_t size;$ R. Y2 J! u9 J( m4 T: Z2 S
  50.   uint32_t in;
    * E$ x4 S1 N& Y( J! b
  51.   uint32_t out;  l) M+ O/ ]7 P
  52. }RingBuffer;. Z8 P: a6 {% |( [, t$ t8 D

  53. " ~. B/ \2 @9 H6 l0 l
  54. /* Variable declarations -----------------------------------------------------*/
    # ?5 r! h5 _1 P: O' ]! \" ~. f  b/ Y7 i/ P
  55. /* Variable definitions ------------------------------------------------------*/9 P$ ~* w5 ]6 P! [" O* M+ p3 a
  56. /* Function declarations -----------------------------------------------------*/
    2 z. ~- X' a$ O1 y" [- r
  57. RingBuffer *RingBuffer_Malloc(uint32_t size);3 q: V0 `5 u4 N& d# ^* m
  58. void RingBuffer_Free(RingBuffer *fifo);
    4 ?  ]7 h3 b, g
  59. & P. w- i; N! }
  60. uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len);  e1 V, h" P. `5 w" C
  61. uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len);
    2 ]( H% ?9 p# c/ D0 z1 V- I, `" @
  62. 7 @3 o: v1 y% L$ z, [
  63. /* Function definitions ------------------------------------------------------*/
    8 ]- b2 P* }9 V& o' u9 z4 I# r- @
  64. - U: L  E) U+ {- o/ a
  65. /**
    6 a  _& t7 @4 b% l' C
  66.   * @brief  Removes the entire FIFO contents.: W% ^/ @+ [8 J3 {4 ^
  67.   * @param  [in] fifo: The fifo to be emptied.% ^) o8 e. h0 c8 `: a
  68.   * @return None.
    * p* }& T& h8 U3 A- v+ }" y# T
  69.   */3 W+ @; t5 O' v% ^+ M6 _. e
  70. static inline void RingBuffer_Reset(RingBuffer *fifo)3 L/ y9 {7 A( I: N3 M7 X0 Z
  71. {5 t0 {9 w5 b  C7 W$ X
  72.   fifo->in = fifo->out = 0;
    6 x" y, `4 L6 L: e
  73. }) D3 e- V' L4 }0 i. T* y7 h

  74. - \& P" G# p1 c7 Z7 ^5 K
  75. /**$ z3 I& A. ~& @; t' h
  76.   * @brief  Returns the size of the FIFO in bytes.
    1 O' T* f+ T) l9 T
  77.   * @param  [in] fifo: The fifo to be used.1 w  C/ A# |2 e6 O' A7 b; V- Y
  78.   * @return The size of the FIFO.9 g7 z* k. _- Q8 |. w
  79.   */# g/ l0 L8 B' k
  80. static inline uint32_t RingBuffer_Size(RingBuffer *fifo)2 i6 k/ v1 L8 F& o& G( X# h- a
  81. {
    & c! c% `! p4 w9 z
  82.   return fifo->size;( B( b/ ?1 @- X/ B# b4 J
  83. }7 O& }5 Q( X4 M' |: H+ K

  84. , _# X3 v4 @; q
  85. /**; g! J+ [: s3 F' R# T+ r4 a# N
  86.   * @brief  Returns the number of used bytes in the FIFO.$ {1 D* g# J. x9 {: ?
  87.   * @param  [in] fifo: The fifo to be used.
    9 j! Q- @8 o. Y' C. V4 R) e
  88.   * @return The number of used bytes.
    8 B5 d2 }9 ?/ ~* {) I0 o
  89.   */
    ( q. N. @: E) R; A6 U9 R
  90. static inline uint32_t RingBuffer_Len(RingBuffer *fifo)
    6 e% [( J* J4 A1 `# J7 ~4 Z
  91. {
    . g+ i# o9 a% b- }0 E2 A
  92.   return fifo->in - fifo->out;9 e! k# d% J2 z& h" l& j& |
  93. }
    , S: Z! U: V8 O" W, P9 K( e
  94. ! z) K' k' h* k$ `
  95. /**$ M& A! c+ O# Q6 [4 D
  96.   * @brief  Returns the number of bytes available in the FIFO.& Z% A# o; Q& s1 V0 _) x
  97.   * @param  [in] fifo: The fifo to be used.
    ; p! f$ C0 G  H; c/ z, c( w  l
  98.   * @return The number of bytes available.# `4 O# Y5 T, t9 F
  99.   */* A' j1 q. p, O1 {' G& V4 m: ~
  100. static inline uint32_t RingBuffer_Avail(RingBuffer *fifo)
    * S1 {8 m% I: m4 {5 A
  101. {; Z( ^/ ]3 `& s) K) p4 m
  102.   return RingBuffer_Size(fifo) - RingBuffer_Len(fifo);8 M- F$ ~+ Q: K3 a
  103. }
    . x1 w5 L- A$ `- T) h9 b/ i

  104. . L3 u4 z! J9 ?
  105. /**
    , p0 h5 t$ s) [
  106.   * @brief  Is the FIFO empty?, A, _+ U; @# ^, d  b& d5 \
  107.   * @param  [in] fifo: The fifo to be used.
      j/ |1 M' J& v1 ^! |) [+ |
  108.   * @retval true:      Yes.
    % x% L9 e& y6 Q: T. c
  109.   * @retval false:     No.
    2 V' v/ L- U* ?& T0 M% i
  110.   */# g; H  d1 n) W
  111. static inline bool RingBuffer_IsEmpty(RingBuffer *fifo)
    ! P% A4 C- S# h, {% B' ]* h1 s
  112. {
    $ H9 R- w% {: D0 k8 u( b8 K1 b
  113.   return RingBuffer_Len(fifo) == 0;
    ' a; `( C7 ?# T8 p
  114. }) n2 }6 K# A" S5 W& M& |3 ?. C8 Z
  115. 4 }* ~9 P# h" ~
  116. /**
    3 y( m! t9 |1 D$ i; y" ?- {* T7 O- k
  117.   * @brief  Is the FIFO full?
    " H& J4 _6 g- M6 I- B# K
  118.   * @param  [in] fifo: The fifo to be used.
    / D& Z* ~2 X; O; T9 u% A$ g4 |' p
  119.   * @retval true:      Yes.$ B( ~" [. Q0 k& `
  120.   * @retval false:     No.
    - l! ^5 _1 T; ~, J. q
  121.   */# ^3 W$ f5 \  W7 p! o# s  `
  122. static inline bool RingBuffer_IsFull(RingBuffer *fifo)5 z, N1 G7 q! _! n% E6 p. b# G
  123. {
    ) c8 |- M* _$ w# j6 `4 ?
  124.   return RingBuffer_Avail(fifo) == 0;6 y3 I- H. Y1 }; {8 G
  125. }) Z& s4 C6 G5 `' |1 Y
  126. $ r( o! K4 n0 K/ I* O. v
  127. #ifdef __cplusplus
    7 d4 f: P, _6 g
  128. }
    1 U3 W& n: E1 |2 ?: c4 p7 _/ {
  129. #endif- ^- y1 u. U+ ^1 F0 g7 H4 P

  130. ) {1 k9 o1 x0 z3 D  n2 P
  131. #endif /* __RINGBUFFER_H */
    * W1 X) P) }" I
复制代码
9 A1 A+ m- J/ C! g9 v4 y8 ^
/ T7 J3 X6 u1 N+ X, ^2 s/ E
RingBuffer.c 文件
0 V7 w( V! V% T3 r8 z! L% i' U% {
  1. <div>/**
    , q( e! q. d4 w/ f' p
  2.   ******************************************************************************; j0 A9 Y- d& M- n8 @
  3.   * @file    RingBuffer.c
      S) w" y9 E  K+ n$ p3 d& n
  4.   * @author  XinLi1 P" y: q# Z" v9 K# ]9 h# c
  5.   * @version v1.1
    " Y; C0 C/ T. J2 l. n
  6.   * @date    15-January-20189 [! z; r9 r7 r1 V  d
  7.   * @brief   Ring buffer module source file.
    ( ^2 E, p, O, [2 z9 ^8 n. R
  8.   ******************************************************************************9 r% f6 z" L$ _7 P  ]
  9.   * @attention% g# ^' ], E0 Z& k/ v2 |
  10.   *6 s2 F4 I# f# I$ a' N$ X  H
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>* h) c- }3 J; [" O, Z% ?1 o
  12.   *4 g/ e4 z) g5 R- |: W/ |
  13.   * This program is free software: you can redistribute it and/or modify
    : G0 V& P1 Q5 ?& G& w. j
  14.   * it under the terms of the GNU General Public License as published by2 i/ k/ ~1 S) Z- a1 H, p" ]* F
  15.   * the Free Software Foundation, either version 3 of the License, or
    9 t. j+ G' G2 _6 a  a
  16.   * (at your option) any later version.
    3 @" v( A0 B7 u6 G4 f" v( o6 A6 y
  17.   *$ n7 Q  E( X0 p$ s  k9 x) L$ L
  18.   * This program is distributed in the hope that it will be useful,
    / `6 f9 q5 d7 ]/ {) O7 p
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of7 v8 n, p' V* E4 T* i6 v
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the6 n7 [; \+ q3 g: T. D5 M- P
  21.   * GNU General Public License for more details.9 s* R. U* R4 O' ?& J& \: i
  22.   *. X, \) z0 j+ A
  23.   * You should have received a copy of the GNU General Public License
    $ [' R- G, b  B
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>: f9 h# v8 m3 w; @" g
  25.   *
    & C) W, D9 @4 A/ e  W" L8 \
  26.   ******************************************************************************
    9 m- x* B. k8 W0 `' G
  27.   */
    " q0 P* f+ @( I6 E# D

  28. 8 Z$ d0 J0 e5 o5 y. ]* j
  29. /* Header includes -----------------------------------------------------------*/
    $ r! d2 B  i* n7 i
  30. #include "RingBuffer.h"
    ( R! m" B' n2 e4 V9 }4 V
  31. #include <string.h>
    5 _" ^; [3 L$ y' _" _! G/ v4 m+ k
  32. 0 Q! O6 Q9 T3 ]% ]; q
  33. /* Macro definitions ---------------------------------------------------------*/# P- K% {" o; P& _6 c' K6 O! j4 Z6 c
  34. #define min(a, b)  (((a) < (b)) ? (a) : (b))
    $ e+ M! {) \6 R; I$ W2 e

  35. . d$ b; ]8 U6 ]" R: k2 }
  36. /* Type definitions ----------------------------------------------------------*/
      L+ N  t) P1 o8 c; n2 I
  37. /* Variable declarations -----------------------------------------------------*/' Z5 N! ?) ~5 G, o9 A7 R+ k0 y
  38. /* Variable definitions ------------------------------------------------------*/6 J# M% e/ s* |& @
  39. /* Function declarations -----------------------------------------------------*/2 R- j; q3 V, c6 ]6 b
  40. static bool is_power_of_2(uint32_t x);
    ! d4 o+ q. e8 R1 E/ I
  41. static uint32_t roundup_pow_of_two(uint32_t x);# p. V, t% l3 K2 A- J6 L: T; n2 _
  42. - A" c$ M5 S2 q$ V  n* X4 P$ s
  43. /* Function definitions ------------------------------------------------------*/( T6 @* I* a7 @1 r, G4 K6 l
  44. ' ^% b. J1 v) f# I
  45. /**
    ( @! x& |" k* B4 ~! O" x
  46.   * @brief  Allocates a new FIFO and its internal buffer.! ~4 ^% a% |5 J$ E8 D1 C! h
  47.   * @param  [in] size: The size of the internal buffer to be allocated.
    3 y7 }0 I! k8 l% c5 X$ F
  48.   * @note   The size will be rounded-up to a power of 2.+ H0 u8 ]* V* S! B) m
  49.   * @return RingBuffer pointer.) D$ T7 Y: G0 x" |9 O( R
  50.   */
    4 p. N7 A4 D( P+ e$ h' q, O9 |
  51. RingBuffer *RingBuffer_Malloc(uint32_t size)1 J) N  M1 x' @8 ]! M# ]
  52. {, G- A, ^" w" C! e+ e
  53.   RingBuffer *fifo = RING_BUFFER_MALLOC(sizeof(RingBuffer));
    ( k% [# Q4 Z0 I* n) d

  54. 1 ~: [; ?) t% q, X: Z& J8 |
  55.   if(fifo != NULL): s8 _" Z: [) r& H- x* e% [
  56.   {
    5 @4 [$ O' E" V
  57.     if(is_power_of_2(size) != true). n9 J7 `7 R: b# E" g
  58.     {
    1 ~2 X; \* \7 \& V( f5 m2 h# |
  59.       if(size > 0x80000000UL)( B" A4 }/ F4 n9 I3 ~
  60.       {
    + a7 |" Y! X# G% p$ D* A
  61.         RING_BUFFER_FREE(fifo);. J! B- s% v9 T5 n
  62.         return NULL;! ^& z( F- D$ O4 W5 P& i& d
  63.       }
    , L7 P9 K' H. d: f$ T+ S0 i" O
  64. % F/ ]3 F/ B8 ?  l+ z. x; p3 r
  65.       size = roundup_pow_of_two(size);, b6 a! [! t( s9 L  L
  66.     }
    4 i" ^% x7 h* y; r

  67. 0 n+ Z6 p; Z% U- N
  68.     fifo->buffer = RING_BUFFER_MALLOC(size);
    ; ]4 n# M6 m, W8 }: R
  69. 8 `# F/ _3 x' ?: Y; Z2 R
  70.     if(fifo->buffer == NULL)
    ( B" J0 I7 e5 _2 [) x4 M
  71.     {3 c1 ?. D5 h: P. A6 g
  72.       RING_BUFFER_FREE(fifo);/ _4 A* S" Q3 ~! I: F
  73.       return NULL;0 U' C$ z+ y8 z. z- w9 i; m
  74.     }
    ' Y) g5 b. t0 p1 _
  75. 9 W+ _7 ]1 l& x
  76.     fifo->size = size;
    7 V5 Z& e* [0 ?/ |9 w8 R$ ?
  77.     fifo->in = fifo->out = 0;
    3 i. }: P- A2 L- W! \- E4 B( c
  78.   }7 r7 Y. O6 ]& V0 \1 W
  79. 8 t! u5 L- u8 Q: m! v) I
  80.   return fifo;
    ) W) c! ]; b+ G" `, _
  81. }8 A" q7 G9 O5 ]7 l' U; w4 H

  82. + h$ a, `6 w5 ~
  83. /**5 K4 ?2 W3 v; }9 h% G+ u
  84.   * @brief  Frees the FIFO.; K; D! m/ [) r8 v& d( g4 {$ v
  85.   * @param  [in] fifo: The fifo to be freed./ j1 c) R( t& X: ^  C
  86.   * @return None.
    3 H8 D! m! k" R( s; u" c" d' C
  87.   */
    * L0 z2 @; y- y' `  h
  88. void RingBuffer_Free(RingBuffer *fifo)3 C, t5 }- e8 K0 L5 _
  89. {
    5 A9 f, m" a: b0 b6 Z" h6 I
  90.   RING_BUFFER_FREE(fifo->buffer);( J+ b+ h# W3 j1 T- G0 `
  91.   RING_BUFFER_FREE(fifo);
    8 Z3 F1 F/ G; b4 M2 l  ~; L; q. l
  92. }
    % G9 s' \) t+ }- {$ u: g
  93. : I- [8 S8 c7 j
  94. /**
    ; d+ b" u, R- N1 l3 y, A0 D
  95.   * @brief  Puts some data into the FIFO.# Q7 _% x- [4 k9 j
  96.   * @param  [in] fifo: The fifo to be used.' L$ T# Q/ j' l. x# O& y" z
  97.   * @param  [in] in:   The data to be added.$ R7 w8 _+ t5 E  u& Z
  98.   * @param  [in] len:  The length of the data to be added.1 u' ?0 ^2 Q& q/ k* I/ ?8 H2 Y! u
  99.   * @return The number of bytes copied.
    4 _% r  ]- W: o% P8 `; S0 i7 e$ z% m9 t
  100.   * @note   This function copies at most @len bytes from the @in into
    9 q) U/ v8 Q1 [. u  S
  101.   *         the FIFO depending on the free space, and returns the number- a5 H2 c; H5 w
  102.   *         of bytes copied.9 B4 c- G) N+ o% b
  103.   */
    5 k$ o" B/ u9 y2 L5 n
  104. uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len)0 W' }* I( [" u, {) w& x
  105. {
    4 H: P7 H, L. f! G
  106.   len = min(len, RingBuffer_Avail(fifo));
    7 ^  |$ u! V! F* V2 l* a
  107. 0 N  H$ ~, V- s! a
  108.   /* First put the data starting from fifo->in to buffer end. */+ y, |1 v( D& T' _
  109.   uint32_t l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));
    * O" }: R( x% Q$ L9 c, D8 p
  110.   memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), in, l);  l; J4 m) q7 u$ E3 b0 M0 H

  111. $ j1 Q* W6 M7 h) ^* K
  112.   /* Then put the rest (if any) at the beginning of the buffer. */
    - P( U& S& a3 W0 `7 A6 w) ?8 b+ g
  113.   memcpy(fifo->buffer, (uint8_t *)in + l, len - l);( d9 i: a7 I) J1 A# g2 T, h1 A+ p
  114. & e( |, m) R4 \0 y
  115.   fifo->in += len;$ @) M/ a" p( L7 S( Y, b
  116. # `3 ]) c5 c0 e' o2 j
  117.   return len;; q( ~; P4 y+ W) z8 R2 p4 `: d
  118. }
      Y6 H+ G3 M, {% u' m

  119. 9 e# e+ i7 L9 @9 o6 b+ f! t0 e! `  ~
  120. /**
    4 A# Z* u9 T4 N0 s0 B% i
  121.   * @brief  Gets some data from the FIFO.' E0 ~' Z8 l+ d& Y# ~
  122.   * @param  [in] fifo: The fifo to be used.
      [: F; H2 |5 J5 S# @
  123.   * @param  [in] out:  Where the data must be copied., n5 P5 Y+ j5 U( d0 y+ f7 J. r$ p
  124.   * @param  [in] len:  The size of the destination buffer.
    " {* Q; b& z9 C( x( X$ u' Q4 X
  125.   * @return The number of copied bytes.% p/ C+ f! K' Y9 V! Y2 V) I
  126.   * @note   This function copies at most @len bytes from the FIFO into: ^( u! y0 {0 O/ ~. r" S
  127.   *         the @out and returns the number of copied bytes.
    " m, d6 Q( i/ |
  128.   */7 a. d0 d" U8 u1 W
  129. uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len)4 |% s1 c4 o. x; |
  130. {; h$ t+ \& q. k. A4 y
  131.   len = min(len, RingBuffer_Len(fifo));5 v9 R! V+ \& ^; \9 _6 @! }

  132. . N# U0 b2 Z/ b# D4 s: @
  133.   /* First get the data from fifo->out until the end of the buffer. */1 p8 l* u$ i" E
  134.   uint32_t l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));" d  T8 O5 k  G
  135.   memcpy(out, fifo->buffer + (fifo->out & (fifo->size - 1)), l);. R: c& D! N! H) x5 u+ T
  136. 8 s- p8 p6 k$ F7 ^2 o/ \$ C/ @
  137.   /* Then get the rest (if any) from the beginning of the buffer. */7 P& e& f3 \  U1 @& y1 H# J+ `
  138.   memcpy((uint8_t *)out + l, fifo->buffer, len - l);; p9 b  X$ V6 ]

  139. 8 @) i: x0 W0 q- O1 Y- c
  140.   fifo->out += len;
    : `. q' B, l( I' [

  141. . m% h2 C& t/ r% e, P
  142.   return len;; w/ Z3 ?7 V; L% n& }9 w7 P5 q
  143. }
    2 k8 O; G# _# Z* Y2 @, V' ^
  144. 9 s7 q  l; B4 s1 ]! J
  145. /**
    8 V! I2 ?9 E' f' L0 Q1 P
  146.   * @brief  Determine whether some value is a power of two.
    * U; w/ _  N6 Z9 P+ |( s/ v& a( K
  147.   * @param  [in] x: The number to be confirmed.
    - t; G8 f  b; t
  148.   * @retval true:   Yes.
    ) u# b' U, n, y" k
  149.   * @retval false:  No.
    1 x) v! I) E/ x* C5 ]& r) }
  150.   * @note   Where zero is not considered a power of two.: w( O8 p. Z6 B  I
  151.   */
    ' S0 {- ?8 _2 t0 S+ U, b8 `: L
  152. static bool is_power_of_2(uint32_t x)* d9 H, h6 X9 q4 q3 U% z& d! f( i
  153. {
    5 k) W6 d/ J4 i5 H
  154.   return (x != 0) && ((x & (x - 1)) == 0);- W" `' d3 z, l& X& Y% j  \
  155. }: n+ u1 O4 q* r( s

  156. 6 U1 T  {9 D8 O2 c
  157. /**0 O, l1 h" ]6 b7 v6 X
  158.   * @brief  Round the given value up to nearest power of two.
    ( m7 g; G6 E+ u) M, N
  159.   * @param  [in] x: The number to be converted.  N7 _. M- i5 ^  c1 d
  160.   * @return The power of two." m3 \* v! K; v! x3 _; @
  161.   */0 _7 [3 q+ C4 ]
  162. static uint32_t roundup_pow_of_two(uint32_t x)- x! M$ c+ V+ X3 L0 L
  163. {' l4 Q2 V' W' r: w! M0 G/ x/ J
  164.   uint32_t b = 0;6 I+ u8 J9 H3 D

  165. $ P' f3 g% E( d/ C! T4 D
  166.   for(int i = 0; i < 32; i++)
    % F2 i5 b0 P4 z9 i4 A; @7 e
  167.   {1 t; J* o1 s) K' T0 j( W( P
  168.     b = 1UL << i;
    3 _  _$ J6 ?! o0 G

  169. 9 o, I4 {  i. T8 b9 e
  170.     if(x <= b)
    ) ~* I0 ?2 O0 {! Y) B( U' H
  171.     {; F" R2 H8 ]( M" ^( s! ^  b
  172.       break;
    : u0 g" P! c% ]7 [5 R
  173.     }" V; P3 V8 ?2 H( m. Z8 r
  174.   }; i/ W' d7 B% P

  175. $ Z7 k. Z: o1 M/ @1 i
  176.   return b;/ {2 M7 Z0 D" l
  177. }</div><div></div>
复制代码
0 W6 ]) g9 v+ ^/ r

, g3 X, Y/ L: f$ B. y% G4 ]CAN.h 文件0 D; r' F- N5 |3 [3 f
  1. /**
    2 b" O6 Y. \6 J: q
  2.   ******************************************************************************* U' q% J7 o2 E, S" z% m6 x, F
  3.   * @file    CAN.h
    3 f6 |3 v  F+ I% o  w
  4.   * @author  XinLi
    & e2 o0 s! b5 e: h; \3 h8 H
  5.   * @version v1.0! }" e1 T5 a$ R1 s
  6.   * @date    24-June-2018
    6 d+ A, a: n# C' W& z4 S8 Q5 l1 w
  7.   * @brief   Header file for CAN.c module.
    9 Y( [0 D( r9 M: G! U9 c
  8.   ******************************************************************************
    : n4 r& o6 W; W/ E
  9.   * @attention
    % {1 k" j" s$ |* b; v9 e: A
  10.   *- o' M8 A3 J& r( D$ U+ v4 U
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    ! C) t# d0 R2 L) {$ r
  12.   *
    0 I3 R2 E7 f0 H' U
  13.   * This program is free software: you can redistribute it and/or modify+ {& C5 B, x* X
  14.   * it under the terms of the GNU General Public License as published by
    2 p! R) ?* \7 ^  p8 u! y* _; g* |) w
  15.   * the Free Software Foundation, either version 3 of the License, or
    - F* n+ V, w$ o# @, K# y7 d! ~- f; x% S
  16.   * (at your option) any later version.+ r, e* p7 H* O( {( G: O  C
  17.   *
    4 F  D: K( \/ [* N
  18.   * This program is distributed in the hope that it will be useful,- I  O) O/ Z% H
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of# D* f& ^  w6 N2 u2 t+ _' g: M# C, z
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the) \* H, J' o, z. M! Y' C( @, }1 {
  21.   * GNU General Public License for more details.- {8 `( F# c; `* C
  22.   *9 v; H1 C0 U. O  Y, \/ J  h7 F! l6 I
  23.   * You should have received a copy of the GNU General Public License3 {* W. _! b% x- p& {
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    6 V" p8 ?" k$ l% N; f9 r* c
  25.   *" L5 o$ h; z) M1 q8 p0 Y
  26.   ******************************************************************************
    # g+ K% ~" e6 x$ m8 [( G& ^9 R7 C6 c
  27.   */
    9 H: j3 u/ X5 @; l( `. z( e
  28. / h1 H1 T6 D/ S( D
  29. #ifndef __CAN_H
    ) ~) i# _) Q& V7 B( I$ H' g& }
  30. #define __CAN_H. v) s$ o5 m5 t7 ^( v9 t

  31. 8 w8 X3 N& k* I% B3 ~
  32. #ifdef __cplusplus& I1 V% B, A. M1 ], _1 R
  33. extern "C" {) a) L( Z, ]; t8 {
  34. #endif1 J6 o0 I. y" L! O
  35. ( w$ h& F' |6 o* h" M7 f/ M
  36. /* Header includes -----------------------------------------------------------*/! L1 F, W  a2 g3 J1 u" N2 K. P
  37. #include "stm32f10x.h"
    8 _6 Q6 T: s* w! C* z/ I6 j: ?
  38. #include <stdbool.h>  b; N, q/ @7 q7 U+ Z$ X, C  V
  39. - a1 C; v- n* [: I: O4 P
  40. /* Macro definitions ---------------------------------------------------------*/
    ) p: B1 ^) ^' Y' {+ h( X3 z
  41. ) X% @2 }7 [  I
  42. /******************************* CAN1 Configure *******************************/
    ( L. [' @5 F# E9 ?: V
  43. #define CAN1_TX_BUFFER_SIZE        (16)
    5 T7 a+ M- \- ?' Q) s. V/ E
  44. #define CAN1_RX_BUFFER_SIZE        (16)2 K9 m8 a/ S! y$ y9 Z$ z

  45. & H7 \  \5 @- Z( M4 ^1 c" ?
  46. #define CAN1_TX_GPIO_CLOCK         RCC_APB2Periph_GPIOB9 m! j; m# ^  B
  47. #define CAN1_RX_GPIO_CLOCK         RCC_APB2Periph_GPIOB
    3 B" N# X' m4 d
  48. & ~8 \5 r* R# _/ P* D: j+ b
  49. #define CAN1_TX_GPIO_PORT          GPIOB
    $ x$ w( Y, \% T, M$ l( c- ^" t
  50. #define CAN1_RX_GPIO_PORT          GPIOB& q4 w, |2 X& n+ r
  51. 6 y4 g4 Q6 z! c* M
  52. #define CAN1_TX_GPIO_PIN           GPIO_Pin_9
    6 Q' ^1 H1 u1 e. m- [3 U4 X# f
  53. #define CAN1_RX_GPIO_PIN           GPIO_Pin_8, k( H( B& E8 T" ~

  54. " h* V' j9 G  l- X$ b7 p
  55. #define CAN1_IRQ_PREEMPT_PRIORITY  (0)0 i- [& L7 w0 H
  56. #define CAN1_IRQ_SUB_PRIORITY      (0)7 q0 `% ?1 R; ^5 @6 t3 p
  57. , ?8 O; j# ?. x) \; F: V7 T
  58. #define CAN1_PORT_REMAP()          GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE)
    / I3 H+ ?  h$ q: v
  59. /******************************************************************************/
    2 j: V5 z/ N: w5 D6 h$ K

  60. + ^, k' m6 @6 c
  61. #ifdef STM32F10X_CL4 [% y1 i4 ^  D$ X/ c7 ^; j" s
  62. /******************************* CAN2 Configure *******************************/
      ?. l* ?' Z/ g1 ~, C" g
  63. #define CAN2_TX_BUFFER_SIZE        (16)
    3 _1 @, R. ?/ b( Q! T9 |1 B: \
  64. #define CAN2_RX_BUFFER_SIZE        (16)' k+ v! {  O9 y1 k
  65. 7 f1 E+ i& l' k) B' ?$ _# F0 z
  66. #define CAN2_TX_GPIO_CLOCK         RCC_APB2Periph_GPIOB
    ; c( x' q5 W' F
  67. #define CAN2_RX_GPIO_CLOCK         RCC_APB2Periph_GPIOB9 _/ ]6 X0 {7 E% c$ d
  68. 1 F) m0 k+ A! z+ T. p6 T) `
  69. #define CAN2_TX_GPIO_PORT          GPIOB
    / v" s/ h4 U$ V- W5 m4 c$ Y1 }
  70. #define CAN2_RX_GPIO_PORT          GPIOB3 D0 c" @8 N. s# ?3 G

  71. 3 @; ?$ _: `; R' X5 A- x
  72. #define CAN2_TX_GPIO_PIN           GPIO_Pin_13
    7 r. ]# f: [3 I
  73. #define CAN2_RX_GPIO_PIN           GPIO_Pin_12* d! H0 t- r! U$ a! f
  74. " }: L9 ^5 t$ j7 {# @: V9 S
  75. #define CAN2_IRQ_PREEMPT_PRIORITY  (0)7 g" Q' O" `2 l+ @! |
  76. #define CAN2_IRQ_SUB_PRIORITY      (0)( r9 c3 E0 M$ ?5 b9 u

  77. 8 C$ f8 |9 v+ H
  78. #define CAN2_PORT_REMAP()          GPIO_PinRemapConfig(GPIO_Remap_CAN2 , DISABLE)( K5 o( T1 t; s  E
  79. /******************************************************************************/
    ; k1 f/ {0 c6 L3 s
  80. #endif /* STM32F10X_CL */
    9 o% J' T: U! H, d
  81. ! h7 M, E8 X" K+ O9 s
  82. /* Type definitions ----------------------------------------------------------*/
    6 [$ A4 Q# m$ i3 r1 P& ?
  83. typedef enum
    5 S. }0 e1 Z- h
  84. {
    . C0 v# `% E* ]
  85.   CAN_WorkModeNormal   = CAN_Mode_Normal,
    ! |) w! L9 \9 U* I) \/ J* o4 }
  86.   CAN_WorkModeLoopBack = CAN_Mode_LoopBack
    8 H' @6 ]- Q8 q/ r: ~+ F  s' E% T
  87. }CAN_WorkMode;
    $ X: }  Z1 J4 j. |) ]9 e/ [
  88. 1 p# \& i; A, }2 y& l
  89. typedef enum" ]; |2 z3 }1 R8 @  t, ^
  90. {
    5 V% v6 D% @; e( _
  91.   CAN_BaudRate1000K = 6,
    * V6 \- o4 D; V: ]$ X
  92.   CAN_BaudRate500K  = 12,
    ) L. y8 Y; |, s- ]
  93.   CAN_BaudRate250K  = 24,
    7 ^) X6 s% u; D8 p! w7 z: m* U
  94.   CAN_BaudRate125K  = 48,1 F, G8 y9 N% k4 E
  95.   CAN_BaudRate100K  = 60,
    0 u/ r+ M8 Y2 G- M0 O+ e/ G
  96.   CAN_BaudRate50K   = 120,
    6 z! A- K0 c! e" ]. e
  97.   CAN_BaudRate20K   = 300,
    8 A1 L0 w* N9 p7 _0 ?
  98.   CAN_BaudRate10K   = 6009 ~' u! ^3 \" b
  99. }CAN_BaudRate;
    1 _* c6 g6 B# @; P3 Z+ @7 Z

  100. & W: A+ B- @$ x! _
  101. /* Variable declarations -----------------------------------------------------*/
    # q" X9 C# d1 |( A" d
  102. /* Variable definitions ------------------------------------------------------*/# Q3 G" p$ j4 t7 k+ N9 T7 r
  103. /* Function declarations -----------------------------------------------------*/8 m2 v" i9 r1 l6 \. w% M& y9 ]
  104. void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId);
    : y/ d' y/ r+ m9 Q
  105. void CAN_Unconfigure(CAN_TypeDef *CANx);1 G8 I" f% j6 |0 S( i  D: l
  106. 9 I! g7 |, S2 o! Q
  107. void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));) O; d, x' e* ~0 C* ], A1 }( W
  108. void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));
    5 H; d6 x; V9 Q; S6 \
  109. % Y1 V# C0 k: w
  110. uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number);
    $ _' |4 t, |* m0 C- n
  111. uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number);
    & ?+ i; d, E' p
  112. 4 I! p0 C4 O+ G: ]
  113. uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx);7 y' b) D4 w# n& v7 h: V
  114. uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx);
    2 v6 q9 I4 b6 D, x3 n& Z4 X, X" H
  115. uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx);, v/ w4 i$ D8 N% A, t9 ?5 Z
  116. uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx);
    ; z( k7 _, [& B

  117. / D5 D0 ]5 C, T' ?8 S
  118. bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx);
    ( |) S3 E) L/ o! I2 I
  119. bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx);$ |/ T: a( t/ A+ ^, d
  120. bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx);; P/ S8 M, n$ |) x- h0 n$ N
  121. bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx);7 e& C/ X- Z  y; \4 i0 q9 M
  122. ) |; q& ^! c! U* E: i' B- c
  123. void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx);
    . p. ^* T5 r" _; e4 h6 B9 D$ o
  124. void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx);
    5 u& b& q: P) C8 W7 P

  125. + q. E+ M7 U' C' \7 ^
  126. bool CAN_IsTransmitMessage(CAN_TypeDef *CANx);
      |  H: D$ V& f" H3 R7 ]
  127. ' h. y! S9 {" T: I0 I  W6 Y
  128. /* Function definitions ------------------------------------------------------*/
    8 h  B$ ?# N3 y+ G; ~

  129. 2 [7 T" g1 k. e8 N' z
  130. #ifdef __cplusplus
    % v. p. @& J( A4 K
  131. }& n  n! j+ W0 F
  132. #endif
    1 }) |: K1 f0 e
  133. 7 Y5 o- g& _" i* N0 K+ X2 w
  134. #endif /* __CAN_H */& A# I/ ~: Z4 `$ k1 V2 w# @" f
复制代码

  z" ]2 r; ^# F4 r) L  h3 f! C% x( {4 ~

3 \) v3 v$ Y# A3 K3 ]4 D+ yCAN.c 文件9 ^! Q- G8 t; n  B. O, H

( r1 D/ t5 t4 j# t9 K
  1. /**
    * d3 m' B6 a4 j: V2 P6 }0 ?: {. G3 |. |
  2.   ******************************************************************************/ {2 U; [- g8 Z2 Q' |( I( K
  3.   * @file    CAN.c
    - t; b& S. p" X) f. ?( e
  4.   * @author  XinLi% p/ h3 G% M# J0 ~" G
  5.   * @version v1.0, n; E, ~; _2 Q& e
  6.   * @date    24-June-20184 r9 r; }; n( T& T7 ^+ u
  7.   * @brief   CAN module driver.$ f$ E9 ?" F: N6 ~* N  b. |
  8.   ******************************************************************************3 T; ?: i" I# s  y9 e
  9.   * @attention
    0 L" m7 r/ l4 U+ j/ K
  10.   *
    ( ^# {8 g6 J6 r+ G
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>% i6 w( A1 \5 }) o, X! s
  12.   *5 z; F# S9 x" n% |# |+ T, j. A8 c
  13.   * This program is free software: you can redistribute it and/or modify4 W" ~/ K+ ]# p
  14.   * it under the terms of the GNU General Public License as published by' u/ ^/ ?* g: U/ P" R# ^: ^. S
  15.   * the Free Software Foundation, either version 3 of the License, or1 ]4 Y* H; f9 ]# E% M' b9 F$ h7 v/ v8 m
  16.   * (at your option) any later version.( `) v& l. L  I6 \
  17.   *
      H7 F2 r7 R! s( U7 B
  18.   * This program is distributed in the hope that it will be useful,
    5 z+ s; n3 F  b# f9 K0 O7 D! J" S: {
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of* r7 E+ }' [  @" F3 z5 w
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    / ~, N+ j4 @. u1 ]
  21.   * GNU General Public License for more details.) }& {5 g* E; j" q5 U2 [0 W
  22.   *
    $ a: \: ?/ n  i' P9 `5 B( R* p
  23.   * You should have received a copy of the GNU General Public License
    6 O/ c! z9 Q# G; r. D; l
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a># ?; {8 Y5 N2 E6 j
  25.   *
    4 l2 B: a2 J9 w1 S0 N
  26.   ******************************************************************************
    & Q  R/ s+ v: i
  27.   */
    / y9 a% g. Q# w8 H  x! J: U7 e9 M
  28. ! o7 R3 V- _  S; w- [6 ?
  29. /* Header includes -----------------------------------------------------------*/
    1 y, P9 W  {5 D6 t+ u
  30. #include "CAN.h"4 x7 Z4 v- G% M1 _: v7 O& T
  31. #include "RingBuffer.h"
    0 e- x  N4 X  Q  g$ M2 @- F, @

  32. 8 g$ r4 d8 q- u7 x
  33. /* Macro definitions ---------------------------------------------------------*/
    * l: o' L) s2 t
  34. /* Type definitions ----------------------------------------------------------*/
    / ?$ b: ^5 P  z* v) O- N5 f
  35. /* Variable declarations -----------------------------------------------------*/
    ! j8 L) q- j6 B5 N6 c
  36. static volatile bool can1InitFlag     = false;
    0 C) Z4 M+ r$ ~0 ?
  37. static volatile bool can1TransmitFlag = false;
    ' u" |" ^5 z0 T2 O3 i) J3 U3 N
  38. $ U9 K6 _- k5 U6 q
  39. static volatile void (*can1TransmitFinishCallback)(void) = 0;
    8 a# s# S0 Y6 G" D  Y
  40. static volatile void (*can1ReceiveFinishCallback)(void)  = 0;
    4 t2 [2 H( L- ^+ t9 @8 l; j0 {( S& s
  41. 6 _. \1 H+ A" C5 e% D/ L
  42. static RingBuffer *can1TxBuffer = 0;
    & Q' u$ o! A: @" y3 R- m
  43. static RingBuffer *can1RxBuffer = 0;0 r9 W' R8 w  \% [& A( }
  44. ( f2 @0 E0 k. H0 z7 D
  45. #ifdef STM32F10X_CL
    % W. ]$ r# x" M0 m( \; D
  46. static volatile bool can2InitFlag     = false;2 {7 S0 P" Y0 M9 I0 J0 M. c+ j% n1 \
  47. static volatile bool can2TransmitFlag = false;
    : I. M$ d, e9 E( N$ ?

  48. 0 F/ ]% G9 H, ?. v5 M
  49. static volatile void (*can2TransmitFinishCallback)(void) = 0;
    / N4 G* _* m* e6 v; O* b
  50. static volatile void (*can2ReceiveFinishCallback)(void)  = 0;
    4 i. P& k. \) s
  51. ( o8 p* l4 k( `/ P- M
  52. static RingBuffer *can2TxBuffer = 0;
    ) _1 V! |4 o5 ~1 g
  53. static RingBuffer *can2RxBuffer = 0;
    ' A1 B9 k3 W9 v- D2 q+ D
  54. #endif /* STM32F10X_CL */* T" s+ N- C9 F$ G1 ?% k
  55. ( W! U) D( C& m8 {  H  a8 e5 O' W: y
  56. /* Variable definitions ------------------------------------------------------*/( N2 S, ^: N9 `- f2 V8 z
  57. /* Function declarations -----------------------------------------------------*/
    & w% X9 N' T/ y/ u; T
  58. /* Function definitions ------------------------------------------------------*/
    ) c6 |& H. E$ \! W$ m( H! L

  59. 3 Q3 v- @; z: C& w
  60. /**
      J1 i* }2 }7 R
  61.   * @brief  CAN configure.
    ( Q5 D4 W; Z5 @
  62.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.
    * L" k  v* I: Q# D; ^- E  ]* I
  63.   * @param  [in] WorkMode: Work mode.* [) M, o2 C/ X' ^2 v6 A
  64.   * @param  [in] BaudRate: Communication baud rate.; q0 k( P' ]7 W# l; c
  65.   * @param  [in] StdId:    Filter standard frame ID.
    . }+ Q  B1 r+ E( Y$ o& d  [
  66.   * @param  [in] ExtId:    Filter extended frame ID.% T- R) d8 V/ s- A+ t3 L: ^
  67.   * @return None.
    ( u$ g9 {2 ^9 J, v9 L$ W
  68.   */( g; d5 S4 ]3 d3 i# e5 S
  69. void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId)
    7 F1 H5 E9 h, U' J1 Z% |$ R
  70. {& H) s6 I# |( ^& O2 `/ |
  71.   GPIO_InitTypeDef      GPIO_InitStructure      = {0};
    7 w' m6 A) |' m& k' R$ z
  72.   CAN_InitTypeDef       CAN_InitStructure       = {0};
    * h+ L& }2 ~* A- f0 r1 p
  73.   CAN_FilterInitTypeDef CAN_FilterInitStructure = {0};
    ) i0 x+ U0 ]1 B  M, o) |
  74.   NVIC_InitTypeDef      NVIC_InitStructure      = {0};
    9 h" Y6 s' ~7 C! x) ~

  75. 3 A$ C3 S, i/ ~) ~
  76.   if(CANx == CAN1)% q( s( z/ M. r6 j$ d
  77.   {5 ^# N- J2 b! L! h2 ]7 L6 ?2 A# F) `
  78.     if(can1InitFlag == false)
    & `1 i6 z* h& B8 E: ~. V
  79.     {
    " T* \0 y) }$ G. S4 s6 e* u' ]
  80.       can1InitFlag = true;
    0 c7 _) X, y. I% l0 j# r

  81. . q! J# Y: l  z4 @7 G. `( f+ k/ G
  82.       can1TransmitFlag = false;
    6 X3 @2 \% r  a0 ~0 |7 _4 H

  83. 6 S( R: F& U# Q( E- e2 Z
  84.       can1TransmitFinishCallback = 0;
    8 H  ]+ @- f/ S; g. a
  85.       can1ReceiveFinishCallback  = 0;. d: Q; }( J6 C3 H) n% o0 _( s2 e9 g
  86. ! K3 M' @8 r2 F5 q+ y9 W5 f" f
  87.       can1TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN1_TX_BUFFER_SIZE);+ C- L; n- T5 q" c
  88.       can1RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN1_RX_BUFFER_SIZE);
      }$ F# _* B$ }/ ?
  89. 1 H  e' ^% |  a! w' ]6 U6 M0 H
  90. #ifdef STM32F10X_CL
    ! A! `# x2 ^: {: a
  91.       if(can2InitFlag == false)
    ' h; K2 x% r3 @
  92. #endif /* STM32F10X_CL */7 n  o0 [  A# q1 Y' n
  93.       {" B4 r& e' p; z. l0 K9 x/ ], r5 }
  94.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);0 {& i2 e8 p9 K
  95.       }: a1 P! @6 _! e3 Y/ @
  96. * b# o" R2 U  d
  97.       RCC_APB2PeriphClockCmd(CAN1_TX_GPIO_CLOCK | CAN1_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);
    0 y! G' F+ e2 r

  98. ( H  ]# |/ ~. S
  99.       GPIO_InitStructure.GPIO_Pin   = CAN1_TX_GPIO_PIN;6 c3 g4 k/ M+ [2 s
  100.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;) E" z  Q5 [* i* @. V, k
  101.       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    5 _7 L  _6 M/ n4 N' u
  102.       GPIO_Init(CAN1_TX_GPIO_PORT, &GPIO_InitStructure);4 ?: ^3 {9 E& O" z+ B8 b

  103. 1 _3 S" d/ S2 l
  104.       GPIO_InitStructure.GPIO_Pin   = CAN1_RX_GPIO_PIN;
    . y& f; c7 ~# z% Y8 t8 F" |
  105.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
    $ Z1 @" z9 ?0 Y" ]7 t6 L8 Q4 l
  106.       GPIO_Init(CAN1_RX_GPIO_PORT, &GPIO_InitStructure);
    5 _- ?& D+ s' s0 z

  107. $ ~9 s4 c' u  K7 k" p6 S6 u. f; F
  108.       CAN1_PORT_REMAP();$ X: K7 l  t6 K1 j' t, E; \$ e3 ]) U

  109. ! z3 L! |, ~% K% A7 X/ M
  110.       CAN_InitStructure.CAN_Prescaler = BaudRate;
    5 @4 i% w- A4 }( X1 K% J
  111.       CAN_InitStructure.CAN_Mode      = WorkMode;
    0 u/ f$ }0 a6 q/ {( B& Y
  112.       CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;
    # S( Q2 s6 R7 u" I* W. F
  113.       CAN_InitStructure.CAN_BS1       = CAN_BS1_3tq;$ O* J0 o; r. H; O3 n0 y
  114.       CAN_InitStructure.CAN_BS2       = CAN_BS2_2tq;
    " n) h* S" c) W, P- L
  115.       CAN_InitStructure.CAN_TTCM      = DISABLE;
    ( T* z% W9 g2 A- p% B, R
  116.       CAN_InitStructure.CAN_ABOM      = ENABLE;7 x7 i3 E& B% M8 T4 }" s: c. S- a
  117.       CAN_InitStructure.CAN_AWUM      = DISABLE;: s# w. X& w, r  Q& `  I/ f# ^
  118.       CAN_InitStructure.CAN_NART      = ENABLE;+ h( W  w: s% z) A- u
  119.       CAN_InitStructure.CAN_RFLM      = DISABLE;2 ^5 z# `2 U* M* K
  120.       CAN_InitStructure.CAN_TXFP      = ENABLE;3 O5 n% k7 F+ x9 F9 @2 X4 [
  121. * F; h1 _  _# V0 p1 b
  122.       CAN_DeInit(CAN1);
    3 B% e7 N8 D( n) f: h. `7 @
  123.       CAN_Init(CAN1, &CAN_InitStructure);+ M0 y& k) c6 Q7 `/ r5 t, r

  124. ' }; D1 t0 v. D" Q! k
  125.       CAN_FilterInitStructure.CAN_FilterIdHigh         = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);
    $ A0 b( }" g$ k* L7 y
  126.       CAN_FilterInitStructure.CAN_FilterIdLow          = (uint16_t)(((StdId<<18)|ExtId)<<3);
    . O% Y# }5 K- o0 h3 k
  127.       CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;( l! j; g. d7 t* f) f
  128.       CAN_FilterInitStructure.CAN_FilterMaskIdLow      = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;. {' \& G1 e" ]6 Z
  129.       CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
    $ y6 K* X! f: x* I, K( B
  130.       CAN_FilterInitStructure.CAN_FilterNumber         = 0;
    & V7 k9 o9 v7 o0 o- f
  131.       CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask;
    7 K" e/ t; j# c4 c  Z# l4 b+ ?
  132.       CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit;
    % f1 d) Q7 k: ~
  133.       CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;# U$ D2 ]+ G$ S# b
  134.       CAN_FilterInit(&CAN_FilterInitStructure);$ _+ A; C6 ]9 s7 i0 v) p  Q
  135. 6 \  t% B; u9 l0 n# V
  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 |
    , K1 a- n2 _! R* n2 Y' x
  137.                          CAN_IT_WKU | CAN_IT_SLK  |CAN_IT_EWG | CAN_IT_EPV  | CAN_IT_BOF  | CAN_IT_LEC | CAN_IT_ERR, DISABLE);! v" U/ B* |2 N0 {
  138.       CAN_ITConfig(CAN1, CAN_IT_TME | CAN_IT_FMP0, ENABLE);8 v: ?0 z! @: Z+ I. S1 U

  139. - l: Z  u' u4 K( P- y4 m
  140. #ifdef STM32F10X_CL* Z6 m! S$ ]1 ^) Y9 o
  141.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_TX_IRQn;7 r! C* N' l' y* T% v
  142. #else
    7 y0 \9 T6 f9 C1 L# w
  143.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_HP_CAN1_TX_IRQn;
    # M, X3 ^* {  f7 N
  144. #endif /* STM32F10X_CL */3 d: l1 d6 [* _7 w4 H/ x% n' P
  145.   L& r& {7 L3 \# e3 V/ ?& Q
  146.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;
    3 G* V$ W  |9 c8 h
  147.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN1_IRQ_SUB_PRIORITY;
    % C9 l, C- M& W) F2 y9 N: a3 h
  148.       NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;8 b# k  P/ U) h+ q9 V
  149.       NVIC_Init(&NVIC_InitStructure);
    0 I* b; Y6 m2 _. [# Q& |* A
  150. 9 a$ q* s3 S: i1 `. p1 `# c# Q
  151. #ifdef STM32F10X_CL
    " B8 `# r# C4 ^% M
  152.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_RX0_IRQn;
    " Y0 q1 t! `6 i% i% ~! u2 V
  153. #else
    ! p" _. Z7 J# A6 W" F+ U9 R7 b/ H
  154.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_LP_CAN1_RX0_IRQn;) L% K5 {% A$ V0 S" Y2 `% P
  155. #endif /* STM32F10X_CL *// z4 f' a" B1 M4 X/ t. F1 ]6 r% b
  156. 6 o; r/ @2 G7 ?/ \
  157.       NVIC_Init(&NVIC_InitStructure);
    7 M/ {% D2 e0 M) t; `9 D
  158.     }* t1 ?' _! t0 X6 Q: ?; p, C4 P
  159.   }
    : b2 p+ F$ a" x7 Y; z2 s% `0 e

  160. 7 c! j& G' ?6 u7 K/ i
  161. #ifdef STM32F10X_CL
    ) R5 B, \7 P6 n1 T8 @
  162.   if(CANx == CAN2)% _4 \7 d2 _  l* l
  163.   {
    4 \' N1 V3 f+ D3 \6 \) S
  164.     if(can2InitFlag == false); Y& g4 ?5 m$ l- H+ w2 ?  C( @
  165.     {
    8 \: I/ f( ?0 V1 z& A! t
  166.       can2InitFlag = true;
    3 t6 x2 m2 G4 W4 D7 H! M

  167. ) I: K5 W1 N( \* @6 T, _- m7 V
  168.       can2TransmitFlag = false;
    0 _& ^3 ~3 w4 P& c& b& q1 l
  169. - U, L* {' l. T9 n
  170.       can2TransmitFinishCallback = 0;. v& k( p8 a) a3 E4 m0 ]2 c3 V
  171.       can2ReceiveFinishCallback  = 0;- `: r- U+ j' Y5 h
  172.   L& `% O( T0 E$ K# t
  173.       can2TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN2_TX_BUFFER_SIZE);
    $ ^& _" B: R, d7 o1 M9 {
  174.       can2RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN2_RX_BUFFER_SIZE);& q  t$ ~' o; @+ X2 o& Q% c
  175. 2 z8 o) l3 I2 h) |1 v8 \
  176.       if(can1InitFlag == false)
    3 P- K' j/ \, ~7 t# j4 w
  177.       {* ?  s" a' b) z; j
  178.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
    % {- i9 \# \/ G9 f0 A
  179.       }
    * `; O- K! ^7 i$ U/ i5 x

  180. ) m8 K$ v6 w; \' `2 h! H) H7 I
  181.       RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);, W! M' i% K+ O! U. V( Z
  182.       RCC_APB2PeriphClockCmd(CAN2_TX_GPIO_CLOCK | CAN2_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);
    7 G- k( l1 r) l4 C" ?7 O$ k  N
  183. ) I  m4 ?8 i2 I/ k$ P- V
  184.       GPIO_InitStructure.GPIO_Pin   = CAN2_TX_GPIO_PIN;
    : ]# `/ l% J* Z- j
  185.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;+ }4 J/ Z2 n: g" q; ^; {  I% Q! M
  186.       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;% e. I, q) V1 k
  187.       GPIO_Init(CAN2_TX_GPIO_PORT, &GPIO_InitStructure);- O2 A. w# c5 T! H. J" ?
  188. % A' e; q; t) ^& c
  189.       GPIO_InitStructure.GPIO_Pin   = CAN2_RX_GPIO_PIN;
      ^+ m; I: I5 ^
  190.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
    8 W8 {- x7 e/ G( \& L1 B8 F+ D
  191.       GPIO_Init(CAN2_RX_GPIO_PORT, &GPIO_InitStructure);" a! i% ~  E0 v5 U1 r
  192. . `5 [& ~9 ^8 W. K
  193.       CAN2_PORT_REMAP();$ f1 q( D, f( f* I/ C* }+ ~- s; E  z+ d
  194. $ V+ i4 ~, Y; J$ B. M. k
  195.       CAN_InitStructure.CAN_Prescaler = BaudRate;
    , ]+ \% _3 y5 ~$ Y
  196.       CAN_InitStructure.CAN_Mode      = WorkMode;( y; Y3 Z8 N2 T* `# g# c1 m: Q
  197.       CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;
    . C) L" e2 A7 m4 G
  198.       CAN_InitStructure.CAN_BS1       = CAN_BS1_3tq;
    " f6 v- X9 `" {, L1 D' t3 [
  199.       CAN_InitStructure.CAN_BS2       = CAN_BS2_2tq;4 m3 ^! ?: T( r- v; Y( S
  200.       CAN_InitStructure.CAN_TTCM      = DISABLE;( x; n9 {  O) j4 }& Y0 s  \# A
  201.       CAN_InitStructure.CAN_ABOM      = ENABLE;
    & y( N, n5 p0 m+ V1 z
  202.       CAN_InitStructure.CAN_AWUM      = DISABLE;
    ) d. |' h4 n6 k6 D! L4 A
  203.       CAN_InitStructure.CAN_NART      = ENABLE;
    1 ?9 ^) X7 n" A8 v4 m
  204.       CAN_InitStructure.CAN_RFLM      = DISABLE;+ g6 g' C( E9 s3 F7 w
  205.       CAN_InitStructure.CAN_TXFP      = ENABLE;6 l! u1 t! x% t1 ?& r/ G! p
  206. , {. |0 A% \6 |
  207.       CAN_DeInit(CAN2);
    ; B  s2 I/ [, o
  208.       CAN_Init(CAN2, &CAN_InitStructure);2 r; ~: i2 {9 G( S

  209. 0 ]9 \! F3 k; |+ {9 A
  210.       CAN_FilterInitStructure.CAN_FilterIdHigh         = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);3 n6 ^) s0 I: ]$ i$ r5 k
  211.       CAN_FilterInitStructure.CAN_FilterIdLow          = (uint16_t)(((StdId<<18)|ExtId)<<3);
    & F# Q/ R+ j- V! y7 @1 ~; _! G
  212.       CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;- ?% g) ^- D0 ]/ V+ E% o
  213.       CAN_FilterInitStructure.CAN_FilterMaskIdLow      = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;3 u; F6 s: o1 b
  214.       CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
    * N! d2 ~2 ^2 O' Q- t
  215.       CAN_FilterInitStructure.CAN_FilterNumber         = 14;! I$ E) o# E5 f( `# ^9 y
  216.       CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask;
    + w6 s. ?3 q# w  h
  217.       CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit;7 J7 ]' p# j6 n2 Q% N  C0 V; o5 m
  218.       CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;
    $ m& J8 W9 r( N* c
  219.       CAN_FilterInit(&CAN_FilterInitStructure);$ D5 }3 }( Y+ t7 [- ^; M

  220. 7 o( R$ M0 Q; D- f  a, r  S
  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 |
    ' o: U6 f# c( X& B  I! `! J
  222.                          CAN_IT_WKU | CAN_IT_SLK  |CAN_IT_EWG | CAN_IT_EPV  | CAN_IT_BOF  | CAN_IT_LEC | CAN_IT_ERR, DISABLE);
    5 ?- h# s( n0 }5 A. C
  223.       CAN_ITConfig(CAN2, CAN_IT_TME | CAN_IT_FMP0, ENABLE);
    ) Y- F  M* Q0 h3 E

  224. 2 g/ ]2 Q4 G+ [& L; T0 ~
  225.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_TX_IRQn;" R9 y1 E; J$ d9 P9 d# V7 c
  226.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;5 m9 p) f3 d  b& V% P1 {
  227.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN2_IRQ_SUB_PRIORITY;* E( V: s1 D& ?/ a
  228.       NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;/ Q3 B# b% B: X) T% L$ [2 C& N" @
  229.       NVIC_Init(&NVIC_InitStructure);
    7 r8 g4 ^8 I4 F  E

  230. * A  H# }* {8 F+ f
  231.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_RX0_IRQn;
    " W! r. y7 Z" h* l
  232.       NVIC_Init(&NVIC_InitStructure);
    0 a5 o! k4 G  y. y: H
  233.     }
    + E* G1 r/ i$ C% z8 n' I
  234.   }
    . D" R1 B: i$ r% P5 H; t0 c
  235. #endif /* STM32F10X_CL */  @6 r9 F( ^4 y6 E8 C$ Q" r; C
  236. }
    0 }5 @# d* z+ h' I; \
  237. # F1 ^8 K5 V2 g. O
  238. /**, V: Q) I0 P* [7 L" r
  239.   * @brief  CAN unconfigure.
    9 i- O$ _( e% l; C; K. G
  240.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.: Q$ Q: l2 d' G2 m* S5 h
  241.   * @return None.
    . m; A2 T8 t$ q- N& j+ ^2 B
  242.   */
      a: M9 J4 v) h6 K4 U, |$ f# k
  243. void CAN_Unconfigure(CAN_TypeDef *CANx)
    0 S. N) b8 \5 k; t! _5 o
  244. {; e. e+ |& |* c7 u0 I0 \/ R3 J' F
  245.   NVIC_InitTypeDef NVIC_InitStructure = {0};
    $ M2 B' z" n. j3 x# y: F! U

  246. : S+ @: v+ b& l$ K6 l
  247.   if(CANx == CAN1)
      |7 L% Q" y2 O  Y
  248.   {) ^: u( A/ E. N! B4 P) z5 G. ?
  249.     if(can1InitFlag == true)
    * A" P9 a+ U8 e: f5 f0 W8 }9 |6 u( J
  250.     {
    0 w" g  E* l) i' J" }- H& {# ]
  251.       can1InitFlag = false;
    5 ]& E5 \! {  t7 J
  252. 5 w! e/ [" n. G3 H8 v: G& y
  253. #ifdef STM32F10X_CL
    ! X$ S% @. Z9 E1 i* n
  254.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_TX_IRQn;
    2 H+ m  }) y- q
  255. #else. c: O3 [7 h, Z$ j4 K
  256.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_HP_CAN1_TX_IRQn;
    , b& D! W! t0 i8 @( N" \, J
  257. #endif /* STM32F10X_CL */0 m' r( {* _2 V+ }
  258. 6 }% @) ]7 i2 R3 C! U" ]+ m7 T6 d
  259.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;& W* B7 ^9 s! J2 v
  260.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN1_IRQ_SUB_PRIORITY;- x4 X' m1 E! T; E- [
  261.       NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;7 _$ h4 y1 U5 c1 e
  262.       NVIC_Init(&NVIC_InitStructure);
    2 n( I5 D1 K! E2 _6 e

  263. 9 o4 z" k9 J9 L8 t, E
  264. #ifdef STM32F10X_CL; T  N* k9 W; R  V; g
  265.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_RX0_IRQn;
      d: S# v* N# _& g# Q; c
  266. #else, c4 c7 [. E4 M. _0 R9 ?( X8 U) D; R0 S
  267.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_LP_CAN1_RX0_IRQn;) ^- P0 N: w$ U3 v% S8 x8 @
  268. #endif /* STM32F10X_CL */
    ! A, v" i, \# \& O/ x

  269. 8 x6 P& m" p$ Y: t8 W. H0 ]& A' S
  270.       NVIC_Init(&NVIC_InitStructure);
    7 Q0 c3 `5 q+ D) E7 l

  271. ! }" |9 n9 @  S: X2 Q
  272.       CAN_DeInit(CAN1);1 [# n/ @0 r* S+ l) U& l

  273. 3 e8 s: B0 J7 ^( j, K+ W
  274. #ifdef STM32F10X_CL/ T6 V* ~( W# R# F) O$ m
  275.       if(can2InitFlag == false)6 _3 ~& Z% u  [' g6 j4 N6 B$ F+ G
  276. #endif /* STM32F10X_CL */2 O, U5 _7 j$ I" ], n
  277.       {, H( J! |9 Z; T$ l' {
  278.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);& k9 p* f  M; g( ~) Y7 J5 I; f
  279.       }0 c0 G# ^( a/ d) h  z

  280. / r7 |# C* H9 e6 y) R
  281.       can1TransmitFlag = false;
    ' J! b" Z8 @4 D# X4 i/ X

  282. , Z* `3 O" {. v
  283.       can1TransmitFinishCallback = 0;5 L9 ^$ d" {1 A* @5 T8 g2 K
  284.       can1ReceiveFinishCallback  = 0;
    : x1 \; C0 A) j, R, s* O8 S6 g! Y

  285.   Q: G! P, w: F, f2 n
  286.       RingBuffer_Free(can1TxBuffer);% p& v: r( a+ n% u8 v+ e
  287.       RingBuffer_Free(can1RxBuffer);6 d8 d4 T2 ^. J' U. w& e/ [/ B0 F, ~) N
  288.     }
    6 t" `1 }) V: ~6 P$ P
  289.   }
    $ F# u1 ~( _& r# U6 _! b3 I* |

  290. ) c% ]& a5 E. }7 H4 {
  291. #ifdef STM32F10X_CL- \# B* d2 F! o: a2 J- V
  292.   if(CANx == CAN2). s2 d5 A# K) b- W1 z
  293.   {, c( Z6 l9 K! U  K! h/ {, S
  294.     if(can2InitFlag == true)
    6 P% U( K, q1 R/ q6 R
  295.     {
    % x' E# K2 I% v) ]# h% K
  296.       can2InitFlag = false;4 U3 C9 ~8 s1 l- h1 j' r% ]

  297.   c# f! A  \1 z% Y# t, v
  298.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_TX_IRQn;
    ! N9 p+ t( N6 B1 @+ `
  299.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;9 Y0 g% q+ a$ J( {2 k' b& u
  300.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN2_IRQ_SUB_PRIORITY;
    + Y, U1 H8 B/ E) ^$ a
  301.       NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;" ]3 \3 Z: ~3 r6 D2 w
  302.       NVIC_Init(&NVIC_InitStructure);
    7 X7 p: F( U7 A: g; [

  303. & D/ ~4 ?$ M- Y$ O% |3 k8 @) H+ g
  304.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_RX0_IRQn;
    7 V+ b, x0 A& _
  305.       NVIC_Init(&NVIC_InitStructure);
      V" E3 X  K, R* P" Y$ @  K
  306. ; j2 l" Q7 ]3 t  T! X- V
  307.       CAN_DeInit(CAN2);9 s. w) i8 O9 {2 U* g

  308. # w. M; w1 W- r" U1 Z
  309.       if(can1InitFlag == false)
    : m6 C* q4 I4 y4 J$ E/ p: D
  310.       {
    # ]" h! |3 g& f7 ?2 ?, [
  311.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);& ?7 u" o( E8 L1 K: U5 ?: I3 V
  312.       }& b6 l# g) z' v+ X1 _! v
  313. . U  S- D. f0 f, @* q0 s
  314.       RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, DISABLE);
    - D. l$ a3 J% k3 z2 z3 S
  315. 6 c9 ], y3 z+ _; W
  316.       can2TransmitFlag = false;0 z4 c; z+ Z$ P) ]5 a" W4 W

  317. 2 X' b# ^8 v, c6 X/ W! f7 L# |
  318.       can2TransmitFinishCallback = 0;
    + L0 r: K& w9 P$ F' T, p- D
  319.       can2ReceiveFinishCallback  = 0;
    ' T% y; \  N& D7 j2 S
  320. " P; M9 U, O) W. v, O) [
  321.       RingBuffer_Free(can2TxBuffer);
    ' K' N/ {+ r! _; o4 ~6 {( T
  322.       RingBuffer_Free(can2RxBuffer);- T+ C: t, W. Q$ ~. L
  323.     }
    / q! I- y6 W+ h8 q4 ]. d. n: ^
  324.   }
    % K/ `$ Z/ W4 \! C" H6 V1 m* |  S
  325. #endif /* STM32F10X_CL */# t6 J8 s: R# U6 k( ?$ C
  326. }
    0 S/ S! X. [8 C8 [8 W4 Z. R7 U
  327. / g3 ?6 `& g% i9 b3 U
  328. /**! {( m- N5 m* G
  329.   * @brief  CAN set transmit finish callback.% M6 L' {) _( H5 o: c
  330.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.8 G1 ]. q  Y; P& M, e7 ^1 d9 M
  331.   * @param  [in] Callback: Callback.
    ) o& l+ H5 e8 _, W8 J) ^
  332.   * @return None.3 l6 [2 j& F' O4 J- W+ h+ w! t4 f
  333.   */
    + M+ M2 B* S6 N* U5 a
  334. void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void))) k, {# ^! W* P1 W  z7 Y) Q
  335. {9 e7 o8 P- S' F& M# X
  336.   if(CANx == CAN1)
    ( p& H: q4 G$ B: s) c
  337.   {; J7 H6 V0 I5 m$ L6 @; G
  338.     if(can1InitFlag == true)' V7 q  \1 m+ v4 d
  339.     {
    ! F2 M% c7 ~5 S0 p6 ?
  340.       can1TransmitFinishCallback = (volatile void (*)(void))Callback;
    / c8 I) K3 F6 b) m8 \( K* g' p9 R
  341.     }. ]4 h, j: T5 l$ H2 }9 w
  342.   }
    , w/ l7 x# G! o1 y! Y% p/ B
  343. ; Y" X5 o- A, n) w! m0 k6 L
  344. #ifdef STM32F10X_CL, N, j8 A. V% N
  345.   if(CANx == CAN2)3 v6 `. v; y; s6 r5 G2 [  R
  346.   {
    # B+ q$ X8 \( ], f6 \% P2 \
  347.     if(can2InitFlag == true)5 ?. y4 B( x! K
  348.     {
    / O; E7 a, T& y1 `
  349.       can2TransmitFinishCallback = (volatile void (*)(void))Callback;
    . ?- |/ y4 g% b) R1 ?' z
  350.     }2 v& s9 |- d) F, Y
  351.   }* c& @4 ~1 `2 l' r* ^7 d* R1 P# t6 d
  352. #endif /* STM32F10X_CL */7 M! m* t) S+ h7 z4 r; ~) ?
  353. }, I* J! I: z* V
  354. 5 G- j2 x+ [& z8 q# r
  355. /**
    % f: F" P' B! d- |
  356.   * @brief  CAN set receive finish callback.8 f2 x/ A- w2 c! ~$ m7 p$ D
  357.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.
    # {7 Q4 Z+ H7 Y' j  f, z/ Y
  358.   * @param  [in] Callback: Callback.
    8 W6 {. ^" m" h1 R$ T/ R
  359.   * @return None.  _; i7 B6 y4 S. g
  360.   */) J8 z) K" _+ d. Q
  361. void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void))
    / K, P1 @( d$ `! o! u& M& O$ t
  362. {$ z; B7 F) s1 w
  363.   if(CANx == CAN1)
    ' K7 B+ Y+ [1 p6 a9 H
  364.   {5 R4 z: b2 E6 o1 ^  x' h8 H* f
  365.     if(can1InitFlag == true)
    ( R6 p% c5 U3 j% O1 {" _
  366.     {
    6 w8 F! x3 E9 L; f7 L
  367.       can1ReceiveFinishCallback = (volatile void (*)(void))Callback;9 U* [+ |* p6 ?
  368.     }$ i& Y' V# |* E% Y$ ?1 d4 `
  369.   }* z9 y% J4 @! X0 G
  370. & i  g3 c9 @8 O% L
  371. #ifdef STM32F10X_CL7 x8 c  o* ~& F& a& I) ?9 O, _. a5 p
  372.   if(CANx == CAN2)# C9 _& X4 o; g+ u' V  K- B3 P8 s
  373.   {
    1 Y; P: h" P: g& |7 X" \5 r& D
  374.     if(can2InitFlag == true)
    * y: I. f& n( F/ ~6 Y) t
  375.     {
    & C+ _8 D0 P& R1 s; W# w' ^
  376.       can2ReceiveFinishCallback = (volatile void (*)(void))Callback;% f. f7 S3 K- _' f. a
  377.     }3 D% V8 r8 I8 c, ~% H7 m
  378.   }0 h$ B. E3 A' V$ a( {5 g0 U
  379. #endif /* STM32F10X_CL */
    3 v$ E. F/ n. ?6 ]$ o% \1 J* C
  380. }3 \# J' M- T9 I3 n; {- k6 r5 N

  381. ) V, Z) r9 _+ ]" F, o* @8 N
  382. /**! r8 \/ z! O" d6 u% m2 A
  383.   * @brief  CAN set transmit message.' \$ Z6 S! f7 ]6 L+ V
  384.   * @param  [in] CANx:    Where x can be 1 or 2 to select the CAN peripheral.1 a* ?% c. a; y9 _; p* s
  385.   * @param  [in] Message: The address of the message to be transmit.& D: X8 Z6 f/ N: H, B% J
  386.   * @param  [in] Number:  The number of the message to be transmit.% t/ N/ M. K4 Y, z! d
  387.   * @return The number of message transmit.' k7 W% A* F" V5 d% p* q
  388.   */- F) }# d0 u6 P. Z- _) O& E2 f- H
  389. uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number)3 M: e- T2 l. z  _; Q6 c
  390. {5 i( q$ B7 Q$ M5 |4 P
  391.   if(CANx == CAN1)
    8 Q; C% v6 e3 F" I+ B  j
  392.   {  d9 l9 J+ m7 G+ w# N! l
  393.     if(can1InitFlag == true)
    ! F6 W# G3 |, e4 K5 e4 T
  394.     {
    ; \. v! ~8 x0 D9 F9 O
  395.       uint32_t available = RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);
    8 O1 Z/ b- \+ Y% q8 |9 W
  396. . M5 m" E  h( @0 n# t- e
  397.       if(available > Number)
    / a4 f! J. H* f0 I
  398.       {3 }) f' |: t# K$ y6 y
  399.         Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);
    / o# I  _8 P8 `  U  `  I
  400.       }2 W/ ]/ [/ V5 H$ l- ?
  401.       else
    $ o7 A- W6 q& {" K& V
  402.       {3 K  P! ^9 H- ?! E& C# o' F' U. E
  403.         Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);
    ' J  E5 B% T, c$ r/ |
  404.       }: k) |4 V. n& [: ~+ G/ b6 h3 M

  405. ( p9 T* Q- I2 m! L4 W; t& d4 @
  406.       if(Number > 0). a# s, L9 ^& x3 I0 G4 s/ Z
  407.       {! M0 }8 A% j' m% d' X! O  y/ {
  408.         if(can1TransmitFlag == false)# w: x# ?4 v* Q" h4 C$ H
  409.         {
    & p/ J* v" a. i* v/ s# z
  410.           can1TransmitFlag = true;+ Y- x2 D6 K1 A7 H) }- a
  411. 9 _+ ]6 V- `: y7 ]# `9 A
  412.           CanTxMsg canTxMsg = {0};
    5 V$ V3 i% w$ x% e) b& I' k
  413.           RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg));
    9 H  _( G3 v. t
  414.           CAN_Transmit(CAN1, &canTxMsg);
    6 N. P2 @: M' Y+ Q4 g' M
  415.         }
    2 Q- I4 z- H3 Q- X7 }# A
  416.       }9 Q4 ^1 O# y6 m2 j
  417. / B$ q' a! @" x4 U& g: e: T1 M
  418.       return Number;% C: A! x9 x1 e( U+ i$ }
  419.     }* U7 s9 a  F' T" R
  420.   }5 g- x. B5 n1 x8 F& Y* z& Y
  421. 7 v5 o+ ~; A9 r1 D2 V  x
  422. #ifdef STM32F10X_CL
    2 s; p3 O3 R8 @
  423.   if(CANx == CAN2)
    7 L. {" o4 [8 ], I
  424.   {3 v* k5 t# b" b* [2 I/ v3 w
  425.     if(can2InitFlag == true)3 u8 {& z6 ?  ?1 Y% c8 D
  426.     {
    * K+ K) B. [" x
  427.       uint32_t available = RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);' v* {9 n/ b! S$ ?
  428. + _# \  Q& L8 K7 \
  429.       if(available > Number)
      `& w0 n+ m* j% k) t9 v
  430.       {
    ) I- D7 X# N* l$ b: q/ ?! B( o8 o
  431.         Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);% a) P% ]# D; ]2 X8 l7 u& j3 V
  432.       }
    ! s" d3 |6 V$ t
  433.       else
    / `6 ]( r) ^) [2 |# E4 b
  434.       {
    0 I: t* J$ i" O2 b
  435.         Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);
    . E3 t; {+ U7 _; O  i
  436.       }
      [" F2 J0 R8 o- N
  437. ) D2 b- V  R! k2 o  C
  438.       if(Number > 0)
    ) d) G5 V' _' y1 u
  439.       {
    # ?; J6 w; {+ R1 P/ p5 j( l4 T
  440.         if(can2TransmitFlag == false)
    8 H& P0 `1 W3 X6 l2 B+ X
  441.         {
    8 ^) c1 Z) ?* v8 R
  442.           can2TransmitFlag = true;
    3 F4 \, `7 p( O9 ~* f! H
  443.   S0 \" ?; h' [2 h
  444.           CanTxMsg canTxMsg = {0};; b8 |2 n9 j5 n) O, V1 s+ ~8 @
  445.           RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg));+ L% N+ B& j+ c/ y
  446.           CAN_Transmit(CAN2, &canTxMsg);
    0 z0 B; L. H" ^0 i% @5 y
  447.         }
    - G3 H7 |, q% S* ~
  448.       }
    $ A! n/ J$ x  p0 J

  449. 7 s0 ?: H, m9 {- V7 b4 J, e% X* L9 }3 }
  450.       return Number;
    2 ^2 {$ @8 [( G* }+ D) M$ R7 x
  451.     }
    # {8 B# V% `/ k& J6 x, i
  452.   }
    . @9 Z  A. s: H! f3 j
  453. #endif /* STM32F10X_CL */; d- L% ^& S, V& |0 s; @
  454. 1 m8 l  U6 L4 O6 h7 W. Y
  455.   return 0;) W0 ?+ Y9 [. |) l. P* Y
  456. }
    0 |- }+ X* _0 K* Z8 P$ M, H1 G) J

  457. / {! Z3 V. s" d
  458. /**
    7 t% ~/ z+ z; _+ B# {  p4 W
  459.   * @brief  CAN get receive message.# }8 {$ b. `4 z9 u8 K/ _2 |
  460.   * @param  [in] CANx:    Where x can be 1 or 2 to select the CAN peripheral.
    0 H, q" K! T& i7 b5 |4 T
  461.   * @param  [in] Message: To store the address of the receive message.: Q$ ?) ?- t* \/ v) U9 s9 r
  462.   * @param  [in] Number:  To read the number of the received message.- v* @4 Z% H# v& l# u
  463.   * @return The number of message obtained.3 W  H! U+ Y6 {& z
  464.   */' @" V- M2 u5 A8 k6 b: e  |5 j
  465. uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number)
    ! g- r) Q4 ]8 J
  466. {+ D. A% E/ l5 s5 N; b0 ?
  467.   if(CANx == CAN1)
    ( r' I. D( N- r$ Z( v; Y
  468.   {/ l( {/ {% Q3 u- }) l, }
  469.     if(can1InitFlag == true)
    . z* P& ^* k6 m! X" y6 Z1 L
  470.     {
    " Y, d. T* l/ z! o8 N% Q
  471.       return RingBuffer_Out(can1RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);9 y; l0 i$ @0 G- W. y2 o
  472.     }' ^9 b# f7 s% @% _( x
  473.   }; J2 X+ W8 z6 W. ]
  474. ! G5 `7 f) n0 m. U" ~( N! w# ?
  475. #ifdef STM32F10X_CL
    6 j  h7 V7 ^) L, y; O7 _
  476.   if(CANx == CAN2)
    2 o  o2 z( V# D: K
  477.   {
    9 z9 k9 G- C: P9 v) m) V
  478.     if(can2InitFlag == true)* t8 R( `! X4 ]+ P2 `# r
  479.     {
    ' ^1 e$ V2 [  \1 a3 D7 y
  480.       return RingBuffer_Out(can2RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);
    . ^  R0 a1 |$ r# }3 @* _
  481.     }3 R* t9 F# d/ [: W5 @- F
  482.   }% M. o1 m- L, z1 V4 x' g0 \- {; p* |
  483. #endif /* STM32F10X_CL */9 z& M1 C/ C& E5 _/ q/ o

  484. : b( @5 c+ u2 w9 E" G9 f
  485.   return 0;
    ) D4 ~& }* e8 s: ?
  486. }8 o4 |5 L5 @, z3 Z: Q% t/ H
  487. 8 R2 H  n2 m' p7 f7 [
  488. /**- I, X4 A3 n& |
  489.   * @brief  Get the size of the CAN transmit buffer used.
    % |7 q: _" a8 m
  490.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
      |+ K* k- |3 ^8 o  b( R
  491.   * @return Used the size of the transmit buffer.
    $ o( q) S1 M1 j) ]* R( X* x
  492.   */0 a, G. F! B" Y  m
  493. uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx)
    ! J% \# x: w! _! X
  494. {6 q9 _" S0 \+ R# I
  495.   if(CANx == CAN1)
      Z/ Q+ u& U! S. A7 q( W. T4 I6 v" m1 W1 B& k
  496.   {
    : o' P+ q) S( p: U7 w  P+ u
  497.     if(can1InitFlag == true)
    $ o% e- n; A7 Y: N( n) A
  498.     {
    ! L' b' E6 [5 x9 F) c& d
  499.       return RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg);# u/ h# J: x* y3 i' V) ~) A& o3 Z
  500.     }
    , L$ ~1 q- B$ [3 k* |# h& @: }
  501.   }4 S) g' P0 I: V7 \+ e( n0 L) r' _

  502. 9 b% y/ A: F1 Z& I
  503. #ifdef STM32F10X_CL
    4 }, c. U, k6 e/ s' H
  504.   if(CANx == CAN2)
    1 ]: b1 q' L1 K
  505.   {' G, b4 Y/ R' J" o" o* [& g+ M
  506.     if(can2InitFlag == true)9 I0 V) l* l3 n/ z$ ^: M$ n3 {
  507.     {
    " y. j: s% \+ S7 Z7 Q5 V
  508.       return RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg);
    ! f& A1 {( i, \7 A
  509.     }
    ( Z7 p2 L) s- G( R+ e" G# B
  510.   }
    . h+ u' o+ Y! A7 ~
  511. #endif /* STM32F10X_CL */) |" X: T: p# r  H9 K- k0 v+ x6 J

  512. ) G8 D3 @1 d1 Z1 I$ ]2 T
  513.   return 0;
    5 }, U1 c) s- S" O( q7 c
  514. }# l. k; d1 Q; h  B# h" a
  515. % [* P2 V  |9 ], g' ^# Q' p
  516. /**$ y( }! u+ N" f4 i
  517.   * @brief  Get the size of the CAN receive buffer used.! S# F( R* N. y  g
  518.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.1 R7 p' S0 w4 C: r. G
  519.   * @return Used the size of the receive buffer.
    , P$ w! f$ D' m' Q  I; _# ]  I
  520.   */
    ; K4 B5 R# M1 z! G% T
  521. uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx)# ^  u  g3 t' i3 z0 I* z* l
  522. {! L/ @7 O9 c0 S" W$ X0 f6 m
  523.   if(CANx == CAN1): X# I, @  E, b* C' w0 Q
  524.   {
    , \) E0 f6 o  C5 V
  525.     if(can1InitFlag == true)
    " z% `9 s) |: ~" F" L+ I
  526.     {# m+ O. o% K9 o) w( N! m
  527.       return RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg);
    + [4 E7 x5 ^0 L/ s- o
  528.     }
    ) |& C* H1 j* Q
  529.   }
    # k2 d' s; ], N0 n& u& [

  530.   `, ]; O5 E( m5 ?
  531. #ifdef STM32F10X_CL: V! V5 `( u8 U0 L9 |/ a
  532.   if(CANx == CAN2)' h6 J2 J$ m1 H% q
  533.   {% b. A& L/ ]$ }8 G, @
  534.     if(can2InitFlag == true)
    1 z. ~8 o7 l7 h
  535.     {, b5 q3 r) D3 G& _& o  ]6 i
  536.       return RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg);
      P  V8 k1 [! k# @+ K9 g& J3 k/ s
  537.     }
    7 P  |5 q' p1 s
  538.   }
    & F6 f3 t1 ?, _+ y) Q
  539. #endif /* STM32F10X_CL */
    - o" ]1 j) ]* W6 O/ _! s6 F& c: ~

  540. & w8 O, E! P( G$ z  X$ m( u5 o
  541.   return 0;
    ) \$ B# x+ H* i: ^) z+ A- H
  542. }
    ' s! |2 ^8 d9 }% S8 P2 h  ?0 M

  543. ( H7 f" ]! v0 k# h' c* G( @$ z
  544. /**, J" k: q0 v% z: o" q1 Q
  545.   * @brief  Get the size of the CAN transmit buffer unused.
    5 ?4 I5 X7 y0 H" o; t% ?9 x3 ^
  546.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.3 n! y$ l$ J9 ?$ V1 U
  547.   * @return Unused the size of the transmit buffer.$ ^6 _% k" H% u. \" T# h4 o; `
  548.   */' C7 w9 L- z5 ^$ X( q' \4 t
  549. uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx)
    ' w: Z$ ^9 H! i9 P* {% d
  550. {
    ( g# i. E% t- H) ?5 j6 r
  551.   if(CANx == CAN1)
    / `$ W* L1 ~6 N4 j% A) l
  552.   {
    0 E, l! Y+ N4 T- y4 g: y: {
  553.     if(can1InitFlag == true)2 ~$ E! z3 F' Y: ]
  554.     {
    1 `5 [; o- q/ i/ K5 i
  555.       return RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);
    # U8 W% `# _' G- v$ S1 ~' F- [" U% m
  556.     }
    # Z! `! E6 p6 a  A$ R% G9 b
  557.   }( u' A* G% ?4 `3 E# U' D, v2 \- w
  558. / D5 [+ d% K; D! ^! [+ Y3 m1 Y, L
  559. #ifdef STM32F10X_CL
    2 c" i7 K; b- U7 Z6 m! X4 g
  560.   if(CANx == CAN2); T* b( C3 S" z' s$ @8 ]
  561.   {5 o; y* [4 E4 q. t
  562.     if(can2InitFlag == true): F( u  w1 P' B$ y3 w- o/ `: J
  563.     {
    # V$ E6 {, R' A, z6 |
  564.       return RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);! l+ t  J- L. ^; L4 g3 k+ Z$ I
  565.     }
    " _: }3 j/ `( H: w# q
  566.   }  S0 G& E( z% A$ q3 S) J; @5 x
  567. #endif /* STM32F10X_CL */
    - J) Z5 D  S) a; A' r9 }0 j  y
  568. ) w4 H+ j9 x9 ]6 Q! _+ J! B
  569.   return 0;+ q; k  p. s: h) R1 l1 p; K
  570. }- R5 o! g) Y2 K1 o6 _

  571. ) {9 {! u! w: q2 p9 [
  572. /**. d- L; b% j5 Y
  573.   * @brief  Get the size of the CAN receive buffer unused.
    7 o' f: X0 `, s
  574.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.2 K! O! w+ G- n0 ^
  575.   * @return Unused the size of the receive buffer.+ W! ~4 B, t9 N$ X: A+ \' z" C
  576.   */3 I/ `% a( i) G) R# Y: S3 Z. D
  577. uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx)5 X4 N$ F) x: M! M! K# q; X
  578. {- S- T( n2 `) V$ v8 n4 O. E4 s
  579.   if(CANx == CAN1)8 }& g1 n4 `( }, X% {) t+ H
  580.   {+ T- M+ x$ q6 P  N/ r  X8 C  w
  581.     if(can1InitFlag == true)% v- U7 F2 @* h+ p/ y5 @6 y$ y
  582.     {+ ?$ Y  S+ X2 ^
  583.       return RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg);" t: n. Z. ^4 ^
  584.     }
    : d' U+ Z$ N  \: |' r4 u& s1 [
  585.   }% @0 f5 ?; {: q! q) A

  586. . R8 r8 S- ?2 {
  587. #ifdef STM32F10X_CL' ~$ r( b. h6 ?0 j( g% X8 B. \
  588.   if(CANx == CAN2), x/ k0 e2 v2 G7 C( _( k
  589.   {& O7 W4 k' K4 |$ R2 @5 K0 Q8 o
  590.     if(can2InitFlag == true)
    9 `# L  g4 i' Y) T
  591.     {- D6 r' m5 r% g3 p
  592.       return RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg);
    / s" M' V6 s9 j! J4 S9 U+ @0 U
  593.     }- s$ z# \% K2 |8 R; v) M2 u
  594.   }9 K5 S& q! Q+ t* M% p1 X
  595. #endif /* STM32F10X_CL */1 ^& Q7 E- p  _8 [$ V

  596. . W2 O  S! F+ K$ J4 q
  597.   return 0;
    : l5 O5 m  V! u3 G, G$ k/ r( {
  598. }* e! i8 j9 U/ F( L' m

  599. 8 ?. X6 ?1 v: g8 k
  600. /**2 s: `/ A0 L$ N/ {: E9 X* F
  601.   * @brief  Is the CAN transmit buffer empty?
    ( e8 d* i- p0 o+ A  L3 l1 R9 Z
  602.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
      D, p1 u. C7 Z
  603.   * @retval true:      The transmit buffer is empty.5 q+ H3 y' C0 a& ]; ]) V
  604.   * @retval false:     The transmit buffer is not empty.: V' V. Q5 r) o+ _3 N
  605.   */
    $ g% M5 n4 P7 r8 M$ v/ N) W7 n
  606. bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx)
    6 n) f, V7 W* ]. ^4 U  T
  607. {9 V. |4 n% F6 z$ Z( w3 V3 {
  608.   if(CANx == CAN1)
    - }& j5 L9 [$ `
  609.   {" |* q5 i* a( v! T, I0 A. {$ L9 c
  610.     if(can1InitFlag == true)* ]6 x2 X) {7 h9 P- x  R5 }5 `6 {
  611.     {
    7 M! R$ F9 R! d$ ~1 q( I5 b2 D
  612.       return !(RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg));6 m, V6 Q2 A4 C5 t3 a/ h& j+ y: D+ B/ E
  613.     }. S$ e8 l% j; z- f' W, |
  614.   }
    7 f2 V3 b! J0 k3 z
  615. ) T/ Z5 a4 H  o! H
  616. #ifdef STM32F10X_CL1 t5 y( I1 o  {7 H2 `' O
  617.   if(CANx == CAN2)
    $ s6 ?% _! y. C% f
  618.   {! A' D9 D; Q( G- {. G
  619.     if(can2InitFlag == true)
    $ e) R- `4 E5 D# ~+ Z
  620.     {
    * g4 r3 T- W8 z0 ^: ^
  621.       return !(RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg));
    5 ?( r7 X1 r# j+ J4 U8 a
  622.     }
    4 N7 B- z  F2 U  a
  623.   }
    $ l/ j% h4 `9 [
  624. #endif /* STM32F10X_CL */3 T  \& N8 H! F1 ]9 N* f7 p& O  }
  625. * R2 E1 S$ X4 a4 P- U
  626.   return false;
    , B/ S8 p4 I4 G" S' Y
  627. }
    6 C% y2 l3 _; a6 i
  628. ( k+ z' a9 t- n+ ^# G, z! k8 |
  629. /**
    - ^4 _% e" T: P6 X. X5 z; E
  630.   * @brief  Is the CAN receive buffer empty?. U* w, K% T/ x) n* @) X
  631.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    6 \' |! r( [* D! P
  632.   * @retval true:      The receive buffer is empty.7 X4 I! O2 C* T- W4 ?) B
  633.   * @retval false:     The receive buffer is not empty.
    7 C( ~: k" \% [; F5 D5 G0 k+ ^
  634.   */. e' G3 Y/ P, e6 r$ h5 `
  635. bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx)  v, [8 V; p+ i' ~3 w1 G
  636. {
    + O, T1 ?. b2 j0 {/ F
  637.   if(CANx == CAN1)
    0 x$ S% [+ ?2 @( S# _; f
  638.   {
    - [6 \- W2 T6 h! ~) Z8 u
  639.     if(can1InitFlag == true)
    ; D, c' \$ b0 n1 C% y) |5 U
  640.     {7 }. M# G6 X! |
  641.       return !(RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg));( V& a8 Y  t- q4 I& ]9 A; B2 T4 |
  642.     }# X0 T/ r9 S) X8 p4 ]% d
  643.   }
    3 ^0 M0 ?+ ]+ M3 ^  r; M0 ^

  644. 1 X! v! T7 S# @1 `
  645. #ifdef STM32F10X_CL
    & [9 }) Z# u2 q! w& ]; w
  646.   if(CANx == CAN2)$ D8 K; N6 j* ~3 r6 U- }: d8 r$ U6 D
  647.   {- x7 \+ v2 c8 H8 Z
  648.     if(can2InitFlag == true); m2 d. A! L  k  _0 k6 e7 w$ D2 Z: c
  649.     {
    # i/ S" \* G2 F3 C2 u8 a
  650.       return !(RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg));
      l" F$ R; g, G
  651.     }* W0 w' Z, O: j+ P2 t- y
  652.   }6 u0 n( I, U6 F' I& E
  653. #endif /* STM32F10X_CL */2 B# k4 Z4 D5 R7 k
  654. # g2 G0 s9 T0 }( f. M
  655.   return false;* x1 ?6 z2 y  T$ P3 M
  656. }
    , [' g; o# Z8 C, ~8 P2 |( J" \$ a
  657. / T& p* Q9 Q+ h5 ?
  658. /**
    " c& a( }# |# U7 F- A. k
  659.   * @brief  Is the CAN transmit buffer full?8 j& R: Y) x8 l) U# T/ y8 `* Y
  660.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    " x7 B+ `) x8 h: ?) v
  661.   * @retval true:      The transmit buffer is full.* V( z" ^# s+ }. O0 b2 z5 Q0 G: e
  662.   * @retval false:     The transmit buffer is not full.1 C9 f" Z) e/ w
  663.   */( g" I9 Z, U* A% n- s. g
  664. bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx)
    0 V8 R8 ~! `. S; Z  \, @
  665. {2 v6 M# @1 x0 T# H
  666.   if(CANx == CAN1)) u8 T$ a, h; S/ d# S! g6 Z
  667.   {# @2 x. U1 Z' W' Z' `
  668.     if(can1InitFlag == true)7 I- f6 W7 X, {+ l; O
  669.     {
    2 L# J% F% o  `) Z7 B; S" g! W3 \. D
  670.       return !(RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg));
    3 ]% n; G8 e6 u# R" i; z/ A
  671.     }, l9 }* o* N# N. t6 a5 l4 P4 A
  672.   }, Z& w# g: |% t7 [
  673. ' a" t9 F" w# B" ?
  674. #ifdef STM32F10X_CL
    - ~8 a2 M; G! K- k1 ]6 h
  675.   if(CANx == CAN2); r) n2 `+ V% B) k/ I# z
  676.   {
      R% V: x6 @! {8 H$ z' t/ v
  677.     if(can2InitFlag == true)$ y. _: G9 @2 Z+ W; r. d
  678.     {
    + w- s0 V' ?- H* M
  679.       return !(RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg));
    ! _5 ^' a1 r) Z: I3 C
  680.     }8 C/ o4 _. l. m5 W+ n( [$ R
  681.   }
    2 l6 c  T4 T) b' v6 m- q0 v5 ~
  682. #endif /* STM32F10X_CL */
    3 r$ x. L) t7 t
  683. # W5 P. O( _$ V. b( q5 s$ n
  684.   return false;4 ^7 O# z4 s+ D0 A: i5 `
  685. }
    2 B( h) l: [5 ?" c6 @, t

  686. - N* a: \  {; ]
  687. /**
    4 C# r! J" m* m' y
  688.   * @brief  Is the CAN receive buffer full?7 {" U6 C  b$ D; F$ Z% k/ p
  689.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    $ L6 R: e" ?9 w2 j# G$ d0 T. K! Z% o
  690.   * @retval true:      The receive buffer is full.
    / Q: U' N! y0 G: O, _
  691.   * @retval false:     The receive buffer is not full.+ O1 b. V0 t. x  g+ N
  692.   */
      q4 U, b, ?- i
  693. bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx)
    . B5 k% M  J/ N' Q  Q
  694. {
    " X6 V( J& E0 `, }) a: O) m
  695.   if(CANx == CAN1)
    4 c& s  c% U# Q0 ?+ a# f
  696.   {) @& Y. ^+ b: a( C0 J' c
  697.     if(can1InitFlag == true)" P$ k. N) ?6 |' A' N. y2 K
  698.     {' @! D. q: q% c
  699.       return !(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg));0 P1 Q! y$ M; u; H8 j# V
  700.     }
    ! s) [- i6 d$ d$ o
  701.   }. H7 ~6 _2 J/ c# f

  702. 2 N/ q: R0 y4 `  [
  703. #ifdef STM32F10X_CL
    8 o3 E- b4 _8 b3 t5 W7 p
  704.   if(CANx == CAN2)* y% e2 v/ z2 s/ K
  705.   {) l& X4 G8 o% |+ z
  706.     if(can2InitFlag == true)* _: _5 `& @3 X7 x- J8 O2 v
  707.     {
    # H$ h2 e! _; z$ {
  708.       return !(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg));2 F$ J" s- @7 t, t" E6 e0 F: W
  709.     }/ t0 `7 J* j9 o8 a
  710.   }8 V) y: L0 `; l. w$ {/ g  e+ X
  711. #endif /* STM32F10X_CL */; m! k) r% x* M) H: O: z) N9 s2 Z. _7 U- ~

  712. 6 d1 W& F# \+ F& U
  713.   return false;( O6 h, p- G: H0 e9 ?5 E
  714. }& `/ ?) B: K/ l
  715. . B- @; R5 ^  ^1 `0 r% g# m6 j' r
  716. /**4 q" w+ W: A3 q8 R$ q
  717.   * @brief  Clear the CAN transmit buffer.
    8 ]: j( k3 y1 ?
  718.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.# [' x; h' h. u9 i, ^# X" }
  719.   * @return None.
    # p" q% l+ P; f, `- `
  720.   */' r+ s8 a* \% b7 y$ a. Z
  721. void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx)
    8 f* @' u5 s! M- b
  722. {
    ( i7 q, @) [5 E5 \0 l) W7 x' X
  723.   if(CANx == CAN1)$ r# m. C# r) k; P# @* Y
  724.   {4 ?5 m- r3 o8 [) b
  725.     if(can1InitFlag == true)+ p- ^  a& h+ n5 ?+ E$ Y
  726.     {/ G1 w# d) y7 j* S+ m  z
  727.       RingBuffer_Reset(can1TxBuffer);( y# G* s, u* d+ ~* Y$ c
  728.     }! w5 E0 K7 \) T; k, }9 J- @
  729.   }
    . t# \0 E& c; p5 }& b4 |7 B

  730. $ w  K* a0 l, s; U6 E  l) B9 W! @
  731. #ifdef STM32F10X_CL
    . Y5 _" A. L$ D2 n2 d
  732.   if(CANx == CAN2)
    , W$ w3 n3 n! q) t* z
  733.   {' \, p  M2 H3 J
  734.     if(can2InitFlag == true)
    + e9 O$ w0 s2 G* O1 Y
  735.     {8 d/ Y5 a  }" J  H
  736.       RingBuffer_Reset(can2TxBuffer);! l8 V; s: F) l9 p9 }4 _. ?0 f
  737.     }' r, M: t( Y9 B
  738.   }5 T# @$ b9 j! f9 Y% Z
  739. #endif /* STM32F10X_CL */
    # a" P6 Z& w7 C& G/ R
  740. }. g  P  N+ T* Z
  741. 1 V# q# D4 l: X/ L( |: U
  742. /**
    ! N: S; k$ r0 {; k) _6 i' I, s
  743.   * @brief  Clear the CAN receive buffer.' E' [, Z" J  q4 f: _5 W
  744.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.* l7 p6 C% R% H
  745.   * @return None.9 p' j( i3 i& `" y
  746.   */
    3 B+ K; Q* [3 ?% [  Y: [3 x  K3 h
  747. void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx)' H3 N4 Y5 k0 Y  o7 h, H: {
  748. {
    , O# o4 J9 J4 P' j$ }6 T8 Z2 K
  749.   if(CANx == CAN1)
    ( l! a" H* [+ D& {; b, h# ^  G
  750.   {
    - ?7 t' p2 w9 p( k/ z1 g0 b
  751.     if(can1InitFlag == true)# J( a& R( f/ x! w, X
  752.     {8 ^6 `" J, M4 |; Z5 h' j
  753.       RingBuffer_Reset(can1RxBuffer);* k! y1 T! K0 v, h# z4 x, F
  754.     }  c6 R, y  V% L8 v! m/ B
  755.   }
    , \9 [8 W' h( m; h, g

  756. / a% R; @" s$ r: _  g
  757. #ifdef STM32F10X_CL5 K( m- q/ V% U, @& @8 \% C3 [- A; y
  758.   if(CANx == CAN2)
    5 s6 Z9 A# h. j5 Z. }: R
  759.   {2 h5 a: H5 f' @  c8 @
  760.     if(can2InitFlag == true)
    $ W2 H" B) W( q% h0 E2 P! U0 B
  761.     {' [6 m7 W5 Y3 c" I( w# O* Y6 w+ E
  762.       RingBuffer_Reset(can2RxBuffer);
    6 S4 M, G' p9 p+ h. p) z0 X* i
  763.     }& m* w0 `  ^; g& r
  764.   }
    - H  [9 b8 w8 V# W% N
  765. #endif /* STM32F10X_CL */! F) G: q) v; S# ^2 ~
  766. }/ `4 @1 v$ r! R* S9 A

  767. % V) |5 a6 W/ ]  s, v: M  t8 p. H
  768. /**; E; V7 A  i, d* m* ~. i
  769.   * @brief  Is the CAN transmit a message?1 `: _7 t8 |% I/ p6 [6 m9 a
  770.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    - `/ N9 l1 E4 q
  771.   * @retval true:      Is transmit a message.- L8 V( \7 Q; {$ g- h
  772.   * @retval false:     Not transmit a message.) \5 H8 L  ^* d& H
  773.   */2 c7 Y4 D; b0 l+ J9 o
  774. bool CAN_IsTransmitMessage(CAN_TypeDef *CANx)$ q( m; \" g( J" o. c: j
  775. {# P; b8 f2 r  Q6 D
  776.   if(CANx == CAN1)
    : U9 V! W6 {7 W4 b) P6 p# H
  777.   {
    $ T5 a, s1 ?; G* A% m$ B+ w
  778.     if(can1InitFlag == true)
    ) m; H0 ~# d; e
  779.     {
    ; {' d) w4 Z$ g
  780.       return can1TransmitFlag;8 s) o! v5 Q$ A% o8 E3 g4 d
  781.     }
    ) z9 z* Y3 A2 N: z* \. r. x3 B; r
  782.   }- z2 {9 |. ]0 L5 |" R+ Q

  783.   p% [7 E1 Y, X0 m2 g/ k( ~
  784. #ifdef STM32F10X_CL
    9 q1 O! q; y# a
  785.   if(CANx == CAN2)2 A! l0 E. }/ y  E4 b3 g; \, l9 u
  786.   {& K+ t$ k3 {1 K' ~# o: }: R, d
  787.     if(can2InitFlag == true)
      M$ p- N  i5 ?& E2 S
  788.     {
    $ A0 n1 F) u) }6 k
  789.       return can2TransmitFlag;
    6 R" b+ ]0 |8 J' B: i) w
  790.     }* P/ h' w# |3 W) g; n8 v, |
  791.   }
    $ r: s0 o* Q0 e0 u; C
  792. #endif /* STM32F10X_CL */* O* \/ J3 |) [5 J5 N1 J* {) q

  793. $ r$ P6 Y  P2 U3 c7 i" T3 N
  794.   return false;
    4 l- m/ n) O1 t+ i% M+ y
  795. }
    / L3 l8 e! J4 x4 I" g* Z7 F9 g

  796. 2 l. r( i/ R! \6 M1 c- m' R
  797. /**  I5 F. t2 m1 O
  798.   * @brief  This function handles CAN1 TX Handler.
      e  b) G! L% D& I; f
  799.   * @param  None.% J2 B3 b* |* E; w6 p- Q
  800.   * @return None.. l$ Q1 S: v( o
  801.   */# n3 i( l/ s6 D% G6 ^+ t1 T2 x, k
  802. #ifdef STM32F10X_CL3 y: q- E+ N) x8 y7 D
  803. void CAN1_TX_IRQHandler(void)5 B! {' {) z) P8 ?3 h
  804. #else  Q: Y6 [- s/ ^: \) u
  805. void USB_HP_CAN1_TX_IRQHandler(void)+ P4 f4 L) q) x( |8 C7 z; h! W
  806. #endif /* STM32F10X_CL */; T( G! n5 Z! |8 C' A; T& h
  807. {
    $ g; \9 l4 ?* M, `
  808.   if(CAN_GetITStatus(CAN1, CAN_IT_TME) != RESET)* q5 G, @! u8 R1 Y. c1 E) E
  809.   {
    , Q& D* N  w8 y- O& @( p
  810.     CAN_ClearITPendingBit(CAN1, CAN_IT_TME);
    8 g: P! `# u) J0 C9 }  s

  811. * R5 ^. p, R3 m: y0 R* G
  812.     CanTxMsg canTxMsg = {0};" @9 p" U3 u- E( C* u
  813.     uint8_t  number   = RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);
    ! j2 E5 d8 Z2 f/ _" q. {
  814. : C" V- \) A$ b3 }4 P
  815.     if(number > 0)' w/ x* Y. |3 g. X5 l
  816.     {# w7 P/ N& A; I8 n+ B4 v0 g
  817.       CAN_Transmit(CAN1, &canTxMsg);0 C+ r2 S, M- l# `/ P: {
  818.     }
    - ^$ a" M# g( ]. G
  819.     else
    & S( @* Q$ t# _- d* y" E
  820.     {4 Z1 D$ ~/ T9 {
  821.       can1TransmitFlag = false;5 z8 X; `) P4 E3 U

  822. 6 _5 L- _: [" m, x
  823.       if(can1TransmitFinishCallback != 0)
    8 o& C7 x4 c! T3 k" X
  824.       {
    * b1 h% A" A4 f" ^9 q( i" w, j
  825.         can1TransmitFinishCallback();
    9 E4 O8 \' W& B! I+ E" V. r
  826.       }
    6 k) E4 ]! g" T% X8 j  |
  827.     }& Y( N! V  [4 m& J8 L5 O
  828.   }
    # f3 m7 B  t& X2 S9 [
  829. }! {. [: B" D  X  U3 R5 b4 X' R  C

  830. ! O! ^/ ?0 E6 M/ M5 E( K% s
  831. /**
    ' \7 x% p4 J" ?
  832.   * @brief  This function handles CAN1 RX0 Handler.
    7 J6 Z+ E  V7 D$ P. B6 {
  833.   * @param  None.1 b' J' |! W( o
  834.   * @return None., M, ?. j. W. K& l- A
  835.   */! q0 Q5 D1 Z8 a* i5 Q
  836. #ifdef STM32F10X_CL
    * w* q- B& m% M% N
  837. void CAN1_RX0_IRQHandler(void)* g9 I! J" |! g3 n' J* \6 J. n8 m
  838. #else
    9 Y: v  v9 q/ ~3 u% C6 b8 ]# l  y
  839. void USB_LP_CAN1_RX0_IRQHandler(void)# V- M& U7 t3 N; A3 D: {0 x
  840. #endif /* STM32F10X_CL */! V  ?  W$ O- K8 @0 s
  841. {  y% [+ H- ~/ B; b+ g+ Y
  842.   if(CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET)
    # t' I1 A/ ~9 w
  843.   {
    8 j' S" p2 u7 K# S& ]9 C
  844.     CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0);
    & m* Z, Y$ M7 A7 \
  845. , o. V# S4 C$ J% C# V: k
  846.     CanRxMsg canRxMsg = {0};
    / Y5 p) S) A+ b  ?
  847.     CAN_Receive(CAN1, CAN_FIFO0, &canRxMsg);
    % T. G/ Q6 h7 u% J9 ^" u

  848. & o. Z& L" s; B+ t) I0 v. k
  849.     if(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg) > 0)4 h3 @' T0 |# `8 K9 `
  850.     {2 L7 D/ H4 q+ [6 s- t
  851.       RingBuffer_In(can1RxBuffer, &canRxMsg, sizeof(canRxMsg));  e8 o1 q6 \  W. d3 \- U
  852.     }
    # R  u2 i5 T/ g7 R! d9 b

  853. # i; X+ e' I8 q  l! t, s
  854.     if(can1ReceiveFinishCallback != 0)$ K& x2 A3 g6 M" V
  855.     {
    & A' N- @6 p2 O0 K) E" w7 v% B
  856.       can1ReceiveFinishCallback();
    * `! w5 ~4 k, {& `# v
  857.     }2 {- E; P# K- S+ ~2 M( @/ Y
  858.   }6 s1 z$ N/ E$ V+ y% I1 ?/ x
  859. }# p) Z$ b2 W$ p5 i; u5 x
  860. # i  x  @( e+ m2 `
  861. #ifdef STM32F10X_CL
    3 ]3 U$ W8 b$ p
  862. /**+ z2 J; P" t6 B4 X* J/ ?
  863.   * @brief  This function handles CAN2 TX Handler.
    # {+ }& [# s5 g0 k( `: E
  864.   * @param  None.
    , Q, D( f2 D  L9 d
  865.   * @return None.% ?# `$ q4 ^# C6 o
  866.   */
    ' _4 C  h% P" r- y! E- T: k
  867. void CAN2_TX_IRQHandler(void)
    & z) g/ Z3 y8 D3 }6 l3 n8 F
  868. {
    2 K$ @- h/ W: u/ x7 o) b2 A
  869.   if(CAN_GetITStatus(CAN2, CAN_IT_TME) != RESET)2 _1 l. p; f/ ^3 e1 _& ?
  870.   {
    / `" ^+ G+ a9 W" O& A5 m- g# e
  871.     CAN_ClearITPendingBit(CAN2, CAN_IT_TME);9 R- d$ p- ^" C, C3 U
  872. 9 d5 p: a& k  J* w. p
  873.     CanTxMsg canTxMsg = {0};
    9 c2 d  X5 R/ D
  874.     uint8_t  number   = RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);& a! A5 i' J3 f: G# C

  875. 2 Y& o& [- s. c' o# M) t. [1 `
  876.     if(number > 0)
    + D4 b! U! q& M8 f# O' x/ J" g4 ^
  877.     {
    ; U  D& N9 M) T% v: |$ @
  878.       CAN_Transmit(CAN2, &canTxMsg);
    $ B' [* [+ G$ T2 l
  879.     }
    7 e+ l# C1 i( p: U! }1 L
  880.     else% K3 f- W  P( ~6 A1 L' ]
  881.     {3 t4 O2 u" c' ]) P5 ^
  882.       can2TransmitFlag = false;7 O8 F* w" i9 s6 j; n
  883. ) P6 X6 x# u' |5 c' C
  884.       if(can2TransmitFinishCallback != 0)
    , K6 |& n6 {2 b5 B! @2 h9 S
  885.       {
    3 t9 o. K0 E; B# [6 w9 f8 s# L! Z6 h
  886.         can2TransmitFinishCallback();. D) ^: M( M* ?
  887.       }
    - o8 W% r; [# H" {/ x
  888.     }/ {/ K  ]$ ]. ]- `1 Y) L
  889.   }6 k- h+ b* _/ Y; S' j
  890. }6 t- r7 S0 V6 v+ f8 S9 E
  891. ( Y; s5 H# ~6 M( ?" D6 O7 k
  892. /**
    7 q7 Q6 q& K, K: \, I' N0 ~% {
  893.   * @brief  This function handles CAN2 RX0 Handler.
    & Q# G" D: T+ u4 T) Y" P1 Z3 p
  894.   * @param  None.
    * a: w0 t, t8 }) E* e5 u% }' L
  895.   * @return None.4 w! M5 l5 d2 ?: o1 ^& z: O
  896.   */, ~+ O" Z" J5 i4 S6 M: e
  897. void CAN2_RX0_IRQHandler(void)  e% Q* Z: F$ ]2 F) R3 B  Y2 u
  898. {* a0 c6 D' b+ b
  899.   if(CAN_GetITStatus(CAN2, CAN_IT_FMP0) != RESET)
    4 ?* O8 Y" O% w$ G( T1 ]
  900.   {5 ^; g+ v8 z. m
  901.     CAN_ClearITPendingBit(CAN2, CAN_IT_FMP0);
    : E! o9 N- f: N# W. B$ ~
  902. 9 U, |" y6 N2 G
  903.     CanRxMsg canRxMsg = {0};
    5 }+ H* M  _/ K: W- J# b# s( _
  904.     CAN_Receive(CAN2, CAN_FIFO0, &canRxMsg);
    5 L. |" R; W  s- D

  905. * z( C, O+ P1 a7 E* {3 x9 y* Y. L
  906.     if(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg) > 0)) h" r- H6 y- g1 G
  907.     {
    ' W3 r8 i- S8 V! n
  908.       RingBuffer_In(can2RxBuffer, &canRxMsg, sizeof(canRxMsg));
    ; `7 C+ ~2 P8 X, F; x( u' c  ~
  909.     }! {0 l6 k; i! b& r

  910. + ^" I! W$ }6 D/ t2 f& _- f
  911.     if(can2ReceiveFinishCallback != 0)) T! @9 |! T' ]( Q' G/ L) g( t
  912.     {
    , h4 y- _- s, ^# i& B, q% `
  913.       can2ReceiveFinishCallback();# t# K/ v0 c* |3 G: F
  914.     }6 K/ `% b" n; R1 {
  915.   }
    + Y0 G* ^5 J4 J( t: ^2 u0 t: l
  916. }1 a7 ]5 o1 k: z! n8 v
  917. #endif /* STM32F10X_CL */6 h( o: K+ j) V  c
复制代码
% W3 h# F, E1 ?1 z  p9 v' l! H0 P

  s3 k! S+ e3 C4 j" l/ j( xmain.h 文件
, N+ i( |: s4 P0 n. u6 d
  1. /**$ j! I$ I' @5 x) {# s
  2.   ******************************************************************************* ~; a/ r! C2 ^/ g1 f
  3.   * @file    main.h) H# ?/ J3 J- _9 [- }. T
  4.   * @author  XinLi
    3 T7 }5 A5 n: i  X& ~7 P$ a- B
  5.   * @version v1.0& u' O( t! ~$ c1 t
  6.   * @date    24-June-2018* h3 h1 c' E2 Q0 Q
  7.   * @brief   Header file for main.c module.
      }: C: Z1 Y, C+ z' {$ A# e1 l
  8.   ******************************************************************************! t  N7 {% u# m9 |
  9.   * @attention% m7 D# F" R  [; A$ S/ U* R! N
  10.   *
    : [, W# p# X/ {) b$ S) b. N
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>) Z4 h4 G( ~# [( W, P8 K$ I
  12.   *6 u1 L& ?3 K0 L- [$ u) E9 p" v- N
  13.   * This program is free software: you can redistribute it and/or modify
    . C+ z6 j* B5 K# B( Z- K: d
  14.   * it under the terms of the GNU General Public License as published by
    + I2 k) h5 R# z! k! r( B/ s
  15.   * the Free Software Foundation, either version 3 of the License, or4 K) A. I4 M1 t$ z) W. W
  16.   * (at your option) any later version." l- l& m9 i0 {
  17.   *
    & O: `, ?! q: Y
  18.   * This program is distributed in the hope that it will be useful,
    $ e5 y4 Z  ^+ h* f) s! ~. u' \' Q
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of3 {- @7 _; e  Z0 b3 O/ J
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the1 e2 W  }% Y  q8 s( l
  21.   * GNU General Public License for more details.7 J2 p! d4 l( b1 M' K
  22.   *
    + \6 G' k1 S! i6 J* _! m4 C# r
  23.   * You should have received a copy of the GNU General Public License
    0 Z7 @& r% V$ D2 f  a0 B
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>1 S2 V# i! u% K* ~' y# ]
  25.   *3 F( G& e1 V: n' }0 k/ I6 [2 x
  26.   ******************************************************************************
    5 _. N  d: C" l2 n& Z5 u
  27.   */
    3 `/ H, j7 i& p9 {1 V* j' T

  28. 2 F- C3 i, A% O) C
  29. #ifndef __MAIN_H
    / [/ N" L, A* Z; z) H4 Q+ ?; U
  30. #define __MAIN_H
    0 J% x" T" X. j0 N% H, L

  31. ' g3 R7 m  P) S% U2 o) v
  32. #ifdef __cplusplus: L( z# J5 @6 l/ _$ Y. z' G8 D& a
  33. extern "C" {
    8 h/ ?$ o( _5 D
  34. #endif' {2 n- j0 u- U( T0 ]
  35. 7 q- H& g* J+ W' l7 I
  36. /* Header includes -----------------------------------------------------------*/
    ) K4 U* G) p% A% r" |: ]0 r, ~
  37. #include "stm32f10x.h") v- _- G% w6 h) n1 J( w0 d

  38. 7 e- {6 i6 `" F: Q
  39. /* Macro definitions ---------------------------------------------------------*/1 k. W- H5 v3 O2 u1 X3 v9 f* j
  40. /* Type definitions ----------------------------------------------------------*/9 A& x7 o3 O; O1 I
  41. /* Variable declarations -----------------------------------------------------*/3 E, ~! `+ [' T
  42. /* Variable definitions ------------------------------------------------------*// W; O1 H. u( K5 H7 X' r' I6 w
  43. /* Function declarations -----------------------------------------------------*/4 }. D" O! O% @* D. a0 i
  44. /* Function definitions ------------------------------------------------------*/
    1 z& v- f" O2 S' ~6 Q& {+ P3 E& E
  45. * N! @$ u; _8 H" ^# V% u/ U
  46. #ifdef __cplusplus2 X% Z  F3 H, h9 a
  47. }
    3 e, t8 w& }8 p+ g7 L
  48. #endif6 ~9 I+ B6 [3 g

  49. ' f$ H9 U4 L7 c. F: [
  50. #endif /* __MAIN_H */
复制代码
$ V0 e; j! H1 t8 G

6 j4 p/ I0 L9 `7 U" h8 H5 dmain.c 文件2 p( ^& y$ h0 u, O! ^/ X
  1. /**: S1 A8 Q6 _4 E/ O
  2.   ******************************************************************************
    5 O5 B- w* P0 o% z1 v
  3.   * @file    main.c; R; w1 a$ n3 Q' w' d& s& f
  4.   * @author  XinLi* S( v/ {4 Z& m' `
  5.   * @version v1.06 i+ l. {# c; x
  6.   * @date    24-June-2018  R' N7 m/ D* E5 E
  7.   * @brief   Main program body.
      T3 B' D( W! F- c9 {  i7 S
  8.   ******************************************************************************1 i/ X* b7 @3 V* g3 H: m
  9.   * @attention/ ]. I% U- m# t! d  s* [
  10.   *
    6 Q+ h: c! y3 E, J5 {2 D
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>5 p# `  z- w# F5 {4 p
  12.   *
    2 d  ^/ _( r; y6 t
  13.   * This program is free software: you can redistribute it and/or modify
    0 k- y4 k0 ]4 o3 Q& O) [
  14.   * it under the terms of the GNU General Public License as published by+ O& f; S* K3 j; c. Z5 L: E! x
  15.   * the Free Software Foundation, either version 3 of the License, or
    " I  ]6 ]$ @  g$ `  m
  16.   * (at your option) any later version.0 ?/ M# i( j$ `& a3 i
  17.   *; ^' [3 _$ S% h. K4 f. k" _" y
  18.   * This program is distributed in the hope that it will be useful,
    9 m7 o+ a, B" o+ ^/ w& K& K
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    8 g" l3 Y4 Y" S3 V- X4 a
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    9 H/ j% d5 g- s
  21.   * GNU General Public License for more details.# i% ]' ?- c3 y# M
  22.   *
    7 \2 N4 b& R$ ^- }4 E5 @) _/ q
  23.   * You should have received a copy of the GNU General Public License
    0 s' i* |' D  o+ s1 J0 d
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>8 n. |0 c, B; M7 s! w1 C
  25.   *
    - i4 l. W2 H0 [. h) J6 z6 \
  26.   ******************************************************************************) V; E" W9 t6 X& Q9 }
  27.   */
    1 G4 t8 }+ e8 x* I* |: Y4 V
  28. , _/ s; L, p( I/ [
  29. /* Header includes -----------------------------------------------------------*/( I/ z) x# s4 O& W6 `7 J. U& M
  30. #include "main.h"" `' M  E% ?9 b# t$ g
  31. #include "CAN.h"
    - }$ ]9 W2 t) i5 C5 e% K
  32.   G* E. l( B0 Z$ a/ V' T1 g4 a
  33. #ifdef _RTE_
    1 o- b+ Y+ w; [% Q* i2 q
  34. #include "RTE_Components.h". S8 p9 c$ g1 j+ m# Q9 k
  35. #endif, z2 ^5 j" ]$ V" N5 r% F% z

  36. / u8 h/ B: L$ n0 j1 E4 k
  37. #ifdef RTE_CMSIS_RTOS2% Y+ s+ l8 `* g: _) u; K0 t
  38. #include "cmsis_os2.h") i( ^# ]( Z7 M- o$ d& g+ J
  39. #endif( l4 e" a9 Y/ Z

  40. / N* a, R; O. h
  41. /* Macro definitions ---------------------------------------------------------*/
    . q/ V7 y& S' E1 A3 R  e$ P
  42. /* Type definitions ----------------------------------------------------------*/; I  @0 P6 @1 M$ f" e. F- _1 n
  43. /* Variable declarations -----------------------------------------------------*/
    ! l) o. w' |4 \+ `& f" u
  44. /* Variable definitions ------------------------------------------------------*/1 m8 v, P& e$ D: d% W& h
  45. static CanTxMsg canTxMsg = {0};
    ) q% _% x9 }; D6 p; e
  46. static CanRxMsg canRxMsg = {0};  `" F; G3 k3 a  A

  47. ( W7 `0 E  H/ j( k1 x* ?
  48. /* Function declarations -----------------------------------------------------*/
    5 H$ S/ \0 K. O0 r5 P5 K- ~
  49. static void SystemClock_Config(void);
    ! Y% L# O- e1 H" m
  50. / a2 S# L0 |3 U0 t
  51. /* Function definitions ------------------------------------------------------*/
    2 ?- P7 f9 {; S& O% T# e
  52. 9 a2 c9 u) ^% v" n; u
  53. /**
    . C4 A/ o4 P- g1 b. J% X" X
  54.   * @brief  Main program.
    0 g- v6 l& h; k3 T7 D' S
  55.   * @param  None.
    5 [& I1 d( T+ K6 g% _
  56.   * @return None.) L3 t' b4 X: b6 H
  57.   */
    1 A. _( s6 l% j) \2 U
  58. int main(void)9 b. M: j  f8 U: G  ^) M
  59. {) f/ m# _' q6 {+ g; k2 m
  60.   /* Configure the system clock to 72 MHz */; c$ q+ I% t) [7 V
  61.   SystemClock_Config();
    # M$ L7 R0 x+ c  v  S" ^* c
  62.   SystemCoreClockUpdate();
    0 c" e1 |6 y& J( X2 e! w( a' f

  63.   H' l% L  p( V; ?! L) R2 z  ]( K
  64.   /* Add your application code here */" U; K! B5 Q, j1 G, g
  65.   CAN_Configure(CAN1, CAN_WorkModeLoopBack, CAN_BaudRate250K, 0xAA55, 0x55AA);
    + A" ^4 L6 ]! a% Y5 H( c
  66. ! a9 J1 g% n8 F  p
  67. #ifdef RTE_CMSIS_RTOS27 S& T/ a0 U+ s, u
  68.   /* Initialize CMSIS-RTOS2 */
    ! W+ t" x- M7 C* C6 X# z# s. l7 u
  69.   osKernelInitialize();. [2 s- q, A+ p3 N" ~' V1 N
  70. 7 I" l2 v; N2 ]9 B6 \/ q  y# b, a
  71.   /* Create thread functions that start executing,
    ) F) a1 `& N1 n9 h2 K* P, r! f% \. d
  72.   Example: osThreadNew(app_main, NULL, NULL); */- S1 w$ t8 n5 l6 n  r. `' o
  73. . X! J) p( L3 `, [( q6 t' `: q
  74.   /* Start thread execution */
    0 }5 e4 Q* }2 v6 }/ j8 c
  75.   osKernelStart();
    1 M2 S6 i% I) W3 V. l! |
  76. #endif
    1 T, C& |6 \( n9 [; O# k% K3 p
  77. / t0 p! k& g: A5 V
  78.   /* Infinite loop */
    ' x; R& X- a: \) Z/ t
  79.   while(1)% ^3 ~5 h* V% \" q8 d1 A
  80.   {: A+ a7 A" \: I# U
  81.     canTxMsg.StdId = 0xAA55;+ s4 U* F' w$ J$ K9 H% x- K# A8 v
  82.     canTxMsg.ExtId = 0x55AA;' v7 I" h" s( A7 x- q
  83.     canTxMsg.IDE   = CAN_ID_STD;
      ]9 v* K: M' {& Q, e% u5 H, w' I
  84.     canTxMsg.RTR   = CAN_RTR_DATA;
    8 ~) @3 c% e4 h8 F8 W% z2 i! e
  85.     canTxMsg.DLC   = 8;6 `9 a2 M( R% V" b
  86. # Y0 ?1 V9 _; ]3 H
  87.     canTxMsg.Data[0]++;
    ! O& U5 z5 {! x+ l' D
  88.     canTxMsg.Data[1]++;4 h9 p) L- k/ N
  89.     canTxMsg.Data[2]++;+ i" L* `: G1 {# a: u7 o% ~
  90.     canTxMsg.Data[3]++;
    , V2 s! X" E- a( \8 D" g8 I2 l
  91.     canTxMsg.Data[4]++;
    " B* k4 [$ Q) o5 e3 n, b6 g
  92.     canTxMsg.Data[5]++;1 S) `; V7 `  Q& }% I
  93.     canTxMsg.Data[6]++;+ j9 q+ q" M9 H/ [) m7 f) G
  94.     canTxMsg.Data[7]++;
    6 }0 O. b. B/ E
  95. / g/ r0 v' o& e# o* Y
  96.     CAN_SetTransmitMessage(CAN1, &canTxMsg, 1);+ g0 P$ |6 c* P4 u
  97. $ N& @9 R. [; Z' [" d
  98.     while(CAN_IsReceiveBufferEmpty(CAN1) == true);) t# ?* S  N* i7 u' H3 D4 R3 I

  99. ; I; ?4 L: s2 r  m4 ^
  100.     CAN_GetReceiveMessage(CAN1, &canRxMsg, 1);0 U* w1 h% e, p4 }, Z. K
  101.   }! P/ J# |1 E1 S, z3 q4 V
  102. }
    , `7 d* K) l4 A$ O# Q
  103. + c$ v3 v& L8 i1 {- j
  104. /**
    # k1 m5 E! P# i) }  x1 O; ?
  105.   * @brief  System Clock Configuration.8 O8 a* B2 Q5 u
  106.   *         The system Clock is configured as follow : ( f% s1 q* d6 [2 K, L# e6 f% A; N
  107.   *            System Clock source            = PLL (HSE)
    , u" O$ b' K" u
  108.   *            SYSCLK(Hz)                     = 72000000- r- M4 s# o6 E* o
  109.   *            HCLK(Hz)                       = 72000000* v3 ^' Y. n3 S5 U& n0 |- @0 a$ e9 [
  110.   *            AHB Prescaler                  = 1
    4 w8 |0 _$ `, D" m5 V
  111.   *            APB1 Prescaler                 = 22 q) Y" F* c# Z$ H$ Q2 ]' m. o( C
  112.   *            APB2 Prescaler                 = 16 O4 w8 N# f/ {, w
  113.   *            HSE Frequency(Hz)              = 8000000- _1 J. F! |, J( [8 U4 r8 P% F% p
  114.   *            HSE PREDIV1                    = 1
    8 K3 \/ a& G$ w! f, _
  115.   *            PLLMUL                         = 94 t: ?! P, v: _4 n9 B7 `0 t; f
  116.   *            Flash Latency(WS)              = 2
    5 e! d( z: d/ p4 E$ h
  117.   * @param  None.( V. i9 I, v! O3 j
  118.   * @return None.1 Q5 n! C% Q1 B2 ]
  119.   */# L) w- y& q. H4 Y9 W& s. t9 n
  120. static void SystemClock_Config(void)4 Q7 a7 M; O/ a8 d; W  J" d( J! [
  121. {9 f( f1 b* G9 k2 `- `
  122.   /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration */
    # T; F; ~) k' ]2 c2 F
  123.   /* RCC system reset */
    " u8 C3 h1 `5 ~2 v( p
  124.   RCC_DeInit();5 k9 K/ P* v% x! W  B; @# Y
  125. ; p4 S# W9 ~' `5 X; L! L
  126.   /* Enable HSE */3 X+ d: _% v/ O' @/ f2 x
  127.   RCC_HSEConfig(RCC_HSE_ON);- h- s8 ?& n1 t7 M9 L+ Y' c

  128. , d% }0 u' h% f7 _: U6 M4 ^
  129.   /* Wait till HSE is ready */
    & \4 Y) y! e1 \& B2 Q0 c# R' O
  130.   ErrorStatus HSEStartUpStatus = RCC_WaitForHSEStartUp();
    8 q  s4 ]  }* S0 g. C) g
  131. : a, [/ U5 Z9 _4 Z
  132.   if(HSEStartUpStatus == SUCCESS)( k3 b# [! r) L
  133.   {2 b% m: b8 Z3 u1 F+ _7 q# Q
  134.     /* Enable Prefetch Buffer */
    , w! C) f- h  o; f6 s8 K) _
  135.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
    " {4 s4 E$ T9 U

  136. + G& {; F5 \6 A4 V* ~
  137.     /* Flash 2 wait state */$ f. o$ Y" d7 f# X
  138.     FLASH_SetLatency(FLASH_Latency_2);
    - D7 [& r- w- s  n* O; u

  139. : z4 S: F! t- ~
  140.     /* HCLK = SYSCLK */. u( X) i6 L5 h2 N+ b! z9 Q. ?6 J9 Q
  141.     RCC_HCLKConfig(RCC_SYSCLK_Div1);
    9 q& D1 j+ L4 I6 Z& b# J
  142. ! R, ^/ x# M" g* }' y; ~/ P
  143.     /* PCLK2 = HCLK */' H# v$ K6 `! M6 b
  144.     RCC_PCLK2Config(RCC_HCLK_Div1);
    0 N8 E; u: J' f# n  c
  145. ( F' O4 U6 x; l4 t: \
  146.     /* PCLK1 = HCLK / 2 */) O) a! i" s) `* I
  147.     RCC_PCLK1Config(RCC_HCLK_Div2);
    & ?/ F( \) o: p4 C* d8 T
  148. # |% j1 m. x% X) k( d
  149.     /* Configure PLLs */
    4 r& ^# n# M* h0 [. U! F! b9 A. k
  150. #ifdef STM32F10X_CL
    - n1 L# s$ \  D. X) n4 X
  151.     /* PLL2 configuration: PLL2CLK = (HSE(8MHz) / 2) * 10 = 40MHz */  ~7 }; B' {1 M* w2 w! c. u
  152.     RCC_PREDIV2Config(RCC_PREDIV2_Div2);
    3 e5 _- c; h, l/ F* F# D: p- [4 {
  153.     RCC_PLL2Config(RCC_PLL2Mul_10);
    , v8 `+ s7 P* D$ t* ~4 c
  154. 6 {) r9 x0 p% H+ u
  155.     /* Enable PLL2 */
    + }. @3 L& h( v" T, Z0 C" Q
  156.     RCC_PLL2Cmd(ENABLE);+ v+ n5 U3 A) c

  157. . p2 ^$ W% J; I' ~# e: x
  158.     /* Wait till PLL2 is ready */
    + k# V+ f# o2 Q# m0 @/ o
  159.     while(RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET);- E+ Y/ S+ H& _- |

  160.   G+ J+ l/ m! U$ z
  161.     /* PLL configuration: PLLCLK = (PLL2(40MHz) / 5) * 9 = 72MHz */+ k1 c& R& r6 p5 g$ a6 [
  162.     RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div5);
    7 L% T2 Q7 g2 L! c& T  J9 U
  163.     RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);5 n, x/ ^+ D- w! X- M! Y
  164. #else7 [) [8 e$ k& i  f* \/ T. L# F, I
  165.     /* PLLCLK = HSE(8MHz) * 9 = 72MHz */. Z; C0 a# p  e
  166.     RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
    9 T& Z" t( z: v3 d2 U( O4 R  f
  167. #endif
    8 v+ g# X! u9 U. j" g, u+ d. `
  168.   i8 |6 R1 i7 W1 f7 w* \! {' L; G" m2 A% n: ?
  169.     /* Enable PLL */
    , n$ D! q1 S3 ~1 f0 t+ R& o
  170.     RCC_PLLCmd(ENABLE);! {- ?2 w/ C; a2 l; X
  171. , [' a* U0 m; F" D) F/ P
  172.     /* Wait till PLL is ready */# t# |1 p8 ^3 l( e1 Q# f
  173.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);2 K( Y& S. a( m( c, k6 n/ y4 Q

  174. 1 C7 q% q' k/ S1 l
  175.     /* Select PLL as system clock source */+ P1 t# ]# N, I
  176.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    : b  x: ~: S" }) L8 q

  177. / `% l1 Z- c3 j9 b6 D, M3 Z
  178.     /* Wait till PLL is used as system clock source */! K3 o" \" ]; y$ H' z- C9 F; L* j# I
  179.     while(RCC_GetSYSCLKSource() != 0x08);
    2 ^$ W4 Q9 c: l7 k! X! v
  180.   }7 ^) Z$ V* `" N
  181.   else, C7 L$ S* P; Z# }8 ^
  182.   {
    0 n0 N" S" i7 Y
  183.     /* Disable HSE */2 n! \2 g$ |: T9 `7 }
  184.     RCC_HSEConfig(RCC_HSE_OFF);
    7 _  j2 y4 w8 [( X
  185. & k( h6 {8 p. B  C, S" \9 W
  186.     /* Enable HSI */  ]& f9 b* R. j, X
  187.     RCC_HSICmd(ENABLE);7 X5 l' v/ g( V4 G- I! [

  188. - }9 f0 g" x6 \: @/ d
  189.     /* Enable Prefetch Buffer */
    8 F9 m* f0 j# {8 L, |, s3 e
  190.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);( N2 r& C9 B! m; r2 L" N
  191. ' @2 U4 B% N9 o; O: {2 A; \; Z% o
  192.     /* Flash 1 wait state */
    9 c! n. h" K" J! K1 ?0 ?) g6 j. f3 ]
  193.     FLASH_SetLatency(FLASH_Latency_1);
    2 T- [) P5 r  F% `3 {0 D
  194. & D, Y6 Y' p) `& y
  195.     /* HCLK = SYSCLK */% V1 d8 M. i1 k! t2 _2 p8 p
  196.     RCC_HCLKConfig(RCC_SYSCLK_Div1);
    2 i0 L$ `8 J& O  q; j9 X

  197. : @/ q7 n; r+ z; B
  198.     /* PCLK2 = HCLK */# n  n2 ^. W  _3 A
  199.     RCC_PCLK2Config(RCC_HCLK_Div1);
    / v8 t. r7 [8 K  o5 E
  200. ) l/ B( r7 P( R
  201.     /* PCLK1 = HCLK */
    5 q5 s1 T; A# h( f5 [
  202.     RCC_PCLK1Config(RCC_HCLK_Div1);) q$ x# }/ X- [! K

  203. ! F/ G) H, G  w
  204.     /* Configure PLLs */+ I: Q) ]/ `# t/ E
  205.     /* PLLCLK = HSI(8MHz) / 2 * 9 = 36MHz */$ c! }7 b4 {& x1 \
  206.     RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_9);
    % e' C9 r2 X. h0 s) f- X/ d2 B

  207. ) A% B. N9 W0 }# i( X" G; R
  208.     /* Enable PLL */3 s3 n+ J4 G5 Y$ z& J$ d
  209.     RCC_PLLCmd(ENABLE);
    - n  _3 k4 E; A* Y# U, A

  210. & l/ W; B: X4 Q& C* y8 [, y
  211.     /* Wait till PLL is ready */
    ; K2 o: Q- U, N
  212.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);) a; h! @9 Q' D
  213. 2 j- s' R8 m9 s7 }2 h" j
  214.     /* Select PLL as system clock source */* b* P9 p& T6 m/ H3 v* Q
  215.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);% J* ^, Z! h6 X  }. T/ M
  216. / p3 Z5 X+ a2 A) }7 _0 [
  217.     /* Wait till PLL is used as system clock source */2 p. x7 a: R; b+ T7 Q$ |8 n. t
  218.     while(RCC_GetSYSCLKSource() != 0x08);# X9 f) M: [9 w! e6 ~4 e! E2 ]2 P
  219.   }: q0 o" ^2 }% r; j- h( b% f
  220. }
    6 M. i, j7 k+ V8 |8 b2 c" s
  221. ) a" |, P) g$ n7 q: O% y
  222. #ifdef USE_FULL_ASSERT
    9 f% ]( p. T) |* _0 L6 l8 S
  223. /**
    % t* k+ g- T6 T" M& S
  224.   * @brief  Reports the name of the source file and the source line number
    0 K. P$ u* a: p6 E
  225.   *         where the assert_param error has occurred.
    , h: t& M/ @) V8 ^6 ~) S! x6 {3 B, p
  226.   * @param  file: pointer to the source file name.
    9 r0 h- P  G- ]  p- J
  227.   * @param  line: assert_param error line source number.$ N: {4 n. _2 h9 d
  228.   * @return None.6 @& W: ^$ C6 h$ n$ M
  229.   */
    $ q2 j, o; c9 X- X3 G
  230. void assert_failed(uint8_t *file, uint32_t line)
    6 J5 O( a5 J' u! V; a0 ~# g. ^5 l
  231. {- l2 _+ \# O% ]/ u# Y- y
  232.   /* User can add his own implementation to report the file name and line number,$ D4 |9 ?" f, g
  233.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    1 C& w% N- X/ h) W  J3 T

  234. 9 I; n+ H/ a* f, z! z
  235.   /* Infinite loop */
    5 {# Y! r( n* U, r! O
  236.   while(1)3 b8 s, Y/ i0 e% Q& m
  237.   {
    / b1 x3 i0 r# @/ x/ a2 e& N
  238.   }0 O% U7 |4 P6 ^
  239. }+ ^+ d0 m( l3 @" w2 M
  240. #endif
复制代码

5 _$ g5 Z4 F  h6 ~1 c! J' G) u3,注意
, c1 j& s4 T& T2 |/ h
/ F9 k9 F/ ]- d3 cCAN 消息发送缓冲区和接收缓冲区的大小,可以根据应用的需求进行修改,缓冲区使用的是堆内存,需要根据缓冲区大小和应用程序中堆内存使用情况进行配置。. F; \( ~- I9 h$ B8 c( y

* Q& X4 A$ v. }% g7 j& w4 d
" q* t+ _5 b- W' f, |8 B+ g; p- e- `" e: g% W& ?' X
收藏 评论0 发布时间:2021-11-26 17:00

举报

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