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

【经验分享】STM32F1(CAN)

[复制链接]
STMCU小助手 发布时间:2021-11-26 17:00
1,开发环境' d( ]. N, R, s2 [
7 |( c5 i3 H8 Z
1,固件库:STM32F10x_StdPeriph_Lib_V3.5.0
# N/ w! V/ g7 M' n" `3 T
! C( I8 ^. \& v/ T2,编译器:ARMCC V5.06
6 d, C7 [; [4 _: k4 G( g* p+ K: l7 Q- q3 H) @6 D
3,IDE:Keil uVision58 J8 x. o; O1 F& s
9 C0 o% @" D( `; V
4,操作系统:Windows 10 专业版5 S5 q' B# L/ g8 U. L8 B0 `

$ |& g4 r  D5 E2 k* g2 S+ R1 w8 ]( ~; |! _' b" [
2,程序源码
5 f$ j. I: X6 g3 G! |" N5 P# {3 t, n- l6 K; J% x& L
RingBuffer.h 文件
8 a3 e/ ~$ |/ z$ z# p8 v
  1. /**
    2 X2 d' N. w- X8 ^' Q" m: t+ Q$ q
  2.   ******************************************************************************- S) ^0 A0 y4 Z% a$ o
  3.   * @file    RingBuffer.h
    ( d* w9 Q9 c& ]2 O" T
  4.   * @author  XinLi! u4 l7 @. ?3 }+ a8 _9 J! h6 R9 `
  5.   * @version v1.1
    & x& `3 J# y0 v# K
  6.   * @date    15-January-20181 \" m9 w% ]! [
  7.   * @brief   Header file for RingBuffer.c module.6 z0 S% V' Z: ]/ \* A/ D; ]- p
  8.   ******************************************************************************9 e! q: B8 O9 [! Y9 X4 q
  9.   * @attention
    ; B& K1 S7 C; @* }& M
  10.   *6 Q+ i+ x& U) ?( e$ \% i0 ^- ?
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    # V( A9 w  H$ e" {1 B
  12.   *" h( n& T- T) y: ]" H: ?
  13.   * This program is free software: you can redistribute it and/or modify
    ! X# z1 v, Z- i  T7 X
  14.   * it under the terms of the GNU General Public License as published by
    ' W: C. g' |% E" T0 M# N9 w- ^' Q; D
  15.   * the Free Software Foundation, either version 3 of the License, or. X( X9 ^1 S; S, }* `( {
  16.   * (at your option) any later version.# P4 q) a: W+ S- {9 I; J
  17.   *
    3 E$ r: @( h9 }3 M& N
  18.   * This program is distributed in the hope that it will be useful,
    * B/ @) v# ]; f8 g# E7 X+ v
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of1 V! g% D- T; Q- g% q& f  w
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the, o: s  _+ S: |
  21.   * GNU General Public License for more details.' b9 t9 Z2 C  H+ h4 t$ @
  22.   *
    1 N4 e' F* v  \! d
  23.   * You should have received a copy of the GNU General Public License' n, |3 z. u9 X: J  a+ Q/ e
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    . j* G0 @( P6 O1 p8 n  A
  25.   */ [5 s- |7 M6 o6 m5 k
  26.   ******************************************************************************7 ?6 B( @8 t3 F' [# D) q
  27.   */; o) R* ?6 V/ ]5 ^2 W$ r9 |( R$ @
  28. 0 W' @3 d% K; e* V9 X+ Z
  29. #ifndef __RINGBUFFER_H
    , z4 [7 M0 f5 [
  30. #define __RINGBUFFER_H
    ) L4 E- w% p! P

  31. 7 `. x1 N8 X* {' g: M; r- E
  32. #ifdef __cplusplus
    ' `% x2 W9 |  \
  33. extern "C" {+ T% O# u4 K) ~8 _* B) a) K0 y4 V
  34. #endif
    % f; O7 ^0 ?( W8 ^8 U2 u8 u
  35. 6 s9 d! q: k5 _, J
  36. /* Header includes -----------------------------------------------------------*/% b" Y" p% N# Q9 H: @
  37. #include <stdint.h>
    4 n  \0 q- s  B  |
  38. #include <stdbool.h>
    & S: D. _$ ]: x6 P* ]& D9 K
  39. #include <stdlib.h>
    8 W' R6 ~; a- c4 N/ C% M- K8 R8 o
  40. / C0 P1 O9 D2 R* `- d& Z
  41. /* Macro definitions ---------------------------------------------------------*/
    ( [2 O/ m: v; }  k7 C
  42. #define RING_BUFFER_MALLOC(size)  malloc(size)7 j0 k' j1 ]# ]/ C! W1 D4 f
  43. #define RING_BUFFER_FREE(block)   free(block)
    * T5 {5 w) ?8 {. G% A2 T

  44. & R% A7 j7 @, ]3 w- S& @# \
  45. /* Type definitions ----------------------------------------------------------*/
    ' y( E% e# y# E* K
  46. typedef struct' D, ?- j) u; s/ C) ]& c. l, z! x
  47. {
    5 J& c" `; |( M% U* r2 S# Q1 H
  48.   uint8_t *buffer;& G6 P5 W1 a, _, N' v1 a$ s8 o
  49.   uint32_t size;
    ; D. i9 i7 Z9 p2 l- B: \
  50.   uint32_t in;
    , t2 k2 e5 ]! N7 {
  51.   uint32_t out;
    ( g/ y+ e2 Z9 _3 q: y2 y
  52. }RingBuffer;- A4 V- C" A# b

  53. % u2 n' Y: n$ ~. Z! h3 i: z
  54. /* Variable declarations -----------------------------------------------------*/0 \4 Z! `- s& i" \; J" X
  55. /* Variable definitions ------------------------------------------------------*/9 n" \, N7 F( x% \$ J6 ^. c1 b; q
  56. /* Function declarations -----------------------------------------------------*/
    2 o* Y( k2 Z) `7 y, |1 b5 D
  57. RingBuffer *RingBuffer_Malloc(uint32_t size);4 P2 h8 z# w; G( d" U" a
  58. void RingBuffer_Free(RingBuffer *fifo);
    2 a6 Y. n, _) {* q: c6 o
  59. 9 d8 [0 ^) I: `$ ]8 T" o
  60. uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len);
    ! @: }5 w: f5 y2 T
  61. uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len);( B; L) d5 G. \: F
  62. : S  Z6 Q3 u0 [- s7 |/ X. O! [
  63. /* Function definitions ------------------------------------------------------*/: j9 o" ^1 v8 o
  64. 6 ?3 m( i4 B5 X+ r- J( Z# B: ]
  65. /**& _, J% Y2 a2 T2 y
  66.   * @brief  Removes the entire FIFO contents.
    , Z9 K+ d# C: R9 K/ J% N0 k2 \
  67.   * @param  [in] fifo: The fifo to be emptied.
    0 M1 R3 H  f6 K) k% y1 q
  68.   * @return None.
    9 K/ i, l5 \" Z2 ?
  69.   */
    / P& t% F- a. M' t2 Y$ p. r" d; l
  70. static inline void RingBuffer_Reset(RingBuffer *fifo)
    6 [1 C) \! \8 v* ^  [7 _1 N
  71. {
    2 R- c5 U6 G! B, x; E$ I
  72.   fifo->in = fifo->out = 0;
    * Z, E  ?  X; _* i; C* I
  73. }
    : L: t% q- a4 m2 R+ V% m

  74. " u; y+ a9 X9 i, _
  75. /**
    4 y$ J4 q2 U; k9 R( V' h+ S  ]0 V* u
  76.   * @brief  Returns the size of the FIFO in bytes.
    ( j% l/ o" N& S1 V! A: Q  V" P1 _
  77.   * @param  [in] fifo: The fifo to be used.0 y3 T( T" f! f0 I. K0 B0 j8 `
  78.   * @return The size of the FIFO.
    4 {* R  \& R+ o) }
  79.   */
    ( N  e" Q4 U" z* a; Z% X& }: R
  80. static inline uint32_t RingBuffer_Size(RingBuffer *fifo)
    # Y1 g5 ~- t0 `4 Y. {9 z
  81. {
    * [: N, l& c8 w6 k! J
  82.   return fifo->size;
    # K1 j% @$ f3 @$ X
  83. }
    0 f+ `- I  J) S+ t. E) E
  84. 3 }# D! L# I$ y8 U) D. V% T
  85. /**
    8 `, E" s8 N- R7 s
  86.   * @brief  Returns the number of used bytes in the FIFO.
    1 M0 F' R9 T9 I5 X& d
  87.   * @param  [in] fifo: The fifo to be used.
    + j: S7 I7 S3 w1 @# S6 u) g" @; ^
  88.   * @return The number of used bytes.6 q* R5 G9 `0 X( ]
  89.   */" {: t1 D1 ?% W# O
  90. static inline uint32_t RingBuffer_Len(RingBuffer *fifo)
    4 n% ^. u7 q( h1 V( v" l, B% s
  91. {+ D: q: z! e8 Q6 R* ~
  92.   return fifo->in - fifo->out;: r* l, r' j' u
  93. }
    * d+ ^  i& |- A+ `6 A, E

  94. 9 H( O+ i1 y/ M+ F, q1 n% G2 r
  95. /**( N1 u4 `$ _* N* }# N' F; K
  96.   * @brief  Returns the number of bytes available in the FIFO.2 s' X3 K$ l5 e! e2 H
  97.   * @param  [in] fifo: The fifo to be used.
    ! q4 h" ]# C# c' ]
  98.   * @return The number of bytes available.
    9 m* i7 _5 W7 n2 \; j; w* [
  99.   */; |! c* h" j) `# I7 J7 G7 i
  100. static inline uint32_t RingBuffer_Avail(RingBuffer *fifo)3 T0 u) o8 l; Q/ y
  101. {
    . t2 e7 ?( H/ r
  102.   return RingBuffer_Size(fifo) - RingBuffer_Len(fifo);
    # j! k2 i+ \) I8 h" Q+ H- R
  103. }8 D$ p% g8 i+ }7 W0 ^2 X

  104. ' k* T) z6 F1 f4 \
  105. /**
    , ^' H; F# x3 z/ j: P$ `( |/ L6 y
  106.   * @brief  Is the FIFO empty?
    5 @. c' ^! h4 {/ }' A0 q- T* i+ A, u* m
  107.   * @param  [in] fifo: The fifo to be used.
    2 G) F7 g4 P8 m% X, m- c
  108.   * @retval true:      Yes.6 ^5 u: q: I# G( E* G
  109.   * @retval false:     No.
    " f8 @' `8 @+ O3 ?8 h, j" p/ m
  110.   */0 M+ y; e  o- J0 v
  111. static inline bool RingBuffer_IsEmpty(RingBuffer *fifo)
    6 E3 C9 s& p) B/ g9 y4 b9 K9 L7 R
  112. {$ ?6 G4 J* Z$ `9 f
  113.   return RingBuffer_Len(fifo) == 0;
    ) ?/ B5 y. V" M
  114. }) i1 d; H- n2 B& J4 Y

  115. - k  v% U- V" F1 E. Y& [; m
  116. /**4 {5 a7 J+ O2 U  r
  117.   * @brief  Is the FIFO full?8 P4 o* o# t- [, I! k  i
  118.   * @param  [in] fifo: The fifo to be used.
    0 ]8 j1 p/ S! V* h0 ]+ {% g$ j6 H
  119.   * @retval true:      Yes.
    $ G1 i' T0 r& E% z# a8 j* }
  120.   * @retval false:     No.6 g5 _$ r  k1 P
  121.   */
    # ?9 l# [. p8 ^5 U2 w6 E1 o
  122. static inline bool RingBuffer_IsFull(RingBuffer *fifo)4 V; ^4 O& H# R( G  v
  123. {
    % r+ A0 w. j/ ?% m$ H
  124.   return RingBuffer_Avail(fifo) == 0;% J3 e6 v: ]1 [; w' B
  125. }
    " z& z  p% T+ C% D1 [+ S

  126. % [9 Q- ^" ~: B5 ?7 ^' Q& V
  127. #ifdef __cplusplus
    % }+ R+ D* h! u" m# B: f( w& l
  128. }) c* z4 {* x5 W2 d
  129. #endif
    ! l+ ]! a9 V4 H( X* A

  130. " p: T! T0 J+ X) J+ F% ?
  131. #endif /* __RINGBUFFER_H */. v/ R8 W1 ?, w: N' ~
复制代码

9 a# x  w0 N% ]: J  _4 a  K$ y8 q! ~* b
RingBuffer.c 文件! l' [: o% a# W" A
  1. <div>/**/ Z0 v/ Z$ X) X5 `
  2.   ******************************************************************************
    $ ^0 u1 g9 b. I* p
  3.   * @file    RingBuffer.c8 b# E. L1 E- A) c+ c( @
  4.   * @author  XinLi
    # B/ ~+ J; _3 h8 s! i
  5.   * @version v1.16 I! a1 _% Q! l9 N9 ^& b" g
  6.   * @date    15-January-2018! z7 _6 ]% S* [7 V) g) a
  7.   * @brief   Ring buffer module source file." h, Z- A' e) O; H* h
  8.   ******************************************************************************) }1 R1 @9 p, f
  9.   * @attention
    6 Y0 r& P, ~. ~" P
  10.   *
    0 G& y1 ?9 E! b* D  h9 v9 O" c
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>7 r+ a. b2 K0 S5 G7 p
  12.   *- d+ r4 I6 h3 `0 l% a
  13.   * This program is free software: you can redistribute it and/or modify& X/ B' H% q7 D! U7 o$ P5 o; b
  14.   * it under the terms of the GNU General Public License as published by# l3 Z( q4 \. b9 n& p
  15.   * the Free Software Foundation, either version 3 of the License, or
    5 R; a. I$ n$ u8 W' ^7 e
  16.   * (at your option) any later version.
    . U- L4 E$ Q+ l, i! N
  17.   *& J. j! [, k! _( `
  18.   * This program is distributed in the hope that it will be useful,$ S0 c' h2 b2 Y. k/ x2 B2 w
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    8 M, q4 X% ]# k/ W- [0 S& g" V
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    / u9 S5 g3 `! J8 t7 b% n
  21.   * GNU General Public License for more details.
    2 i- m! V% {1 W+ l
  22.   *
    % W+ Y! v! S4 J3 o+ ~, v. @
  23.   * You should have received a copy of the GNU General Public License
    . \# i4 G) u: S( n. |) I; @
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>3 n7 c% g$ i4 m
  25.   *! ~0 u) g: F& ^7 J5 v1 F
  26.   ******************************************************************************! u* N7 }; y/ B+ t4 ^# |
  27.   */
    9 d: I9 s4 d5 g- N
  28. 4 @( [$ n) R. q/ i6 Y* B* r, l
  29. /* Header includes -----------------------------------------------------------*/
    + C4 u1 r8 c# z
  30. #include "RingBuffer.h"
    1 b" V, c' g2 @
  31. #include <string.h># u7 e' ?7 z+ W7 W  J3 ?( S

  32. : H/ V/ Z% W# M$ e4 ?
  33. /* Macro definitions ---------------------------------------------------------*/1 f+ G9 x( g: M
  34. #define min(a, b)  (((a) < (b)) ? (a) : (b))
    # M/ i& Y* n5 k  `2 t+ r! w% E7 ~
  35. 8 K. o$ Q! C: j7 I  C3 W- X* H1 u
  36. /* Type definitions ----------------------------------------------------------*/
    , s" w& P, i4 [
  37. /* Variable declarations -----------------------------------------------------*/6 [+ O. R. i$ Q! y
  38. /* Variable definitions ------------------------------------------------------*/; F9 u+ C' K: M* w. b- r
  39. /* Function declarations -----------------------------------------------------*/
    7 g6 G0 q# r# k
  40. static bool is_power_of_2(uint32_t x);
    8 {! _8 u0 m1 ^2 _# ]
  41. static uint32_t roundup_pow_of_two(uint32_t x);: s/ \6 u' z, Z' o" `  C

  42. 1 q) G$ n& l1 w3 ]
  43. /* Function definitions ------------------------------------------------------*/
    4 r6 u+ \$ W/ H# A6 Z
  44. 2 K3 l  a+ s, s
  45. /**2 L4 Z3 u% r; m  o% C3 h* o
  46.   * @brief  Allocates a new FIFO and its internal buffer.
    ( V' p0 C8 E9 c& A: n
  47.   * @param  [in] size: The size of the internal buffer to be allocated.
    & |2 E2 L8 I# g( ]% S2 a' F' \) Y
  48.   * @note   The size will be rounded-up to a power of 2.
    ' D! j) d) G! H* ]& ?! E# ]; a0 l
  49.   * @return RingBuffer pointer.
    3 Y& E3 e9 z8 E/ z1 C9 h
  50.   */1 E8 c1 d" F; b. x
  51. RingBuffer *RingBuffer_Malloc(uint32_t size)4 N: D% @8 m" o9 e
  52. {
    4 p* Y% S% z8 C+ P# \9 C9 {% n) H! Y
  53.   RingBuffer *fifo = RING_BUFFER_MALLOC(sizeof(RingBuffer));5 s; I$ p8 V+ ?+ q% |, P
  54. 4 v/ S& a3 c* V5 c; F
  55.   if(fifo != NULL)
    ) ]: _* [; r, a8 i& A( }: C
  56.   {6 ]6 w. g9 r5 O: |- ]. w! U
  57.     if(is_power_of_2(size) != true)1 [1 ^3 l% C  B
  58.     {
    / B* U: s5 J' i+ H, B
  59.       if(size > 0x80000000UL)* f$ f& ~+ f! y2 ]
  60.       {7 |/ V6 t. K9 I! r! i& U
  61.         RING_BUFFER_FREE(fifo);, K( N' Z! E$ d2 X: J) M3 {6 p
  62.         return NULL;2 p3 h" G3 G; x
  63.       }3 B' I6 W0 g- ]* F

  64. , V  H% J8 B' @) t# B
  65.       size = roundup_pow_of_two(size);
    . }- h" T$ R+ p
  66.     }
    9 l; M, Q; B( o" o, h# y
  67. ' {5 ~8 m" e: z5 a+ v' [- R8 v. e
  68.     fifo->buffer = RING_BUFFER_MALLOC(size);
    ( I. l& p0 }% h
  69. + K( V9 B; s. h
  70.     if(fifo->buffer == NULL)
    ; N: g. M1 r5 j7 V( F
  71.     {; ~2 M& c3 ?  v
  72.       RING_BUFFER_FREE(fifo);
    : X7 C7 O/ \  V$ Q4 B
  73.       return NULL;
    . W. f" s$ w4 D4 @6 G, ]
  74.     }8 [+ @! D; x- m/ D

  75. & s8 v1 |) ^) N- k+ ]5 a
  76.     fifo->size = size;
    : h/ i% v$ n0 m1 s
  77.     fifo->in = fifo->out = 0;
    6 M+ W2 B2 [7 v3 c) c2 J
  78.   }
    0 E& A& ?, P7 a
  79.   [( R7 T6 N$ H" f$ r# v' {2 T/ a
  80.   return fifo;! E" b% [8 f  j6 d
  81. }
    - n8 C8 \" S1 D; p# Y4 d
  82. 5 ^5 e5 `( d, j5 r) Y: r9 p
  83. /**
    % e* B2 l& h0 }5 H/ {, }/ K$ t7 ]- T
  84.   * @brief  Frees the FIFO.% P$ |4 G3 ?* K0 v8 x( g
  85.   * @param  [in] fifo: The fifo to be freed.
    7 Y0 u8 N$ ^% B8 b
  86.   * @return None.
    + l& e0 M0 p4 B2 H
  87.   */1 u1 f$ ~1 y/ m. T- i
  88. void RingBuffer_Free(RingBuffer *fifo)  D+ p4 J% ^- W+ \
  89. {" `! v) f9 ?* y( y1 {
  90.   RING_BUFFER_FREE(fifo->buffer);
    6 @0 v& s% T8 A) l' V& x
  91.   RING_BUFFER_FREE(fifo);. _3 T- h+ Q! ?+ y; B
  92. }
    : s# _* r; d+ V9 h

  93. 1 m9 l7 D" x% U+ u7 ]
  94. /**
      [8 @/ e' Y1 ^0 ?* a( J
  95.   * @brief  Puts some data into the FIFO.
    ! }" b0 J& ?# ?' z! Y4 O0 F6 _
  96.   * @param  [in] fifo: The fifo to be used.% B" n2 b# e0 r" s9 b9 y
  97.   * @param  [in] in:   The data to be added., ]6 f# T2 B" D2 ?8 k' R! _
  98.   * @param  [in] len:  The length of the data to be added.; c2 F  a( q) l8 g0 h: ?
  99.   * @return The number of bytes copied.
    + t% f! W. s6 x
  100.   * @note   This function copies at most @len bytes from the @in into
    ! I% M7 k: s; |
  101.   *         the FIFO depending on the free space, and returns the number% e( o( ^. v1 G+ p+ n! B: |
  102.   *         of bytes copied.! i- _+ N! M$ z
  103.   */
    7 o" Z4 f0 M4 C; Y4 N) F8 L* O$ H
  104. uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len)) c/ }/ _9 \- p+ O
  105. {/ \. S- I/ I& X3 n  o, g; k0 v/ X0 ]
  106.   len = min(len, RingBuffer_Avail(fifo));
    8 p, K: H+ U0 K
  107. # N8 `9 s0 @4 y/ C8 ^
  108.   /* First put the data starting from fifo->in to buffer end. */
    3 h! |1 Q$ M0 X! P/ j3 o
  109.   uint32_t l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));
    6 Q+ [- {) J, h6 T
  110.   memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), in, l);4 `$ G$ s$ o5 N5 S/ q" x! A

  111. 0 _4 B5 s* C& l' G. r
  112.   /* Then put the rest (if any) at the beginning of the buffer. */
    8 w1 C" K( x! j! M% I
  113.   memcpy(fifo->buffer, (uint8_t *)in + l, len - l);
    9 ^% |. |: [! \% g

  114. + l5 O- v7 U* y$ f* U* y% P# f
  115.   fifo->in += len;
    ( }% T9 [8 j5 k* D

  116. # Y; Z- F/ [! |+ Q5 V4 \
  117.   return len;
    7 B0 f2 s% ?9 O4 {
  118. }
    0 a) H8 y4 V( @

  119. / {4 }' y3 g( u1 X( ?- l
  120. /**
    2 Z+ t0 c. `+ `1 O7 l" u
  121.   * @brief  Gets some data from the FIFO.% @; c" _6 L7 \% I5 `- d
  122.   * @param  [in] fifo: The fifo to be used.
    ' }$ h1 C4 W3 q3 ~0 m% Y
  123.   * @param  [in] out:  Where the data must be copied.
      N) f( [; n7 d: [5 ?0 r
  124.   * @param  [in] len:  The size of the destination buffer.
    $ u: F; c, X0 @& x
  125.   * @return The number of copied bytes.4 W4 E7 J. T1 b" ^$ Z8 m2 b# T
  126.   * @note   This function copies at most @len bytes from the FIFO into! A' E- U9 i( l: e6 ^( ?
  127.   *         the @out and returns the number of copied bytes.
    ! ]- i- n5 V3 L3 P0 e  d* _3 h
  128.   */
    ; l, O" O9 l' B
  129. uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len)
    3 m$ ~  s! n+ O5 X
  130. {
    3 t0 T4 }% n4 I8 w" h9 ~
  131.   len = min(len, RingBuffer_Len(fifo));
    % n3 q3 p, u: w; {" u) ^
  132. " W; O( f  I0 ^' k4 f8 U- G8 }  u
  133.   /* First get the data from fifo->out until the end of the buffer. */$ M( n6 o) {3 }4 V/ j2 t$ R
  134.   uint32_t l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));/ ]+ D6 k! j) Q6 o  z
  135.   memcpy(out, fifo->buffer + (fifo->out & (fifo->size - 1)), l);
    7 U8 G6 f8 p1 X7 K( P- _

  136. + X$ p$ t( {7 x& J% l
  137.   /* Then get the rest (if any) from the beginning of the buffer. */- c8 B* L, F: _" n* C
  138.   memcpy((uint8_t *)out + l, fifo->buffer, len - l);
    - ^* t! F! d& A) m9 q: O

  139. # M* f; J. s. n' l
  140.   fifo->out += len;% e3 ]3 V1 g( p' V# O  o
  141. 8 `1 ^9 v9 m# @- C) z! y% r
  142.   return len;7 Z# R# f; Z" u* `3 [& _% C, D
  143. }
    1 U, A1 w4 f% W; c1 N/ k

  144. & z1 X3 j! T* z4 m* y- a- i& E
  145. /**
    6 @/ M# g$ [3 }2 Z! d: A( @% |
  146.   * @brief  Determine whether some value is a power of two.# K, x' C& ]; Q2 P" h0 N) D
  147.   * @param  [in] x: The number to be confirmed.5 c% |" C) w5 N% }1 f$ a
  148.   * @retval true:   Yes.
    % d  |  ?) x$ ^" d; Y( ^, K
  149.   * @retval false:  No." S3 q2 ?9 x; m8 o8 G: S
  150.   * @note   Where zero is not considered a power of two.
    % I3 V9 \; Q( L, ?* O5 {
  151.   */
    2 G% j. K) B1 `! b
  152. static bool is_power_of_2(uint32_t x)
    & W- |, b: B' }  N7 C. m
  153. {/ [/ ?$ |/ R: x3 G+ j: b
  154.   return (x != 0) && ((x & (x - 1)) == 0);
    6 h4 a9 O4 p3 V2 j) P9 B
  155. }) t7 f& K- R7 n* j- \) z
  156.   }' w0 _" ~, G* t+ A* q
  157. /**% I/ J$ C+ j$ D+ h3 M3 E) C
  158.   * @brief  Round the given value up to nearest power of two.0 s$ ]; I& K3 m# V& J% h4 h4 X) @* F
  159.   * @param  [in] x: The number to be converted.
    * E3 M) z( p! W! N; B: b
  160.   * @return The power of two.# a' {& H# ~! x5 q
  161.   */
    6 h; Q3 X' m1 c) \/ }. g
  162. static uint32_t roundup_pow_of_two(uint32_t x)
    * G( `- y  h* }+ g: k
  163. {
    2 l- f) ~" e+ A0 z2 l+ g
  164.   uint32_t b = 0;6 ]. R. \- `+ ?  s' w# R7 B

  165. / }  ~0 Q$ E. v: C/ j$ f  D! Y
  166.   for(int i = 0; i < 32; i++), D5 M" a3 [  p8 |7 k% z% p
  167.   {/ @6 O" v- t7 h/ m4 C' t4 o" x
  168.     b = 1UL << i;
    ' p' n# N) i8 f
  169. - n) @. @* `7 o0 b( k' y
  170.     if(x <= b)
    ' u* U1 N  u& L& L
  171.     {
    ) q5 @) E  G  B; ~+ y# }
  172.       break;
    : ?- M+ R3 E: ~+ i4 B$ C; U
  173.     }3 H6 z5 m6 Y" |- Z$ [# S
  174.   }7 E& {3 Z! v& ^; j4 L2 ]3 J
  175. 4 o! |% F4 E$ [2 U6 [
  176.   return b;
    1 z" _& S7 `- X5 b& l; ~3 T1 y
  177. }</div><div></div>
复制代码
3 {0 h$ T, D1 r7 h

' z. {3 s0 G' a3 kCAN.h 文件
+ m9 U2 V. R9 \- X( k6 T8 V
  1. /**8 Y( K3 F" G) {% [6 _. k: h5 l" n. A
  2.   ******************************************************************************0 L  z$ M4 D- J" j7 q+ P$ Q
  3.   * @file    CAN.h- Y" o' Q4 b, [% C  `
  4.   * @author  XinLi: b* E" y3 y$ ~- S6 a8 h
  5.   * @version v1.0$ ~0 j. Q1 N& m" z! W( [
  6.   * @date    24-June-20188 q$ b0 c1 E3 h& a& b
  7.   * @brief   Header file for CAN.c module.7 f% v  S9 s+ U: a
  8.   ******************************************************************************: R: y; \+ ~2 O% D! ?. M
  9.   * @attention" H' w; v4 T- x* e1 H3 C6 d/ W
  10.   *# |- ]  L/ X9 ?0 f
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>8 F8 y0 K2 e& q2 d: n3 K- {) ?* {
  12.   *
    5 ~& k- O0 \$ [* j2 }
  13.   * This program is free software: you can redistribute it and/or modify# j1 F9 E) i, o; a4 g: ]6 R& K
  14.   * it under the terms of the GNU General Public License as published by
    % L$ X4 E& R8 i" ~' }
  15.   * the Free Software Foundation, either version 3 of the License, or
    : |, G$ R' p1 U0 j1 s2 f1 ~+ ^0 u
  16.   * (at your option) any later version.
    ( ?' o1 I4 E. i* d" @) L
  17.   *
    ; ~* ?! t, W- k, C, h4 _
  18.   * This program is distributed in the hope that it will be useful,$ h& X5 n  n  ?, y  l4 G
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    0 X% M8 r$ R' v8 O" Y, n5 s
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    * ?0 z' u! K/ [
  21.   * GNU General Public License for more details.
    * l$ ~9 u. g. x; C
  22.   *
    , q) {! S+ E( k- [, t+ @
  23.   * You should have received a copy of the GNU General Public License8 M, o8 n4 w4 M& E
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
      c9 ?0 I8 m7 K
  25.   *
      Q5 m/ }) T7 K: A6 R/ M+ x
  26.   ******************************************************************************7 N( L+ v9 |, Y
  27.   */
    - f. D  P# @  u* B) }5 [+ J. z
  28. 2 f1 h. k/ T+ [  T# ]+ V
  29. #ifndef __CAN_H7 @2 g+ F2 l: U  q$ N- v0 Q
  30. #define __CAN_H# y# t1 p5 A6 S$ L2 s/ U
  31. ' r. K5 ^* r8 @( T5 x
  32. #ifdef __cplusplus
    4 _7 K! n3 l  [" x( Z) P3 X
  33. extern "C" {
    . X" X: \8 B3 C1 X: R
  34. #endif3 P4 z9 ?8 J: d2 l& l- r
  35. - {  m! `' g9 n, f9 d1 X
  36. /* Header includes -----------------------------------------------------------*/9 c; ^: F% [: \; V$ q6 i
  37. #include "stm32f10x.h"" g4 [, S  E; }/ p0 h8 l4 Q$ F1 H
  38. #include <stdbool.h>
    4 W; V. b! r+ v1 R; s

  39. , ^. O$ `; L1 s7 H% B9 H
  40. /* Macro definitions ---------------------------------------------------------*/
    , j8 L  _; L* h/ L4 G# }& e/ `
  41.   k0 e5 S3 d# j. p. j7 M+ V- Z* ?
  42. /******************************* CAN1 Configure *******************************/: s6 j) J( R# {: Q3 s
  43. #define CAN1_TX_BUFFER_SIZE        (16)
    / a6 f  O* p4 d) Y& [
  44. #define CAN1_RX_BUFFER_SIZE        (16)2 m3 @! s) L4 X5 @  i- D
  45. . \4 h9 `1 N9 P# p# s3 p% Z
  46. #define CAN1_TX_GPIO_CLOCK         RCC_APB2Periph_GPIOB
    $ ]; p. i6 ^; ~) T9 X
  47. #define CAN1_RX_GPIO_CLOCK         RCC_APB2Periph_GPIOB) C& u$ l& _# F! @4 P5 l# {

  48. . ]9 s: \) m7 [! m" L
  49. #define CAN1_TX_GPIO_PORT          GPIOB( V- r* R! g) Q  U/ U) u5 K% z2 @* s
  50. #define CAN1_RX_GPIO_PORT          GPIOB
    ' B+ L0 Q  r6 ?. x# E  \

  51. ( k# P& r, s: V6 m* B
  52. #define CAN1_TX_GPIO_PIN           GPIO_Pin_9! B( ~$ g" W9 O4 i9 A
  53. #define CAN1_RX_GPIO_PIN           GPIO_Pin_8; z" v$ `4 i8 r9 D& h

  54. / y# B; `' y8 m" M
  55. #define CAN1_IRQ_PREEMPT_PRIORITY  (0)  E$ Q5 D0 t5 y& S% v7 O6 o9 g& c5 D
  56. #define CAN1_IRQ_SUB_PRIORITY      (0)+ Q6 v! z3 J' k

  57. " b) @$ O0 J+ ]! B
  58. #define CAN1_PORT_REMAP()          GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE)
    ( ~4 e) K5 B! C$ l' G
  59. /******************************************************************************/& d9 [, y9 P/ i& |
  60. & l! r6 {+ f6 G. ]- [% ~
  61. #ifdef STM32F10X_CL
    : B1 l2 k% N7 p* f) f
  62. /******************************* CAN2 Configure *******************************/
    7 N! {1 d) |3 L% g
  63. #define CAN2_TX_BUFFER_SIZE        (16), Q; `3 E- \, I* X* H7 _
  64. #define CAN2_RX_BUFFER_SIZE        (16)
    8 s6 ~5 t  W' A/ K) c) ?4 Z

  65. $ i! L# D& N, M# ]
  66. #define CAN2_TX_GPIO_CLOCK         RCC_APB2Periph_GPIOB2 @( w& U& ~3 L. X5 ?; y9 S' h
  67. #define CAN2_RX_GPIO_CLOCK         RCC_APB2Periph_GPIOB
    * X( M3 L3 K  N* R1 U2 i" c

  68. 9 e4 `# j8 y6 |4 @
  69. #define CAN2_TX_GPIO_PORT          GPIOB
    - j( r. ~0 I$ Q9 d5 C" c
  70. #define CAN2_RX_GPIO_PORT          GPIOB
    0 f1 v( ^! c0 |7 K4 ^- c$ M9 W9 V' T
  71. 3 v8 A1 [$ {9 B/ H& \
  72. #define CAN2_TX_GPIO_PIN           GPIO_Pin_13
    : d( F! E; F& u1 e6 I  p8 ]
  73. #define CAN2_RX_GPIO_PIN           GPIO_Pin_12) L* ^, f( i! i' c$ Z

  74. * ~2 W" I; C3 F- h3 b: [$ c
  75. #define CAN2_IRQ_PREEMPT_PRIORITY  (0)
    3 D7 U7 \6 ^! k( S6 O& S
  76. #define CAN2_IRQ_SUB_PRIORITY      (0)
    - w+ i- o+ B$ h
  77. 0 U( f* J9 A+ v8 i3 O
  78. #define CAN2_PORT_REMAP()          GPIO_PinRemapConfig(GPIO_Remap_CAN2 , DISABLE)
    5 a, H0 B2 }& s
  79. /******************************************************************************/
      u9 h+ r! O  X& s' Y
  80. #endif /* STM32F10X_CL */0 `" P# J% X) d
  81. . k( z+ s  d9 V# d9 |7 s8 X
  82. /* Type definitions ----------------------------------------------------------*/
    1 @1 q3 l- X8 V6 z& A
  83. typedef enum! i1 Z$ ?4 l8 o% c9 v$ U: O8 F: I
  84. {/ u2 G& W, p" P7 C& S# _5 k
  85.   CAN_WorkModeNormal   = CAN_Mode_Normal,
    - e* T% D* U( z5 |
  86.   CAN_WorkModeLoopBack = CAN_Mode_LoopBack8 M( S! I6 y3 m
  87. }CAN_WorkMode;5 O; o* ~: A; z

  88. * e  w: _6 U6 Y1 a" p$ U
  89. typedef enum
    1 f7 L& f) D8 G5 [  q/ P/ c+ w" u1 h
  90. {$ U6 j& l7 i! M! J& Z
  91.   CAN_BaudRate1000K = 6,
    7 _% z  b# q, b0 }" T8 Y
  92.   CAN_BaudRate500K  = 12,9 B/ P; G" }! h8 A9 B: `1 R
  93.   CAN_BaudRate250K  = 24,
    , M: i$ y0 q% H5 `' ?/ N9 w5 c& j# y
  94.   CAN_BaudRate125K  = 48,
    8 r$ Q' m' O- }  I. y2 O, R
  95.   CAN_BaudRate100K  = 60," c  C2 h  y+ i9 ^0 t* a
  96.   CAN_BaudRate50K   = 120,2 u5 c9 a8 V1 Y- A; i6 ~, I# Z6 o
  97.   CAN_BaudRate20K   = 300,
    : I) y9 v2 T! I( A: }$ N
  98.   CAN_BaudRate10K   = 600
    8 \$ l/ }2 ^4 h: N' b
  99. }CAN_BaudRate;6 H9 c7 A6 U. d5 C- A6 }

  100. 7 u# B* c! x# F& ~2 k
  101. /* Variable declarations -----------------------------------------------------*/  M0 ?& M" G8 }- B) v
  102. /* Variable definitions ------------------------------------------------------*/
    1 r  [- m' j& u
  103. /* Function declarations -----------------------------------------------------*/; C8 A5 r, [7 I1 d$ K8 Y. N; @
  104. void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId);
    ! O1 F' N+ P2 J# j. c
  105. void CAN_Unconfigure(CAN_TypeDef *CANx);
    9 D* g3 \) d0 l& J
  106. 8 o$ ?! c" ^$ z- |, T4 g
  107. void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));
    * {- M9 E7 B/ I0 P7 g
  108. void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));. h+ w: e& g0 D+ J; K

  109. % }/ f  m# G" _
  110. uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number);
    4 H1 W7 V- E" q# q; y8 S
  111. uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number);
    ' ?+ |* s' }- x

  112. 9 |" U9 c: g6 c0 B8 W" [4 K$ a! k
  113. uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx);
    / R1 S7 |5 S; m" `) X% ?
  114. uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx);
    0 f* c* y# q( v1 y; \3 M: t* k) J
  115. uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx);7 p) j; p; T) a; y1 H
  116. uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx);& H0 E. k. a7 [
  117. 4 O& Q! o# S! {! |& ?; k  g7 s
  118. bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx);$ b- l& g' \% m7 m3 s. p# ^
  119. bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx);5 Q4 f+ d. b8 \0 N& x
  120. bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx);; y* Q0 P8 E! [, j8 k: ?
  121. bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx);; c5 |; b8 y2 j: @8 Q) c" R$ i
  122. 4 N; Z1 E" [. Z9 D# M1 |+ z8 c
  123. void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx);6 [7 @3 m  i6 t* B* B1 c
  124. void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx);
    * f! f, A- Q- O1 n& l  p

  125. - a& G' [& {; F
  126. bool CAN_IsTransmitMessage(CAN_TypeDef *CANx);+ f: z  `( t1 S- c
  127. # D6 `$ B  ?$ m% n- y
  128. /* Function definitions ------------------------------------------------------*/9 r7 j$ |8 d, \- ]  p! {) x) Y* N$ y
  129. . ?: N- o5 ~! h' ~: b  L
  130. #ifdef __cplusplus0 v8 D+ t8 T+ k5 u/ F
  131. }& R" M  q: W& q. k+ p2 Z/ B
  132. #endif
    8 X# ]8 m5 |( \

  133. ' ^4 Y/ H* g( V
  134. #endif /* __CAN_H */
    & V4 X, }4 O/ T$ X, e: z1 \
