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

【经验分享】STM32F1(CAN)

[复制链接]
STMCU小助手 发布时间:2021-11-26 17:00
1,开发环境
! q; e- u& f# i; ]2 D. s. L! u0 o7 B
1,固件库:STM32F10x_StdPeriph_Lib_V3.5.0
/ ?5 l: E  F+ ~' y( K' Y( |9 L# _5 c
2,编译器:ARMCC V5.06  h1 e7 h7 s0 s; c8 H

1 \8 z& k& r8 a7 @; w$ ^3,IDE:Keil uVision5
' [" b& B  L& f: d; ]# e
) i5 S" |8 u; _4,操作系统:Windows 10 专业版5 v# L) \$ S/ n; p

+ b! B" Q" D6 v
( v7 t$ t3 c- C8 T3 T$ k  H, [2,程序源码
- o* I8 I/ p& ~: M# k
% X4 K. i' G/ t+ t% M# O# s1 `RingBuffer.h 文件, y9 p- A( e7 Y+ R
  1. /**. d  s. z. t5 T: p
  2.   ******************************************************************************+ t  e. D  Y/ ^/ m. p/ h
  3.   * @file    RingBuffer.h! P" q( u, E# }' `
  4.   * @author  XinLi9 X  U' K/ A: u5 E( H9 _
  5.   * @version v1.1' `7 f3 K9 `! e& J
  6.   * @date    15-January-2018
    ( i9 k( l! w7 N# Y' N/ c
  7.   * @brief   Header file for RingBuffer.c module.
    ( R) o' c' m+ D- `4 e
  8.   ******************************************************************************% x% c- s, i; I% I
  9.   * @attention
      S8 m/ x$ g& e1 V  {% {) W/ i
  10.   *
    % D9 d, Q' L+ F- M" Y
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    0 R- Q. l' D- r: E0 F! f
  12.   *
    2 Y6 X" Z- [/ }5 P) N: f
  13.   * This program is free software: you can redistribute it and/or modify1 r: E8 U5 O) ?4 G
  14.   * it under the terms of the GNU General Public License as published by
    1 W* H3 ?1 J& y* `
  15.   * the Free Software Foundation, either version 3 of the License, or# W6 P( k: B/ {
  16.   * (at your option) any later version.. q) o( V/ Q9 x- n- V( B% Y
  17.   *+ M" F8 q" @5 B0 B" a
  18.   * This program is distributed in the hope that it will be useful,
    4 D9 i6 L# ]5 N1 j  T
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    4 m+ J9 V1 p/ f- S2 {
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the, d. ]; N% w. a7 I
  21.   * GNU General Public License for more details.0 B3 l& D0 f% I% b# }
  22.   */ k: c# ^" u2 u7 L2 x
  23.   * You should have received a copy of the GNU General Public License
    1 P: p% @6 t8 ^1 C. w( N
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    ' i' c% W9 E7 ~* Z' Z
  25.   *
    ' ]+ L) Z# u6 c4 i* w" V4 \
  26.   ******************************************************************************7 G; m5 \' W9 A- T+ E" d! x
  27.   */6 e( C: P! C  a
  28. ) F0 U* f+ L" \' O) I+ s
  29. #ifndef __RINGBUFFER_H8 l1 _, K. h9 s  y
  30. #define __RINGBUFFER_H
    6 @$ \: P" p$ p

  31. 3 V0 z" D  f* M4 C: ]
  32. #ifdef __cplusplus" u" \0 [; d0 t: ?* I% K
  33. extern "C" {
    . o9 B/ N* C4 w8 d" e
  34. #endif# N9 f$ B' R4 I, h1 y3 |! a: _
  35. / L1 d; J. b' \/ D
  36. /* Header includes -----------------------------------------------------------*/
    ! I: |0 e3 |. w) C* f, y! {. ~
  37. #include <stdint.h>
    8 F- @6 Q- s+ u' A; ]1 _* T. O; ]
  38. #include <stdbool.h>0 ]- c* S/ h2 L3 s: g  {5 P
  39. #include <stdlib.h>3 a( l0 B! B, B/ K4 B
  40. + Y7 ]. c3 U) ?$ Y- [/ W# @
  41. /* Macro definitions ---------------------------------------------------------*/0 O+ g+ G0 y: ~& O( Y2 d
  42. #define RING_BUFFER_MALLOC(size)  malloc(size)3 ?! K1 ~$ ~$ |8 }$ [5 @+ U
  43. #define RING_BUFFER_FREE(block)   free(block)  u4 A! Z0 B. h3 q
  44. * a: X) {; E* }9 i% I5 X: N
  45. /* Type definitions ----------------------------------------------------------*/' M7 g& W$ A: y, W- E
  46. typedef struct: q/ Z( T/ `" d* x4 L! O
  47. {) F% v" w- d: V8 W3 L( l
  48.   uint8_t *buffer;
    4 B$ y' N* _3 h% Q
  49.   uint32_t size;% e& v2 T7 i* ^; t- ]6 `
  50.   uint32_t in;! a3 Y. k( s  Y% I
  51.   uint32_t out;
    6 P/ M1 g8 P$ y
  52. }RingBuffer;
    - f' A6 F3 F. c  V- T# o; }
  53. : o# |) [8 g  Q( v- E
  54. /* Variable declarations -----------------------------------------------------*/
      L  x2 ]& z% J3 B" E) z- H6 y
  55. /* Variable definitions ------------------------------------------------------*/# O" p: m& f' H0 @; z" t$ R
  56. /* Function declarations -----------------------------------------------------*/5 Y! `7 A& F1 ?" b* O( J1 M8 w
  57. RingBuffer *RingBuffer_Malloc(uint32_t size);
    1 g; f4 d. W6 Y6 j
  58. void RingBuffer_Free(RingBuffer *fifo);" y  m( m; W! c# v' w
  59. 6 F, e* G# j, `2 z& b& A4 g
  60. uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len);
    2 D) U* E8 o4 o- S7 I  K
  61. uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len);
    9 [2 Z9 F3 Q# p0 F- u" A' d3 x; A
  62. / u$ `. x5 K8 S, z4 t2 |
  63. /* Function definitions ------------------------------------------------------*/& x1 z( G- w# V. Y

  64. 5 _1 G4 Z6 O' H$ w5 V% f( c
  65. /**
    7 j( M* a: D. K+ D/ W5 O
  66.   * @brief  Removes the entire FIFO contents.3 l5 Y: o( P. {+ @
  67.   * @param  [in] fifo: The fifo to be emptied.
    2 U$ M7 v9 L7 W0 |6 s3 M
  68.   * @return None.
    ) a, q' m+ |& _; Q- {8 _3 @
  69.   */( o) E* L# b/ a# n
  70. static inline void RingBuffer_Reset(RingBuffer *fifo)' r: M8 i* v* P2 F" q: v' e
  71. {& `2 q. D/ ~$ u0 Y& k) }8 i- ~# j
  72.   fifo->in = fifo->out = 0;
    ( b* \% S; Y3 v( J1 j( w
  73. }
    2 X1 c. y1 i" G9 I5 |
  74. 4 U5 S- K8 w1 K* S
  75. /**: h+ K8 @1 X8 F/ B/ Z5 S* {+ A3 A/ f
  76.   * @brief  Returns the size of the FIFO in bytes.
    % z% [- T/ e* F4 Z" L! L5 R. T
  77.   * @param  [in] fifo: The fifo to be used.
    2 _& \/ J! C0 J( a% @/ s6 b0 s7 `( H
  78.   * @return The size of the FIFO.1 I; [- D# x3 y* N" f$ O9 v, @; N
  79.   */" a& b8 Z* _6 [7 e- K
  80. static inline uint32_t RingBuffer_Size(RingBuffer *fifo)
    / X& H9 e8 Y: w, S/ J
  81. {1 L4 w7 b$ ~: [& x
  82.   return fifo->size;( O# d2 |0 \3 e: `1 L  X
  83. }
    6 v+ g0 T' \7 g( H

  84. 8 O" ~! c1 S! B. z
  85. /**
    4 T% g( F& e1 I  g/ f6 ~$ l# V( Z
  86.   * @brief  Returns the number of used bytes in the FIFO.* J, q# n2 Y& k1 }- B
  87.   * @param  [in] fifo: The fifo to be used.. S7 G! N3 N- b1 a0 r
  88.   * @return The number of used bytes.
    " v% O1 Q" C. D  G; K: b% H# h0 d
  89.   */( i8 K3 ~% m  M6 G
  90. static inline uint32_t RingBuffer_Len(RingBuffer *fifo)
      l& @/ R$ i* B& E0 k/ b+ j
  91. {
    : x1 S8 D: y$ Y) {, ^
  92.   return fifo->in - fifo->out;
    ( i7 {$ t& F4 T  h; [
  93. }
    2 V5 L" f  P+ B, A0 ?
  94. 6 C5 d  v/ a5 M/ Z
  95. /**0 ]1 ~" r5 I: v3 Y3 y. z
  96.   * @brief  Returns the number of bytes available in the FIFO.
    . m9 o/ A( P9 P% V( }- R2 K
  97.   * @param  [in] fifo: The fifo to be used.
    $ c9 ~) V  X$ h& M4 d9 P
  98.   * @return The number of bytes available.
    " t! i, D2 \) L* q8 Y
  99.   */
    8 \: h7 F. [; g5 F; h7 V% }3 e$ ]
  100. static inline uint32_t RingBuffer_Avail(RingBuffer *fifo)3 I) h+ D0 z, ]% o; j. g5 B, @% a
  101. {
    ! Z$ c  R- R& _6 t3 M# m. Q
  102.   return RingBuffer_Size(fifo) - RingBuffer_Len(fifo);! o6 z$ P" a8 A$ o, q2 W% v; h& G
  103. }
    / f. x. a% O- C+ ]; E, R& U

  104. " {3 d0 J; v/ y7 ^) }, L
  105. /**
    ; K/ g5 k/ g- v) @: \! C$ o
  106.   * @brief  Is the FIFO empty?4 z& E+ l- m) E- V' M! ]
  107.   * @param  [in] fifo: The fifo to be used.- s1 d. X3 \4 h3 ^- x' H
  108.   * @retval true:      Yes.0 G1 e" _& U/ u
  109.   * @retval false:     No., Q# C; L$ j' p! ?8 p/ B
  110.   */
    . H! D% B' u# ~- q7 S% r" |
  111. static inline bool RingBuffer_IsEmpty(RingBuffer *fifo)
    1 m* }9 p5 R7 z5 w
  112. {2 U% h9 v+ G( U
  113.   return RingBuffer_Len(fifo) == 0;
    : K; r8 g- ?9 K% D) a) r8 A
  114. }
    2 T2 S" p* J( ?# W2 q
  115. / \9 ?9 ?% J% i3 ~; O: T+ u
  116. /**
    , O# x/ d$ J# V8 e% N! D$ u+ F
  117.   * @brief  Is the FIFO full?
    5 W2 n# ~# p3 D
  118.   * @param  [in] fifo: The fifo to be used.+ W$ I( Q6 ^1 `( x
  119.   * @retval true:      Yes.
    7 \$ F, E5 g- z- y5 x/ z$ I
  120.   * @retval false:     No.
    $ O3 M$ c9 v7 w
  121.   */
    ! S% W, U' N/ v% q% _: H1 x
  122. static inline bool RingBuffer_IsFull(RingBuffer *fifo)3 c  ^/ t! N7 a
  123. {
    $ f8 @  T3 C# N
  124.   return RingBuffer_Avail(fifo) == 0;
    ; d3 R1 K$ ^* U
  125. }
    + e, H* k) c* b

  126. 0 z1 B& k0 L8 h
  127. #ifdef __cplusplus% L! V" K/ T1 g7 Z# V% j' O% D
  128. }
    - S/ H# U+ T$ w. W; |) U5 S4 s; S
  129. #endif2 T; e$ G% e6 [, U7 |) j8 K

  130. 4 U& e0 ?' n: G
  131. #endif /* __RINGBUFFER_H */
    ( [1 c3 l8 R. @8 Z" ^
复制代码
$ u; x1 @. ?3 z7 F& [$ T

: }4 @) z" z7 H  Z8 ERingBuffer.c 文件! U3 ~% e( u' G& p& h
  1. <div>/**" T& ]+ f1 P* {
  2.   ******************************************************************************
      a, d3 c; }( S6 J
  3.   * @file    RingBuffer.c
    0 E' G1 @+ u3 k2 T+ ~$ ]
  4.   * @author  XinLi! y+ G8 g- G, m* {2 w: s
  5.   * @version v1.1$ V6 \' d$ B& L! g. n
  6.   * @date    15-January-2018! @$ X7 g. O( L' u5 D' W6 c: s
  7.   * @brief   Ring buffer module source file.; l" J9 I" Q" C. _$ N
  8.   ******************************************************************************8 x& e% K5 B+ K, M, h5 _
  9.   * @attention# O* `) [$ J1 I. H5 r" Y
  10.   *
    % A* h" d9 v3 T3 Z
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>2 P4 s' H- {( [, C+ P' j1 z
  12.   *
    ! Q0 Z, c# U4 d& U* t$ i5 f8 [
  13.   * This program is free software: you can redistribute it and/or modify1 _1 l( s& Q( n4 R! l$ |& ^$ y
  14.   * it under the terms of the GNU General Public License as published by& D4 \5 [, l$ q. R
  15.   * the Free Software Foundation, either version 3 of the License, or! d8 p$ @8 T" o1 y/ n0 U
  16.   * (at your option) any later version.2 `$ f, }/ H4 ^1 b
  17.   *6 Q5 c( c2 y5 t" {1 A- L
  18.   * This program is distributed in the hope that it will be useful,
    . l; |( O/ d! u. ~/ k' Y/ E
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of% l3 j. O! T* h- L7 _$ f; B; m
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2 h1 M$ i. T' O% z% V, m+ z
  21.   * GNU General Public License for more details.
    - r! u# D; C8 D9 }; H2 k- t
  22.   *: ~4 [: u3 \  O! o# A) o# j+ d
  23.   * You should have received a copy of the GNU General Public License
    $ p0 e/ X# x2 \
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    $ [3 u+ v  W. y0 X7 v- K6 @
  25.   *% z) M1 L0 l" w2 a
  26.   ******************************************************************************; o4 D& a) |: G* G4 x
  27.   */
    2 ~2 L( s1 ^" H0 K8 J+ j( d
  28. 1 ~* R7 l8 Y. T0 N, t
  29. /* Header includes -----------------------------------------------------------*/5 e$ q! f8 v7 k# I6 n' P6 T
  30. #include "RingBuffer.h"
    . V( x/ S6 q  y
  31. #include <string.h>
    / w/ d( q1 k' ?/ w2 V: t$ X

  32. ( ~: j3 [3 E" o& t8 b
  33. /* Macro definitions ---------------------------------------------------------*/: g: N, W; e0 b1 G+ \4 N) t, C  \6 F
  34. #define min(a, b)  (((a) < (b)) ? (a) : (b))
    % p  R; o( E; N+ v4 x1 E% `2 p+ W

  35. , v' l/ }& x$ K7 e4 V* w
  36. /* Type definitions ----------------------------------------------------------*/
    9 t6 ~+ ]' ~  [8 l% f) l9 [+ q
  37. /* Variable declarations -----------------------------------------------------*/
    : ~9 v3 W  y! X8 G& h/ m
  38. /* Variable definitions ------------------------------------------------------*/
    ; {( Z' w! Q4 i5 U8 d
  39. /* Function declarations -----------------------------------------------------*/
    , A5 @: \$ A0 j* a0 }! S  k8 t0 M( s
  40. static bool is_power_of_2(uint32_t x);+ z/ E0 n, B( w/ q0 P
  41. static uint32_t roundup_pow_of_two(uint32_t x);- z% D) t( ]7 V8 Y( Q7 ]
  42. 8 C' x$ f6 B$ ]  u1 y' f% t$ v7 e
  43. /* Function definitions ------------------------------------------------------*/
    . T" w  b! f# r/ M8 f

  44. " ^+ h8 Z0 @: Y8 S5 c. D: H
  45. /**
    % U$ W& W1 q5 A+ k4 i( v- `
  46.   * @brief  Allocates a new FIFO and its internal buffer.
    ' u) q. g' o% }  X. L6 Z8 k
  47.   * @param  [in] size: The size of the internal buffer to be allocated.7 f3 K& o' |3 ^+ @6 j
  48.   * @note   The size will be rounded-up to a power of 2.3 I4 E' K' f$ g* s, z) B% r
  49.   * @return RingBuffer pointer.  K; z1 s5 o$ a& i+ G' Y9 p1 O1 f
  50.   */: M9 u) j/ Y8 s1 L/ G
  51. RingBuffer *RingBuffer_Malloc(uint32_t size)# W2 L' s! y/ B$ J
  52. {
    ! W; `: G8 p) K6 C3 `
  53.   RingBuffer *fifo = RING_BUFFER_MALLOC(sizeof(RingBuffer));
    0 t* X2 @) {4 n# V) H/ l3 N
  54. % l+ v  B  d5 d0 S: F5 r
  55.   if(fifo != NULL)
    " b" c4 s' e! J% S( X; ~
  56.   {: N1 f" U0 N( g) V5 j) `- l$ G
  57.     if(is_power_of_2(size) != true)9 ]- h0 I0 ]% U4 G' V
  58.     {3 A0 Y" D$ p. Y
  59.       if(size > 0x80000000UL)- I1 }& l/ P$ V6 {1 t
  60.       {5 H7 L  ~% c3 y: w% ?: {
  61.         RING_BUFFER_FREE(fifo);
    & u6 ]$ N' l0 @
  62.         return NULL;% I# l2 `" ~2 J$ W, O2 [
  63.       }
    5 K7 u/ o; f& q" u. G4 D

  64. 3 `( i; f' d2 g
  65.       size = roundup_pow_of_two(size);8 ?- T! w5 Y* N% d6 B5 [
  66.     }- u' z1 T. ^( [" D* H

  67. 8 _: X0 p/ M( o" [4 y, c4 N
  68.     fifo->buffer = RING_BUFFER_MALLOC(size);9 V0 V2 _( ?3 Y

  69. : ^9 |; C5 j" m! i# `
  70.     if(fifo->buffer == NULL)) k- U* d0 U" S4 d
  71.     {( Q$ c/ n5 e: w' {* t7 Z% U
  72.       RING_BUFFER_FREE(fifo);: C- m+ O4 C* t" o( w
  73.       return NULL;, x, }$ O9 j4 W) m
  74.     }
    3 E$ M. S/ t+ K
  75. 8 U) d  q. C+ j; N" ?+ r+ Z
  76.     fifo->size = size;
    9 u6 U1 K8 X3 t% z3 ?
  77.     fifo->in = fifo->out = 0;0 a$ u" T8 i7 d) g0 k
  78.   }
    ; _" d! X/ s: y& W& `

  79. ! k( w9 B& @( r: `/ u: ^
  80.   return fifo;8 \8 o: U. ~( D1 V4 C
  81. }8 v1 _: d( z# \0 T

  82. & q; M2 e& v+ o+ ^2 X, T
  83. /**
    ; K4 N! k) [7 [* ?) W$ _' \
  84.   * @brief  Frees the FIFO.
    1 c- ]) K4 O9 O
  85.   * @param  [in] fifo: The fifo to be freed.: x. M0 L1 h  {! |& ~, g
  86.   * @return None.
    " j; S" V7 K1 F& ~) e
  87.   */: q  g, F' ~5 S7 m
  88. void RingBuffer_Free(RingBuffer *fifo)
      }* c5 ^. I2 L. g1 _( v8 t: j/ i
  89. {' t  n: B1 U9 r. k9 `, q% g$ b
  90.   RING_BUFFER_FREE(fifo->buffer);
    - X& x& Z3 k4 E
  91.   RING_BUFFER_FREE(fifo);# n+ @7 X! p, ?8 q; M5 F
  92. }
    ( N' E  q1 y5 B2 z
  93. 3 f) e3 z) D4 k* e* R
  94. /**
    $ z' `  R* W3 @+ l
  95.   * @brief  Puts some data into the FIFO.: D  b- D3 v) i+ M# Q6 N6 L
  96.   * @param  [in] fifo: The fifo to be used.. b0 \. H) m6 U- P, p, P# |8 A: |
  97.   * @param  [in] in:   The data to be added.
    ' v" @+ d# I( Q# _2 i) d* d6 u
  98.   * @param  [in] len:  The length of the data to be added.
    . T6 Y4 a& `/ R. C
  99.   * @return The number of bytes copied.
    " W6 \$ c) O4 k3 O* l. W- M3 O" P
  100.   * @note   This function copies at most @len bytes from the @in into
    9 \2 v5 T+ p! i7 W
  101.   *         the FIFO depending on the free space, and returns the number$ P8 @$ U* g3 G8 b" ^
  102.   *         of bytes copied.6 j: u6 {5 I$ e0 K9 Q
  103.   */2 i: U; Z; S2 ^% _  A
  104. uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len)
    9 z8 r" E$ J8 G% t6 Q9 N
  105. {" ~# k+ g4 B! c3 |- z! t
  106.   len = min(len, RingBuffer_Avail(fifo));
    3 |  o6 Q; o5 g7 C/ `: J# j" }1 Q

  107. ) O) _5 g4 @* u' Q
  108.   /* First put the data starting from fifo->in to buffer end. */
    1 I" V, Y# h1 m1 T2 e- g
  109.   uint32_t l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));/ f2 [8 K- u3 C, ^- X9 q
  110.   memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), in, l);
    * P' c; c& B& e7 Z  O4 S/ {, a8 x

  111. 4 c) V) ?) ^# x7 d6 R: U* @
  112.   /* Then put the rest (if any) at the beginning of the buffer. */
    # G8 d% h* ~2 u6 x0 M
  113.   memcpy(fifo->buffer, (uint8_t *)in + l, len - l);- V8 E& c. H& l& G; {

  114. 4 d. y9 ?! e  q
  115.   fifo->in += len;8 }( J; [/ B1 B' D3 \4 {5 S; y5 k

  116. 9 F. M1 s! S6 a* j  ^
  117.   return len;
    . M! Q" I# U- D$ N# H+ m" F
  118. }
    5 ^. D3 m: I7 a6 r/ x
  119. ) T& F/ C5 y' p0 v3 w) P
  120. /**
    6 }0 J4 L6 }; x
  121.   * @brief  Gets some data from the FIFO.9 t0 r$ J$ D+ W  z% Z9 ]) a
  122.   * @param  [in] fifo: The fifo to be used.8 q; f3 {6 p% d3 t5 r8 c
  123.   * @param  [in] out:  Where the data must be copied.
    * B7 [. f. t1 ^5 t# b' M0 q$ ]
  124.   * @param  [in] len:  The size of the destination buffer.
    6 j8 ]2 U$ B4 R$ {3 y
  125.   * @return The number of copied bytes.0 m8 g& o, a% H: J; h
  126.   * @note   This function copies at most @len bytes from the FIFO into2 Z. Z% n9 T( i
  127.   *         the @out and returns the number of copied bytes.6 r5 t& J# A& j) E3 R
  128.   */
    # C% p- j" F5 L6 v! b/ q6 L
  129. uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len)7 F( \7 a9 t6 Q% ^
  130. {* ~& {2 o# ?( ]7 {9 t
  131.   len = min(len, RingBuffer_Len(fifo));) M3 x+ w4 m8 V! S4 @3 p- }6 C$ N

  132. 4 c9 F! J9 a) e0 K$ W
  133.   /* First get the data from fifo->out until the end of the buffer. */* c1 g8 g: F% @- Z: n" O6 [- B. m
  134.   uint32_t l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));
    . [) T0 H0 p2 w
  135.   memcpy(out, fifo->buffer + (fifo->out & (fifo->size - 1)), l);, `% ^% r% y! l: b- i; k
  136. # S" F9 X5 p7 j8 ~/ L* L0 T! K
  137.   /* Then get the rest (if any) from the beginning of the buffer. */
    - |3 X7 z, H* c4 ]* ^$ I
  138.   memcpy((uint8_t *)out + l, fifo->buffer, len - l);. _2 y0 c' z2 j

  139. 6 m3 N3 O. r: e4 C1 O# Q" ^2 g5 B
  140.   fifo->out += len;! q( b/ e$ ]" \) |1 j& c
  141. 8 f: u: o8 ^) g' i' U8 [0 _9 b
  142.   return len;
    3 G6 e) a/ f& _/ R/ Q6 X2 y
  143. }
    3 a. D3 `7 O( H2 H. ?! K

  144. 6 n! B' g4 d! z8 {2 l/ H- a; x
  145. /**, `) c. K  j) k( [: n
  146.   * @brief  Determine whether some value is a power of two.8 b! }' O4 [2 {+ e3 c
  147.   * @param  [in] x: The number to be confirmed.  s. o8 a# M2 E9 B5 V  `$ N% t! s# d
  148.   * @retval true:   Yes.
    . J. r9 y+ ]; Z. y  t! Q
  149.   * @retval false:  No.
    2 v. x$ t  H; j
  150.   * @note   Where zero is not considered a power of two.
    ; O  l! A  Y- F
  151.   */! f- Q, |; w7 \5 K! Y
  152. static bool is_power_of_2(uint32_t x)
    5 C: P( [2 u# X; W' y0 b4 m- V
  153. {6 p/ M8 h0 i; [; L& E2 o: B
  154.   return (x != 0) && ((x & (x - 1)) == 0);
    ; M4 u; d' Q- r# a0 N+ O7 i( e
  155. }
    4 l# H: p( Y- J+ H& Y4 V+ l; ?2 E# W
  156. ! C8 W1 t: K/ k; s' L
  157. /**
    : l; [# D( o2 f
  158.   * @brief  Round the given value up to nearest power of two.
    9 m" |( M; E- T# g1 z
  159.   * @param  [in] x: The number to be converted.
    " U. @' w/ b7 U' u
  160.   * @return The power of two.# R; |* \7 i  f: @
  161.   */( l2 Z1 Q. [& Y0 l! s8 y6 y9 N2 H
  162. static uint32_t roundup_pow_of_two(uint32_t x)
    % t3 `0 T5 k6 k/ {# v. A9 y  Y
  163. {
    ! ^, c2 _& Q3 n3 C4 n' S
  164.   uint32_t b = 0;
    ) a* K. ]' a9 _) \7 g
  165. , o! e6 {7 B3 Z
  166.   for(int i = 0; i < 32; i++)
    " e$ i( _( S: Z/ _. p6 C5 J
  167.   {3 [4 u! p+ J# |2 _% L
  168.     b = 1UL << i;
    # v+ e; g; @4 e$ A, C8 x& S4 N& {
  169. : P* K  T* |/ y, l" o. u
  170.     if(x <= b)
      o; k: X8 }2 Q% C$ f
  171.     {
    # c8 g. v6 R0 q$ a* B$ s3 |
  172.       break;: D9 c5 g" I3 P: {3 A0 O+ a
  173.     }0 i" x! g/ m' P$ z; E6 l; ?" y8 T
  174.   }3 D  ^- ~2 b5 U3 p1 D+ X, o
  175. . H1 {0 v, j0 L! _2 @
  176.   return b;# F/ f- n* M! j
  177. }</div><div></div>
复制代码

- N! Y5 [! h& Q& @8 m: K# Y* A4 m6 a' |
CAN.h 文件
8 s1 t6 l0 g5 a" ^* G6 z
  1. /**4 }4 K& a4 P, V- X! i& M$ p; @  z
  2.   ******************************************************************************4 g* p. m7 |  [( n# e
  3.   * @file    CAN.h
      f& R! e* e7 U4 h: r6 V4 C+ [
  4.   * @author  XinLi
    4 \1 t* S( r& {' [9 {0 m
  5.   * @version v1.03 P7 Q2 p6 J( q8 K( a( `
  6.   * @date    24-June-2018
    . ]9 r! C1 q; _, `. s( O# b
  7.   * @brief   Header file for CAN.c module.
      y) x* {" u/ M* q/ m/ z
  8.   ******************************************************************************
    4 Z' S' N7 Y  @9 U) r4 F& i2 j) v
  9.   * @attention* o7 Y4 o4 H- B
  10.   *
    , X( h* k; U/ U
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    ; N6 C! d% \5 V. b, n
  12.   */ R" a, z) z7 B3 ]5 n* O
  13.   * This program is free software: you can redistribute it and/or modify' A- j/ x. r; Y7 n; l. G  E, _
  14.   * it under the terms of the GNU General Public License as published by
    ! h& r, P; ?. ]
  15.   * the Free Software Foundation, either version 3 of the License, or# K( a" T' @4 B" [; ~6 M/ I! t3 b
  16.   * (at your option) any later version.
    - |" V+ M# _) T0 W+ g6 m
  17.   *5 ]0 U& L* H/ O) N
  18.   * This program is distributed in the hope that it will be useful,2 g4 n, J5 G0 ^* n1 n# y9 ?
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    9 j7 o, T* f: R9 ~# m
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    + H+ I+ G7 k: i& {) A5 b& X4 D
  21.   * GNU General Public License for more details.2 y" X( n: |7 b
  22.   *9 B' @7 Z2 M) \: O
  23.   * You should have received a copy of the GNU General Public License
    # W  K% b3 b2 F6 h; }$ a
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>& [4 B5 p8 _, {8 E  f
  25.   *
    & C" [# @9 w1 C; C9 A
  26.   ******************************************************************************
    6 Z9 g5 N' j# R# Q
  27.   */
    0 k0 F3 Z0 L! B; `6 Q7 H

  28. 6 f" [; e5 B/ v% j( j6 a
  29. #ifndef __CAN_H
    $ f: ^, N, \2 Z0 Z9 v/ |1 @# p' u
  30. #define __CAN_H
    4 E+ x9 j3 w+ E' L' n
  31. 5 }, I' I" [$ a( Y: y
  32. #ifdef __cplusplus2 ^5 H# X- c$ f7 E0 T' O/ G4 B
  33. extern "C" {
    - T. M& x4 i% \& l5 ?4 r- V
  34. #endif* z3 S* q$ X- X0 M' a  w$ W
  35. / W' h& U, d) W" k. ?7 Z
  36. /* Header includes -----------------------------------------------------------*/, r+ j6 i7 E! `, x$ x4 Q
  37. #include "stm32f10x.h"% c  T8 Z  u+ L7 ^
  38. #include <stdbool.h>; f1 O1 F0 x7 f! b
  39. # s; y! K' \9 w. ]. R  J' l
  40. /* Macro definitions ---------------------------------------------------------*/. B; e: K4 T+ E8 h3 E
  41. 7 @8 n! w4 m9 B' \
  42. /******************************* CAN1 Configure *******************************/
      K2 V& M; F! u* y+ p, g" Y4 N
  43. #define CAN1_TX_BUFFER_SIZE        (16)
    & G* k4 N  O* ?( \
  44. #define CAN1_RX_BUFFER_SIZE        (16)$ K6 x- Y+ y8 C7 V3 M
  45. 5 @( p* E3 y" M2 S
  46. #define CAN1_TX_GPIO_CLOCK         RCC_APB2Periph_GPIOB
    . `! f: C" v' S; i# u# K
  47. #define CAN1_RX_GPIO_CLOCK         RCC_APB2Periph_GPIOB6 }) r9 G$ G8 `' l: I0 b

  48. ; i5 @! P5 V4 A0 y
  49. #define CAN1_TX_GPIO_PORT          GPIOB
    1 \! |/ K+ W& R
  50. #define CAN1_RX_GPIO_PORT          GPIOB
    , c8 }, V7 m% f5 }' ?

  51. ' E9 ?% C0 J" Z- z3 X* @. v
  52. #define CAN1_TX_GPIO_PIN           GPIO_Pin_9
    % {. n! }- H2 v, I: q$ W
  53. #define CAN1_RX_GPIO_PIN           GPIO_Pin_8
    ( F$ _3 X9 o5 h; c, H
  54. * m+ `( n) ~' {) c
  55. #define CAN1_IRQ_PREEMPT_PRIORITY  (0)" d4 r( r: S6 ~8 \
  56. #define CAN1_IRQ_SUB_PRIORITY      (0)2 e- `# Q" b' _7 g6 L
  57. * j. R& h: b$ D' i: W
  58. #define CAN1_PORT_REMAP()          GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE)
    6 l+ S1 b* ]  a, h- p; U5 W( Y
  59. /******************************************************************************/
    . C6 A7 X0 m  X2 u
  60. 5 l' W/ n+ u2 A. S8 V2 E' x
  61. #ifdef STM32F10X_CL
    9 {0 u) ~+ ?5 z1 g
  62. /******************************* CAN2 Configure *******************************/* x5 `- ^) e" y7 V# |
  63. #define CAN2_TX_BUFFER_SIZE        (16)+ m: Q% |# M. i* P# y6 F. H
  64. #define CAN2_RX_BUFFER_SIZE        (16)
    4 X$ S9 d) N! c5 G: X9 S! t

  65. " w. ?; g1 O$ E$ J7 Z( x
  66. #define CAN2_TX_GPIO_CLOCK         RCC_APB2Periph_GPIOB0 [9 U2 |: t4 N( Q  h0 L
  67. #define CAN2_RX_GPIO_CLOCK         RCC_APB2Periph_GPIOB+ d8 J+ \: @: w7 G& v. `

  68. ) e0 _% E8 h, L- C  E+ B% Q
  69. #define CAN2_TX_GPIO_PORT          GPIOB
    $ o' Y5 [% x- p; F
  70. #define CAN2_RX_GPIO_PORT          GPIOB
    ( g( |- k+ V# i" o& ~  X& `6 s' V
  71. 0 x3 e- Y9 E* {! s) C: T
  72. #define CAN2_TX_GPIO_PIN           GPIO_Pin_133 m5 Z3 k: {) h$ D2 k' I
  73. #define CAN2_RX_GPIO_PIN           GPIO_Pin_12
    3 q% }" s2 T' {0 z
  74. ( W$ z! U4 s1 K6 \, D
  75. #define CAN2_IRQ_PREEMPT_PRIORITY  (0)
    ( l+ f" W* P6 b; A; d6 X
  76. #define CAN2_IRQ_SUB_PRIORITY      (0)
    ' e; c1 o+ _0 u! ~' H
  77. * p8 r* N! m2 o  X" U3 a7 ^
  78. #define CAN2_PORT_REMAP()          GPIO_PinRemapConfig(GPIO_Remap_CAN2 , DISABLE)2 R3 N# t& a; H( s/ z4 V
  79. /******************************************************************************/4 K! t% L* ~( ?
  80. #endif /* STM32F10X_CL */& d  i5 C' n) C% S
  81. ) P7 O( U$ H: }9 N
  82. /* Type definitions ----------------------------------------------------------*/
    , [, r2 A0 j) u8 n' F
  83. typedef enum  V. Y5 T7 E. ^' [
  84. {
    # ]" n8 h0 q0 \2 n; P
  85.   CAN_WorkModeNormal   = CAN_Mode_Normal,& Q+ Q# I" M/ v- ]* S
  86.   CAN_WorkModeLoopBack = CAN_Mode_LoopBack
    0 k% o, ^% S# s
  87. }CAN_WorkMode;
    : e+ S6 |1 ?3 |0 H' j0 b

  88. / F' Z0 L( y- l4 \, k# t9 t3 o
  89. typedef enum
    $ m( _1 c6 Y/ B: T! a0 J$ L
  90. {: s1 b7 i/ Z5 \
  91.   CAN_BaudRate1000K = 6,
    3 a  J" X. F5 Z% H; S, w. b
  92.   CAN_BaudRate500K  = 12,' E. k1 C# W( s1 n
  93.   CAN_BaudRate250K  = 24,
    - V2 y4 Q" U8 Z; ?+ |
  94.   CAN_BaudRate125K  = 48,
    2 r' M$ F( R) k
  95.   CAN_BaudRate100K  = 60,
    # c  l, \# r" H8 U  y5 T: k8 C
  96.   CAN_BaudRate50K   = 120,
    ( t: v0 ~' y7 s& i' A# y9 y
  97.   CAN_BaudRate20K   = 300,- w/ W: v& G- l$ q
  98.   CAN_BaudRate10K   = 6008 x  w2 \3 [$ u& O  l& V
  99. }CAN_BaudRate;
    / [$ g, _7 ~( @
  100. $ V. C$ J( T6 T5 W8 u
  101. /* Variable declarations -----------------------------------------------------*/) ^  E. }! [& g7 I3 ^# @8 D
  102. /* Variable definitions ------------------------------------------------------*/4 F# N& I5 o1 _) T" p
  103. /* Function declarations -----------------------------------------------------*/. z, w, X( M* ^" j& v, T* `: g
  104. void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId);* W! c) ]% Y( x
  105. void CAN_Unconfigure(CAN_TypeDef *CANx);7 s0 ^( ^. }3 t& B  M- k
  106. 8 D% Q( y! \+ d" T* ~
  107. void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));
    - ~, F9 k  O, K6 I4 i( Y9 s7 H
  108. void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));5 m  S6 W" N0 M5 |9 k! Q
  109. 9 h, d, |, e) a+ }, `  S' A
  110. uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number);
    ! L7 y0 o# T6 Q/ P( E' U+ C: b
  111. uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number);
    ; V* J; [8 V4 }; P6 r

  112. * M( h" r! H8 d: x. m( d
  113. uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx);
    ! W! G6 H" K" e; c+ R4 K( Q
  114. uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx);; ]1 f& U( c' d: a$ ?! d
  115. uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx);
    ; D( V0 q7 E6 i. m0 {: z
  116. uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx);, o# v  K% a) l/ A$ y* t# x4 p7 b

  117. ' |4 q/ J4 g  \' z6 x
  118. bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx);
    0 M; D2 h% ~" h% G( S+ D8 k; Y% B/ v* f
  119. bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx);& t/ {. J8 i" m
  120. bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx);" g3 d8 s; l1 w3 G0 B# ^. V& N
  121. bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx);
    8 n4 }7 `8 n) W% j/ X. L

  122. 7 J4 ^. }9 k/ [- ?& h! a
  123. void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx);" f- p( d! k1 E, |) C
  124. void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx);
    " I9 V2 z0 v% V

  125. * W% C7 s5 u8 N$ b, b
  126. bool CAN_IsTransmitMessage(CAN_TypeDef *CANx);4 T# ^+ d, _# Y2 v9 N

  127. 8 U  ^7 y/ P* Q) @- I! Y$ x! ?' d. P
  128. /* Function definitions ------------------------------------------------------*/
    4 f8 L% q& g# Y; k9 _

  129. , N% K" [  h: G! y. Q
  130. #ifdef __cplusplus7 P% t, I! A! Z
  131. }
      K& c( v) m6 |' @  k
  132. #endif0 o+ B5 A6 B1 q  U- R9 ^( g! k9 F

  133. + s! L0 B6 _( P- q8 R5 N
  134. #endif /* __CAN_H */
    , Y1 e9 h! ~/ }# A  q
复制代码
: K& K! N8 e1 \/ M- o, b

: ~4 k7 w' r" F" s! g( \
8 l! ~5 i# q" U1 h. E5 GCAN.c 文件
) [, L* {) o; _7 r$ Z/ R" a7 n7 S# z/ _: K  A
  1. /**$ c* b) Y! W7 `6 x" ?. C
  2.   ******************************************************************************
    & v  e4 n8 l, V% |
  3.   * @file    CAN.c8 {5 w/ W' z' O% ?, B! T* w
  4.   * @author  XinLi
    5 u8 j$ ~8 U2 G1 u# ^
  5.   * @version v1.02 h: _# k2 A+ K# n: l, t+ y3 _
  6.   * @date    24-June-20182 k8 \$ X. {+ i/ F
  7.   * @brief   CAN module driver.
    - x* c9 |& C- t
  8.   ******************************************************************************8 P# ^4 G# c2 j( L/ g6 v% M
  9.   * @attention. ?" I* ?- Q4 j. o9 G
  10.   *
    1 |0 l1 @  z7 ]
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>5 f  N9 R# {) _6 i) M) t6 t
  12.   *
    9 x9 Z; L  E/ e
  13.   * This program is free software: you can redistribute it and/or modify: n. h' Z0 C. Y' W3 U' k1 u1 n/ I
  14.   * it under the terms of the GNU General Public License as published by
    5 M; p+ b9 t$ d' ?" \! x
  15.   * the Free Software Foundation, either version 3 of the License, or$ n) m4 O3 r- A- L
  16.   * (at your option) any later version.  C; `0 A1 o, j% ?9 g
  17.   *8 o2 L5 i+ s: A
  18.   * This program is distributed in the hope that it will be useful,3 p4 ~, s" A: G" P: L: `! m0 i
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of" n% w& Z: j5 ^4 h$ m6 W
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- F: u- F; R" [( |2 C; T4 W
  21.   * GNU General Public License for more details.' s/ X! o/ T' e7 p$ d2 ^
  22.   *7 W& j' {8 S5 Y1 B7 N/ {) x% B0 C
  23.   * You should have received a copy of the GNU General Public License' \1 ~9 |  ~, ]
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>. h0 |' S$ {8 d8 s& R. Q% r' l- l
  25.   *
    / n" e6 n7 e4 u1 Q% Y
  26.   ******************************************************************************5 o/ I5 k. |# [8 c- l. S+ l( H
  27.   */
    : t& d, [( d- Y. N& s& Q. U
  28. ; s2 P0 _/ E0 V% C4 M; ^
  29. /* Header includes -----------------------------------------------------------*/- x% k3 h  W) g0 ~8 W' l
  30. #include "CAN.h"
    + ?. j# t! s; j& `
  31. #include "RingBuffer.h"
    4 v. ?' x) w% V- g( |1 j+ R' {$ y: n

  32. , j, k; C6 @4 v! Z" e% B
  33. /* Macro definitions ---------------------------------------------------------*/
    . Y' X& y! ]1 v" `# |4 K7 j& I
  34. /* Type definitions ----------------------------------------------------------*/) V6 M* S0 R" L7 ^; P
  35. /* Variable declarations -----------------------------------------------------*/# y" k; W! ]; x% Y6 Z9 t$ g
  36. static volatile bool can1InitFlag     = false;" d; s4 O6 ?4 H) |- e" J
  37. static volatile bool can1TransmitFlag = false;& O- y. P. |8 w9 L3 x# c
  38. 9 {/ }) g5 l. K- \" {
  39. static volatile void (*can1TransmitFinishCallback)(void) = 0;1 g+ W5 f+ F; h
  40. static volatile void (*can1ReceiveFinishCallback)(void)  = 0;. r, h6 n+ E" l5 F8 z
  41. , u, g; O. z  h- F2 f# u, F
  42. static RingBuffer *can1TxBuffer = 0;
    7 {7 v, S+ a% C1 \/ W; j
  43. static RingBuffer *can1RxBuffer = 0;
    " ~# V1 `" L9 ^9 d) p

  44. * ]0 W7 [! Y' R9 ]; }+ p8 O7 \
  45. #ifdef STM32F10X_CL1 Y. a0 y4 h+ S! P3 S* ~" a
  46. static volatile bool can2InitFlag     = false;9 A, [# ?6 A" }4 q5 F
  47. static volatile bool can2TransmitFlag = false;
    3 ^4 e5 n: ^6 |. {& x
  48. . \0 V2 p) R; Y8 n
  49. static volatile void (*can2TransmitFinishCallback)(void) = 0;
    1 @4 V! L6 ~  M
  50. static volatile void (*can2ReceiveFinishCallback)(void)  = 0;
    1 a# \! O" G9 Y% ^; K' k2 R
  51. 6 g  c' ?3 D* b! D
  52. static RingBuffer *can2TxBuffer = 0;9 ?/ ]" F& h, t1 ]# w9 ?
  53. static RingBuffer *can2RxBuffer = 0;
    % ^3 M0 m% U3 J1 ^& ^
  54. #endif /* STM32F10X_CL */1 p9 Z7 u3 z2 p& o9 c

  55. ; u( ?- @0 f! l$ v$ e4 o
  56. /* Variable definitions ------------------------------------------------------*/% I2 b+ R* l- T; W
  57. /* Function declarations -----------------------------------------------------*/
    ' u% _2 X# _; U& \; W1 d- b
  58. /* Function definitions ------------------------------------------------------*/$ L2 N2 O4 i; }# d. X# c& U
  59. 5 e# E9 j* C: L0 i+ ^
  60. /**
    * f& s7 v$ X3 {: K0 m
  61.   * @brief  CAN configure.8 S/ u6 {+ u) A- ]
  62.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.
    6 {# b# Y$ e8 e7 H% f0 [6 {
  63.   * @param  [in] WorkMode: Work mode.
    / X( e5 Q  _7 \' t9 Q
  64.   * @param  [in] BaudRate: Communication baud rate.
    7 d0 ?1 W- u$ B; n% a
  65.   * @param  [in] StdId:    Filter standard frame ID.
    ! B3 f8 @1 h  u3 Q! n1 w
  66.   * @param  [in] ExtId:    Filter extended frame ID.. }! o1 c2 Q7 Q, q8 p+ L
  67.   * @return None.8 O, k+ c/ C6 v) `
  68.   */
    . W+ |" f; i( r3 q
  69. void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId)
    3 D: c+ g$ ?6 x$ i- L# W$ S
  70. {
    , k9 E1 t; H8 ]/ U
  71.   GPIO_InitTypeDef      GPIO_InitStructure      = {0};
    # s/ a0 L1 e! e: U" E* E! |
  72.   CAN_InitTypeDef       CAN_InitStructure       = {0};, o; n7 L, t9 E
  73.   CAN_FilterInitTypeDef CAN_FilterInitStructure = {0};* d& q0 E9 J6 N+ i2 N6 P8 @
  74.   NVIC_InitTypeDef      NVIC_InitStructure      = {0};
    / @/ e3 y) x3 Z

  75. ; h( }$ c2 @. n! M$ Q: p: v& B
  76.   if(CANx == CAN1), m. S2 ~1 X: ^$ J& w
  77.   {8 ?# [' e$ U" d$ ^7 p; F
  78.     if(can1InitFlag == false)
    : _5 ?2 c0 [+ O4 f0 E0 S
  79.     {, ]) }2 [. m% ^" C3 f
  80.       can1InitFlag = true;
    4 @5 k8 y# m1 ?9 F5 E8 s

  81. 6 b( o( I  J& Z
  82.       can1TransmitFlag = false;
    9 \1 B/ @; e5 K4 w# j; o! f: Q

  83. " {3 f4 L- d7 x0 l/ o) V! q( _
  84.       can1TransmitFinishCallback = 0;
    . _4 u1 e! J7 K
  85.       can1ReceiveFinishCallback  = 0;  r1 o  b' h6 @; O
  86. , O: N9 R1 t  ^
  87.       can1TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN1_TX_BUFFER_SIZE);& j! g1 W% p" ~6 O' ]9 c, M" J. e- R
  88.       can1RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN1_RX_BUFFER_SIZE);
    " l# d! D6 W) _* S+ [

  89. - e" M* o6 g  k& O1 K$ @
  90. #ifdef STM32F10X_CL
    , s4 K" \" {2 c0 P  A) I
  91.       if(can2InitFlag == false). X. l. u& A/ W
  92. #endif /* STM32F10X_CL */  e( d6 ]; f: [; R4 S9 L7 ^) h! K& V
  93.       {
    3 o% i! \, i0 \- T2 U# N/ @
  94.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);9 ]0 {0 x$ |! d1 k" p) X0 w
  95.       }2 W" S. k  H5 o' G+ A( ~0 N
  96. - r" Z4 t$ a+ x, R9 i( O" ~, m% J
  97.       RCC_APB2PeriphClockCmd(CAN1_TX_GPIO_CLOCK | CAN1_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);. q- Y0 M# |4 M% p, }% v5 \8 e

  98. 6 u, ^& b! \. w. y; G1 h
  99.       GPIO_InitStructure.GPIO_Pin   = CAN1_TX_GPIO_PIN;
    5 d: o6 l8 y3 \$ N. U0 b7 c4 `9 }
  100.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;" a# |8 H5 i  p) e0 h* I
  101.       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    + w! E  Z+ I' Y8 Z: r8 w
  102.       GPIO_Init(CAN1_TX_GPIO_PORT, &GPIO_InitStructure);
    3 {4 Y' Y! a8 t0 ?% o
  103.   O# u9 S: ?/ X( k
  104.       GPIO_InitStructure.GPIO_Pin   = CAN1_RX_GPIO_PIN;( q1 n* T9 B# \2 p, k7 K! c& v9 q
  105.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
    ( f1 J# P, p5 A* P
  106.       GPIO_Init(CAN1_RX_GPIO_PORT, &GPIO_InitStructure);
    4 |& p( y% O3 k7 k% c+ E

  107. " O# J- Z0 \0 l. s( o0 l9 D  E
  108.       CAN1_PORT_REMAP();
    # p( C' w& B3 V. U/ Y

  109. 4 m: M+ v& s0 d+ Y( ], L0 Y3 X1 U  Q
  110.       CAN_InitStructure.CAN_Prescaler = BaudRate;4 z4 X/ S, C# C' k) y
  111.       CAN_InitStructure.CAN_Mode      = WorkMode;
    & Y1 \+ _8 N0 Q5 l2 z
  112.       CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;6 _) S' q' C) Q  z1 J" l
  113.       CAN_InitStructure.CAN_BS1       = CAN_BS1_3tq;: p; u; K" Z+ n" |! |
  114.       CAN_InitStructure.CAN_BS2       = CAN_BS2_2tq;
    * _- g% n7 l) d0 i; ^9 Q. |2 h# A
  115.       CAN_InitStructure.CAN_TTCM      = DISABLE;5 [/ h, F3 _' e; J3 M5 W2 ^
  116.       CAN_InitStructure.CAN_ABOM      = ENABLE;6 }/ f8 ~6 M4 s/ C, ~9 ^$ S( J
  117.       CAN_InitStructure.CAN_AWUM      = DISABLE;
    5 @+ _! Z6 Z. s# D
  118.       CAN_InitStructure.CAN_NART      = ENABLE;. K5 Z8 p  t& [/ e" x
  119.       CAN_InitStructure.CAN_RFLM      = DISABLE;
    6 e; W+ a& u* F9 C2 s7 x4 G
  120.       CAN_InitStructure.CAN_TXFP      = ENABLE;
    $ [6 \$ v' H3 A, U  P- l# k
  121. ; T6 u/ i9 p& b! B; y' z
  122.       CAN_DeInit(CAN1);
    ) s6 h5 o8 j; d4 j, o' w' F+ e
  123.       CAN_Init(CAN1, &CAN_InitStructure);& H8 U6 u) Q3 G. J& ~; s

  124. ; b, G7 ?5 G- a
  125.       CAN_FilterInitStructure.CAN_FilterIdHigh         = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);  J0 P9 g6 ~9 m" p8 |  D; H2 V7 i
  126.       CAN_FilterInitStructure.CAN_FilterIdLow          = (uint16_t)(((StdId<<18)|ExtId)<<3);7 c. ^' l+ h! `( C5 H  k! \  }. ~5 v
  127.       CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;$ G9 K8 h9 U& h0 b" ]) X! s% D7 {
  128.       CAN_FilterInitStructure.CAN_FilterMaskIdLow      = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;
    ' i* S3 a7 c( J
  129.       CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;6 V/ [6 @0 F8 r: s2 b  H
  130.       CAN_FilterInitStructure.CAN_FilterNumber         = 0;* Z8 k* K  x& E: C3 M
  131.       CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask;' L8 b+ F: w4 h1 K3 ~% M3 h, V1 p
  132.       CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit;/ s, V0 T% F0 z# `$ D2 t! y% L! K
  133.       CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;
    ) Z3 ]# k/ j% W/ o' k2 N" m8 Z! o! T
  134.       CAN_FilterInit(&CAN_FilterInitStructure);$ x- s3 Q# W! w& ^/ {
  135. % j, x" b% H+ c7 A: E) o5 K
  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 |& d& U2 V  W: N3 N; ^
  137.                          CAN_IT_WKU | CAN_IT_SLK  |CAN_IT_EWG | CAN_IT_EPV  | CAN_IT_BOF  | CAN_IT_LEC | CAN_IT_ERR, DISABLE);
    : W- f% C, s8 ?3 F9 p' _, ~
  138.       CAN_ITConfig(CAN1, CAN_IT_TME | CAN_IT_FMP0, ENABLE);
    % J6 p; t. Q; l& C

  139. + k& J$ D2 ?1 O
  140. #ifdef STM32F10X_CL
    % x6 g* _, S9 Z5 }' ^  w
  141.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_TX_IRQn;
    0 X- K" @; l9 n8 c3 ^7 i0 b% a
  142. #else
    ( s% e2 M/ Q/ W* n7 _
  143.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_HP_CAN1_TX_IRQn;
    $ ?7 M" `5 e1 q0 ^
  144. #endif /* STM32F10X_CL */! ]2 H7 f* w+ g6 {  N7 y
  145. $ T. f- b3 A5 K, E, x! [3 D; S
  146.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;! R  x- m5 L/ @
  147.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN1_IRQ_SUB_PRIORITY;! D4 Y$ M6 i2 H8 a! X& b# k
  148.       NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    3 I4 P( _9 q# z  b8 @4 z, F1 f
  149.       NVIC_Init(&NVIC_InitStructure);; C$ Q; H5 l6 J+ w6 R
  150. * y. W' h2 W( d8 n0 ?
  151. #ifdef STM32F10X_CL' q9 W6 W; u1 H7 z5 J
  152.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_RX0_IRQn;2 f" D9 ]) y) e8 A6 A, ]% }5 c
  153. #else
    , M5 {9 M$ u/ r: {  A
  154.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_LP_CAN1_RX0_IRQn;! ~8 T" O8 g7 ^" Y9 `+ H" @) i- [
  155. #endif /* STM32F10X_CL */
    % L# x6 V7 M' C7 I! w& n
  156. 7 D7 s9 t" E* x( `/ c! x) T
  157.       NVIC_Init(&NVIC_InitStructure);
    2 `( s2 Q- G8 y0 m, ~4 A
  158.     }
    * u+ Z: T0 t% h$ _
  159.   }
    $ ?# a% P1 C# y% x# l

  160. 2 o( ?# F6 C; J* z/ O3 ~1 Z
  161. #ifdef STM32F10X_CL8 [: c& b* S7 F! Z( a
  162.   if(CANx == CAN2)) \! K) D( }6 t1 v4 W7 K
  163.   {* Y% B. `0 {, o
  164.     if(can2InitFlag == false)0 M) k3 `& D7 a' E& q1 X
  165.     {
    8 `; y" |1 S2 `) X8 V1 }
  166.       can2InitFlag = true;5 i% ~0 {- t3 U7 {

  167. ; Q" j& n& }1 ]* @% N$ A
  168.       can2TransmitFlag = false;" i# j' {- @9 u# a' @& v
  169. 6 L7 l, S9 k6 F8 b- J! ^8 W
  170.       can2TransmitFinishCallback = 0;
    * q# L: ]7 }' P/ l2 I
  171.       can2ReceiveFinishCallback  = 0;
    ; S( Y: U+ V# s* w
  172. 7 ~% k5 K2 N! {7 k0 w
  173.       can2TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN2_TX_BUFFER_SIZE);
    * m8 s1 T7 Z! ]9 R% v9 E3 ?1 J
  174.       can2RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN2_RX_BUFFER_SIZE);
    / `0 a- i4 p/ k+ I
  175. 1 O9 _2 r1 y' d. }+ B; Z- T
  176.       if(can1InitFlag == false)
    % U% s1 V. b% o1 ?+ g6 X
  177.       {
    , p7 Y6 R% a; P! d. E  x$ J( h# X$ S+ u
  178.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);8 i2 q3 v0 V% A
  179.       }
    # a- T1 S/ Q# E: b: I

  180. ' N7 n* s6 n' ?$ V" o4 N
  181.       RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);  S, Q3 T; V4 t+ I  ~/ M8 n
  182.       RCC_APB2PeriphClockCmd(CAN2_TX_GPIO_CLOCK | CAN2_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);% F  I/ ]& Z4 ?% f* n

  183. 9 W: e, h# [; T  K  T. `
  184.       GPIO_InitStructure.GPIO_Pin   = CAN2_TX_GPIO_PIN;
    2 Q6 b7 c! ~8 Y( U3 q  u' d
  185.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;1 T& y) }5 ]4 J
  186.       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    ' {3 l) v( e: u) K" w, w
  187.       GPIO_Init(CAN2_TX_GPIO_PORT, &GPIO_InitStructure);
    4 b8 R% ?! b- p' L& j
  188. 5 O& c5 S, Y8 v4 \" A; p5 }
  189.       GPIO_InitStructure.GPIO_Pin   = CAN2_RX_GPIO_PIN;9 E/ U: h8 j$ H3 c! x9 M* _
  190.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
    * H( V. I' h" u, {5 _
  191.       GPIO_Init(CAN2_RX_GPIO_PORT, &GPIO_InitStructure);
    # }0 @* }4 L5 X% ~$ p7 x6 }

  192. & r& R, v+ W9 g  {$ Q
  193.       CAN2_PORT_REMAP();6 J9 X$ Q3 S' o9 e) v
  194.   j1 B+ T* M) f6 ?) I1 ~
  195.       CAN_InitStructure.CAN_Prescaler = BaudRate;( O3 j% g( H% t+ b/ U# ?
  196.       CAN_InitStructure.CAN_Mode      = WorkMode;
    3 g& t$ M& F; ~) C. g
  197.       CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;
    , w2 l2 a& c9 g9 e' v
  198.       CAN_InitStructure.CAN_BS1       = CAN_BS1_3tq;6 t; K9 K- ?$ p4 U
  199.       CAN_InitStructure.CAN_BS2       = CAN_BS2_2tq;
    2 n4 K5 T3 b5 [) [2 I: u( |
  200.       CAN_InitStructure.CAN_TTCM      = DISABLE;
    & I2 R2 L8 }7 m9 L
  201.       CAN_InitStructure.CAN_ABOM      = ENABLE;
    4 h3 h9 J) _4 z7 }) L
  202.       CAN_InitStructure.CAN_AWUM      = DISABLE;
    7 r; G, u9 G! X; y1 Q1 \- h' g9 R
  203.       CAN_InitStructure.CAN_NART      = ENABLE;
    ; c: m3 Q5 B( [/ s& e
  204.       CAN_InitStructure.CAN_RFLM      = DISABLE;+ z0 ~/ A7 \- `4 h; G
  205.       CAN_InitStructure.CAN_TXFP      = ENABLE;( f" J7 x1 ]" V% O
  206. & m1 }6 ~/ q: ?2 [! ?3 R
  207.       CAN_DeInit(CAN2);" `8 ~% H2 V) c3 z# Z8 i( ~
  208.       CAN_Init(CAN2, &CAN_InitStructure);
    " F- T8 n$ G2 [" J. f) ?7 S

  209. - G2 ]0 x1 J$ ~
  210.       CAN_FilterInitStructure.CAN_FilterIdHigh         = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);' p- u' ~5 G" v7 P; z
  211.       CAN_FilterInitStructure.CAN_FilterIdLow          = (uint16_t)(((StdId<<18)|ExtId)<<3);% E8 T: L8 d! k% C. W5 r
  212.       CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;
    % p: T; P9 J/ l4 ^0 Q: N) g7 }
  213.       CAN_FilterInitStructure.CAN_FilterMaskIdLow      = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;
    0 b9 y) L& }# G- p: y
  214.       CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
    7 V2 k- p/ t& i) G0 g: e5 U9 Y
  215.       CAN_FilterInitStructure.CAN_FilterNumber         = 14;
    . J: [) w: g7 J
  216.       CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask;
    ( A; m, G# j& X
  217.       CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit;
    / L/ C; x  a( c% H4 f
  218.       CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;
    0 L) }0 m, U/ R
  219.       CAN_FilterInit(&CAN_FilterInitStructure);" I0 j0 I) \$ v1 U: D3 ]
  220. + K* {/ s/ u+ t4 I
  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 |
    9 E: m. t7 \8 o- I, l7 @
  222.                          CAN_IT_WKU | CAN_IT_SLK  |CAN_IT_EWG | CAN_IT_EPV  | CAN_IT_BOF  | CAN_IT_LEC | CAN_IT_ERR, DISABLE);
    3 H% p6 e; U2 B
  223.       CAN_ITConfig(CAN2, CAN_IT_TME | CAN_IT_FMP0, ENABLE);
    9 I6 D/ |5 N$ }+ ]1 k: F, W
  224. " p5 f! x5 g; u9 Y3 e' w! ?. r) s1 B
  225.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_TX_IRQn;
    : v1 Z& N0 s! U; }
  226.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;
    4 k, D: O) d5 Z8 V* i$ f+ u+ p' w9 B  E
  227.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN2_IRQ_SUB_PRIORITY;1 L$ [: d4 y0 f& ]
  228.       NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;5 N$ X- p  r) a0 w- {( ]# c
  229.       NVIC_Init(&NVIC_InitStructure);
    ) R8 \# i) i) N% T/ A& s1 w3 z/ s

  230. . |+ |' Z2 Y7 {1 U. b4 A
  231.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_RX0_IRQn;
    : w8 d. z. r5 {  ]; b
  232.       NVIC_Init(&NVIC_InitStructure);
    2 T; j/ R% z; @( P9 R
  233.     }
    / F) L) \6 J) r/ z  W. S2 \2 Z5 D- y
  234.   }. p1 c! S8 `. a1 M% R# w
  235. #endif /* STM32F10X_CL */
    # [" U% n- l, m# @( ]
  236. }0 h5 y* O* [4 E6 }; l

  237. 7 }; k( c- C! ~* S
  238. /**7 l: Z$ u" U) d! H1 f7 a
  239.   * @brief  CAN unconfigure.6 t0 X8 l5 V9 w3 J1 H( _3 k
  240.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.) d: q1 ]0 t8 L  s; V
  241.   * @return None.
    + b3 \% [3 w1 `7 T
  242.   */
    / ?* U8 D, C8 V9 O/ q
  243. void CAN_Unconfigure(CAN_TypeDef *CANx)+ U# l+ }& e# S+ N  y: N& E+ L2 M$ Q
  244. {
    % n( B1 R% E2 F4 ]0 ^; H7 `
  245.   NVIC_InitTypeDef NVIC_InitStructure = {0};
    * _. h, u3 h: Y; `

  246. . ?& X, L  A7 x$ \% S- \
  247.   if(CANx == CAN1)9 \. E; {2 N( n1 M
  248.   {
    , p5 r5 V% `8 D
  249.     if(can1InitFlag == true)
    3 J& k) X% E7 |) Y( \
  250.     {
    $ `5 Z, U% v# ^0 A- q" [
  251.       can1InitFlag = false;1 m' A4 x8 t2 B* M4 E

  252. % r5 \' E) R: ]% H1 L
  253. #ifdef STM32F10X_CL4 I$ f% M# E/ ?5 K1 k1 a8 L/ Y  M& m
  254.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_TX_IRQn;+ g9 b/ Z/ Q; Z1 Y* c; b+ B+ _
  255. #else
    . B. T/ b' J5 i) y
  256.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_HP_CAN1_TX_IRQn;
    , X0 j( F* w5 o0 T3 B+ ?: S$ c4 A
  257. #endif /* STM32F10X_CL */
    - r, G6 v  {+ ^2 u3 ]! N$ `6 E

  258. " ]( y: Z1 c' s( N' v
  259.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;
    % d1 r& v0 ^6 U1 D1 k
  260.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN1_IRQ_SUB_PRIORITY;! r" H$ y* C7 y" K* v6 i3 o
  261.       NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;+ B7 ~& _4 D/ r+ a! p
  262.       NVIC_Init(&NVIC_InitStructure);
    6 i  e- J' k* S" ^9 O
  263. 6 G: I7 x/ O. v3 Q/ ]7 W
  264. #ifdef STM32F10X_CL
    ( L( V, t6 N# t7 e- m4 h' K2 B
  265.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_RX0_IRQn;- g# z, Q7 o0 U6 J1 y+ Z' v- R, g3 X
  266. #else
    # b1 h- G4 G1 ?- X4 k0 N
  267.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_LP_CAN1_RX0_IRQn;9 Z1 ]( f+ {. V
  268. #endif /* STM32F10X_CL */' q, u* p8 _( }
  269. / y$ D5 |- B7 d* g
  270.       NVIC_Init(&NVIC_InitStructure);' e6 S: [" U8 Q  G% w; P6 @: j

  271. " W6 J' H: Q5 o1 l1 W* Z
  272.       CAN_DeInit(CAN1);9 p% p( F% F2 |* ?4 _
  273. 9 s5 x0 R/ {) \" y- q
  274. #ifdef STM32F10X_CL: l6 q  v3 s. z. O: y$ X
  275.       if(can2InitFlag == false)
    3 w. y- r( C  E! i: Q0 y
  276. #endif /* STM32F10X_CL */
    ; Y2 Q6 f+ R7 u6 z- |! D- n
  277.       {
    ( e5 l) u0 n/ i4 v1 o
  278.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);
      o/ }9 y5 s0 ^7 i/ _
  279.       }. u9 ?& Z2 \. U( x7 c5 ^
  280. 7 b6 L8 V) x* s
  281.       can1TransmitFlag = false;6 e# M1 q; [" n- z9 a9 N1 ?
  282. & b& B, B, Y8 x! v6 {
  283.       can1TransmitFinishCallback = 0;1 V& s9 J; [6 b
  284.       can1ReceiveFinishCallback  = 0;) S, u6 i3 h. |' D. C6 X* O/ Z

  285. 5 L& s& Z: P2 b$ ?' H9 k
  286.       RingBuffer_Free(can1TxBuffer);
    0 a  l8 j& [1 ^7 J2 u) q
  287.       RingBuffer_Free(can1RxBuffer);
    . \, ?" G. O5 u9 c% T* E2 a
  288.     }) H2 r, ^4 ]2 r4 V3 p6 T  G
  289.   }) c, y1 E9 k8 J+ [, H
  290. 9 Z& w& j- W- o3 h6 i, o. Z
  291. #ifdef STM32F10X_CL3 g6 B  Z. {1 H" j0 P; {; Y) _8 M
  292.   if(CANx == CAN2)
    2 C" K# L- k* b- r0 l3 O  {
  293.   {
    5 Z, {2 n7 ?8 _. b( r+ @! `
  294.     if(can2InitFlag == true)  A3 k# ]8 W" x
  295.     {
    - j( L0 ?/ x- E( A
  296.       can2InitFlag = false;6 z+ c7 _9 v# S8 t; u7 J% a5 }

  297. 1 [+ @. q) A( f9 i# N* ]
  298.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_TX_IRQn;
    ! k# y3 l: k7 n0 y
  299.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;' P* M( l) T/ R$ `- ^
  300.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN2_IRQ_SUB_PRIORITY;
    9 i+ Z0 m9 C5 W6 ^
  301.       NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;
    & [. r2 L$ ]8 A1 E
  302.       NVIC_Init(&NVIC_InitStructure);
    8 L7 t5 B6 o) n9 \
  303. 8 b  o/ I+ G9 A1 v- {# S
  304.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_RX0_IRQn;( h7 W' ?2 h, ~) F
  305.       NVIC_Init(&NVIC_InitStructure);3 G+ [* m4 Q" [7 B9 E* f% @% a1 Y+ D

  306. $ c/ U# G$ Z- B
  307.       CAN_DeInit(CAN2);
    ' s) C/ q8 ~3 ^& ]7 j/ m8 l

  308. 1 O$ w7 V: Y+ v3 v+ a
  309.       if(can1InitFlag == false)
    . o$ s( G9 f' e: A! g. L4 M! e  J
  310.       {
    8 o0 N! U. q( t4 |, T& q3 y1 [& P
  311.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);8 ?- U8 x# Y% Q8 y+ B0 m4 D
  312.       }
    8 d' }9 q% m2 n

  313. ! y; P7 T6 N; q% O1 \0 e8 e) z
  314.       RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, DISABLE);/ Z# O* V$ z6 D( j0 N% \6 h! R
  315. - q0 _/ [6 ~. p! u7 c  r. G
  316.       can2TransmitFlag = false;) ]5 H  f' `7 F" B# e! u* W

  317. 3 w- ?* _4 K# C$ z" |0 e% U
  318.       can2TransmitFinishCallback = 0;
    2 T( S% l8 H, V) h7 P) ^9 r7 U
  319.       can2ReceiveFinishCallback  = 0;" M6 b2 R7 M2 N) r% h2 R

  320. 5 D8 n5 Y' b! B1 ^; @. X
  321.       RingBuffer_Free(can2TxBuffer);
    # ^$ i2 G2 d' k3 `
  322.       RingBuffer_Free(can2RxBuffer);! }0 a9 O7 r% M
  323.     }4 c& k6 n- W3 U8 v/ V# P
  324.   }
    % n& ~8 s2 N# B) z4 p
  325. #endif /* STM32F10X_CL */
    + a. n3 d6 f/ q2 ]
  326. }
    8 }! q' h1 K; N* L' `

  327. $ k% e4 N5 I$ m; T* A
  328. /**
    2 N2 ~2 I. H) U/ Q( \& k) V& H) }
  329.   * @brief  CAN set transmit finish callback.
    , t$ z6 O: q' ^% K) o3 O6 B
  330.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.0 N+ c% r  V8 R% b
  331.   * @param  [in] Callback: Callback.
    , p' i0 p9 |: F" w# S
  332.   * @return None.
    4 K( Y: V- s, `7 ]
  333.   */5 {2 `6 p3 S2 c9 S, P
  334. void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void))
    / \8 Y+ M; D; e
  335. {4 ]. [( v4 A/ p) T
  336.   if(CANx == CAN1)
    - `. K3 B& R  C
  337.   {- W( u. O* A1 Y9 u7 |
  338.     if(can1InitFlag == true)
    " g( z7 @0 ^6 M3 k4 ~
  339.     {: b9 t5 S' t2 y7 S- h$ F# @
  340.       can1TransmitFinishCallback = (volatile void (*)(void))Callback;
      X) I( ]& v" ^, H
  341.     }
    ( i9 Z! G: n% d5 k2 |7 H5 r
  342.   }
    ) D. Y6 R. l# v+ E) R

  343.   L( T% [# E3 k; J4 g4 X8 N0 B- }
  344. #ifdef STM32F10X_CL
    $ A2 V" l% n$ Q! Z& }! E6 u
  345.   if(CANx == CAN2)! C* c* W1 t2 {  K$ R! A
  346.   {, ]/ i+ ]( ^5 ]# `1 @8 B6 ^
  347.     if(can2InitFlag == true)1 K  @# ~$ l) W9 I; z
  348.     {
    % v9 h$ ~% S$ y9 p1 A
  349.       can2TransmitFinishCallback = (volatile void (*)(void))Callback;
    & t# x' h' e8 Y% M
  350.     }8 T; H$ n1 l, w: S
  351.   }
    " X3 r. y6 S) [0 q6 y" s
  352. #endif /* STM32F10X_CL */
    $ ^  o/ }* R/ Q6 H7 |3 K
  353. }
    ( ~8 S/ O% Q: Q0 l

  354. / D; j* m8 X1 V; I- Z, v, i
  355. /**8 j( e* W; B5 p8 d9 @4 Y5 |: T8 E
  356.   * @brief  CAN set receive finish callback.
    3 ]% P' Y. i3 k6 k) c+ j) r% u
  357.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.
    1 Y( `/ ?* I' H4 l, Q
  358.   * @param  [in] Callback: Callback.# ^4 U, |! U$ @9 f
  359.   * @return None.  K+ ^) M$ {. b6 l0 y4 D: P! R
  360.   */" M! z' A7 Z7 s2 x$ U" G' b) ~
  361. void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void))7 O2 @, {( q4 `' X
  362. {& k. d! {8 x5 C* X
  363.   if(CANx == CAN1)
    5 |6 K. P$ Q( x: l' k. g  f
  364.   {
    & C  O' t4 Q: F/ L  N. V/ M
  365.     if(can1InitFlag == true)
    ' ]: x! ?% x8 E  n$ x
  366.     {
    9 B, {. L5 a$ s% I* \8 O0 U4 ]
  367.       can1ReceiveFinishCallback = (volatile void (*)(void))Callback;# `9 k6 j6 u) [+ M0 G7 Q
  368.     }
    2 ~: D& }7 @5 r; E, m( p' J( N
  369.   }
    8 l- j7 g" \; _
  370. 7 M% K- z- g5 n& S' u9 a7 `: v
  371. #ifdef STM32F10X_CL
    & U2 o" o: e0 j& r; D
  372.   if(CANx == CAN2)
    " k; _, W9 B5 ]. B; a
  373.   {3 K4 ^. {& H* _  K3 V3 ]/ D; ]
  374.     if(can2InitFlag == true)9 m7 I( u) Z9 F* u$ V
  375.     {
      ?9 j: }% [! B; f$ I- d4 S
  376.       can2ReceiveFinishCallback = (volatile void (*)(void))Callback;# x+ D) j9 m0 K# W& [
  377.     }
    8 c# r; Q' y5 m6 P: {5 r
  378.   }
    + H, m) N9 D: l6 g
  379. #endif /* STM32F10X_CL */* q" w7 K0 \; ]9 {: D
  380. }) Y5 g6 u7 T/ r4 Y9 Y' K, g
  381. ' U  D+ U6 x  n' a. p7 v/ y
  382. /**
    + J- H) \3 Q8 z$ p4 ^6 P
  383.   * @brief  CAN set transmit message.% B& {. {' L2 K) M6 H0 q) W  |$ J. p
  384.   * @param  [in] CANx:    Where x can be 1 or 2 to select the CAN peripheral.3 O- X) l0 s9 ^" M+ {
  385.   * @param  [in] Message: The address of the message to be transmit.
    % Q6 ?  E+ ~# e8 m0 V
  386.   * @param  [in] Number:  The number of the message to be transmit.0 C- D& V# `9 R4 P; @# r6 t8 |, p8 u
  387.   * @return The number of message transmit.2 [5 A+ K7 g1 ~0 B9 ^; p4 h& W: R# S
  388.   */
    6 }, n3 i% J6 \$ [4 v
  389. uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number)0 ^1 T# m  s4 B% y' q
  390. {
    4 g; a/ z3 ]1 U  R/ Y* O1 @! c
  391.   if(CANx == CAN1)- S) {8 D; w) A( t
  392.   {) P  h  e8 |. |! p$ l: h( s/ N1 O
  393.     if(can1InitFlag == true)
    ( F0 X5 Q" G5 @& c0 D' Z9 L
  394.     {
    / F3 o: Z: L& Z. Z6 t% A
  395.       uint32_t available = RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);
    4 p* r  l4 _, S+ U3 V: F& H
  396. . {5 [% E% i* a
  397.       if(available > Number)
    " X6 J/ }" M$ r7 e# U
  398.       {
    $ s1 b: m+ M% \- h% @  ^0 v
  399.         Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);& f  u. ?" ~& R$ V1 ^* f
  400.       }
    ! a9 `/ \) f/ C! z+ ~" ~/ c
  401.       else- b' O  b- I: f3 f9 w
  402.       {
      {1 a: q  i( A3 y1 t' n( c# N- m
  403.         Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);, g& t/ [' C+ C+ [* u. k4 {
  404.       }* Z3 t6 s9 [5 ]+ l# `/ r
  405. & r7 I8 i2 p  P& \" w- {
  406.       if(Number > 0)2 W; }( E7 _- a2 P, a+ r( T2 w
  407.       {
    ) S. I! X  g# \; e+ F2 ^, \; D, {
  408.         if(can1TransmitFlag == false)
    3 `% L5 g+ \  K8 z0 t, |; Q6 ~
  409.         {& S4 Q8 H% _8 c3 t' B
  410.           can1TransmitFlag = true;# r4 u+ W& b- \: A0 Q$ Y

  411. 3 W7 R  |( K+ H0 ^: v! Y
  412.           CanTxMsg canTxMsg = {0};1 B# l) t* o9 z9 ^& k2 |( V6 o7 W
  413.           RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg));
    * T! c6 Q3 W) C( ?; Z
  414.           CAN_Transmit(CAN1, &canTxMsg);
    3 f5 s" P% O6 Y' k. b1 Q
  415.         }: r7 j. |, o1 w( ]) n) y
  416.       }+ Z& U% V# T. S$ t
  417. ) S* h' d& P& t3 s9 |
  418.       return Number;
    * p+ M/ c7 f6 m6 G/ I
  419.     }+ y7 \' S; C7 y4 Y9 D
  420.   }  Q5 n# [: e2 D1 h; F5 _- {
  421. $ ]7 D! C. M5 w2 y
  422. #ifdef STM32F10X_CL/ e2 g6 a! ]2 r9 l( G
  423.   if(CANx == CAN2)' E% R& L: U* p: ]4 C5 n- K
  424.   {
    ) v" q% s9 y0 f) e3 f
  425.     if(can2InitFlag == true)# y! G( P8 f) u! }/ c) E& Q
  426.     {
    " @7 y  x4 e6 M: I2 ]8 I2 C
  427.       uint32_t available = RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);2 m6 N: ~) q  R& E$ D, y

  428. # ?% g) S9 {! y! ~5 G
  429.       if(available > Number)
    6 ]% s. ?$ H& i- s+ W1 Z
  430.       {
    ( X8 @9 `/ m8 h  E. S4 N
  431.         Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);
    5 e' v& a. E: ~* S+ [) V6 C4 ^
  432.       }
    8 E# t: x. g- e3 q1 n5 r1 J
  433.       else  s/ B: E, p5 ^$ g6 A  L# }
  434.       {
    8 M. p$ D8 G  \6 U9 \& h0 I6 S
  435.         Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);
    5 j5 @8 y2 d) z) d5 Q1 j
  436.       }4 w# f3 N# i' Q& W8 r& I# u

  437. . x5 y% }4 i( i+ x! d
  438.       if(Number > 0)
    6 [+ Q# P9 d* E$ i
  439.       {
    9 k- k: t  l' ]+ k' \: K; W0 |# ?: z
  440.         if(can2TransmitFlag == false)% V* @# `* s1 Z# c! O) i
  441.         {' m+ K9 t  Z% q
  442.           can2TransmitFlag = true;
    - h# m, ?+ v; L$ W4 k. x
  443. " X+ H6 J7 i* H. t7 ?
  444.           CanTxMsg canTxMsg = {0};% Z4 T8 T; T: b6 l& u; H+ H2 r
  445.           RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg));
    % q/ ^# e  t/ k5 l0 e
  446.           CAN_Transmit(CAN2, &canTxMsg);# T( f% q; h3 i3 F; `: G
  447.         }
    8 M/ Q4 c- p, N7 `9 Y, c
  448.       }5 z& x( r; f0 S) T/ Y9 A- E) F
  449. 3 k6 o4 J$ c  H+ E
  450.       return Number;
    5 |& F0 I* t" d! L7 z
  451.     }
    3 |! Q9 ?: _! V
  452.   }
    # P: {+ s: W4 A3 R& f- D
  453. #endif /* STM32F10X_CL *// P3 e6 e; |, y5 v$ C- }9 V
  454. ; x1 u# A* ^3 h& j% }
  455.   return 0;( ~7 ^" n, x$ C# ~' u  r; ?% e
  456. }
    2 B9 n! N4 M' B2 t$ K6 h5 z
  457. : w! I$ q/ v4 ~* q, c( z- P
  458. /**% J  S, s3 M% ]4 s3 o9 g
  459.   * @brief  CAN get receive message.: O7 u- i* J5 `" p
  460.   * @param  [in] CANx:    Where x can be 1 or 2 to select the CAN peripheral.* z- B) r: U# T: N* z
  461.   * @param  [in] Message: To store the address of the receive message.' w+ R; i% o9 m( ~" A
  462.   * @param  [in] Number:  To read the number of the received message.
    9 Y7 _: o3 l- C1 N( X
  463.   * @return The number of message obtained.8 E  h& X* H; R# E* d9 t: p4 E* N
  464.   */
    ; Q( d3 w+ P/ K5 f. ]! Z$ j- H
  465. uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number)
    8 H  k' [; V2 r! G3 G1 n
  466. {. X) w2 o2 B6 r
  467.   if(CANx == CAN1)$ x- R2 K& x" A) A1 e) h
  468.   {
    - E1 Q( b3 d. M6 N
  469.     if(can1InitFlag == true)3 C" ^6 z6 r2 h  \1 O- v
  470.     {
    & J# ~0 G" |5 ^3 F4 y# Q" r
  471.       return RingBuffer_Out(can1RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);
    : O# L2 ~' [* O8 G3 y
  472.     }# c. g# d+ j+ W6 e% x
  473.   }
    " x# p1 v+ g6 J& a

  474. $ T& m$ d4 i, U5 J% H& J* a
  475. #ifdef STM32F10X_CL6 |) `9 q% V+ l  {- O) Y' q4 D
  476.   if(CANx == CAN2)9 s8 \5 \, S7 X
  477.   {6 o! b! g0 V$ ~, S
  478.     if(can2InitFlag == true)
    & t: f- [* s5 @( O: s! @1 O
  479.     {
    & z2 }4 v& }# n' y/ W7 m
  480.       return RingBuffer_Out(can2RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);
    # M5 R6 r! s2 i( a$ j& e, |
  481.     }
    + P0 y% J! Q) u. n4 u4 I
  482.   }
    ! h' a* s3 }8 Z* Q! j  W
  483. #endif /* STM32F10X_CL */" x5 H  B+ k9 H3 a2 O4 ^' e& `- z( ]" u

  484. ' p; r7 Q1 A  q' D0 @/ z4 k/ }
  485.   return 0;
      D4 b" w  l) r) W2 N
  486. }) F5 z6 U" a4 {, g
  487. : h# ~7 C, p  y# V5 R& u
  488. /**- M3 o; |! V3 @( s0 {' n
  489.   * @brief  Get the size of the CAN transmit buffer used.
    ' q5 m7 S* `4 }  _9 C% f
  490.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.7 h& [  N2 a- ~0 Y$ Q
  491.   * @return Used the size of the transmit buffer." T$ @, R0 R+ @
  492.   */1 n. j3 B( S0 L4 I
  493. uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx)
    3 H  L: X7 T% x. w* Z
  494. {
      v5 F& o8 X; e2 w- M' ~
  495.   if(CANx == CAN1)
    ; _+ F& k& G) @! G$ ^4 a8 ?% U
  496.   {0 D) y6 z, u, O" z6 ^- s
  497.     if(can1InitFlag == true)% M0 ?' Z" ?# i- q" o5 y- h
  498.     {
    2 m' I& J+ P# u& u) {  i! ^( C
  499.       return RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg);8 X  V6 {! J6 n1 ]
  500.     }( r3 k( x, `5 K$ e& _3 w2 H4 ]
  501.   }
    - W) ?" S' ^0 F5 T

  502. $ X! u- w- U" H/ U) i
  503. #ifdef STM32F10X_CL
    . x4 J: a; @1 o. C( @
  504.   if(CANx == CAN2)
      u5 @6 C6 w2 H* I6 B
  505.   {
    & V& S; N, B, A$ J1 H5 p
  506.     if(can2InitFlag == true)9 r3 c% L4 X$ q. F3 a) Y. u# |4 x$ B
  507.     {- F& D. c4 a+ h$ X3 f1 E( J1 _& a  J0 S% E
  508.       return RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg);
    - B8 r3 E7 t7 j
  509.     }" m  N% y% I2 v* \3 Z
  510.   }
    # R. V* q8 Z8 ]+ p+ G# f$ P
  511. #endif /* STM32F10X_CL */. N/ t! p% l  n$ Y% ?1 [- v
  512. 3 a6 ?" D! T- z% W
  513.   return 0;9 e- C4 X  e3 q3 S- W8 ~, V0 {
  514. }
    4 S, ?' @+ j! m3 L+ ~  N
  515. / L3 c% H& o& |+ _9 T1 n
  516. /**
    9 S6 [3 S' @1 I. Q, _$ J3 ?4 B5 @0 F
  517.   * @brief  Get the size of the CAN receive buffer used.% V! E9 a: H/ W
  518.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.% G* W/ q9 Q3 T2 }) j1 o$ |9 `. ]
  519.   * @return Used the size of the receive buffer.! f+ r6 G2 _$ E9 t8 E+ Z4 I
  520.   */
    & i- J- M! E7 B$ ~) v3 E6 J2 b! @
  521. uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx)0 A# u4 e$ Z: q/ [6 I
  522. {
    % O) Y5 K' A( i8 `" Y  ]
  523.   if(CANx == CAN1)
    + {2 z% v/ z; r" S
  524.   {# o  Q1 K9 J4 ]7 F
  525.     if(can1InitFlag == true)
    & v3 O" j7 K) P) }( G6 w* @- K
  526.     {! g& h1 M5 {  c& R; j  h8 n/ `' L
  527.       return RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg);7 U  T. L- P) J  ?
  528.     }
    ' v- T) D) E6 E+ L
  529.   }
    & T# H% U! t. B8 h/ i( \

  530. " V4 @) x+ \! D0 ^) d
  531. #ifdef STM32F10X_CL8 i1 q6 c5 c! H- f" K
  532.   if(CANx == CAN2)& H, u. _8 P" E  l, _! m+ C
  533.   {
    7 ]' `9 f* u, {. h) U
  534.     if(can2InitFlag == true)- p$ o# E7 x) D' g4 w" t. p
  535.     {$ i! Q- J0 @: U+ R9 Z
  536.       return RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg);
    6 h+ A. z; ?( d% e
  537.     }
    ( S, ?- J4 X5 u& Y- |. j$ n1 b6 S* C
  538.   }
    & y* O4 z9 Y2 P+ V, y: v' C2 x
  539. #endif /* STM32F10X_CL */$ y. h; B; v0 r5 g

  540. ! f: }6 Q6 o! Q
  541.   return 0;: q$ x% d$ k  ^1 ^1 u1 U0 u$ S2 ]
  542. }9 \. V8 b# H4 b8 u! U% I% `2 L& P
  543. & L( S& F3 u/ p+ ~9 _
  544. /**
    % x( ^5 Y: U+ E
  545.   * @brief  Get the size of the CAN transmit buffer unused.5 k$ e; r/ b: b0 q$ I8 N, j( c: v5 H
  546.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.; s& J: X* X/ w- D3 P
  547.   * @return Unused the size of the transmit buffer.
    8 z% ~& Y- J! H7 P
  548.   */6 l3 ]; L& S# N$ q& @( a4 {
  549. uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx)% {  [3 k$ i8 {  Y0 ]) _
  550. {
    1 j/ a0 X/ i7 k3 q
  551.   if(CANx == CAN1)* C+ M1 h0 P. q7 Z5 N5 D
  552.   {
    . K, X% t4 Q# w- ]) g* i: d  p
  553.     if(can1InitFlag == true)* r% J6 q( J1 o: g- m; ?  g( n
  554.     {
      s& b4 ]' l9 F5 O" W% o
  555.       return RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);
    , U1 E: d) N. s' E
  556.     }0 p- A0 K# b+ ?: n) Y4 m% N6 M
  557.   }
    ; u2 r( D& C4 z: S' D

  558. - ]# w/ ~8 J8 i# e5 g4 D5 _3 k
  559. #ifdef STM32F10X_CL9 B! C/ b" `$ Y6 O
  560.   if(CANx == CAN2)* V" }; j: [, K3 Q0 \! @9 t. r
  561.   {! b( ?' d4 e' F
  562.     if(can2InitFlag == true)
    ) M$ D5 B8 ^( A- y# a  ]
  563.     {
    ' T+ a1 _# j8 N. O+ b6 Y
  564.       return RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);/ y. k5 f& E/ O5 ~
  565.     }
    8 F6 d; [: n+ @1 w) x
  566.   }
    9 x8 m! B+ W* N" O6 \4 `0 A
  567. #endif /* STM32F10X_CL *// h# ]# e7 q! _3 E7 }& Z2 Z6 q

  568. 9 N# i1 L& G' G* E7 Z+ x6 z: Q
  569.   return 0;$ t# u8 E( |3 V" s/ |8 R( ]
  570. }
    ( }. K/ [/ \* O6 h2 F- }9 u

  571. , C  X" c5 |% X" C3 I
  572. /**
    9 C& S- t- ~! s' g* a2 d
  573.   * @brief  Get the size of the CAN receive buffer unused.
    ; E! C! D$ U5 T- e5 X
  574.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    , \, I, R9 D3 C% N" E
  575.   * @return Unused the size of the receive buffer./ I, V/ J( h1 C: z
  576.   */
    / g- O8 }  M. y) g: ], l
  577. uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx)
    * M" m; r# z& D
  578. {
    ( X7 ]% l5 T5 l+ V: [0 E
  579.   if(CANx == CAN1)$ A9 D; `& g% y2 H: q4 F
  580.   {1 q( u9 x  W  u& Q! N2 R# i$ B  m
  581.     if(can1InitFlag == true)7 P$ I: n8 u+ ]% K6 F- V' |7 i
  582.     {
    1 U/ H5 g4 l6 k- F
  583.       return RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg);
    , t7 n& ^' ?3 t' @  e6 D3 s
  584.     }
    ! V0 S# I( B7 t  H) P  |$ r# o
  585.   }
    4 ^; t* g! S, O  P7 M4 z) S+ D

  586. . T+ C- {3 ^1 n! Y# a+ y0 S
  587. #ifdef STM32F10X_CL$ C7 N9 }8 [# J8 D! X1 i$ j3 d* E
  588.   if(CANx == CAN2)5 I( }% g5 H# k( L7 O, _
  589.   {
    5 D( b: k! O9 `, a
  590.     if(can2InitFlag == true)1 `' E: q; V, p  a8 ~" w* y& T
  591.     {
    / \' }* P+ j1 A8 n8 p; w5 m- F( E
  592.       return RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg);# S* ?5 R! m4 r
  593.     }
    & U0 S3 d2 g7 l" a9 h$ a
  594.   }
    4 {' V6 M; R3 s. i& f
  595. #endif /* STM32F10X_CL */
    ( C" i2 L# ~+ H. V* s2 X. l  q7 A6 D
  596. 0 \! o1 i. c+ }) {% H
  597.   return 0;
    8 n# D- l$ ^5 j: v& z1 ]
  598. }
    / r& b! l$ @( h* f, S( K& l- d
  599. " h) Z) I6 @" k- O( p3 G$ J1 }
  600. /**
    : D8 e1 V$ u6 I+ n+ C; [
  601.   * @brief  Is the CAN transmit buffer empty?+ x& I4 ~0 v) @9 n" h( A. o
  602.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    8 ^% `+ a* c* ]) {/ C. Z
  603.   * @retval true:      The transmit buffer is empty.
    ' `% y+ \# h7 w. x
  604.   * @retval false:     The transmit buffer is not empty.
    $ B1 a/ K  |- F1 `. y+ N
  605.   */
    6 Z, w1 e: k" J6 k) \* Q
  606. bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx)
    ; L- Z$ ?% T( b# W
  607. {
    # i- @2 F! B: \3 D9 V, Y
  608.   if(CANx == CAN1)( K3 I4 c! w2 [% e5 e9 P
  609.   {
    8 q8 c- O: H- r  `* Z; b5 s1 b
  610.     if(can1InitFlag == true). m$ m6 _7 X0 h/ O  N& ^
  611.     {4 J% j9 n: N: ]# k, J# C8 Y  ~
  612.       return !(RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg));
    % l; K/ V1 X# j( _% v- m. a
  613.     }
    2 y4 n2 U+ T! T0 u- Z) J
  614.   }
    + d2 b) x$ Y' E  m4 m" z
  615. 7 F0 d  F9 l% @+ q
  616. #ifdef STM32F10X_CL
    ' t1 D! I1 f# H
  617.   if(CANx == CAN2)0 Y5 x* o9 x$ t3 O( U' w
  618.   {
    1 I' Y4 n2 ^9 Q
  619.     if(can2InitFlag == true)
    + Y* a* N3 ]& @! O& C
  620.     {
    . r) x2 B) D4 z6 l
  621.       return !(RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg));
    ' c! z7 d( H! c4 ], @& ^/ R
  622.     }
    2 r; \- H4 N9 _5 C
  623.   }
    ! B0 @; G7 z5 a2 R% g$ H* S; r
  624. #endif /* STM32F10X_CL *// N! f, K1 u+ ~: z8 y

  625. 8 u- H8 E0 @  \; `! _
  626.   return false;
      `. ~% Q! b9 j( x( F/ I$ O
  627. }, w0 u) t" l( ^; d' m  t# _" b( g/ n
  628. 5 Z: S, g; L: q
  629. /**
    5 ]5 i; C6 y% X0 @( T
  630.   * @brief  Is the CAN receive buffer empty?
    + i0 [( Q- Z6 ?
  631.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.$ `. t8 r  m3 E, p" F6 R9 h  i
  632.   * @retval true:      The receive buffer is empty.
    % I3 a# v% C4 P1 h
  633.   * @retval false:     The receive buffer is not empty.
    $ o/ J0 t: E; i( v9 r
  634.   */2 Y" A# t( o) h+ k
  635. bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx)
    2 J# a% T$ ~; J3 g* p; X# Q4 b
  636. {# u; d1 e* b2 X! k2 J
  637.   if(CANx == CAN1)
    & }- I4 F* U6 i9 }1 Z% K
  638.   {
    ' g" V: {  J9 Q5 f5 r( d
  639.     if(can1InitFlag == true)* a( X+ e9 d+ [6 _  M- y! E. S+ e* J
  640.     {
    ) d/ Y9 a; n5 g( }5 }" {+ R; w
  641.       return !(RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg));
    ! k% k; }* N4 U# J
  642.     }  H* Y  F; W6 J
  643.   }4 I2 C/ m9 e% C" C
  644. - e0 V3 K, q# W6 Y' D) Y
  645. #ifdef STM32F10X_CL
    * ^8 H# _, G8 J
  646.   if(CANx == CAN2)7 p% @& A3 U5 t; P# |6 N
  647.   {
    6 y3 K- M' N8 f  G
  648.     if(can2InitFlag == true)( \. {, T! i# o" z+ c* w, \2 `
  649.     {
    1 V2 k* r* G0 s) i& h; P0 ^0 q
  650.       return !(RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg));2 r, l8 M; R  `! U! @' ]* R3 o
  651.     }3 A& ?& k% I0 d3 G6 S6 r
  652.   }
    # G- z+ ?; q- i! Q$ R  `) Q( ^
  653. #endif /* STM32F10X_CL */
    ' e( G$ @  G4 \3 s" f4 P

  654. 1 ?3 K) S. W$ \* _0 w! a2 F
  655.   return false;
    * j8 L9 q$ y0 D" e& i
  656. }& ]  B  d( ?" j. N- Y/ Y/ [$ }4 ~

  657. 5 ?- I/ \0 u" i* {
  658. /**" J" m( x& v6 ^0 K/ p5 `! P
  659.   * @brief  Is the CAN transmit buffer full?
    * Z  k8 C7 F+ j$ G3 D8 Y
  660.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.& l0 a& O5 O0 j" Y/ k. D8 I/ n
  661.   * @retval true:      The transmit buffer is full.1 {& s/ H  {' G/ I3 e9 f  t7 y3 x# K
  662.   * @retval false:     The transmit buffer is not full.
    ) B2 {" y  u# V
  663.   */
    8 E2 R. O, o  R. L( z$ E  `
  664. bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx)# q: `3 O0 c7 w+ N0 R8 @7 }  ~* R
  665. {
    # ?" y! N  L& M: T$ w/ v
  666.   if(CANx == CAN1). |& O: y. Q3 `
  667.   {: I  T' Z. W) \* T) B. z
  668.     if(can1InitFlag == true)0 g+ w, ?7 e! q+ d
  669.     {
    ( [- y& }  H5 M% Y' A8 T( x
  670.       return !(RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg));
    ( [" G1 X9 F0 {& Z& W& l% P2 ]
  671.     }& R5 ]. V- L, J0 ]0 l+ N3 g, @" ~5 ]
  672.   }: ]) S, t' |+ b& q! v6 z- X
  673. " g& _4 H( D- D9 I" E- a, K
  674. #ifdef STM32F10X_CL
    ! `0 o2 a4 m" `5 h3 |4 R3 L
  675.   if(CANx == CAN2)3 n; H; ~1 U& k( f
  676.   {) c! [% a- T' w7 u& q8 p8 c& v) i( Y
  677.     if(can2InitFlag == true)
    ( Q5 U2 N) W" w+ _+ u
  678.     {8 C$ L) v9 h  L. _4 o: k5 @6 A9 Z
  679.       return !(RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg));- e7 v8 [; z  U0 g
  680.     }
    $ w) E3 J; x% \& f
  681.   }+ O9 `) l: O4 M! J% P
  682. #endif /* STM32F10X_CL */" m3 x/ q# c, ^& u' h7 R) Y
  683. ' e* ]8 U. z6 w
  684.   return false;5 v2 _/ i( G+ d2 n6 a( m+ {& y& D2 Y
  685. }
    . e/ x& X. K; @4 m
  686. / {2 a8 D/ ?. K8 z1 y0 b
  687. /**
    : F: s1 A; e- z+ C
  688.   * @brief  Is the CAN receive buffer full?
    3 [: ~- F1 c2 P
  689.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    % L! ]0 Y, z# H6 A: G4 T
  690.   * @retval true:      The receive buffer is full.
    ' e# ^/ ^9 s1 H. `2 K
  691.   * @retval false:     The receive buffer is not full.: ^/ _' q! |$ D4 i9 j8 ~
  692.   */, v9 W+ ^( ~) y2 _
  693. bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx); N6 O# R2 J" F, c- Y- I
  694. {
    ; y; ?! D, O: p! O8 H7 ]! d
  695.   if(CANx == CAN1)
      d$ f& f* n1 b  S$ O
  696.   {2 x. f9 j) y7 q6 u. c4 E5 B4 m! L
  697.     if(can1InitFlag == true)/ P3 V% |) h' d4 M' R* a9 x% H
  698.     {
    ( P8 [  C# m# _8 X3 ^) b# X
  699.       return !(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg));# a+ d* L" f7 m. T8 b, n
  700.     }
    1 A3 C$ ^+ c$ ?* q2 l) i. Q
  701.   }8 U0 E# @! o" ~( @* W

  702. 4 c& E# t1 f- R0 q2 h$ i
  703. #ifdef STM32F10X_CL4 I8 N: |; |+ L. u
  704.   if(CANx == CAN2)- \* ?, C9 g4 V
  705.   {
    8 W* |. c1 g% n) w! G
  706.     if(can2InitFlag == true)
    6 T5 j& v* W* o5 j7 J$ J' Z
  707.     {
    & @0 n8 ^) U2 [' W3 L
  708.       return !(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg));4 @' a! ]+ b+ u* d) Q. \
  709.     }
    $ i. U8 q; t7 p  ^
  710.   }/ ]- G" k  \' ?# H0 [! w) a- w
  711. #endif /* STM32F10X_CL */
    " V% q' M' O: V( ]* S  Z
  712. 2 _' c$ @  u/ E# M* H
  713.   return false;3 u, T7 M1 [) X' C* y* h& a
  714. }: M$ C; g) p1 O# k! N
  715. 4 `2 T4 s/ O, M3 c7 t' Y0 f6 c/ x$ t/ S
  716. /**( C" }  h" @& s+ S0 `: q8 {5 A
  717.   * @brief  Clear the CAN transmit buffer.; M2 M& C' A0 N" a  O
  718.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    $ ~7 I9 F  t9 ]% u* u
  719.   * @return None.
    . d# g3 A9 `7 ]4 Q6 P- E# p, d
  720.   */! U/ i+ ^: P! t9 s
  721. void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx); i1 p7 G' S) b) w8 ]' Z
  722. {5 _0 p+ W# }1 w7 ]" t* ]
  723.   if(CANx == CAN1)
    % d5 U- _) q' r6 N) x
  724.   {9 ^- Z; {1 B) \; d7 L: G
  725.     if(can1InitFlag == true)
    8 {  L4 M$ [( x5 a" e% g+ w
  726.     {
    + o4 l, T+ }4 d) |* M- ^
  727.       RingBuffer_Reset(can1TxBuffer);
    & ?: C% }& m8 b
  728.     }% U! v& d( n% o$ r& E3 U
  729.   }
    ' X9 w' g1 K) ^5 N6 a# m+ b) w

  730. 3 c4 I* n: O+ X' x5 z! [" @
  731. #ifdef STM32F10X_CL
    , n2 z" n. z$ i* H2 r
  732.   if(CANx == CAN2)
    : J- [  A% }' h* M# ^" W4 U
  733.   {& B% Y: i6 v6 R4 B4 K. T+ c
  734.     if(can2InitFlag == true)$ J! a0 G' c  C, _+ L4 F- a
  735.     {
    0 r/ ^3 ?5 _" r  _3 f+ f! l0 j+ C
  736.       RingBuffer_Reset(can2TxBuffer);% ]3 l9 n1 L) k! \) D
  737.     }5 W3 i3 {9 ^' j' {; E, v  f
  738.   }& q& |' E: s" R& Z  M; \7 f
  739. #endif /* STM32F10X_CL */
    6 [* b! ~3 u2 \
  740. }" T6 P3 P! k9 y3 U" p
  741. + {" d! b& {) e9 X# F
  742. /**
    / d3 l* b( I9 Z1 B6 o- F2 T9 n
  743.   * @brief  Clear the CAN receive buffer.
    9 m8 D: S0 j8 s1 d
  744.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    # s( Y1 S5 W! u' k) z
  745.   * @return None.
    2 Y4 `6 I- x2 n
  746.   */$ w& x- K# b. ^% v
  747. void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx)
      f, B6 ~1 m6 l4 B4 ^' v, E4 O
  748. {3 h. E! n9 y$ ^) j
  749.   if(CANx == CAN1)  p" A% J* @7 s# i- x
  750.   {3 U; y2 O+ B( K5 R. T* K/ |
  751.     if(can1InitFlag == true)
    3 H2 m4 T( H! R1 u) v+ K9 u
  752.     {
    : D' Q0 G: k8 G+ c
  753.       RingBuffer_Reset(can1RxBuffer);6 _6 @+ N  v( H
  754.     }- n& n" a  P' a
  755.   }
    % d# f( d: d: {/ `; R8 Y2 J+ o

  756. 7 R& v3 Y' D/ e* R
  757. #ifdef STM32F10X_CL) R  e2 L7 Q% u7 X- j
  758.   if(CANx == CAN2)
    8 C9 R' s9 P" m8 w5 _5 U
  759.   {: C$ M6 E; N( @7 r
  760.     if(can2InitFlag == true)
    0 F1 n# f/ U$ n" q7 S/ |$ e
  761.     {# }; W9 T- @! H/ j9 I
  762.       RingBuffer_Reset(can2RxBuffer);' J* W, ^$ Z9 ~6 _9 E, ]
  763.     }0 c! ^3 ~( h% ^3 O8 |# D! G
  764.   }
    2 A7 N) m8 b1 }1 @; g3 z  H6 A
  765. #endif /* STM32F10X_CL */
    7 S1 i* I; M8 I9 `* Y
  766. }
    7 [; W! V2 z$ l5 v1 V- Q$ U" C

  767. % @$ N0 Q5 H" `* P4 R
  768. /**) U; O% B3 J' i* p0 u; v: i- L
  769.   * @brief  Is the CAN transmit a message?
    9 i% ^/ ?2 {/ l& \! R& g1 ?  Q
  770.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.1 ^8 J; c6 k4 g0 Q" n
  771.   * @retval true:      Is transmit a message.
    ) D4 l5 o  d4 O3 O* K2 B% |- s
  772.   * @retval false:     Not transmit a message.# b$ B4 v2 ^6 X4 L. Y- @0 a
  773.   */
    9 M( T/ i5 T0 R
  774. bool CAN_IsTransmitMessage(CAN_TypeDef *CANx)* M) k$ M' e1 Q* y
  775. {
    # g* f/ e! R* O! |, A
  776.   if(CANx == CAN1)
    # I! \( N( l6 x; D% G
  777.   {% y0 ~3 g+ k( X' Z$ O4 N6 O* N
  778.     if(can1InitFlag == true)/ R; A; Z% \1 q3 D, R
  779.     {" _& @$ F/ w( x# I, Q' l
  780.       return can1TransmitFlag;
    , r& o! p5 g' c8 u) D/ \( n
  781.     }) T& V0 L$ r4 ?* _
  782.   }
    4 C4 {6 H. V/ ^1 Q  b( v
  783. 2 m& j% p8 [2 l$ G! X5 _  h
  784. #ifdef STM32F10X_CL
    . ]* y2 {( L, H$ b
  785.   if(CANx == CAN2)& A: m! |# w1 ]( q7 B4 ~3 z: J
  786.   {
    ) p* [9 d. ]  Y% {
  787.     if(can2InitFlag == true)
    " p3 @) Z* k1 @; F( ^9 W, ~
  788.     {
    # ]6 X# d; ^. L( |1 v8 f
  789.       return can2TransmitFlag;
    " {, Z$ I' K4 \" Q" I7 a/ p
  790.     }$ {2 z6 }. [3 |2 P: y4 j4 ~- w, W( i  E1 T
  791.   }2 l0 H; C* a0 W5 \: G7 {
  792. #endif /* STM32F10X_CL */, X( y  s7 ^; z9 _8 y, m  l% z

  793. 4 Z* t# d4 c/ Z, r, E
  794.   return false;$ O  U' K$ Q! b8 d( c3 K( T
  795. }# a. [% I! ]: r4 Q- v

  796. ! V. P  F3 q7 `" D0 k* w$ K9 D
  797. /**
    4 q$ }: a' D; k& z; d6 d- f1 K3 s
  798.   * @brief  This function handles CAN1 TX Handler.
    " t+ j' H! d/ z5 A. U
  799.   * @param  None.
    $ t$ m. B2 A& G9 b
  800.   * @return None.9 j( m2 B5 h+ W" P% w, H# ^& Q
  801.   */
    % X& i1 |& c! ?3 Z7 ]; n- s
  802. #ifdef STM32F10X_CL+ ~+ C- c8 z* ^
  803. void CAN1_TX_IRQHandler(void)
      U1 ?- q" o% I( b0 u
  804. #else
    8 n; ?" ~& m' I" J
  805. void USB_HP_CAN1_TX_IRQHandler(void)3 Q: l" t9 F9 [. Z& t% }: y7 }/ u
  806. #endif /* STM32F10X_CL */
    7 {* U* k! @! q( ^/ ^; t- K
  807. {7 [. q1 s- e, B
  808.   if(CAN_GetITStatus(CAN1, CAN_IT_TME) != RESET)* t; G6 w' Z' B  g9 n
  809.   {
    - R: B: I9 f8 ^: P0 j' ?, r+ u* Q
  810.     CAN_ClearITPendingBit(CAN1, CAN_IT_TME);
    / h( h; D/ }6 I
  811. % d+ |) P7 c5 M7 F' D5 M; T
  812.     CanTxMsg canTxMsg = {0};' K7 a7 D4 {/ S
  813.     uint8_t  number   = RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);
    9 S! ?- c) [0 f% U. N
  814. ) d! K% x0 k- t6 H& P) w
  815.     if(number > 0)
    % i3 q, y7 R0 o
  816.     {+ ~7 g( U$ a; T2 l. l0 z
  817.       CAN_Transmit(CAN1, &canTxMsg);
      x: ~6 X1 [# ~9 `3 L, V# V% Q# L
  818.     }0 R- C- a0 R" Q6 Z6 ?$ A
  819.     else3 q1 s5 U* _$ b4 j( I
  820.     {& `5 [0 j: A' |5 c- {  B
  821.       can1TransmitFlag = false;
    6 ]& ^: r- |8 ]) Z" @' q$ j. J
  822. , G1 {! F2 G6 I, O$ p  _+ L% S
  823.       if(can1TransmitFinishCallback != 0)1 d" _" I/ p: G3 q" c6 k2 M
  824.       {
    ) A& Q- \6 g" Q' _$ P
  825.         can1TransmitFinishCallback();' B" S5 x% s4 B3 F9 ]' _& m/ b
  826.       }
    ) \) ~/ |2 O# X+ }( J/ n8 T: C
  827.     }
    8 s9 [( H& @  I" [( I( ?
  828.   }
    ) j' [8 ?3 D4 U5 [% {! ~1 d4 A
  829. }9 r0 N7 G3 X6 [& ?5 Q+ t2 a

  830. ) h! }& A! I8 ~$ f' ?/ M  S
  831. /*** Q6 n% K* q9 w. i! i8 C
  832.   * @brief  This function handles CAN1 RX0 Handler.
    $ l& f; @* q. N7 F2 h  X
  833.   * @param  None.
    & _9 q+ K! I! y4 p8 r+ G; f  ~
  834.   * @return None.
    , N$ f" i  T% m9 D9 }( E
  835.   */9 F) C9 n, d, \5 g9 V5 M- g
  836. #ifdef STM32F10X_CL
    ) O2 y5 P# C9 J* C, q$ D
  837. void CAN1_RX0_IRQHandler(void)
    5 P4 C5 V$ c. Y! t& @
  838. #else5 [8 T! y5 w1 }( O) Y
  839. void USB_LP_CAN1_RX0_IRQHandler(void)
    # v# z& s0 t* J: y
  840. #endif /* STM32F10X_CL */
    " U. D  @+ }6 K# D
  841. {6 S2 T: b# p' S# l# j
  842.   if(CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET)
    ) _7 v4 O  }" Q( G. t' J
  843.   {4 _) V8 v( l' l* p  [
  844.     CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0);' t& j: Y& t! ~7 M8 B  f7 ^2 e

  845. 1 O& w$ |) q7 K
  846.     CanRxMsg canRxMsg = {0};- V7 z4 R" D! n
  847.     CAN_Receive(CAN1, CAN_FIFO0, &canRxMsg);  }+ y+ G7 H+ Q& l  b! h

  848. 7 X2 o& B4 G+ @
  849.     if(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg) > 0)( a+ j6 F0 R( s6 q8 d0 g/ G
  850.     {& ~1 C1 M, r5 c3 u! S$ }7 x  K
  851.       RingBuffer_In(can1RxBuffer, &canRxMsg, sizeof(canRxMsg));9 U2 ~) H3 D6 W- K
  852.     }
    $ f. Q% J# ^* V: \  f& O. Q$ `

  853. - i% U$ B* x: h/ B4 }8 [0 O7 @) u
  854.     if(can1ReceiveFinishCallback != 0)
    ( f; W% B" h, I3 ~
  855.     {5 T* q! V- K% F8 o* U! ]1 v
  856.       can1ReceiveFinishCallback();
    3 r# J+ O6 X5 n
  857.     }( A0 _1 q+ W4 ~% d! \; g
  858.   }* L6 s* [/ O3 ~/ P3 k" m& G
  859. }
    8 t" B" `7 c0 P9 ~4 K4 X9 O* w

  860. , {; n! f& u" w; ?/ T# \/ R
  861. #ifdef STM32F10X_CL! X5 N3 O( q/ k' c+ I/ E" B) R1 \
  862. /**
    9 s/ a/ F) J% o3 d0 h  B9 Y8 O
  863.   * @brief  This function handles CAN2 TX Handler.9 [9 a) v/ w! y% \* p, a3 E
  864.   * @param  None.# r* ?4 s+ m- g* J" p
  865.   * @return None./ e8 h* F% r, W- A
  866.   */
    : ]8 }* v+ z- h) m2 _
  867. void CAN2_TX_IRQHandler(void)
    " r8 y% J6 P# Z- h. R
  868. {
    / h. L3 Z+ ^* I
  869.   if(CAN_GetITStatus(CAN2, CAN_IT_TME) != RESET)% S2 I+ s  w: u9 a+ L5 n+ M
  870.   {6 D% l+ z! M, k% z2 T' Q
  871.     CAN_ClearITPendingBit(CAN2, CAN_IT_TME);
    & P/ L$ _* B) u2 I( P4 h. C
  872. / [* m  w$ a+ y8 Y7 @4 N
  873.     CanTxMsg canTxMsg = {0};
    " r; q% p  d9 q' j9 K" x3 ^* \
  874.     uint8_t  number   = RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);6 U2 }8 N5 d$ u0 P5 @
  875. + F# j# ~/ ^- K2 \& f/ p
  876.     if(number > 0)7 {2 P# M" a" E1 n( F
  877.     {. P7 k' S6 f- t. B
  878.       CAN_Transmit(CAN2, &canTxMsg);
    , F( W' I- K8 ^' E" A, l" d
  879.     }
    - ?* l% H& p6 o: o9 e: D$ w" u
  880.     else
    ( s+ `: g* D4 L. b+ X
  881.     {# x0 s. a! u$ J$ c* |
  882.       can2TransmitFlag = false;
    ; a: `- m; p' ]7 t# C9 ^

  883. 1 _( U' N+ K0 Y, m
  884.       if(can2TransmitFinishCallback != 0)$ a3 [0 F5 V3 o
  885.       {
    4 R9 C' ?0 s9 I/ U
  886.         can2TransmitFinishCallback();; k& u$ O( |5 x
  887.       }
    - v  d3 j8 _; S1 F. e
  888.     }+ z9 O7 C9 u+ U9 x9 ?; G' P
  889.   }
    " S: B+ [6 ^- i6 R4 y6 s4 `4 P5 P
  890. }
    $ D2 L, O& r& `% X, ~* ^& x2 t$ f

  891. ( c1 n9 C" C8 s4 T
  892. /**
    " F" ~7 j* J6 u5 Y- y+ E
  893.   * @brief  This function handles CAN2 RX0 Handler.
    : t5 \9 I* f" \, d) W
  894.   * @param  None.; c; x. z! r' o* E
  895.   * @return None.6 z; k& [) B  D
  896.   */
    # w! p  i$ Y7 f$ t7 g. \1 \
  897. void CAN2_RX0_IRQHandler(void)
    , \$ n! l! a$ L( }1 I' i
  898. {% I, [4 W) i- }/ h1 W+ ^
  899.   if(CAN_GetITStatus(CAN2, CAN_IT_FMP0) != RESET)
    : ?( M: f: A- G$ Q4 s' e/ O, z) X7 `
  900.   {
    . C3 |5 a6 R4 z
  901.     CAN_ClearITPendingBit(CAN2, CAN_IT_FMP0);+ d3 F/ E0 e" X" ?- u0 O$ `

  902. : l/ T  o: A+ L# Q- o. ^* Q
  903.     CanRxMsg canRxMsg = {0};4 L" {; a& q0 v* ^; v. i- L# c
  904.     CAN_Receive(CAN2, CAN_FIFO0, &canRxMsg);
    4 a, v2 |" f8 z1 M$ `8 k
  905. ) x  E" v1 |8 s8 ?" o
  906.     if(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg) > 0)
    ' w7 m3 H( ^0 X
  907.     {3 N4 E7 A. l; ]2 i) M. u3 ]( @
  908.       RingBuffer_In(can2RxBuffer, &canRxMsg, sizeof(canRxMsg));; u6 z, e8 S$ T9 W& K
  909.     }+ N7 g4 W( V5 T
  910. 2 N5 N" q) V. Q! ]
  911.     if(can2ReceiveFinishCallback != 0)
      i# e! g  c  g, T
  912.     {6 z  a$ F7 b* Q5 I6 ?8 k
  913.       can2ReceiveFinishCallback();' t. k6 K9 x! `; s3 a$ {
  914.     }
    * P8 [& ]0 q6 r! _/ j: V8 r$ Q
  915.   }7 M+ D) Q* r* H3 \% u6 X
  916. }
    ; e% ~$ {9 ]1 `9 ?
  917. #endif /* STM32F10X_CL */
    # T0 g8 f" W7 B
复制代码
0 F8 p% j4 H3 p' C& N# u
, K# B9 g7 _  [$ E: F, e& u* T
main.h 文件, d' |& s8 B  j; [1 G# U5 Z* w
  1. /**$ L7 `2 H" ?5 r+ l) B/ c
  2.   ******************************************************************************+ o: @( |8 K; b* `
  3.   * @file    main.h
      @! R% r- o! b
  4.   * @author  XinLi
    0 p0 p! T. @4 F
  5.   * @version v1.0
    $ |% D/ N6 V$ u: K8 T$ s
  6.   * @date    24-June-2018
    $ |5 f. d3 E( `( Y  R2 H! I
  7.   * @brief   Header file for main.c module.
    . s5 T$ f# F+ p% t- M! }0 S6 \7 c
  8.   ******************************************************************************/ x! j) `! l+ H7 f- n2 n
  9.   * @attention
    6 v# Y0 I, d$ T* \
  10.   *
    7 p& L5 y4 G* P6 {( y
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>3 P% D4 F. g; |
  12.   *: x, C8 [6 J6 s. m* s3 E6 \) i
  13.   * This program is free software: you can redistribute it and/or modify
    5 y' v2 U: }5 L! O/ r1 p! A8 _
  14.   * it under the terms of the GNU General Public License as published by
    * D( @- b% z  W
  15.   * the Free Software Foundation, either version 3 of the License, or
    . x! n/ G% d: w0 o
  16.   * (at your option) any later version.
    ! J! F$ X) f' [) ]+ O; I- _
  17.   *5 a) R& d8 f$ \" F9 D8 }
  18.   * This program is distributed in the hope that it will be useful,' L$ h+ y9 e& v( S
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    8 M) Y2 C: A3 V2 Z7 q  I
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the+ b1 N5 U; ]& @5 n
  21.   * GNU General Public License for more details.
    6 x8 a& H8 O" ^0 i
  22.   ** k" H: Y1 i2 D4 r% ~7 L" L
  23.   * You should have received a copy of the GNU General Public License
      n) ?: m! N7 r+ ^$ M
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    / F1 t6 U, }% v1 K
  25.   *5 a2 V$ X, [% y5 y% G* `/ p5 |4 i
  26.   ******************************************************************************
    , |* i3 y) \2 m2 J( H
  27.   */
    / }% q8 D+ T- g1 ?

  28. - c3 t) p; I+ n) O) M
  29. #ifndef __MAIN_H
    & H4 _1 j; X/ }! v- M, Z, s7 A
  30. #define __MAIN_H
    7 X% ~) b: q& }. v1 Z

  31. 6 i2 N$ @/ M+ m" H. L! J
  32. #ifdef __cplusplus) n6 c1 M- i8 b  X+ J+ H
  33. extern "C" {
    / i& V1 c  k; D& f+ Y! Q# U3 u3 o# o
  34. #endif
    . b8 G8 v( B: B

  35. 5 j+ r! t5 M  G
  36. /* Header includes -----------------------------------------------------------*/. @' Q# w) M& Z( h$ Q6 o- |, r% J
  37. #include "stm32f10x.h"! X" }5 I: t$ c7 x- [( b
  38. 4 M5 x; B3 b. Q" X. j. J& ?2 P
  39. /* Macro definitions ---------------------------------------------------------*/- E& j2 Y% T% d' T! _) s( `
  40. /* Type definitions ----------------------------------------------------------*/
    ! \, T' z: D8 o0 Q) A: L
  41. /* Variable declarations -----------------------------------------------------*/
    ; l: J  D6 H) F8 M
  42. /* Variable definitions ------------------------------------------------------*/3 v8 P; z7 p/ f- J& [* E( H
  43. /* Function declarations -----------------------------------------------------*/
    ' Z& B! k3 S! ~* r5 f: t
  44. /* Function definitions ------------------------------------------------------*/& h- }+ }% u* w1 B, M; G$ |
  45. * f; t6 _* p4 q
  46. #ifdef __cplusplus" E! Y+ l' @" h
  47. }" m  D: u* X+ Q! q8 |
  48. #endif1 H3 Y# T3 z$ c, W
  49. ( f! ~- Y* l7 G4 w
  50. #endif /* __MAIN_H */
复制代码

! k/ W/ ]. D& I0 ^) t3 X
$ o( J4 {+ z4 P  c- t5 bmain.c 文件) q$ J% x6 m( P+ ]3 z5 U
  1. /**5 J- Q' v: W, o% c
  2.   ******************************************************************************2 P4 W. H! i0 e  g' O
  3.   * @file    main.c
    ; ^* v. W8 [( w+ \- Y( {
  4.   * @author  XinLi
    ' |8 t! H5 T" q! C9 P- b6 b: M# T
  5.   * @version v1.04 L6 L3 A2 r! K9 ^3 |. G" E
  6.   * @date    24-June-2018
    3 s8 M6 o- I6 ]- |( N
  7.   * @brief   Main program body.
    - Q) Z# D& u1 i# o5 P3 s
  8.   ******************************************************************************* `7 a$ {7 k7 ]% ]9 B
  9.   * @attention' g. U/ K( F4 `6 b) Q
  10.   *
    $ I$ Z' h) ]4 J, c$ y
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    2 k' @) S6 A; E: B; b
  12.   *& Z4 Q3 ~9 H& S  U: V* X4 q0 J8 x
  13.   * This program is free software: you can redistribute it and/or modify
    ' j" l% a) L5 \! }$ e
  14.   * it under the terms of the GNU General Public License as published by$ r0 D0 p3 x4 K8 n
  15.   * the Free Software Foundation, either version 3 of the License, or5 o* B/ i7 v* r  p/ T
  16.   * (at your option) any later version.
    6 E$ E( i$ S1 N, O9 {  L) c' ]
  17.   *; I& L) Y* d% P* g* `9 r& N6 u
  18.   * This program is distributed in the hope that it will be useful,
    & m! L4 }* ?2 L  ]  K
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    0 U8 b4 x! C& e0 {
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the% m5 i0 X4 B( v, _+ Y9 L6 ^: K! r4 Z
  21.   * GNU General Public License for more details.' @$ _. v6 T+ V: m/ K0 T* u
  22.   *
    ' e" p6 e0 h) J* s
  23.   * You should have received a copy of the GNU General Public License; F  h" y+ i% H7 K
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>) Z1 b: v' J5 \' t# C1 H5 u
  25.   *
    - v, b1 {& a7 Y+ f  F$ ?
  26.   ******************************************************************************
    + i( E6 B4 D1 R) T1 X4 a3 r& r; Z
  27.   */; M7 J0 L5 ]# N7 F

  28. 1 [. z3 Y3 |- f5 A- b
  29. /* Header includes -----------------------------------------------------------*/" l8 T* I; N9 _. u2 x- z; V; x
  30. #include "main.h"
    5 w; t  V7 C1 H5 S& L2 Q  M
  31. #include "CAN.h"* X2 z) H$ h) W& W$ j
  32. / ], h+ w% J4 d1 B1 t- y
  33. #ifdef _RTE_
    6 B5 R( ^) G; K
  34. #include "RTE_Components.h"
    # G7 o9 K/ q! a- q7 J
  35. #endif; y4 Z; {# y* o$ [  |9 o  F

  36. : R) k' {2 X4 t
  37. #ifdef RTE_CMSIS_RTOS21 Y0 g# O/ Q8 q8 `  g; p
  38. #include "cmsis_os2.h"2 M" W9 O2 p( Y, l% ~; {  Z  c
  39. #endif
    % l9 i6 L  S5 P, v8 n

  40. . e  b" b2 G9 p2 }/ G  w1 S( }
  41. /* Macro definitions ---------------------------------------------------------*/$ b# Y* ?, {; M4 n3 K
  42. /* Type definitions ----------------------------------------------------------*/
    : z4 D) h1 ?" o( }0 z7 `
  43. /* Variable declarations -----------------------------------------------------*// O7 ^& Y* `8 n! `
  44. /* Variable definitions ------------------------------------------------------*/. n6 c: ]4 n7 j/ R" i
  45. static CanTxMsg canTxMsg = {0};, N/ O; J" R: e8 G' b3 k
  46. static CanRxMsg canRxMsg = {0};. W& m: m/ m$ Q! j* H; j
  47. , n# [( l/ R) F6 z
  48. /* Function declarations -----------------------------------------------------*/
    , O1 N8 K1 D2 Z- A: \( ]
  49. static void SystemClock_Config(void);
    & K. C5 y4 e4 X4 J' [: c

  50. * a% P: N. W% r) C- p5 m& N  l8 s
  51. /* Function definitions ------------------------------------------------------*/4 {! D  W6 {# t" [4 L# w9 H

  52. 0 Q  g7 _) d; S& e
  53. /**) v; V( K. N( B
  54.   * @brief  Main program.# U% n/ }; y# p  i3 \! N) B
  55.   * @param  None.
    ) H6 P7 L. m8 S4 x2 O, r, Q
  56.   * @return None.
    1 W; v3 v: G1 x. X- p- W& A
  57.   */
    + u$ W1 g3 F$ ^3 \" R/ E
  58. int main(void); G: ~$ `* y2 y1 m- Y
  59. {: E* s5 G. |) X9 Y
  60.   /* Configure the system clock to 72 MHz */+ q: r/ L' J0 [
  61.   SystemClock_Config();' c1 U9 K" v9 t( U+ A
  62.   SystemCoreClockUpdate();7 O: l) a" o6 h7 [( [4 x

  63. 8 F. ?2 @( m8 S5 d
  64.   /* Add your application code here */
    0 z6 j9 \: P$ U- n2 o' d
  65.   CAN_Configure(CAN1, CAN_WorkModeLoopBack, CAN_BaudRate250K, 0xAA55, 0x55AA);, B$ v; q+ g+ y0 U: e3 T
  66. 2 g2 B, m. @/ P0 e) h3 S
  67. #ifdef RTE_CMSIS_RTOS22 f1 Q" F. e2 u! l) t0 v/ t
  68.   /* Initialize CMSIS-RTOS2 */
    0 Q3 p5 Z$ I# y* W% A: ?% \6 S
  69.   osKernelInitialize();
    7 b+ i1 k' p8 M& ?* L

  70. ) l  X8 ?/ D& J
  71.   /* Create thread functions that start executing, ) p+ C  {: i' d# a+ G
  72.   Example: osThreadNew(app_main, NULL, NULL); */9 z) B9 p7 A9 v2 R

  73. : P7 m8 U% Q0 A
  74.   /* Start thread execution */. @5 T8 `( J8 p) S: |4 v4 U& Y
  75.   osKernelStart();
    8 O7 q( D+ I6 X+ n5 P. i5 Y
  76. #endif
    & n! @2 p# B/ S6 k4 ?* i6 A+ j
  77. ( ^* d) n. u( S( z: g! g7 G
  78.   /* Infinite loop */
    . u% F( \3 A2 \/ n
  79.   while(1)
    - D5 K3 X5 \. l5 ]* m
  80.   {
    4 ?( u6 G: j4 Y/ X, b
  81.     canTxMsg.StdId = 0xAA55;0 S5 x+ i3 m% S. I) t$ [
  82.     canTxMsg.ExtId = 0x55AA;
    . J% ]1 B9 M, ?' w
  83.     canTxMsg.IDE   = CAN_ID_STD;
    3 N0 \9 {$ }+ E* W* _+ G) @
  84.     canTxMsg.RTR   = CAN_RTR_DATA;& H) |- @  h5 G1 H0 b5 h1 ?
  85.     canTxMsg.DLC   = 8;
    ' ~' O2 C6 o* i/ {! P0 z! p4 e
  86. / ^4 N: X" i5 A- M$ U' V& @# g
  87.     canTxMsg.Data[0]++;
    / q, d" S: ^+ Y
  88.     canTxMsg.Data[1]++;
    ' c9 p0 V+ V, f. _
  89.     canTxMsg.Data[2]++;
    - g) k: j1 a- @$ E& w( ^
  90.     canTxMsg.Data[3]++;+ @( U* n. H, j& A* U1 ?
  91.     canTxMsg.Data[4]++;4 @0 r  r8 y7 M. k
  92.     canTxMsg.Data[5]++;
    ! h+ ^0 o: @0 Q/ _  V4 l1 L5 R
  93.     canTxMsg.Data[6]++;0 `( U% L8 B1 L* g" Q. \4 b# @
  94.     canTxMsg.Data[7]++;# Q: w% H# R3 W  k- A! }6 h
  95. 9 {; r' t/ }: a6 P: p  }3 G$ W
  96.     CAN_SetTransmitMessage(CAN1, &canTxMsg, 1);( z5 n/ @* x% D: \2 Z' |
  97. 0 p$ N9 g3 T: R, L  e: U5 J
  98.     while(CAN_IsReceiveBufferEmpty(CAN1) == true);
    ; W/ [" {0 u8 {8 ]

  99. , T5 [9 v/ Q0 `
  100.     CAN_GetReceiveMessage(CAN1, &canRxMsg, 1);
    4 _& t0 V5 h3 C3 ]  l2 Z( b
  101.   }5 }: _+ M2 S' T3 e3 M: I: V
  102. }
    / Q- R$ H- t# M4 z/ x

  103. 3 h6 t4 Z) A. `2 A! r
  104. /**+ h# ?1 H" U! Y% b
  105.   * @brief  System Clock Configuration.1 I1 k' v* p* g: G, z9 }
  106.   *         The system Clock is configured as follow : 5 H: }. T! m8 W2 j, ^1 x
  107.   *            System Clock source            = PLL (HSE). K0 Y7 V' S- c9 _
  108.   *            SYSCLK(Hz)                     = 720000000 x. ]5 ^, l( X7 p) t
  109.   *            HCLK(Hz)                       = 72000000
    3 Q  ^( G* E. d! ~) y' q* U
  110.   *            AHB Prescaler                  = 1
    # O8 t% a" V8 W
  111.   *            APB1 Prescaler                 = 2
    $ u* _2 H+ Z& m: ?( S1 J# e5 s% r
  112.   *            APB2 Prescaler                 = 1
    : ~- \2 _! \8 |/ z; ]/ M- c
  113.   *            HSE Frequency(Hz)              = 8000000
    * H9 s4 L/ O$ S
  114.   *            HSE PREDIV1                    = 1
    - S  s4 ~3 N+ q  H
  115.   *            PLLMUL                         = 9
    1 H. X1 i$ f  C' Q' K6 J/ {/ S' w+ e
  116.   *            Flash Latency(WS)              = 2
    6 k. A2 x+ |2 g# n) U2 a2 b) T: ]
  117.   * @param  None.- a% g1 \8 [! o! S& w
  118.   * @return None.
    - |# D. `9 H+ A' [: d( k5 U: R: c
  119.   */" l$ x+ U% M2 y
  120. static void SystemClock_Config(void)% j1 j  `4 E0 S
  121. {
    6 p6 ?/ I: o! |7 m5 O- |. x
  122.   /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration */
    ! W" @( ~( y" A1 ^
  123.   /* RCC system reset */
      @4 F" b- |8 C6 f. `2 u
  124.   RCC_DeInit();7 b' S) R* v) r& D4 P3 `' v

  125. # [4 Q; k/ `) o+ `# S- I5 j
  126.   /* Enable HSE */
    6 a( Q( D% S, c, g- e
  127.   RCC_HSEConfig(RCC_HSE_ON);) W& L+ M. W1 d3 J; e9 [( I

  128. $ C& K% k1 v7 q, d( \; q
  129.   /* Wait till HSE is ready */
    " w) e+ L- n' R6 K7 B
  130.   ErrorStatus HSEStartUpStatus = RCC_WaitForHSEStartUp();
    4 f: a! a7 ~% n
  131. " X4 i- Y# g2 ~4 j1 N
  132.   if(HSEStartUpStatus == SUCCESS)
    + J$ Z& q5 Z) R* b
  133.   {
    & H# Q3 r% s1 v5 _* I2 m
  134.     /* Enable Prefetch Buffer */
    0 w6 ^( e1 {) o  d  w: u
  135.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
    " {  e& C1 s8 \6 l: r3 R; c$ b

  136. : y( Z+ ~- H" b5 E; @; I" {
  137.     /* Flash 2 wait state */
    ) [  z3 `( s' {9 X" p
  138.     FLASH_SetLatency(FLASH_Latency_2);
    . ]( \; b) q) H9 D$ B
  139. 3 k; R: n  N2 `1 o2 i
  140.     /* HCLK = SYSCLK */9 _) O' |  F4 U" o' F
  141.     RCC_HCLKConfig(RCC_SYSCLK_Div1); ! m+ c6 w9 b  P, E6 y: g8 D
  142. 9 ~9 n. W* E" u0 m: j. D7 Q- q
  143.     /* PCLK2 = HCLK */
    ! o7 P! m$ e9 F8 Q
  144.     RCC_PCLK2Config(RCC_HCLK_Div1);
    9 S1 S0 f7 n, m1 u0 b) i
  145. + J6 G6 @" x1 M8 z7 f9 u
  146.     /* PCLK1 = HCLK / 2 */
    2 F" k7 j, m! m" p+ o5 m
  147.     RCC_PCLK1Config(RCC_HCLK_Div2);
    % L- n8 g2 f! y  @4 g5 A

  148. # Q; V+ r& K" L3 ]0 x' r, m
  149.     /* Configure PLLs */+ [3 j+ ^8 m" n' c7 h/ Q5 J
  150. #ifdef STM32F10X_CL5 G3 A, |  B( o
  151.     /* PLL2 configuration: PLL2CLK = (HSE(8MHz) / 2) * 10 = 40MHz */% J( W* T( S$ v1 U' V# x
  152.     RCC_PREDIV2Config(RCC_PREDIV2_Div2);/ A+ `1 W# c( L/ F1 `6 d
  153.     RCC_PLL2Config(RCC_PLL2Mul_10);# O) r" T6 q6 W( r( k; r' A
  154. , a( ]" i: z3 G/ f) o( |/ v
  155.     /* Enable PLL2 */- d. \9 v; P  s/ x4 ^
  156.     RCC_PLL2Cmd(ENABLE);
    7 L& l( u) b0 o* G
  157. & L) g0 B' V  T; O" r, l
  158.     /* Wait till PLL2 is ready */' u% P* N1 m3 E! x  t+ a6 W) Y* j; \
  159.     while(RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET);, @8 v- k9 S2 O( b/ N/ c2 v" z2 E; k

  160. 8 m' V0 D0 L, P. e7 w5 m6 A. l0 @
  161.     /* PLL configuration: PLLCLK = (PLL2(40MHz) / 5) * 9 = 72MHz */
      L9 I  j8 o' i6 D$ v1 z
  162.     RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div5);
    " x- [. i* |) m0 b) y  X1 G
  163.     RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);: N# ~" d8 u  G6 u' }, I. j1 w2 R
  164. #else# M) p" ~: }% |5 Q, W! h0 b
  165.     /* PLLCLK = HSE(8MHz) * 9 = 72MHz */
    / V5 W. F+ W& l: k, ?# f
  166.     RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);0 Z/ W+ t; L$ Y. [5 {
  167. #endif
    , v4 x7 Q' l9 U. m3 b

  168. ; ?: N* I( a% o6 M; k( e
  169.     /* Enable PLL */5 c* g0 K: t0 B5 m
  170.     RCC_PLLCmd(ENABLE);
    9 t8 t& P  i. m$ e' Q* k! V

  171. / K* u7 B5 [" f, _8 K$ e7 E! g3 ~! W% y
  172.     /* Wait till PLL is ready */
    ; S# s, }/ `- z0 n% w# G: ~
  173.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);9 C$ J- K# |9 w$ M6 p
  174. 8 ?5 n& v) ^8 |9 h' x1 Q" I
  175.     /* Select PLL as system clock source */2 ]4 a9 v. R" N- j2 M9 s' _
  176.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    % [3 E' N/ u# m* }5 g; p; u
  177. 0 M9 r% [7 c8 l
  178.     /* Wait till PLL is used as system clock source */. G3 |- Y, V- g7 F/ i1 o' e
  179.     while(RCC_GetSYSCLKSource() != 0x08);) T0 \5 s: _$ o7 G1 Q: Z* d2 M
  180.   }
    0 ^# E& D6 ]( H$ K. Y
  181.   else
    ; ~! V3 Z7 }/ b8 i4 ?! O
  182.   {
    # V- q9 i  W' ~' D: F
  183.     /* Disable HSE */0 ~8 i1 k' B# D! }# _+ D& q
  184.     RCC_HSEConfig(RCC_HSE_OFF);, L8 I. S5 H( A+ N% F

  185. * Q- O7 `" k, Y: F
  186.     /* Enable HSI */
    . H; ~/ @( t( L9 M7 d
  187.     RCC_HSICmd(ENABLE);
    " C( A8 @! N3 A7 q

  188. 4 Q6 r) }! ^; b% ~' t# i' ^. e( q
  189.     /* Enable Prefetch Buffer */: s( g) a* _" K* b4 P
  190.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);0 \: q3 [" t; G" |% d4 X
  191. ( y" \4 |0 a+ a* k, s* u" o# [5 M
  192.     /* Flash 1 wait state */
    % U: O! g& z/ m" i$ v
  193.     FLASH_SetLatency(FLASH_Latency_1);
    + b1 A' c; f7 b% q- c2 C) _
  194. 0 g1 T: t" F/ i" H+ s
  195.     /* HCLK = SYSCLK */
    ; v' N0 U2 F. _. G
  196.     RCC_HCLKConfig(RCC_SYSCLK_Div1);
    - ]) |! C" T: A- {' s% t
  197. ' C( X/ u% |1 ]/ S3 q2 f2 {* X. N
  198.     /* PCLK2 = HCLK */
    / K- V0 t. p$ m5 u  ]
  199.     RCC_PCLK2Config(RCC_HCLK_Div1); ' }4 I6 @4 }, ^% t

  200. 7 T4 o* R, N9 H( O& T
  201.     /* PCLK1 = HCLK */& {# ]& w2 j$ b3 y8 ]$ a6 s
  202.     RCC_PCLK1Config(RCC_HCLK_Div1);
    5 z5 A: e* m) d% e! @. U
  203. 5 s& L, |# F# [0 d) c8 e  O
  204.     /* Configure PLLs */
      R& B/ j* S* e% g
  205.     /* PLLCLK = HSI(8MHz) / 2 * 9 = 36MHz */% S! L  F5 F5 m( t; Q; k8 Y* y
  206.     RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_9);
      }% f! X' q' P/ ^3 w
  207. : f, Q* M& u; T
  208.     /* Enable PLL */
    & A0 n" b% ]* g- R9 e
  209.     RCC_PLLCmd(ENABLE);7 L5 E% D3 z: }

  210. " z; D. j: p* u, c
  211.     /* Wait till PLL is ready */, ^% S# n3 D$ R, F: a
  212.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
    1 v& K/ G2 Y% D8 W: B

  213. 5 ]' \' g) |) R* a! B( I7 Z! D
  214.     /* Select PLL as system clock source */* p! L2 e' G5 Y$ d& s
  215.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);$ `' Y2 Q/ O# S  d8 T! `9 U
  216.   p. C# u" V4 P0 \* v, W
  217.     /* Wait till PLL is used as system clock source */5 l7 K* l- ]; }4 x  h6 m- j
  218.     while(RCC_GetSYSCLKSource() != 0x08);! {" Y* H* O7 r7 C) {
  219.   }
    5 m! _0 t. c3 [8 t
  220. }
    ( A6 z& m' r# G- h) f' ^+ u/ @( F/ U6 G

  221. 4 x9 f' |9 v& N$ R2 k9 d
  222. #ifdef USE_FULL_ASSERT8 b  }- t3 C$ J3 n* A. D) A- \
  223. /**
    6 _, D! `# m2 Y( x$ j
  224.   * @brief  Reports the name of the source file and the source line number9 i6 ?7 r6 V) k5 a0 G3 ?
  225.   *         where the assert_param error has occurred.* M) @* q7 O7 Q4 M9 c
  226.   * @param  file: pointer to the source file name.
    ' V4 a' R+ k' W6 S7 \
  227.   * @param  line: assert_param error line source number.9 G* h  n4 ?, `" U/ F, @
  228.   * @return None.
    0 {; ~) {8 A* ~& Y
  229.   */* K+ [4 ^2 Z$ q. X
  230. void assert_failed(uint8_t *file, uint32_t line): n7 p9 L# W: d6 U. ]! T
  231. {
    7 g6 w& c$ s1 _" x" y
  232.   /* User can add his own implementation to report the file name and line number,
    - F/ o, T+ E% l# N0 e1 m# |3 D
  233.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */6 j  j; G, X1 n# a
  234. & ^  ?) [) g0 G5 e7 V9 ~+ w1 P* j
  235.   /* Infinite loop */. r2 l" ?% x8 ~* H- Q1 D
  236.   while(1)
    * r3 h  V" q4 F% {9 S
  237.   {0 k# }6 i  J. I
  238.   }" k8 L' @/ P! m! D9 [* L
  239. }% y8 y7 E1 V' Y! |# b% Y
  240. #endif
复制代码
; N, J# n; x3 d2 U9 Z% y
3,注意8 ?) o8 U- f& O& G) v( ?% L

$ I  c8 Z& _3 b: Q' L6 M* v+ }* YCAN 消息发送缓冲区和接收缓冲区的大小,可以根据应用的需求进行修改,缓冲区使用的是堆内存,需要根据缓冲区大小和应用程序中堆内存使用情况进行配置。3 {# e9 d4 ^6 _1 R
3 G% ?1 |' r: y4 e. G
1 Q5 Z& A5 ], V8 _& t2 v$ O& R  _

' a( N# X/ A/ Y1 D& t* \
收藏 评论0 发布时间:2021-11-26 17:00

举报

0个回答

所属标签

相似技术帖

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