复制代码

8 E5 R( w1 Y, I9 f* P% b% c/ X7 o. O4 U& C/ b- v

9 G, l& p9 A$ z( GCAN.c 文件! y3 T! ^7 F0 U: Q( [
) x8 T- I: Z$ g
  1. /**  I2 w$ z, \, @& I& m. v
  2.   ******************************************************************************
    , r3 s2 z1 v8 f5 n% U2 Q! K0 k
  3.   * @file    CAN.c
    % n) g+ ?' i0 V% P! m" f6 ^' K
  4.   * @author  XinLi
    7 Z; D, [6 V' a1 `0 s7 k( J  j7 N3 q0 K
  5.   * @version v1.0! z9 `4 {' A! K/ V5 Q
  6.   * @date    24-June-2018
    ; S) }# j$ `. A0 Q) d
  7.   * @brief   CAN module driver.
    ! {" }* z- E$ \- L
  8.   ******************************************************************************
    & t& C$ q6 ^# ^; W, d
  9.   * @attention
    ! R. x; ^" O  b- L! g$ ]
  10.   *
    1 c: @1 L2 O' D- m
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    $ T, D- E7 q& T. G6 u
  12.   *- }- A4 |0 M1 W5 z  |
  13.   * This program is free software: you can redistribute it and/or modify2 V) D! B5 i3 m5 a; c
  14.   * it under the terms of the GNU General Public License as published by
    ) N  B% H9 {) _; _- U" b
  15.   * the Free Software Foundation, either version 3 of the License, or
      e( ]6 r- r+ r* ]" p: E, W% J
  16.   * (at your option) any later version.( O& U: `8 J5 Z) r
  17.   *
      o. l$ ~5 I: O5 I
  18.   * This program is distributed in the hope that it will be useful,
    % E- R. N1 _4 l2 M! q
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of. q3 g* I% g: b, j7 i; `. Q: r# V7 \
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ' r; s% y$ c* w' x& Q1 [7 Q
  21.   * GNU General Public License for more details.: u0 {7 C* X# @6 d5 B! u/ w
  22.   *
    + d# F9 F/ ?( x' X
  23.   * You should have received a copy of the GNU General Public License
    , }$ c3 M5 a: f& F8 ]" ^& D  F
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    ; m2 D/ g+ i# J7 l# n3 r0 @
  25.   *6 R6 U; e7 U- [( N2 |8 ?
  26.   ******************************************************************************* a2 {/ [2 V2 T6 F; i
  27.   */
    ' \" r  _! l. X6 y, F0 @

  28. : v  A; z% o! T
  29. /* Header includes -----------------------------------------------------------*/. S" i0 Z2 c7 c( |6 C7 K# k  b
  30. #include "CAN.h"7 ~/ t% k4 |2 n- z( W, R2 p* H
  31. #include "RingBuffer.h"4 `" k/ @7 {, d

  32. $ A3 q6 O4 @- I: W
  33. /* Macro definitions ---------------------------------------------------------*/
    # U) _1 b$ ^  j# m/ g& r& t" W& `
  34. /* Type definitions ----------------------------------------------------------*/
    2 r- S* t& h5 m7 i' f6 N
  35. /* Variable declarations -----------------------------------------------------*/
    9 T# F! U' N; i
  36. static volatile bool can1InitFlag     = false;# K2 d: w( E: T& G) B7 R
  37. static volatile bool can1TransmitFlag = false;: z( m- W- U' F) q: a( V) C# z2 Z9 m

  38. 3 n" P# d3 R5 z& t/ W) T7 _
  39. static volatile void (*can1TransmitFinishCallback)(void) = 0;$ Y- n. [. _3 P- L
  40. static volatile void (*can1ReceiveFinishCallback)(void)  = 0;+ W0 y" _* k0 l* K) S
  41. # X! _2 \' @2 q( O5 K4 {; U
  42. static RingBuffer *can1TxBuffer = 0;
    8 J- k  z9 Y' i% e( [# U! V
  43. static RingBuffer *can1RxBuffer = 0;
    $ I% ?4 J, L) J0 l

  44. 4 e3 y6 U" t. U- K+ f* f2 ~% R
  45. #ifdef STM32F10X_CL
    0 r2 S+ ~4 q9 L
  46. static volatile bool can2InitFlag     = false;
    " n- ~) L$ ?6 U# b( E
  47. static volatile bool can2TransmitFlag = false;
    8 R- p6 g) a" A$ m! i6 t6 K

  48. 5 j; N6 o& ~; y( p6 T& ]# |
  49. static volatile void (*can2TransmitFinishCallback)(void) = 0;/ F" X" w8 k6 L! O' A
  50. static volatile void (*can2ReceiveFinishCallback)(void)  = 0;2 ^$ A5 r4 }% k4 W

  51. 7 h: S& ]7 G, O; I" R0 H
  52. static RingBuffer *can2TxBuffer = 0;
    ; R. k/ z# Y2 o
  53. static RingBuffer *can2RxBuffer = 0;
    4 X& \- M  g% s1 O# w- ]& g
  54. #endif /* STM32F10X_CL */
    / q, ?; s/ f2 A+ f' [
  55. 8 B$ R3 q+ _7 ~9 u
  56. /* Variable definitions ------------------------------------------------------*/. i$ {4 J' w5 S+ F9 @1 M
  57. /* Function declarations -----------------------------------------------------*/, K: |! k$ p5 V  F
  58. /* Function definitions ------------------------------------------------------*/3 _0 s, I6 w9 k, f

  59. 2 U) i& h! H: U
  60. /**. a9 J# m1 B) `
  61.   * @brief  CAN configure., c2 r7 n( P: f
  62.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.+ p- K1 d8 y% B3 p) ]8 u( q" w
  63.   * @param  [in] WorkMode: Work mode.3 U" m1 S* U: z
  64.   * @param  [in] BaudRate: Communication baud rate.* L: b8 V9 a: Q+ s' |
  65.   * @param  [in] StdId:    Filter standard frame ID.5 t* ?* p! l: g
  66.   * @param  [in] ExtId:    Filter extended frame ID.
      e$ `% X- E" a/ o0 R
  67.   * @return None.  ]+ o; _: E$ c. n3 i0 G$ b  S9 u- G
  68.   */. f9 A: ?4 D, A% z1 x- Q
  69. void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId)/ @. E, B+ k2 G, r  b4 L6 [
  70. {. E& [; h2 p# F  k) a6 k7 X0 F
  71.   GPIO_InitTypeDef      GPIO_InitStructure      = {0};6 c6 [  f6 D+ G) h. j
  72.   CAN_InitTypeDef       CAN_InitStructure       = {0};
    ( p  [$ b9 S& N8 p& M8 U
  73.   CAN_FilterInitTypeDef CAN_FilterInitStructure = {0};* l- K3 }4 p. |( y. t& v
  74.   NVIC_InitTypeDef      NVIC_InitStructure      = {0};- {( T1 {2 e( z3 u4 L( f+ P
  75. 8 Z6 T: E" i% r' P
  76.   if(CANx == CAN1)9 v# M# a% R+ B; P
  77.   {
    ( A/ O7 ?* e/ @9 F0 C. B
  78.     if(can1InitFlag == false)( I+ U3 ]# Q: G
  79.     {
    ! x% n( h1 L) O
  80.       can1InitFlag = true;' E5 B8 O0 v9 i4 }3 F* M

  81. 2 y3 [: e, m4 c* S6 t# f) y
  82.       can1TransmitFlag = false;
    $ i& X7 t) f( d+ z

  83. 6 B2 L- C9 B8 b1 L% x: i# |7 {
  84.       can1TransmitFinishCallback = 0;% q# W$ V: R5 d% z# q! ^9 i
  85.       can1ReceiveFinishCallback  = 0;
    2 ^% Q) P. D; {* H
  86. * \7 b$ u; _  v( l' n
  87.       can1TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN1_TX_BUFFER_SIZE);0 S; ^% |, ]! k" N
  88.       can1RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN1_RX_BUFFER_SIZE);
    / ]; f, V7 {+ O4 c
  89. 2 j, P: f: O: M9 [2 N9 Z4 v4 U
  90. #ifdef STM32F10X_CL
    4 L9 T9 Y7 E; f+ ~6 c& ~& q
  91.       if(can2InitFlag == false)! T/ @  J5 Y' c) I3 f  {8 c
  92. #endif /* STM32F10X_CL */
    + P8 I5 \+ |) l6 X  w/ P
  93.       {9 `8 K0 N0 K2 x2 [& y1 L
  94.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
    ( L8 e- o+ \+ ]9 S3 g3 {
  95.       }
    , L/ `* j% K( _

  96. ' h$ P/ S2 @- h
  97.       RCC_APB2PeriphClockCmd(CAN1_TX_GPIO_CLOCK | CAN1_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);
    9 r" X, Q/ ~# i3 J- i8 @
  98. / c3 L" Q; t- f& k* E- Y0 x
  99.       GPIO_InitStructure.GPIO_Pin   = CAN1_TX_GPIO_PIN;4 L3 M6 \4 x8 p1 F- E
  100.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    1 p6 S5 K; Q! m0 v7 E
  101.       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    ( z! Q/ y- [  W( l9 Q+ d+ W7 A- c( E4 k# b
  102.       GPIO_Init(CAN1_TX_GPIO_PORT, &GPIO_InitStructure);
    * x7 G4 d% c/ D2 F6 e; x

  103. " R, c% a  e& r1 x: r; ^
  104.       GPIO_InitStructure.GPIO_Pin   = CAN1_RX_GPIO_PIN;4 u) X% ~9 W3 R9 u# I% z
  105.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;. i% u! Y1 U( v1 V: L
  106.       GPIO_Init(CAN1_RX_GPIO_PORT, &GPIO_InitStructure);
    2 }* |- i- {( ^

  107. 9 O9 ^. Z2 R/ o+ V( j; y7 b
  108.       CAN1_PORT_REMAP();' G$ G) |# ], L" y

  109. " {% }, J7 T9 ?$ V# o/ d
  110.       CAN_InitStructure.CAN_Prescaler = BaudRate;# d0 g+ X/ i; H5 }8 R/ u5 |% ^
  111.       CAN_InitStructure.CAN_Mode      = WorkMode;
    % n' S$ }# ]6 S& v  J9 ^
  112.       CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;
    , S( v; I1 u- f- k& z
  113.       CAN_InitStructure.CAN_BS1       = CAN_BS1_3tq;8 C4 m. [% p0 `9 }, T2 c' i
  114.       CAN_InitStructure.CAN_BS2       = CAN_BS2_2tq;
    / C/ {1 I* H' ^7 V7 _- W
  115.       CAN_InitStructure.CAN_TTCM      = DISABLE;
    & Q+ w. l# O* t) \% P: p1 s- O
  116.       CAN_InitStructure.CAN_ABOM      = ENABLE;( O1 V' e, ]/ t5 K& e2 ]
  117.       CAN_InitStructure.CAN_AWUM      = DISABLE;1 L- q9 M0 f  _$ P$ {. R9 p, g( h
  118.       CAN_InitStructure.CAN_NART      = ENABLE;
    : V) [/ N1 h& w
  119.       CAN_InitStructure.CAN_RFLM      = DISABLE;
    ) s. ]6 c/ A5 v" i" Q+ s6 T
  120.       CAN_InitStructure.CAN_TXFP      = ENABLE;; N4 `. u, P. `& H0 Q+ k! r
  121. - c3 }" v+ D9 p$ P
  122.       CAN_DeInit(CAN1);
    2 F- K4 q- A% J6 r! O  v) j" k6 L7 |
  123.       CAN_Init(CAN1, &CAN_InitStructure);3 z& i+ a: S( C/ d4 f8 ^
  124.   |3 i9 W: T* p1 u, E+ R( Q8 l( J
  125.       CAN_FilterInitStructure.CAN_FilterIdHigh         = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);
    : d/ g# g$ p/ `  J
  126.       CAN_FilterInitStructure.CAN_FilterIdLow          = (uint16_t)(((StdId<<18)|ExtId)<<3);
    7 B6 ]% O% }+ C; P! b/ G
  127.       CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;
    , j9 r  J, Z! D" c6 F7 m
  128.       CAN_FilterInitStructure.CAN_FilterMaskIdLow      = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;7 F/ H4 G" X  X& |2 C
  129.       CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;% p* l  j  s. ~* g$ \! r5 L" E( A( B
  130.       CAN_FilterInitStructure.CAN_FilterNumber         = 0;" m# y- A! t2 E1 U
  131.       CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask;) D, x9 g6 b+ e6 D7 Z# I
  132.       CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit;; o# g. S5 ?9 S4 \+ V* D9 F& Z
  133.       CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;. r6 F1 k  E3 U/ [+ a7 n
  134.       CAN_FilterInit(&CAN_FilterInitStructure);) l+ T  Y' w* V1 d( b8 r

  135. - V  G. h  h3 |. b5 j
  136.       CAN_ITConfig(CAN1, CAN_IT_TME | CAN_IT_FMP0 |CAN_IT_FF0 | CAN_IT_FOV0 | CAN_IT_FMP1 | CAN_IT_FF1 | CAN_IT_FOV1 |
    9 Y; h: L# r4 \* a0 D
  137.                          CAN_IT_WKU | CAN_IT_SLK  |CAN_IT_EWG | CAN_IT_EPV  | CAN_IT_BOF  | CAN_IT_LEC | CAN_IT_ERR, DISABLE);
    7 j  D! B( A: G! G/ D! T4 X  [- q
  138.       CAN_ITConfig(CAN1, CAN_IT_TME | CAN_IT_FMP0, ENABLE);
    7 h* J" b4 z/ v( t- F$ o

  139. 2 z9 D2 m/ E- d. f; E7 _+ [
  140. #ifdef STM32F10X_CL) W0 \' V8 J5 I( s0 x$ v
  141.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_TX_IRQn;  ~( l- N$ C/ m; T
  142. #else
    9 k( ?/ k) {, |0 S; u0 ^
  143.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_HP_CAN1_TX_IRQn;+ j# F& {7 O" L3 e* Y
  144. #endif /* STM32F10X_CL */
    4 ?# \9 N- `  Z" w2 U0 T. c

  145. 1 W- a  [% e1 \2 {8 y9 R
  146.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;$ m' A% Z: l% z# x5 K
  147.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN1_IRQ_SUB_PRIORITY;
    " J6 e& U4 T5 W( d, [
  148.       NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;  ^# z6 L2 B( a; ]  n
  149.       NVIC_Init(&NVIC_InitStructure);! e. M5 D7 {; C1 w! w& w

  150. 8 h8 W6 h2 i( ]* k! ~
  151. #ifdef STM32F10X_CL& u! W% p# g; I2 r% J2 L
  152.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_RX0_IRQn;
    1 r+ C% c, q; i: a* J% h
  153. #else! P+ F. W7 W, k! V3 W# V; E
  154.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_LP_CAN1_RX0_IRQn;5 p# n/ h+ \$ S+ i; c: z/ r, x
  155. #endif /* STM32F10X_CL */
    ; ?$ ~! W# d+ }

  156. 2 X9 F* N/ ~3 M9 R6 r  A+ Z
  157.       NVIC_Init(&NVIC_InitStructure);
    8 Z$ S, L0 z8 ?* H( g- T3 H2 @2 M8 S
  158.     }8 q9 S/ c/ X8 g! o+ k' T: \: H
  159.   }% j9 O; Z2 D. n$ `! z% t

  160. : m; X6 L) j2 d  ]& g+ ^3 E
  161. #ifdef STM32F10X_CL" n: H4 C8 t8 E7 ]5 K
  162.   if(CANx == CAN2)
    1 ]. f  |) ]4 N0 B
  163.   {
    % a& R( r' F1 _8 R
  164.     if(can2InitFlag == false)
    * N, x- P# T: W' ]8 E4 \: |
  165.     {
    7 L0 Y' p& [$ o9 t$ ~& F
  166.       can2InitFlag = true;0 E, i$ i- V; K- g
  167. " f6 _0 I9 }2 y8 y6 K2 l
  168.       can2TransmitFlag = false;
    9 v7 ~, L* p* u8 `
  169. 5 W6 N7 Y* n4 Y* T4 G2 |
  170.       can2TransmitFinishCallback = 0;
    5 s! X0 O6 H& t0 \9 }9 v
  171.       can2ReceiveFinishCallback  = 0;
    8 L# O. G( }6 A! g" R& A
  172. # x/ g2 q* j- X& n
  173.       can2TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN2_TX_BUFFER_SIZE);
    ! P! B, _& X- [
  174.       can2RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN2_RX_BUFFER_SIZE);
    ( N7 w6 H' ?  L

  175. . b' g/ A* F9 b. W, d' u( b* X6 J
  176.       if(can1InitFlag == false)9 K: k0 e- |, ~5 N! D
  177.       {' J% F3 b3 }! [
  178.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);6 t% q, L8 P8 T5 c
  179.       }
    " i6 H$ G+ c3 B8 {
  180. 6 y( c4 z& H3 l; M2 |
  181.       RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);
    $ X+ B9 a( f3 T" m" x. ^. w& s
  182.       RCC_APB2PeriphClockCmd(CAN2_TX_GPIO_CLOCK | CAN2_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);1 m4 L2 ]! ]. c- {' C1 F
  183. ( s. B% f1 s7 @+ y
  184.       GPIO_InitStructure.GPIO_Pin   = CAN2_TX_GPIO_PIN;
    3 `! Y: G1 y, T5 F7 R, ?
  185.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;; Z! R, Y: V" y# }) o
  186.       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;4 L) O* P& U! }, R
  187.       GPIO_Init(CAN2_TX_GPIO_PORT, &GPIO_InitStructure);* ]$ ?! U( F6 f% I# e9 ~+ U
  188. ) o- b% X, G7 e/ M5 S( }
  189.       GPIO_InitStructure.GPIO_Pin   = CAN2_RX_GPIO_PIN;
    . q% k3 o* X2 H" @  ^# t
  190.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
    " Y, p( I/ {( v+ c8 z
  191.       GPIO_Init(CAN2_RX_GPIO_PORT, &GPIO_InitStructure);" |/ r. X% y* c
  192. ; k7 E3 |# G4 K8 v
  193.       CAN2_PORT_REMAP();, F( Q4 P% R8 L5 w2 {
  194. " [" C. S% G8 ]- ~. O0 P/ g
  195.       CAN_InitStructure.CAN_Prescaler = BaudRate;4 r8 Y: S1 B9 t4 P
  196.       CAN_InitStructure.CAN_Mode      = WorkMode;
    # y7 T# y8 x0 r; y
  197.       CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;
    0 h6 ~8 F( H7 m9 ]1 s& r
  198.       CAN_InitStructure.CAN_BS1       = CAN_BS1_3tq;, |% K4 Z+ z  ^8 g0 K3 E: a
  199.       CAN_InitStructure.CAN_BS2       = CAN_BS2_2tq;5 z3 j* g7 I9 s$ I. c: f0 F1 ?; I  x
  200.       CAN_InitStructure.CAN_TTCM      = DISABLE;" J( l# e$ i/ {0 b2 w- K4 [8 A
  201.       CAN_InitStructure.CAN_ABOM      = ENABLE;& S8 H$ j7 n6 G2 n8 s! m& _
  202.       CAN_InitStructure.CAN_AWUM      = DISABLE;
    5 z. h7 c. _, b! T, H- Z
  203.       CAN_InitStructure.CAN_NART      = ENABLE;3 h* O! F" n2 p) ]# b8 J
  204.       CAN_InitStructure.CAN_RFLM      = DISABLE;% F6 S0 x; [3 w& X& [- O7 G
  205.       CAN_InitStructure.CAN_TXFP      = ENABLE;; W! k0 C1 o* p( Z% Z2 H

  206. : L% F. n+ ^. q# b
  207.       CAN_DeInit(CAN2);
    % e- p9 K  P/ Y! W( i
  208.       CAN_Init(CAN2, &CAN_InitStructure);5 }( b: X0 T% I6 F* V* w
  209. ; M* m% m  A& M
  210.       CAN_FilterInitStructure.CAN_FilterIdHigh         = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);
    7 Y# F4 a  `8 n/ S9 Y% j$ E1 ~9 m
  211.       CAN_FilterInitStructure.CAN_FilterIdLow          = (uint16_t)(((StdId<<18)|ExtId)<<3);
    2 K2 f9 F! v% D2 V  g; x8 N# u
  212.       CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;/ A; c. `' I0 U7 L% i
  213.       CAN_FilterInitStructure.CAN_FilterMaskIdLow      = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;  N" L6 r6 `- k+ u
  214.       CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;- v" O( {" e; d' O' d. d# T0 P
  215.       CAN_FilterInitStructure.CAN_FilterNumber         = 14;1 X' t) U: P# F+ m& U" i
  216.       CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask;! Y. Z3 O7 h3 P% J
  217.       CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit;
    1 j4 y% f! o$ q: Z
  218.       CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;
    * x9 K7 q" E" F% L/ S( v9 w/ @
  219.       CAN_FilterInit(&CAN_FilterInitStructure);7 y7 K3 W4 B6 ^5 b) S
  220. ; A/ n5 X0 z! a! T, B0 J3 A
  221.       CAN_ITConfig(CAN2, CAN_IT_TME | CAN_IT_FMP0 |CAN_IT_FF0 | CAN_IT_FOV0 | CAN_IT_FMP1 | CAN_IT_FF1 | CAN_IT_FOV1 |: n& \6 ~/ K, _/ p7 m1 O3 [
  222.                          CAN_IT_WKU | CAN_IT_SLK  |CAN_IT_EWG | CAN_IT_EPV  | CAN_IT_BOF  | CAN_IT_LEC | CAN_IT_ERR, DISABLE);
    ( g, s1 b" S! }' A  K
  223.       CAN_ITConfig(CAN2, CAN_IT_TME | CAN_IT_FMP0, ENABLE);' B1 E6 R3 l1 m# n7 h1 H9 d' R9 L7 G% b

  224. * `. j4 C$ |( [2 B  I4 |
  225.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_TX_IRQn;
    5 u: p6 r( z6 D( I
  226.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;
    . c' h- S$ [4 l; I- D+ L6 Q0 `
  227.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN2_IRQ_SUB_PRIORITY;
    % p! W: k# Y% N( _, \% k$ h
  228.       NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;8 N9 M: d+ q6 _: ?
  229.       NVIC_Init(&NVIC_InitStructure);
    ( X  n; H) I8 y. n
  230. $ q8 D7 X$ m  o! o) ]" C$ a: r5 j
  231.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_RX0_IRQn;6 X* \$ ]3 {' V; p7 M
  232.       NVIC_Init(&NVIC_InitStructure);) u7 k) o, m8 ^0 u" l- E1 q
  233.     }
    3 I( d1 A" J( S- e/ \4 B" t
  234.   }
    # i, B7 y' `" r) f
  235. #endif /* STM32F10X_CL */
    7 d% }  _$ b, u$ W! b
  236. }
    ! j3 t' ~, f+ f- t& B4 X: h
  237. 2 P5 U9 J$ X  S. h0 _8 z
  238. /**4 f6 d9 v  U0 x$ p# K
  239.   * @brief  CAN unconfigure.# P8 p" M9 w' m: U# e* \7 X
  240.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.# G& k! y) c5 p  S) g
  241.   * @return None.7 Y) E, }7 V9 v$ [. h
  242.   */+ H/ E, C( A/ t
  243. void CAN_Unconfigure(CAN_TypeDef *CANx)8 |; h! U# Y" h) x& U2 ]
  244. {+ j) f- T# T& j1 d2 g
  245.   NVIC_InitTypeDef NVIC_InitStructure = {0};+ ~/ u( Z4 D1 K* S  `; q& l& q

  246. / W- g/ k  P0 D# j4 |8 w/ T
  247.   if(CANx == CAN1)
    ( Y1 Z* c' f" y4 u
  248.   {
    3 g& j6 A) A1 {5 `
  249.     if(can1InitFlag == true)
    0 G; v  K' ~  J6 m5 A( V
  250.     {- \! ]9 Z0 `# w6 z% l+ U" j7 E' _1 y9 Z
  251.       can1InitFlag = false;8 G+ v4 N0 P* E: Q
  252. ) g: {7 g: U2 V/ Z, L
  253. #ifdef STM32F10X_CL
    2 D' _# J" D- |* v
  254.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_TX_IRQn;* A; M, S( Y) o3 A1 i
  255. #else; X1 f* i! {6 n
  256.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_HP_CAN1_TX_IRQn;: V4 D) O1 P, ~( l, C
  257. #endif /* STM32F10X_CL */; @- `4 H/ x/ B/ c# k: p
  258. 2 E" s2 U6 n! d2 p4 O( _$ X0 j
  259.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;
    8 r- {8 V! o' ?+ t; d7 p5 a' F
  260.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN1_IRQ_SUB_PRIORITY;6 C- N6 b/ H* M! b
  261.       NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;% J9 x( K2 Z' d6 d7 s9 N
  262.       NVIC_Init(&NVIC_InitStructure);) ~6 C4 x1 Q# e, l, ?8 I0 l
  263. . ^5 U4 f2 _" }0 C1 k3 R) r
  264. #ifdef STM32F10X_CL
    0 M$ q. o% l* i" a
  265.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_RX0_IRQn;
    ' S  B+ y) _0 Q. v5 J
  266. #else$ |1 s9 w: A! x4 `4 q. a1 f$ w. q
  267.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_LP_CAN1_RX0_IRQn;/ \, x) J: j/ v$ F2 `
  268. #endif /* STM32F10X_CL */
    $ S$ r4 v- c& `  ~' x

  269. : G' v6 t" ~, g& s* c
  270.       NVIC_Init(&NVIC_InitStructure);* X, K% b. u8 K. \
  271. . j5 [: D- Y' @
  272.       CAN_DeInit(CAN1);) s( c& r- b  B. Z+ Y
  273. # z1 k, S: G- R9 @: O4 ]) G# Q
  274. #ifdef STM32F10X_CL
    : ^0 b) X  w2 H
  275.       if(can2InitFlag == false)
    " D3 k6 G) q* w; s& q7 x( V* ]
  276. #endif /* STM32F10X_CL */0 a6 s' w9 O9 ?4 [
  277.       {. t+ Y2 b% B) U0 F
  278.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);
    " m& g: q8 m  B& A! W: y
  279.       }
    # {3 O1 E6 o" ]1 A* o
  280. 8 o: J; c- |- q& V
  281.       can1TransmitFlag = false;
    ' d% {% Z3 |& M6 \! m0 c/ N

  282. ; H9 f: }7 s, Z! j# u9 G; s
  283.       can1TransmitFinishCallback = 0;
    % C  I8 c! E& T+ q& g9 r8 P
  284.       can1ReceiveFinishCallback  = 0;
    2 d6 M9 W; A! O) @. x; A( H
  285. # w1 G- Y! F6 S% \; L# S! n) G9 z
  286.       RingBuffer_Free(can1TxBuffer);
    4 u! ^" g) H9 ^6 ~6 ^7 j- v
  287.       RingBuffer_Free(can1RxBuffer);
    2 s" W' u4 h( H
  288.     }4 E6 X: V3 ^! @: D
  289.   }& @7 r4 `! k% k( @! U9 P; x1 g
  290. 4 `( L$ S4 \) C& [
  291. #ifdef STM32F10X_CL
    & ]: ?1 V  h  ~7 g" J8 I4 u
  292.   if(CANx == CAN2)
    8 `+ R! b3 Z3 F% B" |
  293.   {
    % k& h& ~, G3 J9 ~
  294.     if(can2InitFlag == true)4 E# \1 P8 q  d% i- S8 N# \. A
  295.     {, j0 g0 c5 `) g
  296.       can2InitFlag = false;
    & p& B; m  S  N2 ^
  297. 3 S8 R0 ^7 A! H+ Q
  298.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_TX_IRQn;7 Y2 R( l& ~' E
  299.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;
    1 x2 a) p5 w1 n+ N* [
  300.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN2_IRQ_SUB_PRIORITY;: K; O0 u* C: a3 ]8 N, }
  301.       NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;: [# n% l4 m/ k; _8 v" e& N
  302.       NVIC_Init(&NVIC_InitStructure);
    1 W4 c9 O" j/ D
  303. - Q$ a/ C1 ]' x7 k$ i& y/ e3 l0 U4 n
  304.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_RX0_IRQn;$ i# {' u1 ^& @3 U$ ^5 g
  305.       NVIC_Init(&NVIC_InitStructure);/ I, h8 @6 q  K' Y7 `
  306. . g$ q  n0 z& i+ U
  307.       CAN_DeInit(CAN2);
      Q3 E3 ], a4 a$ f

  308. 5 _$ [* D# }4 j
  309.       if(can1InitFlag == false)4 ?$ J& p1 h' |# `) {8 l
  310.       {8 }/ ]  b* c7 \0 d% u+ |
  311.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);
    # k2 v; G( x8 K4 t9 _' r$ f
  312.       }- V/ {/ c6 N8 C2 J
  313. $ i* z8 `0 e, ?* i1 H: q8 Q
  314.       RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, DISABLE);
    * u9 u! ?1 Q4 ]! p7 t  a
  315. ! k/ K( q& D4 i: ?
  316.       can2TransmitFlag = false;6 [( r0 B7 h+ s% J/ y% T
  317. " z' m. e; U; A4 C
  318.       can2TransmitFinishCallback = 0;2 _5 k" [0 k' T' |
  319.       can2ReceiveFinishCallback  = 0;! j, y( j  [: ]

  320. 3 p/ c  M  w3 Q- {* f" O" v' M$ s
  321.       RingBuffer_Free(can2TxBuffer);6 H+ d: a7 I5 m/ Z+ D9 W9 e+ F. C" x
  322.       RingBuffer_Free(can2RxBuffer);  F; e1 D4 j2 Q4 h! Q: ^/ D- b
  323.     }
    4 v6 z* C* u0 v
  324.   }: q( a0 u# s% Z/ D1 F# U
  325. #endif /* STM32F10X_CL */
    - b' A& M1 _* p: v  P9 N" A
  326. }$ P7 y* f8 t3 h7 O, n
  327. 5 W6 Q- e3 A" N$ Z, K
  328. /**
    ! f% A3 ]* T% E$ U  L. H
  329.   * @brief  CAN set transmit finish callback.
    * f5 D. K' c0 N& s% D) P6 B& l: f
  330.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.
    ) u* B: g1 P) ^1 c4 n
  331.   * @param  [in] Callback: Callback.1 r! g7 N$ u" P$ O
  332.   * @return None.  A, P* C1 o* i1 X9 j
  333.   */
    6 {+ j8 S9 M  t
  334. void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void))
    + l" [/ Z' w- o9 {! _( }
  335. {
    % V- C3 N: z- D3 I
  336.   if(CANx == CAN1)
    & ?% W  s0 M3 I: k; `  b) }) N1 b( b
  337.   {
    ) G: A, ^& E7 Z& S1 k5 h
  338.     if(can1InitFlag == true)1 y# ?' e% y7 f1 n* ]
  339.     {
    5 U2 Y  ~- ]- i& g
  340.       can1TransmitFinishCallback = (volatile void (*)(void))Callback;
    ) C8 a  Y5 c  g, a
  341.     }
    . I2 M, g" L4 D7 R# i% f
  342.   }& \: S" Y8 \" k, C# r" f
  343. 8 O1 k) x5 I, `' T" E% g
  344. #ifdef STM32F10X_CL% d7 u/ `3 L: y/ A: P5 m& r- i- t+ D
  345.   if(CANx == CAN2)" G. m+ E# u' d  p# o
  346.   {! t. b: T1 p' Y/ y$ i
  347.     if(can2InitFlag == true)+ x3 v) S. U% L$ K2 F0 h- z
  348.     {9 C6 D2 M/ f+ h* d5 A) d. a
  349.       can2TransmitFinishCallback = (volatile void (*)(void))Callback;9 w! m/ y/ I. v) Q- H$ @
  350.     }& g; E3 |: a7 \$ l% M: H
  351.   }
    0 v; t2 i( H0 s4 k9 k- G# s5 |; k
  352. #endif /* STM32F10X_CL */1 |# F/ |! k9 {  E! h9 b
  353. }
    6 H5 `) c6 c$ H5 K$ I0 O+ Z
  354. ; U! S+ o& g5 E6 [% V( T6 w
  355. /**6 h/ P! r' }5 m8 d  c4 k4 c" q
  356.   * @brief  CAN set receive finish callback.
    9 O, E. H6 {/ L- N
  357.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral./ A% {$ @& d7 e; ~. w+ b% T" v! T
  358.   * @param  [in] Callback: Callback.2 g/ I* t+ {+ ~$ ]) L; ]( g, G
  359.   * @return None.6 f! ?1 a' o9 w2 r
  360.   */
    8 @9 ~/ A+ S7 U+ J6 D: B
  361. void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void))" A+ @' o. f! k6 K
  362. {
    3 n& G1 Y! h% V1 n2 B& U  |6 ]
  363.   if(CANx == CAN1)
    ! S) J- u- X! l! w
  364.   {
    : p- q3 H+ Z  [* D
  365.     if(can1InitFlag == true)& A4 i4 q, d6 a
  366.     {
    % U' k/ \1 b7 z% B* J
  367.       can1ReceiveFinishCallback = (volatile void (*)(void))Callback;+ L9 x6 q  G- V" R
  368.     }9 P. F. i! ?& e/ N8 b: V8 i
  369.   }+ |% A: G3 E1 ?* x) n- g

  370. # k0 c8 Z. V. h, v
  371. #ifdef STM32F10X_CL1 J0 @( W+ ?$ ~7 x
  372.   if(CANx == CAN2)% x0 i& Z9 S. ^  g( h
  373.   {
    " [( m/ i1 U7 ~7 D
  374.     if(can2InitFlag == true)/ F. J/ J% P* b1 ?& v( |
  375.     {
    # t& \& d3 L. t3 K) q- a: E
  376.       can2ReceiveFinishCallback = (volatile void (*)(void))Callback;
    $ C# R4 `" Q  M
  377.     }
    8 S- U" P( A. a, c; ~( b$ w, p& h9 |
  378.   }. _6 g# A* [, L6 y5 y8 |
  379. #endif /* STM32F10X_CL */
    * F& L; I& |% q. ]
  380. }
    3 \* {% o- m9 t# X# h
  381. - F& [1 W  A9 T+ J$ B: c' r9 Y
  382. /**
    ! w: C! x6 s+ L4 R, g" H) C9 ^
  383.   * @brief  CAN set transmit message., j# L4 Y" P- F
  384.   * @param  [in] CANx:    Where x can be 1 or 2 to select the CAN peripheral.
    % h2 }# ?/ A8 ~, g
  385.   * @param  [in] Message: The address of the message to be transmit.
    ; R* E' x; z( C, W& f* g& u$ W
  386.   * @param  [in] Number:  The number of the message to be transmit./ Q) _- D- M2 B9 j; u* A, f
  387.   * @return The number of message transmit.
    * E$ g+ v4 T) ~3 Q' a
  388.   */2 s8 o) H3 k/ S6 g7 {. S
  389. uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number)
    3 ~# n& Y5 }' J7 k3 I" e
  390. {; ~9 `5 V- W! J
  391.   if(CANx == CAN1)
    $ d3 \% M9 w5 w
  392.   {3 ?9 m$ ?* V" U; |9 [1 F( D2 d* B
  393.     if(can1InitFlag == true)1 Y4 T; r5 D  ~1 u
  394.     {$ N" \6 C  P( B" F, O
  395.       uint32_t available = RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);  }6 [8 [: g- a% N2 v
  396. 2 H) q) v7 ?! _* f1 ?: `
  397.       if(available > Number)
    - @% p* ~$ o+ c. G  Q' \5 N  Y
  398.       {
    * |8 B. f; o( O8 |
  399.         Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);* h( h9 M: M2 J3 y  y
  400.       }
    & e: q1 j  S7 Q# I$ y3 x: k% ^
  401.       else# Z" p& F7 D5 w- {& F
  402.       {
    * C! y' I) f; S6 ^. W" z
  403.         Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);
    5 ~7 ^8 Z# H/ z4 n0 ?
  404.       }
    ' t# \: j% b! n# r

  405. 5 b2 }) z; K9 R; R' H" w
  406.       if(Number > 0)  B- [; h7 r' Z/ b$ @
  407.       {
    ( B# A5 g; v8 n8 G6 x
  408.         if(can1TransmitFlag == false). d. q+ \8 B# W) B
  409.         {& _* B1 G7 O/ P8 y/ |
  410.           can1TransmitFlag = true;8 o% j2 K: X# H* V5 t

  411. ' C' f3 K- i2 E8 v
  412.           CanTxMsg canTxMsg = {0};
    7 D. w: @' O7 }# s+ v# R2 K
  413.           RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg));5 o" O+ X+ o' X2 N. L/ W/ h" }
  414.           CAN_Transmit(CAN1, &canTxMsg);. p3 w+ [' Z5 N% ~
  415.         }4 H+ f/ ~, l/ F) L$ o4 }
  416.       }" }/ T7 s! q2 ^" W! G
  417. 4 a5 W2 ]) K2 M4 r0 A) D, {
  418.       return Number;* z4 ^! c8 u# y6 t
  419.     }
    - ~5 ^) b- H4 T0 j( t4 W/ V
  420.   }
    , @6 W$ D$ f& Z: |5 a
  421. + b* V. ~6 t! s; }. O1 h
  422. #ifdef STM32F10X_CL
    # b, N9 D- c3 Y: @- I5 f+ J6 n
  423.   if(CANx == CAN2)% n. k" b- a* F, y0 \/ W
  424.   {7 j, f) z5 [2 d% ~: M# [# F8 v- ?
  425.     if(can2InitFlag == true): N1 Z6 `; N$ q/ o; A
  426.     {
    3 @, `0 b0 p( p
  427.       uint32_t available = RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);
    ' R) f2 s, Y6 ^5 |3 c
  428. # N$ X9 X: @3 f+ x- j
  429.       if(available > Number)
    5 Z) v& }# k) n* H/ c3 ?" l" w' [4 r$ V& T" m
  430.       {( a  d/ B) u, p, ~
  431.         Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);
    5 |3 [* m4 G/ t0 T* k8 j$ J% |
  432.       }
    + {/ C+ ^( d6 }5 A; |
  433.       else
    / ^0 f/ O+ p/ d) t  E; a
  434.       {( A9 |# {6 p* k6 Q* h
  435.         Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);4 l4 {& i7 X" `' O
  436.       }
    * [+ g% v4 O" o, H; T
  437. , N: C/ a4 I1 v5 {3 h6 S
  438.       if(Number > 0)
    1 B$ [3 M$ a: [5 j) e  _
  439.       {) I2 z% D, L$ ^2 [- O' d. D
  440.         if(can2TransmitFlag == false); g- M% W# H+ k  N1 y
  441.         {
    3 a/ q9 e; l( e4 c$ }! f
  442.           can2TransmitFlag = true;
    - L5 m; f  Z; v# v5 Y8 B
  443. ) |, x& C8 E9 T2 j
  444.           CanTxMsg canTxMsg = {0};
    . k. T% @) e' C6 k4 m
  445.           RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg));: V: \6 T% m' o  b! U/ }
  446.           CAN_Transmit(CAN2, &canTxMsg);$ s1 T$ p, h9 h. x5 D
  447.         }' q* j* r8 G  h$ N  u0 u
  448.       }
    * |% H3 m$ d0 i7 J7 ~- j% W9 @

  449. + x: S2 a0 [" \& X! @
  450.       return Number;
    & z7 S1 n, m; z  F4 R2 `0 y
  451.     }
    5 b$ y/ z- s7 D" E) N. `9 d
  452.   }
    ( S4 w9 X# R% e; l! R. z
  453. #endif /* STM32F10X_CL */
    6 \# z. g$ c' @

  454. ) v8 L6 \1 e7 |* z; X, Q
  455.   return 0;& k8 W, I! l( f4 V% G9 ~+ [
  456. }6 c2 ^0 |! b+ s5 Z# t6 G
  457. ; o" x7 \1 G( {" Q
  458. /**
    " p2 o9 c9 s' d  L  z, N
  459.   * @brief  CAN get receive message.
    0 B% O& S, ?7 z. |
  460.   * @param  [in] CANx:    Where x can be 1 or 2 to select the CAN peripheral.* m3 `. X2 ^" A5 A  O
  461.   * @param  [in] Message: To store the address of the receive message.
    7 e2 F! |9 v7 U1 x+ r, I1 T% l
  462.   * @param  [in] Number:  To read the number of the received message.
    " C3 t5 F/ t, l
  463.   * @return The number of message obtained.( {& s2 p" @1 N* {8 b& C6 z0 I' ]
  464.   */2 j  m7 m# \1 F* X
  465. uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number). Q' t; {! z, k+ G: S" B8 b9 `
  466. {
    6 E! d6 s9 }9 C' P$ @, R  ~+ q
  467.   if(CANx == CAN1)
    5 p& B# j% ^# n
  468.   {9 H5 ]% S* n" K3 U: `3 x7 f- y
  469.     if(can1InitFlag == true)& u* t9 Y& g; P6 _
  470.     {
    . H% }- m7 H" ^5 ?% w. A
  471.       return RingBuffer_Out(can1RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);
    0 w* L6 k0 Z) A
  472.     }7 _3 p2 W0 L1 W4 x; a
  473.   }! \5 v( K& V2 G+ }9 G* F( |

  474. * g) h5 g, {  \- @
  475. #ifdef STM32F10X_CL  J! o0 H3 g1 Y* |
  476.   if(CANx == CAN2)
    / l% E! [( Y$ W3 }" h; `. Y  ^" y
  477.   {
    5 \4 X7 e+ |. B' Z! c5 u  j
  478.     if(can2InitFlag == true)1 K( |4 q. y. S' i% c
  479.     {
    5 W5 i1 `* l  t3 R
  480.       return RingBuffer_Out(can2RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);
    : p, ]; @2 ~, Y/ ~
  481.     }# B/ z4 }& @6 k: v
  482.   }
    - s7 i" ]( W  a* r0 J6 u$ ~% R
  483. #endif /* STM32F10X_CL */
    # I% L+ }2 Z8 _6 r

  484. , n6 O* U1 o& A+ s/ @
  485.   return 0;" ]2 `1 J# t! U( L0 ]) s+ K
  486. }% A8 ]) s8 p; N, o
  487. ' G7 }  Y1 G( |3 P
  488. /**0 P  {! |# u6 |+ b3 W1 v% t
  489.   * @brief  Get the size of the CAN transmit buffer used.
    8 k* p7 ?4 S3 a" [- e, g
  490.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.& h2 x0 `- o9 y4 f
  491.   * @return Used the size of the transmit buffer.7 a- f9 C& Z! t4 `/ [/ c/ o1 x  S
  492.   */
    / N; i0 [5 p0 C. m8 H9 c$ o
  493. uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx)
    ! ~  `- U! x6 R  O9 s
  494. {
    8 \3 e$ a) c6 r+ D
  495.   if(CANx == CAN1)9 y/ c( ?7 i2 q6 G+ Q' M. j- l- H
  496.   {
    5 ^! g, \# J. k* J; I; H" U& `
  497.     if(can1InitFlag == true)( O" ~% z  \. p6 t
  498.     {# Y* _' G7 Z# Y4 k, F
  499.       return RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg);# W* m4 G- d2 |! @' a. o) h
  500.     }
    0 [; y# k7 c! g- I4 g3 {8 y9 K9 [
  501.   }
    9 _* A" j# I! A' I$ ]

  502. ' r1 Q5 u' }' M0 n" ?
  503. #ifdef STM32F10X_CL
    3 U1 \' ?5 m( x4 U. s) K) s% S
  504.   if(CANx == CAN2)
    ; u/ D% K  a4 X# o6 R  E+ a* O
  505.   {
    ; }9 j2 _, a( n) z3 w/ C0 H! s
  506.     if(can2InitFlag == true)( w1 K: r, t- l2 {0 H4 Q
  507.     {7 L3 T0 T3 B! w2 F  y
  508.       return RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg);
    : Q  K" r0 Z$ g8 S3 t+ O
  509.     }; Y- C5 Y  C3 K, v7 [+ m( s. Y
  510.   }; S% Y/ u5 V" D" X
  511. #endif /* STM32F10X_CL */
    . A( F. u" \9 L
  512. - T  n. h8 r4 A( T5 D  L" p
  513.   return 0;
    1 P9 k# G; w3 V/ p/ F) O
  514. }% }4 ]$ J- p5 Z0 e

  515. 4 ?6 D+ t* _6 [- Q& ~' A% [
  516. /**
    % @) x0 C) l6 \7 p9 [
  517.   * @brief  Get the size of the CAN receive buffer used." K7 b; T1 o% z2 u# H2 \3 H
  518.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.8 @0 p3 q" u2 _  e; P
  519.   * @return Used the size of the receive buffer.
    4 y) ^: k3 w( W. }/ m& m
  520.   */
    . Z% U. m& n$ P
  521. uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx)7 f+ {3 B; ^8 z$ c0 J
  522. {
    8 R1 r9 u" L+ _; g
  523.   if(CANx == CAN1), n- g9 e0 h6 m7 |% N
  524.   {* m7 M+ w& L; b
  525.     if(can1InitFlag == true)
    " u. E9 _5 J' L( e5 ~3 H* W
  526.     {! a1 A; y8 H7 ?5 g4 X' E7 u* ~# K( m
  527.       return RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg);0 Y; b$ X) Z2 ~& E
  528.     }
    - Z9 `: E1 j/ ?2 d6 z( ^
  529.   }
    - \2 }. U9 `4 @+ Y

  530. % b( S- `% @3 E/ z  s$ M1 J7 J
  531. #ifdef STM32F10X_CL0 K8 R7 [4 ?8 I* w0 f
  532.   if(CANx == CAN2), U5 m; O3 E/ a' }3 {! P: R7 }
  533.   {
    ) Q. l& W! ~, H% C3 Q  L
  534.     if(can2InitFlag == true), H0 d. I: P8 {# }
  535.     {
    0 ~; a8 B/ o& S7 ?- v
  536.       return RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg);: S! _$ y% v  @& I2 V. l
  537.     }9 p: W2 z  L2 \8 ]7 b6 s
  538.   }+ m2 U( y' ~  M
  539. #endif /* STM32F10X_CL */# J+ f' s$ ?, }/ M) q
  540. 8 ^2 S8 y: @  y, J: ~( r3 H; h
  541.   return 0;4 a- A  R" m6 r, R( V: L1 y
  542. }' [2 B5 t$ M( w$ |1 J. |; Q
  543. 1 x" U) e6 r5 U8 Z7 n6 d; B
  544. /**3 L" K3 ]5 o  y  ~. C7 y' Q
  545.   * @brief  Get the size of the CAN transmit buffer unused.- R  G, q) e2 Q  ?7 R  b$ w/ E
  546.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.1 x5 o5 K- q# `2 T/ f6 t; p( t+ i
  547.   * @return Unused the size of the transmit buffer.
    & N0 {7 [$ q% t9 T4 d: q( G
  548.   */
    1 l; \- k* Y' m/ |
  549. uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx)# s8 z- q; I0 G* X" v
  550. {0 y( H2 V5 q$ x3 d  v0 X9 x7 c7 |; d
  551.   if(CANx == CAN1)- P" w+ k1 M2 N2 M: p9 C7 H
  552.   {) u$ ~$ v: Z' T5 V+ Z
  553.     if(can1InitFlag == true)4 \2 V- ?0 e2 E
  554.     {
    , N- [2 J0 d) M* v3 W
  555.       return RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);5 b* \% K- ?- d
  556.     }
    ; n3 d: \* r* H) i- o5 F1 y
  557.   }
    + z. Y5 U4 c4 W& |2 `* H

  558. 7 b( m$ j' X/ G& B9 P
  559. #ifdef STM32F10X_CL& a, {' A; v% @
  560.   if(CANx == CAN2)$ U* p& b. `% l& b9 o6 v2 d
  561.   {2 ]* N! H+ Q4 A0 e
  562.     if(can2InitFlag == true)% ?, o0 H0 h! m) u* ^* J
  563.     {8 h3 K& o7 N0 G" {2 H* r0 |
  564.       return RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);
    " j! Z% e3 s" S4 d7 S; N
  565.     }* D/ z$ v4 [/ [! T" y2 P
  566.   }
    . c8 Z, A, w) b* G
  567. #endif /* STM32F10X_CL */
    ' X, {+ ~8 T4 j: j1 l
  568. + S/ s5 I8 m- e
  569.   return 0;
    9 J) n4 U0 d2 i! Y1 M3 T) ]3 N7 P
  570. }6 o6 U. C7 @  B" y6 @
  571. ) W$ `- ~! Y  j! a
  572. /**+ R5 J5 G9 s& Y5 X& _! G
  573.   * @brief  Get the size of the CAN receive buffer unused.5 ~" O: p' b: p0 E
  574.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.1 G0 z! O. P0 \- p+ @
  575.   * @return Unused the size of the receive buffer.
    : @; ^9 l! S* [% C4 C
  576.   */
    " W, t) d7 s9 U9 p0 k: s3 [
  577. uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx)
    ; J6 h' d4 `4 Z9 N* A8 Z- w: t4 U
  578. {, u, p8 d. Q, ~7 z9 X( X* X
  579.   if(CANx == CAN1)/ M) u/ f0 |9 ]+ Z5 O  z8 m) Z
  580.   {! g" K2 W& ]' f& t5 m/ b. L3 N
  581.     if(can1InitFlag == true)/ R" H4 }7 ?- N! m
  582.     {/ ]4 o- l% h; ]4 C$ O
  583.       return RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg);
    4 O0 y6 y9 `5 ~2 t
  584.     }/ F0 t+ S3 o4 m5 V" J7 W( u
  585.   }$ R% k( P# r: `* O- q
  586. ) c9 @2 ?% d% f- O( k# r, n4 g9 j
  587. #ifdef STM32F10X_CL
    . z& }- `* p4 r9 T6 \! H  g
  588.   if(CANx == CAN2)
    ; H  y2 }& H$ v, t- [4 u
  589.   {
    & [+ z& `  N% A
  590.     if(can2InitFlag == true)
      W% u) l# w5 k% x
  591.     {8 H# j7 _3 [  _4 z# O& Q4 u; L
  592.       return RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg);
    ( B% c% H7 _2 Y9 l, i
  593.     }. |& t/ ]* s) T( `
  594.   }
    , ?! m$ {4 V0 N$ D! i
  595. #endif /* STM32F10X_CL */& y! b) d1 y* T' p9 b* {

  596. : S2 M) E" h. O
  597.   return 0;
    2 D0 q* v; z' G( W! o7 z% U4 H
  598. }" J7 h/ e+ j3 {0 k  C3 N$ p) J# `
  599. + L1 s. ~/ l8 y6 o
  600. /**
    : m& V7 }+ u( N: y8 g1 e4 M
  601.   * @brief  Is the CAN transmit buffer empty?
    + Y) U! d  B/ n* e1 z
  602.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.5 u% Z2 b! g% G+ `. j3 V9 @
  603.   * @retval true:      The transmit buffer is empty.. Y5 C# c5 u; e
  604.   * @retval false:     The transmit buffer is not empty.
    ' a, P- k9 q* A- P7 B
  605.   */
    : ?7 w$ q+ `) u& G( j
  606. bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx)
    9 B2 N2 V. \& W4 T% g
  607. {
    0 e/ k  b3 d2 B+ ^, ]
  608.   if(CANx == CAN1)9 K5 t+ q$ N3 u; ^+ W7 l
  609.   {
    3 k; R/ ~6 ?: f, n
  610.     if(can1InitFlag == true)
    # n, V! M4 U4 N6 X1 |: W
  611.     {
    ; X! l- c% F6 |% M0 ~. N4 r" I
  612.       return !(RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg));7 [% c  [9 K+ m
  613.     }
    - ~7 o3 m7 [* Y5 s/ k
  614.   }% o1 p8 r$ N+ j9 b  {
  615. # I8 n5 V" W6 O+ Y4 @- V$ R
  616. #ifdef STM32F10X_CL
    & B& x/ Z9 }' M, s" A7 T
  617.   if(CANx == CAN2)
    , B1 [" _2 D( @2 ~/ {( V0 c
  618.   {2 c6 n$ |; f6 N0 x7 r" V1 b
  619.     if(can2InitFlag == true)
    5 c2 @; I2 A8 G$ U: T+ w2 c
  620.     {
    / ~- K) o: |! Z: |2 s. h
  621.       return !(RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg));
    : t2 P( Q. B8 O( J4 {" K  z
  622.     }
    ' b- m! Y# r! @( A
  623.   }) k3 w0 [' l7 l
  624. #endif /* STM32F10X_CL */( w" i, v. G" t) y$ D

  625. # i7 j$ C1 B2 D8 J0 V( w
  626.   return false;
    8 f! @% P+ D2 ~7 M" ]% r  `7 d
  627. }& g3 V# d* Z* [$ k& s4 t

  628. 1 }, [9 z# |  g- w
  629. /**
    - A. P& f& j; g! Z. R
  630.   * @brief  Is the CAN receive buffer empty?! M7 n# B7 l5 r: K/ N1 I
  631.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.. {* i) w: h* u
  632.   * @retval true:      The receive buffer is empty.; X4 Y- [/ K" X& q, I
  633.   * @retval false:     The receive buffer is not empty.
      L1 \! J; g7 ~
  634.   */
    + ^1 y& A1 Q- y$ d
  635. bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx)
    : Z9 t# p; `. v
  636. {4 @" i; o3 B( y/ Z6 Y7 C- s, x
  637.   if(CANx == CAN1)
    * `$ p" m2 o0 m& K$ w7 k
  638.   {. }5 a6 v0 x! G4 M% ^
  639.     if(can1InitFlag == true)2 c, Z2 Y9 w" c  v! y& l
  640.     {. B. v( t- H* u/ Z  G/ G5 [
  641.       return !(RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg));
    9 G; T: b0 h4 U% N8 l: M
  642.     }) N2 R  @- b, R3 l; ?! Z
  643.   }* B1 R. W( {* R' J- D' S. _% w2 ]/ N

  644. ; ]: C3 {; n2 T/ |
  645. #ifdef STM32F10X_CL' c; Y" ?3 i6 U' C/ }+ \) v: j! {
  646.   if(CANx == CAN2), ?& L2 O5 S, f6 ^
  647.   {" O* `$ s# ]" c) ^2 D
  648.     if(can2InitFlag == true)/ {. R- g; Z. ]6 F9 C3 M6 |
  649.     {
    1 V! K. x4 b* L6 w$ g6 d
  650.       return !(RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg));# a& `8 u8 l# ?. y* |/ d9 w$ X: s
  651.     }  S( U8 s* p: T$ a1 ^7 V6 U
  652.   }+ g  t0 H9 o% [# K+ q; p
  653. #endif /* STM32F10X_CL */' u+ b2 o: Q$ `. a
  654. & ^7 \* T; B& b8 j8 B4 j
  655.   return false;2 d6 d9 l* c6 Y( h8 P+ Z. s
  656. }
    ) w: z6 a) I# F0 k3 m

  657. : F' F7 Z; r6 N
  658. /**. V7 M1 b1 d$ e: ~( b2 `- N  g
  659.   * @brief  Is the CAN transmit buffer full?, _9 i3 c% E. o. z& l
  660.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.  _- G9 U9 Q  x' f3 E7 D
  661.   * @retval true:      The transmit buffer is full.0 n* c8 Z% J' ?' S3 n3 g, _
  662.   * @retval false:     The transmit buffer is not full.  A! s# {$ B1 L1 X9 l* m# c) j$ p- D
  663.   */$ F# ^4 ?8 X* w1 ~; ~- e( v& M
  664. bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx)
    + ?3 M, M6 _$ ]% f2 a/ o
  665. {
    + e" S. W: h3 k" b# n  t; F
  666.   if(CANx == CAN1)
    4 q" u% w' }9 |' C7 f1 N
  667.   {
    % B+ F, h4 ]- P1 e: k
  668.     if(can1InitFlag == true)
    4 y5 @4 k) T; c, u
  669.     {
    / D8 W) j1 Q) R5 [6 m
  670.       return !(RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg));
    2 `8 U7 U9 A# t  @) d/ w
  671.     }
    " z1 X! w1 |3 ~/ D2 j
  672.   }8 l: Y4 T8 P# |1 A$ M

  673. ) M4 i2 w( k  z+ w; y8 N- Z
  674. #ifdef STM32F10X_CL
    2 g7 W. f8 x$ v3 f- o
  675.   if(CANx == CAN2)
      E' U" ?" i8 {" {" E
  676.   {+ w6 x, J$ k! j7 ^$ r; _
  677.     if(can2InitFlag == true)/ a7 e; Y- u, O, ?6 x) n8 I
  678.     {) ^' H# [8 X. x6 O- M# A
  679.       return !(RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg));
    ) P# ~% T: j& i
  680.     }7 d' ?; y6 v3 Z7 Y
  681.   }% ~' T( A. x9 ~. W0 a
  682. #endif /* STM32F10X_CL */- B; L* y! i# F' O7 K3 T* e7 x" |

  683. $ z: E0 ~0 Y/ c4 W: {3 x2 B
  684.   return false;( N( d  Z6 J8 L
  685. }4 q8 k0 Q- C8 A' U6 R5 C
  686. $ X: D" b4 R# |4 F3 j; J
  687. /**4 u( c4 M9 C) D# j/ K3 N
  688.   * @brief  Is the CAN receive buffer full?
    9 L( Q) K+ J5 N# @& B
  689.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral./ |+ l$ N/ M1 ^& k
  690.   * @retval true:      The receive buffer is full.( L- O7 W9 w" u: R8 J& T
  691.   * @retval false:     The receive buffer is not full.
    3 x0 ^7 R; G5 Y+ u9 b
  692.   */  O* D/ a, a. X. u- s! W
  693. bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx)
    - {3 a/ L4 b) I5 |, K4 x
  694. {- {: V+ }2 H* h) F
  695.   if(CANx == CAN1)" b* m. E, X; V( t
  696.   {
    # h. p; c: ?0 n+ d+ j6 t2 y# `8 `
  697.     if(can1InitFlag == true)6 q2 z. W9 H6 @$ c0 i" S3 }. A
  698.     {
    " p, k! Z6 b7 r# ?
  699.       return !(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg));7 e* X: i/ R) _- E0 w
  700.     }5 x% x- V- K: g& I; O5 }% `
  701.   }
    5 h# E/ I6 B: u, D1 C! _7 K

  702. + N" R6 K! k8 A2 T: V
  703. #ifdef STM32F10X_CL
    $ J6 V& k* {* ?" ~5 ?7 Z" e
  704.   if(CANx == CAN2)
    : g/ W/ ]# D/ }# B/ \) J
  705.   {
    $ E' z6 V. x2 a. L
  706.     if(can2InitFlag == true)
    + i8 S+ p: w3 o) W) R0 W
  707.     {3 b$ n* W! F6 Z: K
  708.       return !(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg));/ {8 J# o2 D/ D; R) z$ |
  709.     }4 ~7 y+ i9 ]/ h- O  W- @
  710.   }
    ( Q( w9 w. Q  q, A# h
  711. #endif /* STM32F10X_CL */
    $ V; w6 {# f9 Z7 U4 V1 {

  712. / E  a1 ?8 P7 H
  713.   return false;4 O8 q3 P/ h2 g! \
  714. }
    ( a! f/ V+ s; h9 ?8 U

  715. 6 T, R( I! j/ w3 ?, Y  X; }
  716. /**
    5 a. }4 g4 ]% ^: Q% f
  717.   * @brief  Clear the CAN transmit buffer.
    " L. s! r5 O. _, k" N  T9 U3 d5 G
  718.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.; R+ j  h- ?& r' C3 p/ }9 C, X
  719.   * @return None.. s- ^# t! U- s  g
  720.   */
    * L, O* ^: p& G7 U, u: R/ E
  721. void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx)1 v% `2 X, g: O0 y: F9 s
  722. {. i% n) h4 {/ X5 V7 k
  723.   if(CANx == CAN1)5 L% G3 S; d: S( O: C3 H3 P+ Z
  724.   {
    ' C; Q6 M  h( X" G6 X5 L
  725.     if(can1InitFlag == true)
      I3 B+ @2 x' y1 W
  726.     {$ W% C; I& T5 c9 M
  727.       RingBuffer_Reset(can1TxBuffer);! H% _! u4 W" T/ j' U/ K* @6 m4 n' p
  728.     }
    9 c+ W5 T" h# o8 p, R5 S- k
  729.   }& N$ O- l5 S- K9 U( g& K/ x
  730. ' W4 T+ C$ y& o" w
  731. #ifdef STM32F10X_CL
    , g/ M( D; Y5 M6 @6 K- u+ [9 |/ p
  732.   if(CANx == CAN2)
    : g2 E+ ]# p! I# R
  733.   {
    ) t0 h  g, f$ T: h1 m
  734.     if(can2InitFlag == true)
    + z/ _0 L; |. _0 d# I, x3 C
  735.     {; M3 D& s9 l- I( E  ^; D
  736.       RingBuffer_Reset(can2TxBuffer);
    % G( P; y2 f% H# z2 x' d% K
  737.     }0 q; E8 C; A" q4 p; ~* u
  738.   }! J* Q: T( }1 s; D' y1 Z
  739. #endif /* STM32F10X_CL */
    ! y6 W" S# z# A' j7 O& d9 z
  740. }8 W" P' M: L9 r1 S  T, m9 G

  741. * n6 K& r" Y7 w- A
  742. /**; Y& f- v9 c! _& W8 G" R; R
  743.   * @brief  Clear the CAN receive buffer.4 U6 a- x7 k5 F. K: w
  744.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral., }. f* ~( g: O* V
  745.   * @return None.4 Q" T0 s3 s$ Y# K7 U
  746.   */1 }2 r3 a/ b9 }
  747. void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx)2 {2 Q' S: G% T# q
  748. {, {: m( Z' L+ B6 [% W- X5 \% z
  749.   if(CANx == CAN1)
    ' M" h" @4 ]  Y
  750.   {2 ]5 c% T% k: j3 r4 X
  751.     if(can1InitFlag == true)" j9 }1 L! h) w6 \- E
  752.     {
    : |/ D# `- U+ H
  753.       RingBuffer_Reset(can1RxBuffer);, B* b6 U4 b  z& r
  754.     }' S* O) X2 V3 h% {
  755.   }2 ^" T9 O+ \# c7 _- F7 k1 I; k

  756. ' k4 V2 P! Q  I; D
  757. #ifdef STM32F10X_CL+ C/ G; b6 I- J& l& s/ {3 u
  758.   if(CANx == CAN2)5 w! o+ D/ E6 t& B- t, W( h
  759.   {; C: Q7 a% x) c6 S( w, k* Y7 A
  760.     if(can2InitFlag == true)+ Z+ ?+ q1 l4 E( _
  761.     {
    . L( g  D7 h( X% v  u1 t1 ~
  762.       RingBuffer_Reset(can2RxBuffer);
    5 _/ s! ?: _9 P( c
  763.     }
    ; A. F% `$ |( k
  764.   }- }$ ]! u% f8 _) B! f7 Y( d) h" ^
  765. #endif /* STM32F10X_CL */
    ! ^) Z! p- `+ W" e
  766. }
    & E" n$ ?* O. e: \
  767. 0 V+ p1 E* ?' ^
  768. /**
    $ ]3 E& M7 e  Y' @
  769.   * @brief  Is the CAN transmit a message?
    ' X* s9 s7 l6 W4 n$ v2 o
  770.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.* X1 Q, Z3 E* y! D0 Z1 ]
  771.   * @retval true:      Is transmit a message.9 l& w* G! u- W& d: W' w" C
  772.   * @retval false:     Not transmit a message.
    8 g% ]: l+ Y! G; {+ b4 O
  773.   */4 b. c6 H7 a; e3 D
  774. bool CAN_IsTransmitMessage(CAN_TypeDef *CANx): n) {+ `0 \  k0 w$ Y
  775. {
    " R* _9 s; W  b# N6 u' r6 R. x
  776.   if(CANx == CAN1); b+ ]4 c% \/ z' i$ X0 F2 R6 C8 @
  777.   {; K$ h+ Z1 p  P- N' \: h7 V/ g
  778.     if(can1InitFlag == true)
    1 R  R% K1 i7 }
  779.     {
    ( o, D: \" S. U2 J
  780.       return can1TransmitFlag;
    . S! g) S' ~* y4 i. G$ h4 ^
  781.     }7 P4 u! T# f! S9 M) C+ j  S
  782.   }
    . [( O& |# g" z  E2 [7 I3 i* c6 l; D
  783. ; ]) Q1 I5 t; s- E. u* C
  784. #ifdef STM32F10X_CL
    , Q/ m0 N9 l8 n8 w1 c) {- ]* ~
  785.   if(CANx == CAN2)* [* l- W3 @* [
  786.   {
    " I# |- ^+ [. Q: F* @" e
  787.     if(can2InitFlag == true)& N( B9 ]7 T7 Z1 o9 \& E( s
  788.     {+ m  p( m+ b  }9 O: F( y
  789.       return can2TransmitFlag;  c: h+ p" |' y0 O5 j2 C
  790.     }
    ! P/ [% T$ ^+ R# ?& p
  791.   }
    $ u+ J/ J. b: P. b* K0 c) V8 w3 Z
  792. #endif /* STM32F10X_CL */
    & u. Q2 h' X* h, l' `' |
  793. 7 B( x0 R) c! b
  794.   return false;# S! Q" I8 p  T" j9 z) S& H2 t0 l
  795. }
    0 {3 _: c9 U% |( O. \4 k# F- v$ c, g
  796. * L! C7 R+ c0 u. I1 R9 j( q5 A
  797. /**- @+ V4 H3 s4 W) `  K! C3 Z8 K
  798.   * @brief  This function handles CAN1 TX Handler.! T1 Z* {* A- o, t3 L% G
  799.   * @param  None.! t5 U& _5 x3 N
  800.   * @return None.2 n& h- X) k0 W2 |5 E0 j
  801.   */
    " R4 E% W' a* k8 j! Z3 I% k: B2 G
  802. #ifdef STM32F10X_CL
      M6 q* c) m, d- N4 a0 b- @
  803. void CAN1_TX_IRQHandler(void)
    # y/ n% W; k1 ^& @2 T$ i
  804. #else
    " C' z% N$ s2 m9 C7 M0 Y& u5 C0 O+ a
  805. void USB_HP_CAN1_TX_IRQHandler(void)' ^/ u  Y* A' z+ G% C1 S$ J. g
  806. #endif /* STM32F10X_CL */
    ' n& ?/ T/ t6 A# x
  807. {
    ( {1 y/ G) O; \6 f
  808.   if(CAN_GetITStatus(CAN1, CAN_IT_TME) != RESET)) ]6 r6 f- S( @3 y5 D$ |. z- f; Z
  809.   {
      |0 g5 p" e8 o9 Q9 Y
  810.     CAN_ClearITPendingBit(CAN1, CAN_IT_TME);7 s1 X' h% Z' n

  811. * }& @" Z2 w  E2 J5 W
  812.     CanTxMsg canTxMsg = {0};3 K. f5 g* h8 [# w' l- k1 g! ~
  813.     uint8_t  number   = RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);$ b0 d/ m8 W4 e0 ]9 r  E

  814. 5 U+ E6 ~8 B! @7 A
  815.     if(number > 0)
    0 W& _6 b' ~; C  E; n
  816.     {
    ( g7 p, Q  c2 O* T
  817.       CAN_Transmit(CAN1, &canTxMsg);
    6 I6 }7 y8 w9 q; y- F2 I
  818.     }
    2 Q( m! R" i. @2 w2 J% q
  819.     else
    & r( Z2 Y( i$ y0 ^8 L
  820.     {
    ( u! O8 d: m2 {6 ~) A9 C
  821.       can1TransmitFlag = false;0 L$ _! }5 O% B& Q% `5 M
  822. # H0 v# L3 q' A
  823.       if(can1TransmitFinishCallback != 0): D5 v, B' [% j  z/ B" j6 k) E
  824.       {$ D; E8 E) `6 v1 U1 ?
  825.         can1TransmitFinishCallback();
    7 M/ R' H/ Q, b9 r) A
  826.       }1 B+ l1 o6 x9 F
  827.     }! s. y1 r/ z! O5 ^& V# A
  828.   }
    4 Q4 O6 s9 ~- V- v8 H0 {
  829. }+ ~6 I6 o- N' m* {" @. }! ?& O1 f5 d
  830. 2 d0 E2 B# s2 e# V5 j' P* ^
  831. /**
    $ ^8 B7 G' ?! `; p3 N( b
  832.   * @brief  This function handles CAN1 RX0 Handler.
    2 E) F" t( E1 E3 C7 W/ \3 B; i4 H5 e
  833.   * @param  None.
    ! D/ m. m( h2 s! M, x5 |" U) M
  834.   * @return None.
    " v! Q7 [2 `; c4 k' y8 X
  835.   */
    $ j, U- B2 Z) Y& M) P
  836. #ifdef STM32F10X_CL0 N1 e) Y, u; s3 V+ P6 c8 K+ \" {
  837. void CAN1_RX0_IRQHandler(void)' L$ B7 ^. Y( n  G: b, x  L& L
  838. #else5 P! R! @- S; e# [
  839. void USB_LP_CAN1_RX0_IRQHandler(void)
    4 {+ ]4 n, U" Z9 W2 [! ^
  840. #endif /* STM32F10X_CL */
    3 T/ v+ N) [/ i$ d+ a" Y
  841. {
    5 X; L- Q* I$ r( [, r7 }
  842.   if(CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET)
    , B/ l3 `  C! x# n8 o
  843.   {* i# |- j( Q4 U% X: Q
  844.     CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0);
    % B9 a# P, I; J+ Y
  845. " U  m7 n/ w/ |, m: }
  846.     CanRxMsg canRxMsg = {0};/ {3 k6 L6 P2 ], S: U7 z
  847.     CAN_Receive(CAN1, CAN_FIFO0, &canRxMsg);
    ' K  y) t3 S  e! ^
  848. ( t: S" r" ^+ b/ N
  849.     if(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg) > 0)( x0 F: k- L4 Z* s/ s" D# Q; P( a6 z
  850.     {& F8 Y! f* l! N3 d
  851.       RingBuffer_In(can1RxBuffer, &canRxMsg, sizeof(canRxMsg));* q$ e* N& N8 B( m8 W
  852.     }/ g8 G4 G+ l2 w3 u* i+ @
  853. / g1 J- T3 O3 X2 ]2 G
  854.     if(can1ReceiveFinishCallback != 0)# v+ o8 J+ W7 W' v4 g1 C$ l# k
  855.     {& Z3 N  O: Q! J5 o+ ]! m
  856.       can1ReceiveFinishCallback();
    " T6 q1 E! b' r. m' g& s7 }
  857.     }+ U) Q9 n' o1 a, J4 t) F
  858.   }  `& e! }9 @8 S; z6 u9 x
  859. }
    $ H; H' w/ R' o9 R& Z8 f2 z

  860. 8 D( q  x+ L: @+ K4 {1 B8 |$ J8 y
  861. #ifdef STM32F10X_CL
    * W: _% J6 n" |2 h/ I
  862. /**- _0 A5 W1 h8 ~7 ]2 K: X9 T
  863.   * @brief  This function handles CAN2 TX Handler.' \% T9 R8 I/ ]  E) c: H
  864.   * @param  None.3 O9 i2 |5 W7 M3 X$ X* P
  865.   * @return None.
    * r- |1 ^& }5 B, F9 g5 `$ Z
  866.   */" a" F, {0 C$ q, z# B; b( e( ]
  867. void CAN2_TX_IRQHandler(void)8 `. S0 h0 Y4 M3 |
  868. {7 X3 Y* ?' M) X; Y
  869.   if(CAN_GetITStatus(CAN2, CAN_IT_TME) != RESET)
    , i; q# `4 m' ]$ P. p
  870.   {
    # I5 }5 g3 V$ E+ J
  871.     CAN_ClearITPendingBit(CAN2, CAN_IT_TME);8 H* b  {! r$ P. R

  872. # W  D' T4 S$ ^# Z2 J# K
  873.     CanTxMsg canTxMsg = {0};
    ! K1 y' ^9 e; J3 i5 ?6 m
  874.     uint8_t  number   = RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);. }* {7 k8 o$ d+ M
  875. ( M5 d# b- I3 T* S
  876.     if(number > 0)
    # t) {! v) u+ f8 J, _9 c
  877.     {
    & `0 @8 s' b4 Z8 @( T
  878.       CAN_Transmit(CAN2, &canTxMsg);; Z4 g5 T7 V  [5 v- W+ d
  879.     }
    ' ^! ]4 X/ G  m7 m+ }
  880.     else
    2 }! h7 D6 C" }4 Q
  881.     {
    - k! E  Z0 B. X; g* A$ I% {8 i
  882.       can2TransmitFlag = false;6 Y1 s% N# m1 ]
  883. 9 R0 \8 W$ E  j( D5 o
  884.       if(can2TransmitFinishCallback != 0)' T$ u4 _1 @5 a8 [3 a7 W
  885.       {
    ; x; o- ?- d0 R, S+ ~( E! c$ O
  886.         can2TransmitFinishCallback();
    9 c) p* w& c9 u0 Z) p5 L( ~
  887.       }
      C% y$ A7 A3 \8 Z) Z9 |. d
  888.     }
    : F8 p1 T3 v% e+ X! c$ k3 G
  889.   }
    ' L: ~/ E+ N8 j
  890. }
    " ^$ a& p" n8 h9 l4 ?' Q

  891. 1 u# ]$ }( D/ f% p5 T
  892. /**% x7 Q7 ~% B) d! i/ E8 {0 y3 m: _
  893.   * @brief  This function handles CAN2 RX0 Handler.
    4 m# }+ x5 B3 ^9 C6 _# L
  894.   * @param  None.
    9 U/ B: ?( ]; d' f
  895.   * @return None.: }- W, `4 ~  t( b) d; _/ Y/ f
  896.   */8 ]; ~: V& p4 o' I, b, E' M8 x  `
  897. void CAN2_RX0_IRQHandler(void)& v" Y3 z2 c1 a( m- c% [# g
  898. {
    3 p% y9 x! h+ {
  899.   if(CAN_GetITStatus(CAN2, CAN_IT_FMP0) != RESET)3 i1 }  Y. {, R; |7 Z- D4 h
  900.   {
    & @" q$ t+ r. q7 t1 A
  901.     CAN_ClearITPendingBit(CAN2, CAN_IT_FMP0);
    - u3 o' M: j* s3 p
  902. " H: u6 R; }/ L2 o
  903.     CanRxMsg canRxMsg = {0};# l0 Q/ u1 q0 N9 r" N# r
  904.     CAN_Receive(CAN2, CAN_FIFO0, &canRxMsg);3 b# u( v. ]3 ^) N' i/ a& [$ {" Y
  905. ) G- g+ L+ X2 S% B4 V& F
  906.     if(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg) > 0)
    * n2 n" {/ T$ O. p# R5 Q
  907.     {% h' F: K+ D! C2 o9 f. G
  908.       RingBuffer_In(can2RxBuffer, &canRxMsg, sizeof(canRxMsg));3 M6 M( c9 ^# L0 o
  909.     }0 L3 {" `5 O. J. s
  910. ) V: ^# N8 A& {! r' h% g
  911.     if(can2ReceiveFinishCallback != 0)% a) A4 }; e$ v! w% G2 j. s5 r7 h
  912.     {7 G7 |' J+ ^+ S$ c7 }* H- b0 p
  913.       can2ReceiveFinishCallback();+ \2 F  D# X* |) v: y. d# Z3 k
  914.     }* a2 B3 ^/ [% E  F4 j2 X
  915.   }
    6 c/ _2 k1 d6 O
  916. }
    & W. @6 q0 M- z2 n2 A! l1 a
  917. #endif /* STM32F10X_CL */
    6 t" H: A# S, {. d1 f" P
复制代码
8 g) D: J7 R6 i1 `

6 R1 p2 @/ i  gmain.h 文件
6 A' n* O; C4 a% s( l
  1. /**
      A0 N6 |5 n3 d$ x
  2.   ******************************************************************************  ?7 h8 c% Q; o* F7 k3 d
  3.   * @file    main.h
    ( Q+ w- }) x$ ]% h! Y* y
  4.   * @author  XinLi
    / J2 u! R% h6 H, M
  5.   * @version v1.01 m$ T" |5 w# y: w6 u: |! q+ [( |; l0 e
  6.   * @date    24-June-2018
    # O4 w/ ?8 w( v0 n1 V) D- A
  7.   * @brief   Header file for main.c module.; J  V8 ?/ V/ t% u
  8.   ******************************************************************************
    " \* Y0 d9 Z" B* T3 y9 m6 C
  9.   * @attention* Z0 X) u5 [: {6 s% h! O5 `
  10.   *  H( N; W% a: v4 x0 F, Q& y
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>" u& S+ R9 I; t3 I- A
  12.   *- m, R! g5 w) S
  13.   * This program is free software: you can redistribute it and/or modify
    * q. e1 o" m, s
  14.   * it under the terms of the GNU General Public License as published by! ?7 A. z$ B, T% p" p
  15.   * the Free Software Foundation, either version 3 of the License, or
    ) M3 o$ `+ T, O' @
  16.   * (at your option) any later version.% w1 s- l; N3 R( A" M
  17.   *
    , X: p4 o# D3 I4 S8 X* a8 u
  18.   * This program is distributed in the hope that it will be useful,
    & \- \1 Q8 i- |$ P
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of& K) V2 |, @1 X* j; q- L
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  V- l: s: e& k7 E' D7 |
  21.   * GNU General Public License for more details.
    ! p( v. a  r4 i. s5 P1 ^/ S
  22.   *" w" F" K3 q. ^8 @& M& c+ ~# w
  23.   * You should have received a copy of the GNU General Public License1 |" ?8 i" |2 `2 c! E6 i" k
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a># [8 C; b- M% Y
  25.   *$ ^& w/ a8 Q2 t0 a
  26.   ******************************************************************************
    # y& y  J. b6 n- S, l  v* B
  27.   */" ]5 N0 [  l0 f$ h; _/ v" ^
  28. ! K, [0 ?# u0 d( A* a3 |
  29. #ifndef __MAIN_H
      k- F8 _, @- A2 X
  30. #define __MAIN_H
    0 m! l9 q+ B) k$ d: p

  31. 6 v8 p( x; Y& y2 L2 s  R4 r% N
  32. #ifdef __cplusplus
    ' Z1 V1 C8 Q: B& A+ ^
  33. extern "C" {
    , l  a$ [9 U1 g7 [3 W. [# K
  34. #endif% |( p0 p3 ~  V. a4 w' e

  35. % Q3 V- G3 L0 k; S% E
  36. /* Header includes -----------------------------------------------------------*/
    * ~0 M; S* t8 e- ?0 d% {' Y" Q
  37. #include "stm32f10x.h"
    8 p' U( u" y4 [9 H. m
  38. * i3 S% k8 A8 U+ j6 o
  39. /* Macro definitions ---------------------------------------------------------*/. \: J& V. ?  I7 z
  40. /* Type definitions ----------------------------------------------------------*/
    4 ~& o( J, E, v& T$ d$ f$ ~
  41. /* Variable declarations -----------------------------------------------------*/+ w" g  P0 H# T8 A( u+ M9 {& a
  42. /* Variable definitions ------------------------------------------------------*/! r; d/ H* Q+ f/ v
  43. /* Function declarations -----------------------------------------------------*/
    * a, r& Z9 n2 H( a3 }, r% C
  44. /* Function definitions ------------------------------------------------------*/
    7 W3 H" j( t) A5 c' v& B% V$ N

  45. , H" l2 m4 h: B2 U$ v% k
  46. #ifdef __cplusplus
    9 v7 ?/ t9 j9 l5 [
  47. }% H2 H" m& ~  h, y! Z
  48. #endif
    + J' P* m" M6 O! w' \: ^% T

  49. ) Y6 u+ M6 z) b
  50. #endif /* __MAIN_H */
复制代码

0 _0 h/ _+ m* I( ?0 X6 V
" u+ ]3 P. f4 J) o  z5 Hmain.c 文件
$ Y% X  b# B8 L
  1. /**
    ! y1 x9 ]6 ]% B8 e9 d
  2.   ******************************************************************************1 j, o; [! o  m& Y0 Q$ J. l
  3.   * @file    main.c
    . }5 h, y& l" e- A4 o% ]; n7 f- \
  4.   * @author  XinLi
    $ Z  g8 }; Z3 f% J
  5.   * @version v1.0
    , U5 n$ p4 J6 r9 H! |( x
  6.   * @date    24-June-2018
    ; z7 _  n5 V0 }8 N/ a3 r5 N0 e
  7.   * @brief   Main program body.* U8 L0 f/ b8 w/ q; W4 ^
  8.   ******************************************************************************
    5 S% |& [$ Q$ _, `) ~
  9.   * @attention$ h1 ~" D- ~5 l: @# V$ {
  10.   *
    : [; ^- Q6 F; B$ H& i9 K
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    ; ]5 H" R4 Q0 |& w
  12.   *( K8 _0 [( Q9 K/ K7 @2 f9 m
  13.   * This program is free software: you can redistribute it and/or modify
    , a) Y# W& @, ]; B; N, I3 P( z
  14.   * it under the terms of the GNU General Public License as published by' w: S  T1 P  E0 R3 f( E0 [
  15.   * the Free Software Foundation, either version 3 of the License, or
    / ~- \4 a9 x& u  @; u- Z
  16.   * (at your option) any later version.
    : A, ^) y0 x3 v# ]
  17.   *3 o8 a9 Q! ], |9 q) a, y3 S: `/ N
  18.   * This program is distributed in the hope that it will be useful,4 w4 f! y2 W% z* @
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of! t+ y0 T; N, q( G( B3 L
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the% [# o4 |% r- r6 c& W6 b, c" N0 n
  21.   * GNU General Public License for more details.) }" B  W/ B$ E, T; `/ w
  22.   *! G. m6 I5 P% V* O0 R! u3 `
  23.   * You should have received a copy of the GNU General Public License" K) l9 q& u6 k7 W1 i. _. X
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    ! {5 j  F5 f( c, C
  25.   *& \( D4 k# g6 m/ Y) r7 B
  26.   ******************************************************************************
    + ?9 n" w" e5 q" u
  27.   */
    ) W& I- E, F3 W( r) F1 B4 y- D; c' g! Y
  28.   q0 z- K& C8 _7 B7 }
  29. /* Header includes -----------------------------------------------------------*/
    4 m0 c) B6 u( U/ F) {- U7 u: Z2 A
  30. #include "main.h"' d" e/ `5 {. ~* v2 U
  31. #include "CAN.h"
    - c% Z2 m' c* t- N* g; o; Q

  32. . M4 U% A5 {9 M! f& z% e; g
  33. #ifdef _RTE_; M: b6 ]2 A5 J& O
  34. #include "RTE_Components.h"
    ) U" D+ \9 |. k$ A" t3 ~
  35. #endif
    " ~1 @* p# Y( h

  36. 1 |& w5 z% w4 n$ D# H, j7 ~6 F
  37. #ifdef RTE_CMSIS_RTOS20 A0 p+ T: ?% L+ O
  38. #include "cmsis_os2.h"
    * ~  g. h/ N3 E5 J" M
  39. #endif4 C/ I: d" H# N/ }' h% Q$ I
  40. 4 V( I0 v2 E. J- E
  41. /* Macro definitions ---------------------------------------------------------*/+ A7 E2 w0 q6 s4 t0 L
  42. /* Type definitions ----------------------------------------------------------*/
    ( }) {+ }; L( O" }7 B: s4 w6 p) s
  43. /* Variable declarations -----------------------------------------------------*/
    8 f3 L6 |* w. C0 t% A' `3 Q; _
  44. /* Variable definitions ------------------------------------------------------*/9 g8 R- ]7 q$ O1 I
  45. static CanTxMsg canTxMsg = {0};' k! L, ?  G2 y6 M3 Y, f$ f
  46. static CanRxMsg canRxMsg = {0};
    : ~. D# O0 m4 r9 ~: X
  47. 5 [. x% j" N+ x+ u
  48. /* Function declarations -----------------------------------------------------*/
    5 w+ O3 u* ?3 u7 N$ g# @
  49. static void SystemClock_Config(void);
    8 L! x7 M3 ~  T2 w+ X
  50. 0 B3 A3 x0 \" Z2 ~" I' }  P! e/ x
  51. /* Function definitions ------------------------------------------------------*/( }/ Y" R$ w, W) k/ f; m

  52. # \& a  U' i# E. B
  53. /**  G/ g" h  u2 K; U
  54.   * @brief  Main program.# v( c. S8 i0 t1 c2 k, m6 x
  55.   * @param  None.
    ; o* O6 }$ X4 O! @
  56.   * @return None.' C* t  N. H. ^. V. q
  57.   */
    9 S. ^* s! N9 v- G" T
  58. int main(void)
    # s+ c" v/ i& |, b
  59. {
    6 n; [, A$ ~' V: o" t! F3 Y
  60.   /* Configure the system clock to 72 MHz */$ @1 R. R' v9 q8 e$ V# j0 P; T, d
  61.   SystemClock_Config();  o9 T3 z( q* X
  62.   SystemCoreClockUpdate();* ?4 o- d  ~0 q' I& S5 ~7 \

  63. " G+ h0 W' ^2 L5 _, G
  64.   /* Add your application code here */
    6 m2 y7 f1 O- E& y4 d* _/ r- o
  65.   CAN_Configure(CAN1, CAN_WorkModeLoopBack, CAN_BaudRate250K, 0xAA55, 0x55AA);
      Z1 T# h2 l' H  z
  66. 8 v+ Q% L9 y8 U5 x- C, C. B
  67. #ifdef RTE_CMSIS_RTOS2, `& O$ P7 T) o* N! Z# y8 m1 M
  68.   /* Initialize CMSIS-RTOS2 */2 a' u; y7 R8 r
  69.   osKernelInitialize();
    % _: h  a. d& l

  70. * t% H. U! E1 Z, C$ q# R
  71.   /* Create thread functions that start executing, ! s9 k7 y& D% @0 [
  72.   Example: osThreadNew(app_main, NULL, NULL); */9 d# c+ s& E: E
  73. 2 k- H) m/ N& c9 g, Q
  74.   /* Start thread execution */
    3 P  e  f, j( L  [& [
  75.   osKernelStart();; r4 ^0 h1 |1 F+ R% O9 L
  76. #endif( n$ [5 z, I9 Z3 d& f% C: M9 Q
  77. " c/ I4 q# D. }( l3 w+ J
  78.   /* Infinite loop */
    ( V+ a$ f3 i1 ^: r' |- O) ]/ v; F
  79.   while(1)
    ! Q3 p) C% j3 f7 g/ `, S
  80.   {& w" X. f+ U! S. d$ _
  81.     canTxMsg.StdId = 0xAA55;
    2 N: f# E3 c6 B$ z; V* ~
  82.     canTxMsg.ExtId = 0x55AA;
    5 ]0 q6 h8 g1 ~
  83.     canTxMsg.IDE   = CAN_ID_STD;
    % w( w& l' p6 \6 J
  84.     canTxMsg.RTR   = CAN_RTR_DATA;
    5 U( c+ ~, L3 |1 w( E/ X$ ]+ ^, ^
  85.     canTxMsg.DLC   = 8;
    7 z( n6 V# _9 a. W

  86. # |& B3 S2 E4 H: N6 g
  87.     canTxMsg.Data[0]++;
    6 K0 S8 u4 P" J2 ?+ o
  88.     canTxMsg.Data[1]++;
    % w- P3 b! n2 u  c7 w$ X+ ]5 b% u
  89.     canTxMsg.Data[2]++;' r) j; J" _( p, w- C8 K" U
  90.     canTxMsg.Data[3]++;
    ( }% z0 h+ {" p4 R- r! B2 v4 ^
  91.     canTxMsg.Data[4]++;
    0 }& H# J$ ~1 g0 ^2 @4 m0 p1 }
  92.     canTxMsg.Data[5]++;
    ) C# H; E& m$ ?0 b1 O6 X
  93.     canTxMsg.Data[6]++;* ?+ s1 Y# n& t9 @" n) j
  94.     canTxMsg.Data[7]++;# v/ D3 I4 o  s) x( R, M4 s

  95. . j9 f& v1 ^, V/ u1 C) @3 A2 c, q
  96.     CAN_SetTransmitMessage(CAN1, &canTxMsg, 1);
    % i) V2 w0 o/ V5 T6 N( X# [; w
  97. & _4 C5 ]' X. u* U2 B; L8 s5 C  D
  98.     while(CAN_IsReceiveBufferEmpty(CAN1) == true);
    - }% [: ~! ~* `3 U1 m/ g1 L/ _

  99. ( S1 @9 O9 m9 h6 P
  100.     CAN_GetReceiveMessage(CAN1, &canRxMsg, 1);
    " X" Y6 ]1 |, C( g
  101.   }, T/ u4 ?1 P- A
  102. }
    + S; q9 ]. G( r) v

  103. 8 V% u; {' j8 W3 }8 W+ `" l" t
  104. /**" f: s) w8 [% ^/ K
  105.   * @brief  System Clock Configuration.
    $ x! ^2 E1 c$ c, ]# o9 J
  106.   *         The system Clock is configured as follow : 4 z1 R2 s2 _7 C3 K5 z) o
  107.   *            System Clock source            = PLL (HSE)
    3 g' P" c- h6 k" h) k
  108.   *            SYSCLK(Hz)                     = 72000000; c" L4 P+ W  Y! {3 D  W& {
  109.   *            HCLK(Hz)                       = 720000003 R, `2 k' P5 K* b2 I
  110.   *            AHB Prescaler                  = 1
    : \' Q- z! g( k% a
  111.   *            APB1 Prescaler                 = 2
    9 U- M' `6 V8 s; q2 \# ]
  112.   *            APB2 Prescaler                 = 1
    ' T; q5 {2 z3 Q" |; f& V( I% @
  113.   *            HSE Frequency(Hz)              = 8000000
    # U7 ~; X; l4 C' n4 w" Z! O. t$ G
  114.   *            HSE PREDIV1                    = 1
    ) }# h6 B, i" m/ x
  115.   *            PLLMUL                         = 9) P3 H) g, o: H( |; f2 b
  116.   *            Flash Latency(WS)              = 2
    2 f" z4 A, y3 Q8 s4 y( L  n
  117.   * @param  None.1 x' N- s0 ]* \0 @8 p9 c3 W
  118.   * @return None.5 X0 D# n. S: y. g' O/ V
  119.   */; v0 N7 N' g6 P; }
  120. static void SystemClock_Config(void)
    5 |9 {$ B1 X8 D
  121. {
    . ?$ _( |5 U2 P) U
  122.   /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration */
    - g: M9 T' e8 D, w
  123.   /* RCC system reset */
    0 R0 y' v* @7 C9 H$ N# g
  124.   RCC_DeInit();
    ; `0 E- u% A/ t  t8 t

  125. & M6 W' Y: X) b( \, T
  126.   /* Enable HSE */
      }. \8 J3 V- ]
  127.   RCC_HSEConfig(RCC_HSE_ON);
    1 g9 z% C* y) M
  128. : U6 |. o1 @" t9 W
  129.   /* Wait till HSE is ready */, W# v; {2 u% \+ a, S
  130.   ErrorStatus HSEStartUpStatus = RCC_WaitForHSEStartUp();
    6 }: I! P3 K* T
  131. . g0 P+ O( v' i8 i$ l
  132.   if(HSEStartUpStatus == SUCCESS)
    * `7 [  w" d  s& n; m
  133.   {
    / G6 g: v! T% z1 |0 x5 \) m
  134.     /* Enable Prefetch Buffer */+ J) W& @$ E3 @, K6 v
  135.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
    1 Q& c! w. o1 u% R- D' z1 ^& o
  136. ! H) W( h* t3 h/ J+ v. j. y- I
  137.     /* Flash 2 wait state */; r# y2 p3 h% {4 x, U9 e% k
  138.     FLASH_SetLatency(FLASH_Latency_2);
    6 i8 q7 I! T2 r/ i7 S" s
  139. 6 n. \9 o, h3 r3 z/ e$ m# Q( B# y' Z6 c
  140.     /* HCLK = SYSCLK */
      u& O& B& ^" d, M% g
  141.     RCC_HCLKConfig(RCC_SYSCLK_Div1); % t8 u4 x7 L: f9 [3 y

  142. % V( g) h- T% r+ ^
  143.     /* PCLK2 = HCLK */: @+ n1 }6 k( m' b$ L
  144.     RCC_PCLK2Config(RCC_HCLK_Div1); 8 e8 \, e9 S* m& K
  145. 3 T" [9 C3 r$ b3 w3 u8 l
  146.     /* PCLK1 = HCLK / 2 */
    ; g: O# A9 v4 F9 a5 S, H9 \
  147.     RCC_PCLK1Config(RCC_HCLK_Div2);( f: H5 X- a5 D: N

  148. % X4 f, p' F% L+ b5 W
  149.     /* Configure PLLs */
    4 I5 u% v: m+ q6 X  |
  150. #ifdef STM32F10X_CL( l* ^% A* K7 s2 T) [' v
  151.     /* PLL2 configuration: PLL2CLK = (HSE(8MHz) / 2) * 10 = 40MHz */' n$ H: x( u5 m: y7 N' ^* F; W
  152.     RCC_PREDIV2Config(RCC_PREDIV2_Div2);$ l2 b4 H& [2 J
  153.     RCC_PLL2Config(RCC_PLL2Mul_10);! [0 `# j0 k- ?, }. L/ k
  154. 1 ~* D$ y7 V' }3 Z" V  h
  155.     /* Enable PLL2 */
    $ b/ i  @. _1 x2 ^  P
  156.     RCC_PLL2Cmd(ENABLE);
    : p; z3 f! P! p+ i* ~6 f

  157. 4 q. t' r7 b* `8 X' z+ r
  158.     /* Wait till PLL2 is ready */
    0 s/ E# v/ ?( _
  159.     while(RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET);
    6 y$ s" x* G4 ]: a8 }: J

  160. 6 Q1 n/ L. y9 x; m
  161.     /* PLL configuration: PLLCLK = (PLL2(40MHz) / 5) * 9 = 72MHz */# ~& V' D5 Q) I4 R' ~1 h
  162.     RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div5);
    4 p2 s% C- h; Y3 e3 q+ k
  163.     RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);3 x! V8 ]6 K& H- }* y# K- t
  164. #else* J7 I% n+ _9 h# v* a; [
  165.     /* PLLCLK = HSE(8MHz) * 9 = 72MHz */
    / i3 Z+ w3 o# U& X. d9 b/ |* r
  166.     RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
    " p7 W# u- b6 a
  167. #endif
    ; C; _% y/ h, _
  168.   D0 d* e5 F" O) R
  169.     /* Enable PLL */: v! Z) |" G) _' v+ c: `
  170.     RCC_PLLCmd(ENABLE);1 v: j3 P/ J% `; r, Y& W

  171. 1 P" O" z1 i! U: n; h! ]; C" w  n; u% V
  172.     /* Wait till PLL is ready */
    , e! v# G* I" y
  173.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);* F. {+ i% ?+ Q* W9 ~" d: E* _

  174. 2 C) i" y6 |* z; ~- Y  G( b
  175.     /* Select PLL as system clock source */9 S5 `4 }9 P7 i& d( [7 M
  176.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    9 @; f, L4 L% F: T4 E6 n
  177. / ^4 t- n; O% R; w+ _+ W0 {5 l" \4 C
  178.     /* Wait till PLL is used as system clock source */- ~% a. L% ?# t$ Q' i
  179.     while(RCC_GetSYSCLKSource() != 0x08);
    ) A" ~8 [; `# O( s. }# X- G
  180.   }4 ^5 r* o& r) Y% Q: ?8 y' F
  181.   else+ {+ W% ?- t- [+ u2 t
  182.   {
    4 l% K5 B  M# A1 ]% P2 K9 S: L
  183.     /* Disable HSE */
    1 l* j4 f" [0 P* d8 Y* \7 X* G9 ^
  184.     RCC_HSEConfig(RCC_HSE_OFF);2 @! P* {' S$ s* m
  185. 1 V5 F9 ~! D% ~4 I
  186.     /* Enable HSI */4 c8 T7 N2 r9 O5 g
  187.     RCC_HSICmd(ENABLE);4 E2 T* P# V# U. i+ U

  188. ) v. S7 E# J0 k0 N
  189.     /* Enable Prefetch Buffer */
    3 ?, d9 Z$ d  R- o2 W
  190.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
    / }* J' ~$ [  E, C: v; X; P

  191. ; z+ I' y9 r- P9 i7 b
  192.     /* Flash 1 wait state */- K' J* G8 R: T' }
  193.     FLASH_SetLatency(FLASH_Latency_1);8 k" J4 X: A6 E5 k" [, S7 p4 _

  194. : ]) N; ^; l, l% b# V
  195.     /* HCLK = SYSCLK */5 K- Q4 U: s/ _; l5 s
  196.     RCC_HCLKConfig(RCC_SYSCLK_Div1); " ~6 i+ x. H6 a7 V) g

  197. 1 t, g; y# o' E/ h3 z4 f- b
  198.     /* PCLK2 = HCLK */* c" k. Q, s1 q# M3 {8 \! b  b! G5 h
  199.     RCC_PCLK2Config(RCC_HCLK_Div1);
    ) c1 n/ E' X" t/ \, R% c0 m8 b
  200. ( Y3 c) K- e: G( X) k# @" g
  201.     /* PCLK1 = HCLK */1 q( s$ f+ {+ r% m  e# |' e" C
  202.     RCC_PCLK1Config(RCC_HCLK_Div1);+ {3 g4 K  L  M8 d5 `
  203. ) n! V4 }7 j) ^/ j' U! S
  204.     /* Configure PLLs */
    ' V  V9 t9 J* v* b. ]
  205.     /* PLLCLK = HSI(8MHz) / 2 * 9 = 36MHz */0 f9 q6 c, _0 }* h4 d
  206.     RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_9);! A; d* u  p* I  G5 Y$ H
  207. ! T" d8 Q$ [& W" J( k4 i$ B
  208.     /* Enable PLL */
    9 _/ x: k4 x( r: Z5 [! [. ^
  209.     RCC_PLLCmd(ENABLE);
    8 z% ?4 X+ q! m5 c% A

  210. ' V& x) B! j, L0 Y" q8 N+ W( k) i
  211.     /* Wait till PLL is ready */
    5 F  v/ V. l+ X5 A
  212.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
    7 F- ?9 \# T& B) ^1 g

  213. " B! x/ h1 l' F( @, {
  214.     /* Select PLL as system clock source */
      |" s9 p! S8 j; V- Q; \; C" x
  215.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    ' H3 S- [  U9 X
  216. . s% E( ~9 K4 [) S# _# v
  217.     /* Wait till PLL is used as system clock source */
    8 n, y: y. e$ W0 j/ A
  218.     while(RCC_GetSYSCLKSource() != 0x08);
    6 E0 l0 d& i/ U9 }# [* P& t  _$ I1 D
  219.   }
    0 V; g8 W- O" K- T1 F7 B
  220. }
    6 ~; f1 t! x$ K

  221. ! k. B( N, G% t" B/ D
  222. #ifdef USE_FULL_ASSERT
    4 E) [# J6 L" ]( k6 A  R
  223. /**6 @# H! e, Y# _& ^5 w0 G4 f/ M3 L
  224.   * @brief  Reports the name of the source file and the source line number% V5 `. j5 ^, o
  225.   *         where the assert_param error has occurred.
    2 H7 t! T5 r& n
  226.   * @param  file: pointer to the source file name.
    5 H/ e2 t+ T# D9 G0 B$ q0 t2 y
  227.   * @param  line: assert_param error line source number.8 ~8 Q& ~0 e4 q) W+ u3 ~" _
  228.   * @return None.; C2 F& C# e1 I/ f
  229.   */
    ; L& A% N+ |& y* x$ ]) l# S
  230. void assert_failed(uint8_t *file, uint32_t line)2 ?$ ]9 T8 ]) y2 A3 D! q) s
  231. {2 d$ o* Z4 A/ R; H- G" ?2 G1 D) J
  232.   /* User can add his own implementation to report the file name and line number,( x% r$ c+ |& I5 v6 M
  233.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */2 H1 W+ u0 E1 l

  234. * r% g& v9 G* m' @! l# }1 ]8 ^8 O
  235.   /* Infinite loop */1 \; J  e+ K& Z; a: r
  236.   while(1)6 Z/ W" @3 H+ f$ c  N1 w# K7 e9 G
  237.   {
    ; u1 M' N6 _8 S- _# U* A. ~
  238.   }
    . d1 @" ^4 ?. p. B3 X' s8 S; e
  239. }
    ' f. W( `9 C( q) ~# U4 T0 |
  240. #endif
复制代码

# ~+ [% o, ~& P0 A+ w$ \% j: {3,注意
3 K5 u2 {( U& u0 H/ D; ^+ t' }8 L
CAN 消息发送缓冲区和接收缓冲区的大小,可以根据应用的需求进行修改,缓冲区使用的是堆内存,需要根据缓冲区大小和应用程序中堆内存使用情况进行配置。( b! A4 o* Q5 R4 C+ e& t

1 T% f5 H9 L- M. u/ j  ^7 p4 J/ L' b( y( m; J( y: ?

4 J4 |6 p6 T; z1 ~/ S
收藏 评论0 发布时间:2021-11-26 17:00

举报

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