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

【经验分享】STM32F1(CAN)

[复制链接]
STMCU小助手 发布时间:2021-11-26 17:00
1,开发环境
- @) u8 |5 U+ ?6 @% V
( @  n0 }: c) `1,固件库:STM32F10x_StdPeriph_Lib_V3.5.0# x, Z% y0 `7 x! G: }8 L

/ E$ L0 E' f' r" Y2,编译器:ARMCC V5.06
9 D: d$ ^8 Y9 K( i5 F
% q# ~- G" I0 R$ J% Z$ U: s% h3,IDE:Keil uVision50 b$ t$ N3 M/ T! J" M" z$ ?
, P5 ~6 [. G6 {
4,操作系统:Windows 10 专业版
0 m1 G6 j5 z0 T# n& Y3 b/ p( ~- u$ ^1 H7 [0 D, ]

# V) e1 V3 Q2 E/ D2,程序源码
0 o( d# x1 G* X6 k/ C# e2 y( s% b& j+ o5 c5 w4 }8 D1 H
RingBuffer.h 文件- W/ C, a+ G' l
  1. /**
    / v! g3 v- O' H/ G
  2.   ******************************************************************************
    7 C; D# Q; [* s! s
  3.   * @file    RingBuffer.h
    4 [: m# z  X; l, y$ z
  4.   * @author  XinLi
      {" W* @4 q- G" x+ k
  5.   * @version v1.1
    ! \. N# R3 s- X& v4 k
  6.   * @date    15-January-20184 u6 r8 p- }8 y" O9 Z7 R5 x
  7.   * @brief   Header file for RingBuffer.c module.
    & z% T, O* Q9 t2 i. L' E7 D
  8.   ******************************************************************************
    , B& O. R& x% r
  9.   * @attention- g) x5 A" Q1 d/ K+ M. h: j! `  \
  10.   *
    ( t" ]& I2 U/ ]
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    . V- O& }' P9 `8 ?' K
  12.   *
    * C; d( d6 x+ ?
  13.   * This program is free software: you can redistribute it and/or modify/ D8 Q4 `+ @+ k% a8 G6 j% k6 i
  14.   * it under the terms of the GNU General Public License as published by: ~9 {! t1 |4 m0 |5 Q9 }
  15.   * the Free Software Foundation, either version 3 of the License, or4 O( ^9 o: W) k8 n" r" o- Y
  16.   * (at your option) any later version.* ^% O) y" D: R
  17.   *) }6 q. C5 q  V8 C3 h0 |8 v2 D
  18.   * This program is distributed in the hope that it will be useful,
    . q2 P' b& e( y& X& ?1 i
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    & G: Y: e0 N3 n7 @9 a  M% W, u9 b
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the: M0 k& X! ?% Y$ y/ b2 K! X
  21.   * GNU General Public License for more details.# X8 V0 w0 W0 Z: Z
  22.   *0 S0 h# m6 B) }; i( s1 c
  23.   * You should have received a copy of the GNU General Public License
    1 N  P( f7 ?$ G
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    0 o  q1 \* b3 ^! `3 i7 ]7 V
  25.   *7 ]! X9 }/ s. o8 W# f7 h7 c2 F. n  e
  26.   ******************************************************************************4 X4 t) G/ z% Q6 R
  27.   */
    8 X4 l$ e) L) p8 X5 Q( U
  28. 5 l1 c: K: Q# L$ B+ E( y  w
  29. #ifndef __RINGBUFFER_H" n, }) b) p$ t. b2 b8 u6 P. {
  30. #define __RINGBUFFER_H
    ! ^' R( b6 j) d( L7 A" C) \7 F( s! \
  31. ) ?  I( C) {: |/ Q  ^' O
  32. #ifdef __cplusplus4 I5 T4 ?$ D7 S8 W- G$ Z( l, _
  33. extern "C" {5 ~+ S# @8 I$ [; o( y: M. X: t
  34. #endif, a: @- M& Y2 E; A6 v9 l
  35. 0 q0 P6 \( {. E! q, ~5 R* @
  36. /* Header includes -----------------------------------------------------------*/+ G9 ]' |, F; U# ~+ j3 s
  37. #include <stdint.h>) j. o/ A! \: D7 {+ q" D" Z
  38. #include <stdbool.h>- h( E% L- l( @* B9 f
  39. #include <stdlib.h>
    . Y* z7 q. ?/ M( ?5 [$ X7 C
  40. # [' `* s) e4 w
  41. /* Macro definitions ---------------------------------------------------------*/
    ; c9 f# ?) f$ Q1 h6 p1 i9 `1 g
  42. #define RING_BUFFER_MALLOC(size)  malloc(size)6 }9 j+ ^, i1 N' r& ?0 I
  43. #define RING_BUFFER_FREE(block)   free(block)) f4 i' I; \5 d5 E" c

  44. : f9 ~9 p. V- Z# L, E9 c& G% P
  45. /* Type definitions ----------------------------------------------------------*/- c/ @* M7 a1 a
  46. typedef struct
    9 w' x( a) @/ P
  47. {
    0 c7 }: v* ^) Z
  48.   uint8_t *buffer;
    9 H) O/ |8 ^3 f& {+ J+ c# U
  49.   uint32_t size;
    . s/ C2 M0 l6 s6 F$ c, ?: K/ X" d
  50.   uint32_t in;
    ' U" v# ~$ Z9 T4 {
  51.   uint32_t out;
    & g- a1 T5 j( d( X$ O: `
  52. }RingBuffer;; e& a' a8 x6 t6 o* t

  53. # u+ n6 t- Q  W$ L7 V& S% P& |
  54. /* Variable declarations -----------------------------------------------------*/! ^% D8 Z5 n5 K: m: y$ `
  55. /* Variable definitions ------------------------------------------------------*/
    + c7 T2 ~) b  i/ R+ _! H/ O* I
  56. /* Function declarations -----------------------------------------------------*/& F7 N4 g, M/ t- x- i0 }& |
  57. RingBuffer *RingBuffer_Malloc(uint32_t size);
    + f. Y5 _& g4 ?5 x5 H2 s
  58. void RingBuffer_Free(RingBuffer *fifo);- }- M! L5 c: s  p( H: }1 N

  59. - H2 c: `  B6 _
  60. uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len);
    $ g5 N: q( x$ ?: w
  61. uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len);
    * @9 b5 i, ?/ P

  62. ( _! H7 l  i* n
  63. /* Function definitions ------------------------------------------------------*/
    ( p$ v- |. f3 W# i) i

  64. . k* v8 s: s+ X, j; W5 x( M% O
  65. /**: c% B( Q+ X& T3 Q4 ]
  66.   * @brief  Removes the entire FIFO contents.9 |, I" v# w9 I" u! ]$ e" @
  67.   * @param  [in] fifo: The fifo to be emptied.
      q& g, {0 p$ c4 o5 [
  68.   * @return None.
    ( M2 d  i) f% K" }! |: t. M. I
  69.   */1 t5 m9 l, m6 w  j' \+ ~& U8 j
  70. static inline void RingBuffer_Reset(RingBuffer *fifo)
    - S" |2 l- E/ s$ s8 P; _3 `+ O
  71. {
    / [+ @* }! u; b/ j1 A+ I
  72.   fifo->in = fifo->out = 0;: o# g- ?% q' u/ ~/ B+ F; V
  73. }( |& f; A; m) u$ s4 c

  74. + A2 q4 M2 U& R* V
  75. /*** ?* f% _% [4 w& A
  76.   * @brief  Returns the size of the FIFO in bytes.
    * H9 O) j- g) z. d6 a
  77.   * @param  [in] fifo: The fifo to be used.
    ! s' x2 i8 c# T, G# z, x" O, Q
  78.   * @return The size of the FIFO.. m5 f7 e" @( b3 D2 @
  79.   */
    7 p/ o4 a1 Z  Q, ~
  80. static inline uint32_t RingBuffer_Size(RingBuffer *fifo)
    ! y' y% @' r* e1 ]  M
  81. {( W9 G& R# C5 c6 c4 M
  82.   return fifo->size;/ ?: C8 K1 D8 t
  83. }! K8 L: X& e; `  ?% z# |5 m

  84. 3 `7 h+ U6 w3 B6 r- h. o
  85. /**
    ! b* T' J* m& k) d0 U: \6 D0 Q
  86.   * @brief  Returns the number of used bytes in the FIFO.# b3 P' j6 J' l. o8 p0 t' W4 t' \
  87.   * @param  [in] fifo: The fifo to be used., _! l2 w5 `/ }& d3 M
  88.   * @return The number of used bytes.! C  _: j3 {" p# d
  89.   */
    * l! G, B, g: j
  90. static inline uint32_t RingBuffer_Len(RingBuffer *fifo)
    6 w" M, l5 s3 K1 q) F- i! Z
  91. {
    7 X  ~) j7 o: v% _' [: B
  92.   return fifo->in - fifo->out;
    3 ~% W0 O+ M6 d# X
  93. }
    + |) R8 D- l# u

  94. 6 N- J2 b( k6 ]; E" D
  95. /**/ S- w; z' i: v9 F6 g2 [
  96.   * @brief  Returns the number of bytes available in the FIFO.1 |# x' q% A/ Q9 H, j7 ]% S
  97.   * @param  [in] fifo: The fifo to be used.( [. y$ H+ p6 D( m: D; U. i; Y
  98.   * @return The number of bytes available.
    + m: p) u& C5 K1 y1 D
  99.   */0 Z4 q/ R, u$ b  U
  100. static inline uint32_t RingBuffer_Avail(RingBuffer *fifo)6 W* Y8 J) r! e$ I
  101. {
    & F# m$ B0 f) |. ~. z! I2 K
  102.   return RingBuffer_Size(fifo) - RingBuffer_Len(fifo);/ {1 L8 l) d% Z, B" h: X
  103. }7 x# F9 C/ R" H/ r( ^

  104. 2 E+ R( C4 b. Q; l: A
  105. /**
    1 [& c, n' H. q& l4 Q6 a
  106.   * @brief  Is the FIFO empty?+ Y0 E/ k; r, r! B6 s/ _' z' u
  107.   * @param  [in] fifo: The fifo to be used." e4 W2 k5 e; Q$ O9 u! `
  108.   * @retval true:      Yes.+ q4 |# Z" o4 V/ y- H1 E3 H
  109.   * @retval false:     No.
    1 R5 f) N) `9 i. M- I! g
  110.   */
    # N8 i6 k, O, N! s; C
  111. static inline bool RingBuffer_IsEmpty(RingBuffer *fifo)
    ' Z) N& x/ `* O
  112. {# \3 Q6 F/ ^# H: ?6 n
  113.   return RingBuffer_Len(fifo) == 0;
    & `+ w- D' _( r6 S& c, g+ \4 a
  114. }
    / C: x, ^6 a0 h8 T7 m

  115. ; `$ }; i/ x* S* H( D
  116. /**
    - ^, V. g8 p: [! i7 W
  117.   * @brief  Is the FIFO full?! [4 [" L. X! g3 V" M
  118.   * @param  [in] fifo: The fifo to be used.
    * a( L0 I8 Q1 v/ n
  119.   * @retval true:      Yes.
    ! c, k& y/ @/ G: k; `
  120.   * @retval false:     No.
    7 r* _! _) x  _' u% @, J& Z0 R) W8 `9 I
  121.   */4 S, m$ ^$ I7 W! w$ G$ b5 {
  122. static inline bool RingBuffer_IsFull(RingBuffer *fifo)) g# z9 u& T' b6 d/ {" f
  123. {$ \4 k5 Z- Y8 d; G0 ^
  124.   return RingBuffer_Avail(fifo) == 0;  U4 Z6 x+ a) D; y
  125. }
    - p7 L( B9 _/ m$ W; j' n: Q( U" X$ U

  126. 9 w7 q' A  s6 p- b3 G. g$ _6 ^
  127. #ifdef __cplusplus/ i2 X5 p6 x7 P4 m0 M& {: ]2 b
  128. }! b  N6 I3 n+ G! [6 M$ z# `
  129. #endif
    . x& S; B3 C; p5 N8 n/ o! F

  130. * F: k+ q& H) r3 P
  131. #endif /* __RINGBUFFER_H */
    - Z% e+ h' Y. s: Q
复制代码

$ o) I+ J9 z  F5 t9 v* J+ ^# }. \) g6 u$ Y4 S
RingBuffer.c 文件2 R  ?) s' Q' A3 g6 i
  1. <div>/**
    0 M4 R% @; Q4 w) p' _" P
  2.   ******************************************************************************
    7 j$ b( k. Q9 u/ B7 `  s. d/ `6 i
  3.   * @file    RingBuffer.c
    - k0 k6 ?7 p3 Q  O& D* I& V) z
  4.   * @author  XinLi
    ! N( Y, ^/ O* }8 O3 V7 c) f" J5 r; `
  5.   * @version v1.14 E, w- Y; T; a3 n
  6.   * @date    15-January-2018& i4 ]8 r3 m6 K
  7.   * @brief   Ring buffer module source file.
      F7 k. `/ o" L
  8.   ******************************************************************************
    - [% a3 I$ ^" n& v
  9.   * @attention6 Y: a1 c! S3 K' i% ]1 [. A
  10.   *
    ! p0 q( @: C& }& d( Z! X
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    0 }6 w/ G( \1 w' @. \6 X. d
  12.   *
    ) \( y9 G) D, h4 ~! W) \
  13.   * This program is free software: you can redistribute it and/or modify
    ; Q. P: K3 w3 g- |0 @
  14.   * it under the terms of the GNU General Public License as published by# B/ v* K- N9 e* H8 h. b2 T
  15.   * the Free Software Foundation, either version 3 of the License, or
    + \0 k$ a: M1 v8 j
  16.   * (at your option) any later version.
    % U- Z  k# U& A" N, k9 e
  17.   *
    ' [9 U+ Q$ w5 @+ y( N: j# b
  18.   * This program is distributed in the hope that it will be useful,& I+ T' Y* j  l
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    ; P; k  g  ~- t) ~: v. A
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ; S/ q) L+ w% J: G3 _
  21.   * GNU General Public License for more details.
    , a. u3 u9 ~7 B5 v
  22.   *
    9 {: \# I' [! Z9 u2 O, }5 ~
  23.   * You should have received a copy of the GNU General Public License! K- F! ?2 X" i2 \: p: i
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    ' q+ V$ i: C/ T- r
  25.   *
    6 r& N$ A; ~3 `2 j: g+ |
  26.   ******************************************************************************7 V( z4 ?) C; f& J; e
  27.   */
    + |$ e/ Y6 M) I2 `% p8 A. g
  28. & f! ^& N; m3 y; U( G+ s* h0 T
  29. /* Header includes -----------------------------------------------------------*/5 y# k, ^0 P, b! X
  30. #include "RingBuffer.h"* U* V6 A7 ]: W
  31. #include <string.h>
    5 T* P) w' p0 B/ k* _- V! _

  32. % O6 @) g# [* X; E5 Z
  33. /* Macro definitions ---------------------------------------------------------*/
    7 ]4 i+ w4 ~* Y" b5 G4 r6 d
  34. #define min(a, b)  (((a) < (b)) ? (a) : (b))- T4 ~- T9 \8 u! ]2 U

  35. 3 ^2 k( M( y* z# D
  36. /* Type definitions ----------------------------------------------------------*/! C* H! {# {: V: r
  37. /* Variable declarations -----------------------------------------------------*/& g- B  A) p6 l( M# R, _  z
  38. /* Variable definitions ------------------------------------------------------*/
    . x9 j" d' I+ _  \% l/ V/ z
  39. /* Function declarations -----------------------------------------------------*/" ^( a+ l% z' Q. b; F
  40. static bool is_power_of_2(uint32_t x);
    0 _" k* i4 P, q- I$ q* g
  41. static uint32_t roundup_pow_of_two(uint32_t x);. v6 M" U# F/ b' y% I; K; A
  42. + {. h" ]( x* {& S- M& D+ F2 T
  43. /* Function definitions ------------------------------------------------------*/
    . u' i- I% g$ v% K. L  n
  44. ( Q) V) B  V) t" y! n# D1 O
  45. /**4 r4 ]  L( z# ^/ l& `, Q9 p
  46.   * @brief  Allocates a new FIFO and its internal buffer.
    2 Q0 r8 h% Z4 P0 ^
  47.   * @param  [in] size: The size of the internal buffer to be allocated.
    9 Q' @: `, n( Y: `: L  G% U6 [
  48.   * @note   The size will be rounded-up to a power of 2.& j: f1 K4 o3 x: k% ~
  49.   * @return RingBuffer pointer.) j0 S) R7 t$ x
  50.   */
    ! Z5 P! [$ I. D& P" u. O8 k5 z" }
  51. RingBuffer *RingBuffer_Malloc(uint32_t size)
    : z2 P# Z; M: }. u
  52. {
    9 w& g9 j1 w+ I! k& S2 M% e/ F
  53.   RingBuffer *fifo = RING_BUFFER_MALLOC(sizeof(RingBuffer));
    2 H# q0 }3 S1 ^1 `

  54. ' ]/ n7 A; X" g# s/ n7 _# I' h8 c
  55.   if(fifo != NULL)/ @: K3 z' I# P" _
  56.   {
    ) w# u# @( R* l' ]% e
  57.     if(is_power_of_2(size) != true)
    8 ]4 u! V0 p2 n) [
  58.     {0 P5 w# f7 U  y: n0 Y& E
  59.       if(size > 0x80000000UL)& g/ }9 b7 O/ u
  60.       {* A( b( t5 }: O! N$ M
  61.         RING_BUFFER_FREE(fifo);
    4 R- x" o" i1 T# a# f+ L8 F
  62.         return NULL;
    & e# \. d1 s/ A% }* D! H6 o
  63.       }; Q9 r3 n1 T9 v2 z) K  M! X
  64. : [" [% I& P9 q
  65.       size = roundup_pow_of_two(size);  t6 u. u4 c% U8 Z
  66.     }; X8 [9 n/ F0 C- W% {

  67. 5 D- m6 z. l; h& l. s% ], e4 q
  68.     fifo->buffer = RING_BUFFER_MALLOC(size);8 q  ^' n; q9 D3 Q1 m

  69. & p3 C: ]4 \1 g
  70.     if(fifo->buffer == NULL)# F. D$ i4 y/ H- v. j- n5 T5 G
  71.     {+ _+ h6 G9 i* T0 e( b
  72.       RING_BUFFER_FREE(fifo);
    ! T0 Q$ n) {' S, q# y
  73.       return NULL;2 n% H% T! Q* I  \0 q7 }, ~5 j
  74.     }
    - M* N, m5 b# w0 z% a+ @5 f6 d1 z

  75. 0 [; G1 ?8 L# C2 V4 s; V
  76.     fifo->size = size;
    8 g( I7 n  {5 ]
  77.     fifo->in = fifo->out = 0;
    # N/ V7 h0 n  T8 `4 w. {- D$ z
  78.   }
    ( A) Y9 ]) I5 g7 F2 y+ S7 W$ s4 G7 L

  79. ' K8 e) h9 t! g  t) @- y
  80.   return fifo;" ^- h3 x: q1 n3 M1 |$ y0 Z
  81. }
    , I$ O5 C$ r2 t3 U

  82. ( m2 Y0 \& [4 N3 ]+ ?6 N
  83. /**
    % ?" z: y2 F2 g4 m+ }: q- I* v/ {
  84.   * @brief  Frees the FIFO.2 b' a# `7 U; C! i
  85.   * @param  [in] fifo: The fifo to be freed.( Q6 E& ]2 |) W1 G+ k
  86.   * @return None.
    ; x8 ~* ^( Y/ Y: s# ^: e$ V! Y# l
  87.   */
    / J, z7 y& t4 g
  88. void RingBuffer_Free(RingBuffer *fifo)2 S; S  ~: ]/ B# p
  89. {
    8 ?, J+ ^7 H: i/ J' x
  90.   RING_BUFFER_FREE(fifo->buffer);" |+ F" p3 u5 h- k4 \; D: o
  91.   RING_BUFFER_FREE(fifo);. a8 Q  p6 ~) ~
  92. }
    , `+ e% i, {) k/ _) c6 \* z0 W& N

  93. , _  w9 P/ ^$ Z1 e3 o3 E7 I
  94. /**
    3 A5 B  j1 `8 W; q
  95.   * @brief  Puts some data into the FIFO.! W! p/ G# V& }" d6 X9 Z& y
  96.   * @param  [in] fifo: The fifo to be used.8 _. `+ D' ^- L% W2 U9 I+ P
  97.   * @param  [in] in:   The data to be added.. A$ d& t* M  O+ ~3 a! i: H. N3 f
  98.   * @param  [in] len:  The length of the data to be added.
    - |3 @+ u( E. }3 x  N- G, q' T
  99.   * @return The number of bytes copied.8 @! q& w/ q, Q1 _* p! V. l  L8 s4 n
  100.   * @note   This function copies at most @len bytes from the @in into
    5 j$ P+ [2 n; O, R
  101.   *         the FIFO depending on the free space, and returns the number
    " A$ C9 S  A+ c  T4 _; [/ l
  102.   *         of bytes copied.
    : }9 V% M; a/ O
  103.   */- i- Z% y4 K! Q
  104. uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len)
    ! @$ ~, }4 ?; h7 m: m% @  \
  105. {+ B7 s& Q8 b8 H1 S) e$ P9 D
  106.   len = min(len, RingBuffer_Avail(fifo));
      a* U, u0 k3 ~7 f! c  s1 U
  107. 8 {. J4 q( D& H
  108.   /* First put the data starting from fifo->in to buffer end. */' a. t7 t1 K* t
  109.   uint32_t l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));$ _# j6 l- m7 [; m
  110.   memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), in, l);
    2 j0 n6 j/ \+ _) g6 S2 B( a

  111. 2 V+ K  l* B% n* b* W3 r
  112.   /* Then put the rest (if any) at the beginning of the buffer. */7 H8 p3 m* ?/ S  `+ h
  113.   memcpy(fifo->buffer, (uint8_t *)in + l, len - l);
    ; o: z+ e6 i# \( P9 d% ~) |

  114. " Q! d  o; P& a; s; Y- h
  115.   fifo->in += len;1 S& M: P" {( o* ]% _0 K

  116. # u0 `: u' I( R
  117.   return len;# k  z4 Y' V) A2 ^* o3 c
  118. }0 l& C( M5 m+ [# Q7 F% R0 [! e
  119. 8 ~; u% F$ s* r1 ?" t; f9 E" Y
  120. /**! N" m% L/ I& x+ u; {4 q6 u
  121.   * @brief  Gets some data from the FIFO.
    + T7 D7 f% J6 T' J7 x4 E/ H
  122.   * @param  [in] fifo: The fifo to be used.
    2 o- U9 c/ }- A6 I5 }/ r: U1 L- r
  123.   * @param  [in] out:  Where the data must be copied.  ^" T$ z* C0 W
  124.   * @param  [in] len:  The size of the destination buffer.
    # \+ \  @' x' y) r( h' `
  125.   * @return The number of copied bytes.7 a* E  P2 v) j% H! ^0 ~
  126.   * @note   This function copies at most @len bytes from the FIFO into
    $ [& \- I% Z4 Y4 s8 h, ~, Z- `
  127.   *         the @out and returns the number of copied bytes.
    ) D5 P0 n" _7 W) O# }% Z/ a
  128.   */
    - I% g) W# B7 e$ B
  129. uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len)8 @( {$ Y% {' N+ z8 d
  130. {
    : L% R$ v: U* Z8 n% Q: C2 g3 z
  131.   len = min(len, RingBuffer_Len(fifo));5 c, z5 f( ]6 \. N: z$ u* T# h
  132. 0 u8 S* T6 Q3 b# _
  133.   /* First get the data from fifo->out until the end of the buffer. */
    0 i  V5 W- ?* J9 U
  134.   uint32_t l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));) C4 T  _$ g5 {$ I* d3 U. _
  135.   memcpy(out, fifo->buffer + (fifo->out & (fifo->size - 1)), l);& J: }/ _: u4 L* K

  136. ' G3 s+ T' L) y" S9 P: g6 e7 D
  137.   /* Then get the rest (if any) from the beginning of the buffer. */2 c7 D4 k" e& Y3 E, s; J
  138.   memcpy((uint8_t *)out + l, fifo->buffer, len - l);
    / u2 B6 u% [- O: ~8 K
  139. . {# K# F- `0 h& C( L0 K
  140.   fifo->out += len;  a' S* Q/ [- I$ v3 b
  141.   r4 E- i  S. _1 P, G
  142.   return len;" k( [% b# e8 A) G9 h9 f3 z
  143. }& H' H2 U+ Y6 [* o& k

  144. " K( b7 _; l7 w0 s0 k* c
  145. /**
    # S$ z% `* N1 j  K) d7 q# s) O
  146.   * @brief  Determine whether some value is a power of two.2 v1 j8 Z: D0 Y; J* z
  147.   * @param  [in] x: The number to be confirmed.
    5 |; x- d: G4 ~* T+ s
  148.   * @retval true:   Yes.5 Y4 h/ {& c2 e& A+ E# x& @) @
  149.   * @retval false:  No.: [1 R( n8 }  |, ]- z  @2 g5 D
  150.   * @note   Where zero is not considered a power of two.
    ; S/ n4 _% v/ m# U2 l4 l
  151.   */
    4 q& [/ D6 u) ?. z. y! q$ a
  152. static bool is_power_of_2(uint32_t x)+ r% T5 r8 h) g: D
  153. {
    9 O" g$ I( F% R! U7 j$ r
  154.   return (x != 0) && ((x & (x - 1)) == 0);
    7 R* U1 t, u7 Z- l7 L0 a
  155. }
      g; q, o; T8 m! e

  156. ( o' M. C. D9 r$ P6 m. T; k4 T9 F2 q
  157. /**
    7 O7 Q) _& P! y: P
  158.   * @brief  Round the given value up to nearest power of two.
    ) {3 d% }& ^. A- B4 X6 z
  159.   * @param  [in] x: The number to be converted.
    , U' h, U% {1 D2 m# S
  160.   * @return The power of two.4 I* p9 N" v, t% b
  161.   */
    : W: Y* j+ g* D
  162. static uint32_t roundup_pow_of_two(uint32_t x)
    $ ]5 |) a3 @/ H" i( L1 E
  163. {
    ( N4 u0 Q, ?- O: K0 h9 B3 l
  164.   uint32_t b = 0;
    % {1 [/ C% N2 V# z
  165. * T+ l2 {7 S2 e9 h4 f
  166.   for(int i = 0; i < 32; i++)
    ; V4 V3 R* v1 p+ v5 b
  167.   {* |$ R3 o5 S* {5 v( U; U1 d+ l+ T
  168.     b = 1UL << i;; u: ?/ F2 j; n5 T/ P
  169. 7 N3 z6 k( p" o+ v" d  H+ o
  170.     if(x <= b)
    & }) \5 m. M6 S4 e" ?$ H$ {7 r8 t
  171.     {
    / s7 Y$ J$ G' A" W! Q& f" `  \7 N
  172.       break;
    % ^9 h4 M4 @. H6 P+ G& O
  173.     }
    / E# [! {8 w- k" P3 {' P# y! [
  174.   }5 C' j6 q# r  W- k' x6 g7 I9 I
  175. 5 Y, l7 V$ X  O* l) }8 [0 X0 e
  176.   return b;, }& k4 [6 L! U" P$ c& R9 v
  177. }</div><div></div>
复制代码
: t3 |/ j6 K8 z6 X" e' r2 p

% e( G* D4 _8 ?; G) W% Y+ f) PCAN.h 文件
+ R4 d+ E4 d( F- s
  1. /**, R  @$ {" g8 Y% r5 a
  2.   ******************************************************************************
    ' s, m; `$ q5 t; f6 _& t! a
  3.   * @file    CAN.h
    6 r/ P  L- c6 R- |0 D8 S8 A
  4.   * @author  XinLi
    # s  Z3 b9 m4 j2 q( G
  5.   * @version v1.0; d; I$ V7 H' l4 T, x! E( s
  6.   * @date    24-June-2018' ]+ w1 N. f/ q6 J3 D
  7.   * @brief   Header file for CAN.c module.! r4 W! v3 h* w7 h* v. T, e
  8.   ******************************************************************************
    1 c" i) [( n& `1 k& |
  9.   * @attention0 n+ m) L2 `$ ?7 x; w& r
  10.   *
    ! a5 p* |' e$ h
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    , T+ ?9 M, A8 y  u6 K4 l
  12.   *
    2 \2 y3 J1 x" Z0 s5 v7 M
  13.   * This program is free software: you can redistribute it and/or modify! f! L  s/ H3 {/ [
  14.   * it under the terms of the GNU General Public License as published by
    4 D  C: Y; \3 |$ T/ t! R
  15.   * the Free Software Foundation, either version 3 of the License, or
    $ q7 T. I  j* D
  16.   * (at your option) any later version.& ^- q7 Y! M+ a+ ^3 r) H
  17.   *5 x* b- h' m0 y6 }; J; y
  18.   * This program is distributed in the hope that it will be useful,
    2 V$ `2 i7 e) W2 o+ `- g: L6 B2 c! T
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of0 l! Q+ ^! c; Q; b
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    ' e) `3 o' O5 J& \6 q: L
  21.   * GNU General Public License for more details.- Z- |6 Z% o- ~5 {
  22.   *9 ~. f3 p# r6 C1 [4 w/ e
  23.   * You should have received a copy of the GNU General Public License
    ! Y* h  T8 T1 g& V3 m
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a># ]8 T: b+ o0 W# n! a+ g# I; T& S4 f
  25.   *
    % r: I1 y9 S% S9 n; ]3 s# E4 z
  26.   ******************************************************************************# k, d/ K- w! d8 P
  27.   */4 H/ h9 S9 O7 g6 \5 ?2 D0 Z
  28. ) R8 l8 U% s# x( Y
  29. #ifndef __CAN_H7 x* m: P( a6 a+ G. {
  30. #define __CAN_H) _7 R+ F; q( E

  31. 7 Q0 i5 S8 d& \. p
  32. #ifdef __cplusplus: h9 T6 C0 d+ }2 C4 m4 g% v
  33. extern "C" {. O( Y" ?- @5 F
  34. #endif/ _7 g6 J3 J" [! T: u5 [

  35. 5 [+ [1 Y1 t/ `. ?
  36. /* Header includes -----------------------------------------------------------*/
      l; W+ `! p" J3 }
  37. #include "stm32f10x.h", E9 |6 w  z% d9 v" k" n" e
  38. #include <stdbool.h>
    : i- e$ G& O( X/ {7 n

  39. 4 X7 ?' S% Z& m+ G
  40. /* Macro definitions ---------------------------------------------------------*/' d# Z) m9 R8 I. i+ Z7 \4 V
  41. + z8 ]; B$ R! d2 Y; C4 q
  42. /******************************* CAN1 Configure *******************************/' f( v% ^. B+ o( ^$ F$ @$ K/ \
  43. #define CAN1_TX_BUFFER_SIZE        (16)
    : M9 i, R0 @- @. {% ~
  44. #define CAN1_RX_BUFFER_SIZE        (16)  Q7 L9 L: c4 b; M3 B

  45. 2 \. e0 n0 r0 Y1 e, x+ H# O* k1 e
  46. #define CAN1_TX_GPIO_CLOCK         RCC_APB2Periph_GPIOB8 I" f3 w0 R6 k  R
  47. #define CAN1_RX_GPIO_CLOCK         RCC_APB2Periph_GPIOB
    8 l5 _) k, V; A! q& y2 U
  48. " o7 Z  p( s7 g4 T$ M
  49. #define CAN1_TX_GPIO_PORT          GPIOB0 q+ n- _  }  J7 X2 ]
  50. #define CAN1_RX_GPIO_PORT          GPIOB+ U4 h9 u4 u. V: z3 M- Q

  51. 4 }( b4 k- y- {6 w" ~2 Y/ j( q5 k
  52. #define CAN1_TX_GPIO_PIN           GPIO_Pin_97 F7 j0 H& `3 t: L* y/ Z
  53. #define CAN1_RX_GPIO_PIN           GPIO_Pin_8( P- K( V7 |9 R
  54. & L0 T9 g2 X0 e3 J
  55. #define CAN1_IRQ_PREEMPT_PRIORITY  (0)/ c& _( G. b0 K8 c
  56. #define CAN1_IRQ_SUB_PRIORITY      (0)
    0 J: g& M1 z, }

  57. # v0 i9 g' \8 k8 }4 i. Z/ z
  58. #define CAN1_PORT_REMAP()          GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE)% r! P/ H! a7 p  o) J4 s4 E* u
  59. /******************************************************************************/
    ! [) H6 n2 S; t8 W; Y
  60. 0 u: x: p& u8 o7 y/ A
  61. #ifdef STM32F10X_CL
    # ]; X1 v% B: A0 w
  62. /******************************* CAN2 Configure *******************************/3 h$ u# l8 O6 A! Y0 U
  63. #define CAN2_TX_BUFFER_SIZE        (16)
    & h: u; n( X. S4 a
  64. #define CAN2_RX_BUFFER_SIZE        (16)8 ], E& }0 O9 ?9 @3 ~

  65. 3 t: l6 a5 K% H
  66. #define CAN2_TX_GPIO_CLOCK         RCC_APB2Periph_GPIOB) R. c7 w, H$ s0 ^
  67. #define CAN2_RX_GPIO_CLOCK         RCC_APB2Periph_GPIOB
    4 {- [6 A5 [, x$ r* c

  68. : L  j0 N. u( @: y
  69. #define CAN2_TX_GPIO_PORT          GPIOB
    2 y* S5 o. P( d) v- }8 P
  70. #define CAN2_RX_GPIO_PORT          GPIOB' x5 h8 J- X- t" r

  71. ) ^. T2 z% j8 ^* M% j
  72. #define CAN2_TX_GPIO_PIN           GPIO_Pin_13" V8 k" A( {" z- a. m; J# I
  73. #define CAN2_RX_GPIO_PIN           GPIO_Pin_12. h6 I! l/ a2 p+ N& |5 y8 Q

  74. & i  O. }) B9 F
  75. #define CAN2_IRQ_PREEMPT_PRIORITY  (0)$ c7 h) y3 `7 [3 Y& r3 `! p3 ~
  76. #define CAN2_IRQ_SUB_PRIORITY      (0)/ P4 q5 F/ Q/ {

  77. / g% Q! ~( |1 Q  m4 h. U! s
  78. #define CAN2_PORT_REMAP()          GPIO_PinRemapConfig(GPIO_Remap_CAN2 , DISABLE)1 O0 w* _3 N; m3 e
  79. /******************************************************************************/* f2 }2 o- |! ~  L- i
  80. #endif /* STM32F10X_CL */' s# U/ A  ]1 B' I/ v' n
  81.   H- W/ V& ^; Q7 _6 I
  82. /* Type definitions ----------------------------------------------------------*/
    ; X( o, g& M' S# a0 e* ]; g
  83. typedef enum( q/ _6 d+ r6 v9 x' y0 H
  84. {
    9 b" W9 R0 e$ U! K5 `
  85.   CAN_WorkModeNormal   = CAN_Mode_Normal,
    ( h. j, v8 I8 |5 Y2 J+ ~8 C
  86.   CAN_WorkModeLoopBack = CAN_Mode_LoopBack
    $ n+ w% S" |% _  [( ?, ^
  87. }CAN_WorkMode;
    1 N8 f7 f5 i+ r3 w% I; R8 c

  88. " `6 B; {! |9 |4 h6 K3 w  x' {/ p6 Q
  89. typedef enum9 h# C, P  ~  E
  90. {" L% {! N+ a+ i0 V7 K, s$ R; y
  91.   CAN_BaudRate1000K = 6,
    8 U9 L5 l! _1 M) y: o! s" q8 x4 K
  92.   CAN_BaudRate500K  = 12,' s7 Q/ V- X' w/ U% M+ P
  93.   CAN_BaudRate250K  = 24,9 ?( D+ t3 J* B
  94.   CAN_BaudRate125K  = 48,
    ! j+ n2 A4 ]* l8 A: X
  95.   CAN_BaudRate100K  = 60,
    2 X2 U  E/ t4 Z6 x' H# Z) A
  96.   CAN_BaudRate50K   = 120,& Z; M8 L+ R! ^; y3 B4 ?7 j+ a
  97.   CAN_BaudRate20K   = 300,
    " I, Z* c0 D% L3 T3 I
  98.   CAN_BaudRate10K   = 600! t8 J. d( d& V& u' H4 @6 k
  99. }CAN_BaudRate;
      w2 r3 p6 I) c* W9 D6 r

  100. # A4 r) D7 D1 W1 ^/ m
  101. /* Variable declarations -----------------------------------------------------*/
    # ?4 ~0 b7 ]: F4 Z
  102. /* Variable definitions ------------------------------------------------------*/
    : W8 A$ W5 x" v+ a
  103. /* Function declarations -----------------------------------------------------*/
    8 @) c, ]. t1 \! @8 K2 g9 s- j
  104. void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId);
    : T  o+ R( [0 Z. M1 m% d
  105. void CAN_Unconfigure(CAN_TypeDef *CANx);8 Y2 u! H; z+ V( O9 L% H$ l* i0 r

  106. : Q+ D1 z% d8 T
  107. void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));
      ?$ S" }9 X$ h4 _' G8 M2 ~/ {- T
  108. void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));0 P/ h* r: y/ \' L1 ?
  109. 7 I( b0 ?% `9 B0 ^( b2 d
  110. uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number);
    . }) ?# c! u0 n
  111. uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number);/ B% @- c2 `5 {+ w3 M
  112. " e5 U; W7 @, d. g  _
  113. uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx);
    9 |: Y2 F5 l6 E( t
  114. uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx);
    % m  F. M( A7 t
  115. uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx);
    6 t2 a8 S, m7 A
  116. uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx);. z: k5 z; _1 e' O; K: X
  117. : s, B3 e8 ^* |# j/ `
  118. bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx);& M/ |& L( G: U2 ~, K, y
  119. bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx);
    : c$ z6 f! Y9 ?% U) L) V, ^  J& _$ J
  120. bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx);. V3 g0 I) y1 v* M* Q& L
  121. bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx);( v  ?- t+ i5 A0 T
  122. 6 n8 m3 r% j, l( b
  123. void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx);
    ( s6 ?1 ?7 W; C" e9 z: J$ D, [' ~: b
  124. void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx);
    3 {; e9 O$ S4 a* d, P$ L/ B

  125. ; i% N. q9 L: w1 z5 z- l! j
  126. bool CAN_IsTransmitMessage(CAN_TypeDef *CANx);! l) m% j" x$ v( g+ V% I" p

  127. 2 n( w  ?  d2 a
  128. /* Function definitions ------------------------------------------------------*/
    " |! ?! R* l( X3 k6 ^3 v9 E# F
  129. 9 y5 H* {/ U' l" {3 I: @1 W# L6 T$ ]
  130. #ifdef __cplusplus- f. E0 N# S! c8 h# W, }& S
  131. }
    / c! h  X3 ~# q8 n3 N
  132. #endif
    ; L1 _8 C  q  b" [7 \0 r

  133. . B0 H3 F, l. o" T
  134. #endif /* __CAN_H */' c9 o* W5 d) b, [" D
复制代码
4 t* Q  J# k  p4 n. L) ]) g/ ?

8 G1 ?- c1 U* @1 E5 N
' Y; f+ j9 g+ g6 ACAN.c 文件" A) u: j- @+ ?  p

( F) v" R6 Q" T" O' F
  1. /**
    6 `/ O/ B) ^# u, @5 `$ s' }& G( D! z
  2.   ******************************************************************************
    ( j7 q7 f( `2 m& `) ~
  3.   * @file    CAN.c$ w% A, r! y8 n1 n1 m% x* b
  4.   * @author  XinLi% i3 ?4 \3 W- l/ Y  N% D
  5.   * @version v1.08 X( a8 I& a7 q' @
  6.   * @date    24-June-20182 B$ Z& N- O$ w( i' l8 @* U
  7.   * @brief   CAN module driver.
    . k; Y2 j: K7 j9 u! G9 |
  8.   ******************************************************************************
    # Y& @* ]+ V6 n( \4 M% b1 y
  9.   * @attention; ^+ U0 e/ B. S2 v( Z& ]. f. U# V2 X3 q5 Z
  10.   *$ i- ?) j. m% ^0 p  B: m. x0 }
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>& j! r$ c4 O( N$ I
  12.   *
    ; E8 p, y5 @$ }6 k
  13.   * This program is free software: you can redistribute it and/or modify2 p# r9 L8 b3 q2 l$ Y3 W
  14.   * it under the terms of the GNU General Public License as published by
    $ }1 U) a' {2 \/ w% c0 j2 y
  15.   * the Free Software Foundation, either version 3 of the License, or
    ; ]- I' h% R7 d3 E& `+ @
  16.   * (at your option) any later version.' J6 R7 T# ~2 P2 U+ M: Y
  17.   *  N; w6 c! {' {% U
  18.   * This program is distributed in the hope that it will be useful,+ q* o3 `0 U* x0 g
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    3 K8 J7 w( F: j7 O) w/ ?
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    0 z% ?. `3 o- E5 @+ _6 e. B$ s
  21.   * GNU General Public License for more details.3 Q$ P5 U. `% O. p2 N9 _9 g
  22.   *
    ! b' r0 G5 V! w+ F7 A3 W* g
  23.   * You should have received a copy of the GNU General Public License
    , b2 Y) `# l: B* D
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    ' P4 v( b$ G9 N: d
  25.   *
    2 J- X" [* C9 d
  26.   ******************************************************************************
    ( d7 s  ?# {  ^, u' }! c' ^6 v
  27.   */
    , j& n6 d# R' u/ N' [) k3 H

  28. 8 v) T! v: p! l+ n8 n% L
  29. /* Header includes -----------------------------------------------------------*/
    ; L- {. c! N; P- v2 K
  30. #include "CAN.h"/ c4 |4 q3 _& D: i4 X
  31. #include "RingBuffer.h"
    # P( u2 Z" l/ u( d: n8 g5 y

  32. & o; x5 ?, [* ]0 N8 R" c
  33. /* Macro definitions ---------------------------------------------------------*/3 [) e  S$ j* S. H
  34. /* Type definitions ----------------------------------------------------------*/
    % c/ L+ O- |7 @
  35. /* Variable declarations -----------------------------------------------------*/; X. K/ d; Q# {5 M, z% ^. t$ o" J  {
  36. static volatile bool can1InitFlag     = false;
    3 A( S& e) R! C& E0 }3 H" c
  37. static volatile bool can1TransmitFlag = false;. V' Y- u; u$ ^: V" |

  38. / t$ b0 d8 `3 h! P' I; y# M
  39. static volatile void (*can1TransmitFinishCallback)(void) = 0;  y$ f1 Q7 a2 b# i9 C% ~
  40. static volatile void (*can1ReceiveFinishCallback)(void)  = 0;( N( f" l0 W( @2 T7 y& W  u6 a

  41. $ Z! Y8 ]- G0 a6 h4 |# Q) v
  42. static RingBuffer *can1TxBuffer = 0;5 L2 g; U3 T' Y
  43. static RingBuffer *can1RxBuffer = 0;
    ' u* B3 r8 t4 ]- ]

  44. 9 p/ ?: d- Z& @5 g2 j
  45. #ifdef STM32F10X_CL; |9 }/ _; b9 ^
  46. static volatile bool can2InitFlag     = false;# b8 i6 o0 _+ Z& E2 A; Q1 t
  47. static volatile bool can2TransmitFlag = false;, x4 `) N. D/ x: t# {8 v

  48. 3 M9 L; G/ l# E
  49. static volatile void (*can2TransmitFinishCallback)(void) = 0;
    5 k" Y1 V' L0 y! q6 [
  50. static volatile void (*can2ReceiveFinishCallback)(void)  = 0;
    % G9 Q8 M* U2 u# c7 T
  51. 7 l5 i5 z3 x& D' P( D* \% _  d4 `) K
  52. static RingBuffer *can2TxBuffer = 0;# F) |& E, Y( v& f6 }- U& L; b
  53. static RingBuffer *can2RxBuffer = 0;4 }/ P/ v! Q: \' C; h- d
  54. #endif /* STM32F10X_CL */! U- Y& O8 X  b$ K
  55. ' Q  t. b& K- _5 g- a$ @# w" |
  56. /* Variable definitions ------------------------------------------------------*/
    4 ?, |1 o8 @7 P; V
  57. /* Function declarations -----------------------------------------------------*/: Y9 v' |  d( x
  58. /* Function definitions ------------------------------------------------------*/
    + y/ O- ^! z0 p4 U) @) _9 z' h
  59. . V, l1 ]) Z6 P6 r  T
  60. /**
    0 R/ y  Q! V# P0 }; `' d
  61.   * @brief  CAN configure.  ]8 h% J1 h) T. D) Y5 h
  62.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.
    ; w0 E3 d% t" @/ o% q! W
  63.   * @param  [in] WorkMode: Work mode.
    * u7 g& z2 [" ~" C, M* [3 |; u# M
  64.   * @param  [in] BaudRate: Communication baud rate.
    . ]0 H7 k9 Q1 \7 ^% q1 e, s1 l' o
  65.   * @param  [in] StdId:    Filter standard frame ID.6 f! N6 x3 Z$ g7 Z$ u% I( D
  66.   * @param  [in] ExtId:    Filter extended frame ID.3 i1 C7 S# u/ Y8 L& B! v( z! @
  67.   * @return None.
    5 A! n; I* P8 j. O7 s3 L
  68.   */
    / h( l/ H! w7 R+ N: |
  69. void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId)5 J1 R  d2 I2 D
  70. {  G. ?) k% F, B
  71.   GPIO_InitTypeDef      GPIO_InitStructure      = {0};
    / E. H4 Y. T0 v1 V# s+ r
  72.   CAN_InitTypeDef       CAN_InitStructure       = {0};; t( O# n) @4 d0 T6 j
  73.   CAN_FilterInitTypeDef CAN_FilterInitStructure = {0};
    + t8 f" Z! T3 `; {
  74.   NVIC_InitTypeDef      NVIC_InitStructure      = {0};
    4 G' {4 F2 d( W. t

  75. : S2 I* A- L1 r# g; A3 A% ~
  76.   if(CANx == CAN1)
    ( l, W, m4 R4 A' Y  i8 K% u
  77.   {
    ! D5 l/ f! Q% s2 m
  78.     if(can1InitFlag == false)6 h$ W5 y6 o5 D* n
  79.     {1 J! K. W. N5 l3 K( s; b9 y
  80.       can1InitFlag = true;
    + M0 F& f3 e. y1 z) n! B5 b

  81. 0 o8 k/ X  Q# Z+ Z) L
  82.       can1TransmitFlag = false;4 C0 O* e! ~3 D/ K  @7 s/ J/ v# ~
  83. ; ^( C( [- P4 B" |
  84.       can1TransmitFinishCallback = 0;& U# a4 |$ f3 l
  85.       can1ReceiveFinishCallback  = 0;, [$ U) G  E* z9 I: d

  86. ( i8 R6 s8 k5 I8 t
  87.       can1TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN1_TX_BUFFER_SIZE);
    1 Y# Q) D9 L8 C' Z* O. X
  88.       can1RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN1_RX_BUFFER_SIZE);
    0 D4 _% [5 _! }6 `8 n2 s: Z5 l* N" Y1 E
  89. / P, q$ ~3 f+ v1 [
  90. #ifdef STM32F10X_CL
      A3 y, d2 [4 r0 u9 X1 J' S8 H
  91.       if(can2InitFlag == false)
    ) o4 K3 T: i, q8 z+ @8 M
  92. #endif /* STM32F10X_CL */. \2 n$ l' X, t; f0 ^  A
  93.       {
    , O6 Y8 A& }% t5 {" F( \0 Q2 c' D
  94.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
    3 A! U3 i  P; V5 s
  95.       }7 \) W+ w" M1 p5 v" }* D- K, A

  96. 1 V" _4 R4 ~3 \/ o+ \" ]5 \' k1 g- Q; k
  97.       RCC_APB2PeriphClockCmd(CAN1_TX_GPIO_CLOCK | CAN1_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);
    ( M$ P8 U0 W, X/ E0 ?- d

  98. & T* f3 B; W7 ]. u( l* b! [
  99.       GPIO_InitStructure.GPIO_Pin   = CAN1_TX_GPIO_PIN;  y, h# _8 s% _
  100.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;5 {, g. s  n( C" V! L" |
  101.       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    $ d" K; |3 e$ ?  c, F: l
  102.       GPIO_Init(CAN1_TX_GPIO_PORT, &GPIO_InitStructure);
    % S, t2 w0 d* b3 V& l5 G: E: i' d
  103. ( G+ `3 _6 E: F- g9 V
  104.       GPIO_InitStructure.GPIO_Pin   = CAN1_RX_GPIO_PIN;( S+ \5 |0 \+ Z# f% D
  105.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
    - v. Z8 j" p. j+ @0 W2 h
  106.       GPIO_Init(CAN1_RX_GPIO_PORT, &GPIO_InitStructure);/ h) a3 k2 F9 {& p' _
  107. # F+ n$ d# c& [; _) m& a
  108.       CAN1_PORT_REMAP();8 `7 A/ ^% [& {8 m8 y7 V2 L; U

  109. ( ~( c# i% `- I- I% `  n
  110.       CAN_InitStructure.CAN_Prescaler = BaudRate;; L) c* J2 Q/ N- Y; o" m
  111.       CAN_InitStructure.CAN_Mode      = WorkMode;6 \2 I! T3 t' a( M7 I, B3 q3 @
  112.       CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;6 w7 w9 Y6 G$ r' l
  113.       CAN_InitStructure.CAN_BS1       = CAN_BS1_3tq;1 q0 g" V$ B, E+ Q  Z2 `$ X& N
  114.       CAN_InitStructure.CAN_BS2       = CAN_BS2_2tq;+ E, x# V3 S% t" S8 ?
  115.       CAN_InitStructure.CAN_TTCM      = DISABLE;5 w0 I  e$ H* t9 h
  116.       CAN_InitStructure.CAN_ABOM      = ENABLE;
    7 a) v9 l" ]+ l' u
  117.       CAN_InitStructure.CAN_AWUM      = DISABLE;
    - [6 Z4 ~2 T/ D5 b) r
  118.       CAN_InitStructure.CAN_NART      = ENABLE;
    6 u$ e+ D6 ?5 n4 m8 d: j$ k' l& h
  119.       CAN_InitStructure.CAN_RFLM      = DISABLE;
    9 Z9 G& q4 h0 z+ j1 U
  120.       CAN_InitStructure.CAN_TXFP      = ENABLE;# e: m& J* N2 I  u8 `/ L. \, W

  121. . s# o! W5 |! P+ Z8 k
  122.       CAN_DeInit(CAN1);
    3 i) M3 p: O- g3 q3 _' H  _) k
  123.       CAN_Init(CAN1, &CAN_InitStructure);
    ( p3 n# z  d7 u1 ^* Z9 w( }: @
  124. & l9 R- u% o2 G5 T. f
  125.       CAN_FilterInitStructure.CAN_FilterIdHigh         = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);
    . f2 s: z+ t$ J
  126.       CAN_FilterInitStructure.CAN_FilterIdLow          = (uint16_t)(((StdId<<18)|ExtId)<<3);
    % E, Y6 _8 x+ j# G% X% H7 E
  127.       CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;
    8 z$ F" @- C. Y4 ?
  128.       CAN_FilterInitStructure.CAN_FilterMaskIdLow      = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;6 c3 W( V! Q" ^4 j9 K% D: d
  129.       CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
    $ M$ ?5 n) e: h4 m3 ]# E
  130.       CAN_FilterInitStructure.CAN_FilterNumber         = 0;8 l) o: t: |: x/ `' o. H* g0 W4 }
  131.       CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask;
    # B! n( Q4 B3 q2 _
  132.       CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit;
    $ {; Q  F1 e! d) u' M
  133.       CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;3 w/ }7 l% p  t$ ~5 J
  134.       CAN_FilterInit(&CAN_FilterInitStructure);' C- n% ]2 r. Z- d. l
  135. / ?' H" \3 ?% [: s4 U! Q2 Q4 ]
  136.       CAN_ITConfig(CAN1, CAN_IT_TME | CAN_IT_FMP0 |CAN_IT_FF0 | CAN_IT_FOV0 | CAN_IT_FMP1 | CAN_IT_FF1 | CAN_IT_FOV1 |
    0 C! ~4 h2 b. v9 w. d
  137.                          CAN_IT_WKU | CAN_IT_SLK  |CAN_IT_EWG | CAN_IT_EPV  | CAN_IT_BOF  | CAN_IT_LEC | CAN_IT_ERR, DISABLE);% f( B( D) T& r/ _% |+ X8 Z
  138.       CAN_ITConfig(CAN1, CAN_IT_TME | CAN_IT_FMP0, ENABLE);
    * p. M0 l' u& h, {% I/ k

  139. , Q( b( P* `. X5 {8 D& V9 u( W/ S$ G
  140. #ifdef STM32F10X_CL
    2 b( D2 {, j/ ^( f
  141.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_TX_IRQn;, r' _) h* r1 b. d* [
  142. #else$ |& u, m  {) Q, k% o
  143.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_HP_CAN1_TX_IRQn;
    1 M' v. c7 m: j+ ~
  144. #endif /* STM32F10X_CL */. L1 t7 y! }# x) U5 G' i; W4 P

  145. 2 ^' f( a3 c1 b
  146.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;# }- K8 @# P6 }' o
  147.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN1_IRQ_SUB_PRIORITY;
    ! G5 S2 X8 r1 p# X3 s0 O7 @
  148.       NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;6 h# \! e! H$ G
  149.       NVIC_Init(&NVIC_InitStructure);
    : E: }$ A, m. m% j4 N3 g

  150. - h9 S! ~6 {$ V! @% G7 _
  151. #ifdef STM32F10X_CL0 Q& _0 V6 L6 x9 c
  152.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_RX0_IRQn;
    ! ?. x4 o2 X. ], H4 b& [8 H
  153. #else9 \" c, w7 \6 C5 q0 }/ _
  154.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_LP_CAN1_RX0_IRQn;& }* S4 K" U$ d. x- M7 g- \
  155. #endif /* STM32F10X_CL */
    # F0 K( q- O! R5 B/ p: J/ `
  156.   w9 ?: A" C8 s* h% M( T4 k
  157.       NVIC_Init(&NVIC_InitStructure);
    5 V. p( x+ r! Z  a
  158.     }
    6 a9 p/ s" r( K% G, Q
  159.   }
    * k( _/ K+ q* i7 t4 W1 n* R5 t1 W

  160. 3 `- G' }% d8 C1 Z5 [
  161. #ifdef STM32F10X_CL
    5 |8 ]' i6 ~+ V; Z, u
  162.   if(CANx == CAN2)6 ]3 D+ W: p0 z5 ?
  163.   {
    * }! l. y9 [2 H) U# t2 F6 X
  164.     if(can2InitFlag == false)
    - f  q9 |2 r2 d) Y
  165.     {9 z  C7 N. M! V& Y6 O! I" v7 j1 T
  166.       can2InitFlag = true;5 i; ]+ I9 J: M; f, v! j
  167. 5 d9 B& X) N. ]
  168.       can2TransmitFlag = false;
    8 i' x: a3 v3 K9 a2 K

  169. ; F. b! K: R1 k# u  m
  170.       can2TransmitFinishCallback = 0;
    : D! Q# F& h+ C9 E7 |
  171.       can2ReceiveFinishCallback  = 0;
    8 H* N6 I* Z5 d) F! A4 J# \
  172. % z4 ?3 A- K; A: Z( I
  173.       can2TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN2_TX_BUFFER_SIZE);
    5 H9 U% g3 z, P" n- s6 r3 w
  174.       can2RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN2_RX_BUFFER_SIZE);! N& q; q+ K. {' k
  175. / i4 n; X% c& z( M; y* p" ]" k/ H
  176.       if(can1InitFlag == false)$ H& o0 x" G- S' t
  177.       {5 n: s( U; ]+ U) M
  178.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
    % q$ s/ m7 A' {5 D5 y# `6 b
  179.       }
    # H- X/ r' d; ]' X1 a  P
  180. 9 l" l# X9 A' S7 u+ }
  181.       RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);0 P4 i5 F8 b/ `
  182.       RCC_APB2PeriphClockCmd(CAN2_TX_GPIO_CLOCK | CAN2_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);
    ; A8 r/ ^/ E! h+ r

  183. 7 D. D% S. ?+ Y) w, d1 w
  184.       GPIO_InitStructure.GPIO_Pin   = CAN2_TX_GPIO_PIN;
    6 S$ w& I+ v% ]' I  M* ~" w
  185.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;- |9 E, d4 @, D
  186.       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;8 {' y1 k# x2 X7 w
  187.       GPIO_Init(CAN2_TX_GPIO_PORT, &GPIO_InitStructure);" u2 O, L! Y4 U0 J5 R
  188. - V8 H' N) h$ Q9 r6 O- `3 g
  189.       GPIO_InitStructure.GPIO_Pin   = CAN2_RX_GPIO_PIN;
    * o. z: r. M1 S5 h
  190.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;- k5 S) d2 A7 ~$ v' H
  191.       GPIO_Init(CAN2_RX_GPIO_PORT, &GPIO_InitStructure);
    7 D3 ?- f' H. m. V6 u! b- f

  192. ( U" A- t) Z! z& H- z7 _0 N
  193.       CAN2_PORT_REMAP();
    $ w9 y$ O: z- L$ N# T& a& `* z

  194. 1 i! H' w1 W+ I. ]: m# a* Y0 W
  195.       CAN_InitStructure.CAN_Prescaler = BaudRate;
    : a& I4 d. W) Z4 A  a
  196.       CAN_InitStructure.CAN_Mode      = WorkMode;& J+ L$ H% n0 w! D- Z  T
  197.       CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;
    2 q7 o5 e0 i6 N- c0 N
  198.       CAN_InitStructure.CAN_BS1       = CAN_BS1_3tq;
    4 N/ b( X, d( W* V* O
  199.       CAN_InitStructure.CAN_BS2       = CAN_BS2_2tq;
    4 h/ @% k5 m- X, N! N6 G" ~+ E) ?
  200.       CAN_InitStructure.CAN_TTCM      = DISABLE;
    , z; |/ ?5 S9 s. R1 J/ R/ @, e
  201.       CAN_InitStructure.CAN_ABOM      = ENABLE;
    * d8 L% r. [8 K  R' a. I4 Y& Z9 F5 s
  202.       CAN_InitStructure.CAN_AWUM      = DISABLE;& d; z# z( U# P# R7 ]1 W
  203.       CAN_InitStructure.CAN_NART      = ENABLE;2 y1 ^- z( X4 p; X9 r: Q3 n
  204.       CAN_InitStructure.CAN_RFLM      = DISABLE;
    ( O) t, T6 ^9 f& F' Q
  205.       CAN_InitStructure.CAN_TXFP      = ENABLE;
    2 Z! e$ ]& H: s. P; X

  206. ' u0 V4 z: n# Y* R3 g& d
  207.       CAN_DeInit(CAN2);
    4 [$ j# \; A; l) c9 o% [- n* d1 X
  208.       CAN_Init(CAN2, &CAN_InitStructure);
    7 j$ \2 Y6 S' P, g: K! q2 a% ^4 C

  209. 3 f! {! h3 B2 v2 `5 U% d& c2 {
  210.       CAN_FilterInitStructure.CAN_FilterIdHigh         = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);
    % f6 `$ @3 l( j. ~+ J* K
  211.       CAN_FilterInitStructure.CAN_FilterIdLow          = (uint16_t)(((StdId<<18)|ExtId)<<3);
    ( z- J' v* b0 u3 M' e9 B$ H$ z8 K
  212.       CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;- W) N  c7 q  N1 l& m
  213.       CAN_FilterInitStructure.CAN_FilterMaskIdLow      = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;
    " K0 Y( y0 C3 n3 {9 o
  214.       CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
    ! U) y8 K3 ^8 C9 e& p
  215.       CAN_FilterInitStructure.CAN_FilterNumber         = 14;
    * V5 L- r; |" B  U
  216.       CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask;
    + O, `3 b0 Z; |1 L  p
  217.       CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit;
    " W* O- k3 q) t  W6 H0 G4 h
  218.       CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;
    ) Q/ W: W6 r) n9 e
  219.       CAN_FilterInit(&CAN_FilterInitStructure);
    7 E/ M# k( D( F4 D# S+ ?' P- M

  220. # R' v" e0 q* `* n! O
  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 |
    4 W; R9 H3 |' ~- l0 O8 _% T
  222.                          CAN_IT_WKU | CAN_IT_SLK  |CAN_IT_EWG | CAN_IT_EPV  | CAN_IT_BOF  | CAN_IT_LEC | CAN_IT_ERR, DISABLE);
    ; Z/ S4 X6 u/ x% y9 g" J
  223.       CAN_ITConfig(CAN2, CAN_IT_TME | CAN_IT_FMP0, ENABLE);
    , X2 L0 j7 z' C2 f
  224. 3 s# a/ i1 q2 w' L) B8 _! I3 Q
  225.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_TX_IRQn;2 Z, \8 d  R/ F. x, n6 E
  226.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;
    " W' }  r' X' C0 ]+ @
  227.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN2_IRQ_SUB_PRIORITY;; P) P6 W. u; c9 X1 S# i
  228.       NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;8 x& n9 y! h* V& R7 f
  229.       NVIC_Init(&NVIC_InitStructure);9 N" V6 @0 s7 T- v% ?* P
  230.   w+ z" m; h4 [. _
  231.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_RX0_IRQn;5 G9 W. I* f. w- n3 o. P
  232.       NVIC_Init(&NVIC_InitStructure);
    8 m( h& Y" h) I- t
  233.     }
    # T# u9 @1 M; `2 p. d- r  j8 F
  234.   }. k8 q2 @$ J0 D* o! {; a
  235. #endif /* STM32F10X_CL */3 j1 p1 r9 Z( T2 e
  236. }
    & N9 f+ ?# {& q1 ^. @

  237. ' ~3 k# R7 \; B) ]
  238. /**  F! B/ @1 L" Y4 |
  239.   * @brief  CAN unconfigure.
    ) l; P' D& G! w
  240.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    - c0 d! o+ Y' U/ g
  241.   * @return None.+ `1 y% u# @; \6 y) L
  242.   */7 ]2 v- W" @7 r0 E: [
  243. void CAN_Unconfigure(CAN_TypeDef *CANx)
    : U8 T4 T- i, Z- I
  244. {* l6 m) I+ s4 g" n, F
  245.   NVIC_InitTypeDef NVIC_InitStructure = {0};3 k6 J+ A5 r! O$ z. Y4 `

  246. 7 k& @4 t9 h4 L/ f. B' H( z% l
  247.   if(CANx == CAN1)
    5 z+ G: d4 G3 x( r$ \- ^/ Y1 m
  248.   {1 u7 V* k$ U% V) _6 u! }
  249.     if(can1InitFlag == true)9 ^* W" `( g) B& k1 N
  250.     {
    - S9 g- ~( E, p, Q, y$ }9 g) l
  251.       can1InitFlag = false;4 j2 a0 M1 _+ D" H9 U

  252. 5 Q& |9 T# p3 K2 W, D  L/ H( [# X' w
  253. #ifdef STM32F10X_CL
    0 v" ]* Q: @+ s
  254.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_TX_IRQn;( b, R. s0 R! B
  255. #else: v8 W! ^5 q) j9 S. [; X& |* g
  256.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_HP_CAN1_TX_IRQn;
    8 u0 _0 J" {6 w, U9 }1 f
  257. #endif /* STM32F10X_CL */
    0 I7 ?, t8 B9 a# T$ H
  258. # q; z: y3 U7 f
  259.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;- T" c8 E# o. u
  260.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN1_IRQ_SUB_PRIORITY;
    * @$ U9 K: U! p; n4 e
  261.       NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;
    # b  ^: A3 a4 d4 J
  262.       NVIC_Init(&NVIC_InitStructure);( l$ k& ?: L! M  T$ c2 H

  263. ) `9 H7 Z" c  ?4 F+ i  W' [6 a2 ^* U
  264. #ifdef STM32F10X_CL
    0 V! {1 c. i2 S
  265.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_RX0_IRQn;% Y" ~2 m/ w0 u5 ^5 T" e
  266. #else
    , E3 X9 ?7 v5 N, p; c/ C0 C
  267.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_LP_CAN1_RX0_IRQn;$ f5 C8 {; H7 T# R+ Y
  268. #endif /* STM32F10X_CL */
    ' F5 j( _6 d$ p9 T0 l; r
  269. 9 f6 v; o" ?: e1 \3 Z5 _# J
  270.       NVIC_Init(&NVIC_InitStructure);
    * H7 X3 n2 U6 B+ _
  271. ! t4 p3 D+ D6 i  {
  272.       CAN_DeInit(CAN1);7 X" F; ~; i* i( l# w! @) c. J" E

  273. % x" s) C+ g7 w% W* Y- ~
  274. #ifdef STM32F10X_CL" r+ S7 o/ t& m% M
  275.       if(can2InitFlag == false)( T, f% Y+ G8 {( w; ]$ j, w% N/ {& a
  276. #endif /* STM32F10X_CL */
    3 W( `; {  R. D  ~6 d
  277.       {
    ; s3 @% ^: |+ r' U/ _$ k
  278.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);
    4 G& Q/ q8 a& L" e
  279.       }( a( P5 D, N8 I& f2 x4 v
  280. 6 ^; \& _% V8 z. u0 t- `
  281.       can1TransmitFlag = false;! T/ s' b6 O* d: Z

  282. ' m) k+ y2 ~* A( z
  283.       can1TransmitFinishCallback = 0;
    ! ]" {/ y/ q- s# J
  284.       can1ReceiveFinishCallback  = 0;+ q5 t" @  ~5 c: U/ V: J
  285. ( m  Q- V& T/ V- O# _
  286.       RingBuffer_Free(can1TxBuffer);
    # A! G' m9 O4 c' K: ^
  287.       RingBuffer_Free(can1RxBuffer);  g$ I5 B# n# ~" `
  288.     }
    ! X/ c* @" q" e# w+ v
  289.   }+ a3 g) @" Y. S  m3 r+ O' K
  290. # d- g) D9 m# ^3 ]. ~( k7 H/ u
  291. #ifdef STM32F10X_CL  P1 ~" u% t. k! k$ K9 {
  292.   if(CANx == CAN2)1 g& Z: t% r- v( x
  293.   {" T! |( d# B) }, T5 \
  294.     if(can2InitFlag == true)
    , K& t" i1 y( _  {" b0 p+ {' ?
  295.     {4 Z4 E2 ~" T5 f- R7 k2 A/ t' l
  296.       can2InitFlag = false;
    & J7 B( N( V/ y( |$ S9 L

  297. 1 z( A  B: o9 y* M0 R
  298.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_TX_IRQn;5 [; Y) {6 v0 ^: k+ q
  299.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;
      c+ v- H& X$ O
  300.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN2_IRQ_SUB_PRIORITY;
    9 m+ e) W( H/ U1 {1 U4 I( W7 V; F
  301.       NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;
    % }: z) \, G: ^" h
  302.       NVIC_Init(&NVIC_InitStructure);
    " D- q* q) M$ x8 R7 s

  303. & u6 F7 P# l6 B/ |
  304.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_RX0_IRQn;
    4 M. G+ `& `+ @2 a' q3 d9 p$ U( u
  305.       NVIC_Init(&NVIC_InitStructure);
    . w( Q+ V. g; d" w" w
  306. ! E8 h: y* A  `. S7 L
  307.       CAN_DeInit(CAN2);
    " f4 N0 Z4 U3 r( w- F4 N( j# d( z

  308. 2 t/ Z4 ^9 Q  d2 \0 M
  309.       if(can1InitFlag == false)  N! Q, P: V( n% v; w! X+ g0 M
  310.       {2 ~8 M, a# |7 p1 f
  311.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);
    : G9 ]( T# z' ]- }8 ?. B
  312.       }
      y$ L/ ~; z4 r: Y1 `; ^% A4 Z- u
  313. ( R9 c1 @2 H1 y( P# n% u8 W0 x
  314.       RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, DISABLE);& d! @9 ]3 F9 \* D1 I+ a

  315. $ {; m9 U# [, ^- e0 t6 g
  316.       can2TransmitFlag = false;
    4 y6 W" ^1 \! S! p3 O# A' x+ F3 G
  317. 4 n8 }% K4 M3 R. _' g) M
  318.       can2TransmitFinishCallback = 0;2 W2 J: D' y) Z# c  R
  319.       can2ReceiveFinishCallback  = 0;
      o- j" d$ d* P, |4 _$ K

  320. 2 E) U# M1 n/ N/ a1 E- J- b# ^
  321.       RingBuffer_Free(can2TxBuffer);
    8 a5 q: P. n. C+ p8 D  @
  322.       RingBuffer_Free(can2RxBuffer);3 x4 z: i  s* n; n2 ?' z
  323.     }/ ?6 K: I( J1 J2 X' U
  324.   }
    " l  t: Z5 |3 y0 }/ e" }
  325. #endif /* STM32F10X_CL */8 B( y7 I5 O. G) v
  326. }7 {% T$ i  I/ u4 b7 S

  327. ! C. r) U) N4 O1 \- k/ o
  328. /**+ d, w7 W( J7 k+ ]3 b* u% d
  329.   * @brief  CAN set transmit finish callback.
    7 R) I. i  Z6 j7 x
  330.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.3 _) |! ?8 M2 p# R. k6 _  S
  331.   * @param  [in] Callback: Callback.) A1 d! `0 V+ K% o
  332.   * @return None.
    9 c+ F" i) k4 }5 o
  333.   */( a1 w. t0 ]: `- O: h- v! l
  334. void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void)); C9 [0 h; E  [. R! y6 H
  335. {' o3 B, @$ c. b/ j+ L
  336.   if(CANx == CAN1)
    1 l1 n" T0 u* ^/ H; h, B! G
  337.   {
    ! ?; _9 E: _+ H' U" ~) k7 x( [
  338.     if(can1InitFlag == true)
    7 g: b% @. L' S- b
  339.     {
    9 s5 T) ~0 I# J+ b3 s6 a/ X
  340.       can1TransmitFinishCallback = (volatile void (*)(void))Callback;
    + W* q: x# V, k* W- u0 I* q
  341.     }
    . z' z9 S) Q4 r  O9 w' O
  342.   }
    8 P7 x0 F6 X( t. [7 c, e3 B

  343. / u1 v: a* @/ b
  344. #ifdef STM32F10X_CL$ S( a, ?: D# O* c7 i- {
  345.   if(CANx == CAN2)
    9 v4 D+ a6 Q* g
  346.   {
    / q; t* h/ G+ d: P1 g! q
  347.     if(can2InitFlag == true)+ L# d2 h' u; g
  348.     {
    $ c" f# `' K" ]8 T0 n: L* {
  349.       can2TransmitFinishCallback = (volatile void (*)(void))Callback;
    ! S9 G" T& D) ^
  350.     }
    1 Y% W4 p1 d8 s* w: o
  351.   }
    - J% T* \, r6 ~; `2 X! s' q: `
  352. #endif /* STM32F10X_CL */  g2 N; Z2 f; d( r7 y+ [
  353. }
    9 o( J! t$ p, v" S9 Q

  354. $ Z5 s+ v: S# N5 T; G$ O$ j8 i
  355. /**
    4 a; C% H; U* n( K9 S
  356.   * @brief  CAN set receive finish callback.
    7 W$ b5 S( C( J% j# V. |7 K* G
  357.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.9 _: @+ }5 ]3 L& F9 e7 q
  358.   * @param  [in] Callback: Callback.% t9 N8 Y& R9 H1 K
  359.   * @return None.% H' _& @: u8 N( x) ?  J. x
  360.   */
    % _, x6 f  p, [' D/ u* ~
  361. void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void))0 Q. B/ L. O3 X  ^- X' ]
  362. {! E! v! j) F+ D# d  Q3 y
  363.   if(CANx == CAN1)! b: ]) y, X7 y6 |
  364.   {! F% {  A, w1 _, k+ n& n# v% T
  365.     if(can1InitFlag == true)
    ) C2 Z% I  |6 P
  366.     {" U' z- u, Z+ P$ [3 R
  367.       can1ReceiveFinishCallback = (volatile void (*)(void))Callback;
    9 ^; @" D6 G  z$ R5 R5 O' Y
  368.     }
    # m0 L  ]% ~" v9 j
  369.   }5 s; _# U2 Z6 Y5 i
  370. ) @4 H. x6 y8 ^. O
  371. #ifdef STM32F10X_CL) ^) X" a: X6 M3 U) p& W
  372.   if(CANx == CAN2)3 I; N+ E. h$ ?' D( ?/ ^
  373.   {
    & ?+ {3 p' t1 d" f) d$ i8 i
  374.     if(can2InitFlag == true)* W% r3 L5 Y: F% Q- u' T5 ^) z
  375.     {2 U/ b- h+ k. r7 A4 M
  376.       can2ReceiveFinishCallback = (volatile void (*)(void))Callback;) L9 y# q2 K9 b
  377.     }3 w* f: h: X' D  |% H/ f$ X# i2 y
  378.   }
      ~1 g* N7 `( R1 H5 G
  379. #endif /* STM32F10X_CL */  d- J& z5 {% Z' n' z" ]
  380. }* u% f) B, l% H$ {1 B6 |/ k
  381. 1 O1 Q5 r2 W9 [
  382. /**
    & s) u6 J0 _5 B) R1 N
  383.   * @brief  CAN set transmit message.# |( u8 _  [3 p" ^1 |8 I
  384.   * @param  [in] CANx:    Where x can be 1 or 2 to select the CAN peripheral.1 s4 W% @5 T! p% |; @# w
  385.   * @param  [in] Message: The address of the message to be transmit.6 ~" P1 o8 H) [
  386.   * @param  [in] Number:  The number of the message to be transmit.
    6 L. Y: W  O8 U: i0 ]9 z$ a
  387.   * @return The number of message transmit.
    7 C5 V# ~' [2 j- v
  388.   */- n$ i6 b3 b- U( R! y  \
  389. uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number)
    3 Y3 m& P, o1 j0 g& t
  390. {8 o2 \* p& E% U
  391.   if(CANx == CAN1)& K& P; C" a2 K9 n
  392.   {9 Y; P; k- i( o0 a& Z1 s9 Y4 W
  393.     if(can1InitFlag == true)! F8 W  J% x7 H+ ?
  394.     {  W" ]7 i1 e" `6 u
  395.       uint32_t available = RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);) M( ^8 z6 `$ h; N0 k% q/ y

  396. 6 D% I0 v/ z; f1 L) x
  397.       if(available > Number)
    3 u: W8 C+ b: _3 q8 C5 S
  398.       {  Y) e4 ~& E. [0 R$ [, l
  399.         Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);
    ! @7 F  t1 v& F) b2 Y$ C3 G, t
  400.       }( C% _7 `& T7 d4 ]+ Y
  401.       else& \! H# e6 `% j* T
  402.       {8 h4 ]0 m( ~: e+ D& [
  403.         Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);$ E4 W6 P0 f- b+ O: n
  404.       }% T2 q* ?4 `# u- O" K$ s0 k5 g! _
  405.   n- d0 t3 z) J* S7 z! }
  406.       if(Number > 0)
    6 k* Z7 V, G5 e) J- ]: R
  407.       {
    * y! y( B) V4 `5 `9 A
  408.         if(can1TransmitFlag == false)$ ?, b, _( D) b. x& d
  409.         {
    - s4 L4 i3 Y4 v, K/ m; k. d$ y: v
  410.           can1TransmitFlag = true;9 r4 Q$ |( @; i# s
  411. 2 y5 z% }8 v% F7 v" n2 `( t
  412.           CanTxMsg canTxMsg = {0};
    8 l) M7 @2 N! A2 y$ v. o
  413.           RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg));
    ) [( p) k/ i( t% f+ T) s6 E( d
  414.           CAN_Transmit(CAN1, &canTxMsg);
    & [  Y' Z: |+ p; D' n
  415.         }" A. ~! g3 [: ~* j5 L+ _5 X6 _- }& @
  416.       }
    : n) n* z! I' K$ p

  417. 0 e, A$ _' U0 G$ H2 m3 f
  418.       return Number;
    : k8 V0 Y; v9 Z. c  \/ Q+ ~$ i
  419.     }9 c" b3 \! M2 Q8 L% S5 q
  420.   }
    ) W: Z4 W! t6 o$ F2 n2 n& |% O

  421. " c+ l+ t7 P- \! g. D. Z. r8 ~
  422. #ifdef STM32F10X_CL
    : {9 I2 F+ g( B- a' J- _* W
  423.   if(CANx == CAN2)5 W; W8 h# Q. K
  424.   {
    ' P6 a1 O) v4 B# |6 F3 D5 C3 D
  425.     if(can2InitFlag == true)
    & E; G! S% x- Y2 l
  426.     {
    - D7 |/ Q; h2 i! R, i
  427.       uint32_t available = RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);
    . E  g4 y+ U9 C1 z( r8 J2 e
  428. 3 H6 v% n: i; t; i
  429.       if(available > Number)
    8 O4 S0 Y) O& U6 ^$ Z  m- O
  430.       {
    ( s% Y, y. `* h: ~
  431.         Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);
    5 _8 O2 f) A- K, Y7 b) J9 a
  432.       }8 I3 ?+ a# Y0 h& i! v
  433.       else; q7 B# V5 S  X/ c2 j
  434.       {
    : X3 s" x0 D; Z
  435.         Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);$ z! j2 R  ~' u# y
  436.       }/ H* {/ t" n) A" ~

  437. 7 g$ T; o+ t, q6 E
  438.       if(Number > 0)
    ( j+ ]2 ]6 o% y6 u! t% h
  439.       {
    3 D  p6 X0 E1 p
  440.         if(can2TransmitFlag == false)/ h; h1 z+ m1 n2 k
  441.         {6 n0 G1 C4 b9 P7 ]
  442.           can2TransmitFlag = true;
    8 v5 L; r$ g4 Q$ L4 U# O

  443.   n5 k; E$ n+ c' J
  444.           CanTxMsg canTxMsg = {0};6 ?, W- l7 U6 D0 Y% r; a& Y
  445.           RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg));
    5 Q5 p" P% n" B" o  s  p
  446.           CAN_Transmit(CAN2, &canTxMsg);
    % B8 p  I6 f, u2 ~) J& ^+ Y0 J
  447.         }" z0 u0 T) J- e
  448.       }  Z& s2 }! g( X( ~
  449.   o- q5 T4 n* M" {7 e
  450.       return Number;
    8 c6 f- Y+ J1 _9 g
  451.     }
    1 J% x) |: L- b8 ]( {
  452.   }
    2 b# {* m2 V# X
  453. #endif /* STM32F10X_CL */
    5 \2 C0 F( G2 c* c3 U) m

  454. ; ^, Y* M5 [' c" V  W
  455.   return 0;
    9 c/ m: ~% @0 j& P7 Y
  456. }
    / `. ~0 @2 T. N* v
  457. . k" t; Y/ s. v/ h
  458. /**
    $ K) F* h1 a: `, f& y# G
  459.   * @brief  CAN get receive message.4 C) `$ o" W) W+ E. r4 s& T
  460.   * @param  [in] CANx:    Where x can be 1 or 2 to select the CAN peripheral.
    5 R( I+ E" {- T0 L$ a% Y( s* R
  461.   * @param  [in] Message: To store the address of the receive message.( _3 h# a3 L3 Q. B' E5 T' a
  462.   * @param  [in] Number:  To read the number of the received message.
    0 Z; M  _. n( V- }$ q2 [! @
  463.   * @return The number of message obtained.
    $ x0 x0 q, C5 M$ |/ U; G+ F
  464.   */1 P+ J- t. C' s
  465. uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number)
    1 Q+ v* K- ^' l- ^9 \7 r1 X
  466. {; L4 e! {! U6 n/ e1 W+ c
  467.   if(CANx == CAN1)* I1 \* I% _* A# e# P
  468.   {
    * W( K: m. }( k& x9 W; [# {0 e
  469.     if(can1InitFlag == true)
    * {% Q% _; P- g; p3 l/ \
  470.     {4 a0 U) o+ G( m0 l0 f
  471.       return RingBuffer_Out(can1RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);. ?: V, X# S5 @) ]; v
  472.     }
    $ f- v( B+ O1 b4 A2 j
  473.   }1 Z& `4 i0 p8 F
  474. 9 X* ?0 n/ t  \4 E/ V
  475. #ifdef STM32F10X_CL* E' w7 f' d2 G
  476.   if(CANx == CAN2)# A3 Q! z. n4 r$ g0 I  A6 [+ v1 X" I
  477.   {
    1 ~/ A* x2 x" L
  478.     if(can2InitFlag == true)  R2 D1 W) R' ~  ^, {: i
  479.     {
    4 }# t3 V" ~# }+ O6 y! x
  480.       return RingBuffer_Out(can2RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);
    $ U+ @6 u7 S4 P8 ]. S2 q
  481.     }; C6 w1 _# J  o& m7 m
  482.   }& H- m- q( v! R
  483. #endif /* STM32F10X_CL */( v" W; y/ w) |- F# N, }+ B' r

  484. 7 U! `: S0 H2 Z7 }* Q, Y
  485.   return 0;
    2 x$ P" R& X5 L6 D; S5 w
  486. }1 @/ O# z! [; z6 O6 O0 m
  487. . g: P+ ~. ]2 f& ?
  488. /**
    3 c' P+ \7 n6 c- J- J
  489.   * @brief  Get the size of the CAN transmit buffer used.# T6 k8 T" M3 S! b& M. Q7 @
  490.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.! q/ n! d, o$ N7 F/ @, z2 X& j
  491.   * @return Used the size of the transmit buffer.
      }1 f, Z( G& Q, `& s
  492.   */4 P( I7 a* c2 _" d% M
  493. uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx)
    ( B; f' a3 O4 d, Z, x0 J9 |' ~: p, v  O
  494. {
    7 Q! O8 L* Y( H' r
  495.   if(CANx == CAN1)
    / H& _+ Z" y# m6 z; V% G: a$ G) t
  496.   {; ?- Y3 M& R6 p7 K' l+ x
  497.     if(can1InitFlag == true)# t' c, B: }; X; [
  498.     {
    . e! b1 x7 |: I/ x7 C5 H
  499.       return RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg);
    0 y1 c# y" \& l) K1 a: _; U9 _2 E
  500.     }$ M5 Z4 P0 S. f/ R
  501.   }
    9 S, @1 K; C* T& v
  502. $ x* w. T* W  j# o, _9 {
  503. #ifdef STM32F10X_CL9 T) q; S& u7 P% \3 u5 T
  504.   if(CANx == CAN2)2 t3 _( x" S" u1 O# j! x2 }+ q( S( a
  505.   {* w# Y0 n- [# T, e
  506.     if(can2InitFlag == true)9 y; d! K5 V: c+ U2 k8 Y( X
  507.     {
    5 M' `0 G( y1 {- l0 D9 ]
  508.       return RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg);3 U- C) _: ~( H7 J' h7 L
  509.     }
    ! |* g  H# z2 x) T' }
  510.   }; k' }5 S  @% V; T. ^( H3 a
  511. #endif /* STM32F10X_CL */
    ; \6 a' ^* B/ k+ ?( [/ w
  512. 4 W1 D* y) z6 A
  513.   return 0;2 |. k+ ^. h* o+ V" n% {5 x4 H4 h
  514. }, R! q( G, {% P' U  S- O
  515. 9 o/ r. B) i1 E# r' U/ C; g
  516. /**: S8 _' Q" G( }1 x( K5 D
  517.   * @brief  Get the size of the CAN receive buffer used.
    # C0 A" e. {3 m
  518.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.  ?7 h1 @) s  h  M! ]
  519.   * @return Used the size of the receive buffer.
    : K1 ~, G; U  V2 N+ j! w
  520.   */
    # F! s& g) }  A1 W2 t
  521. uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx)
    6 O1 C, [' ~; j7 G! z
  522. {3 u; R+ x) o) y% u  M
  523.   if(CANx == CAN1)
    5 \+ `9 n! t) P6 o: q7 p% c0 p1 @& p
  524.   {; H# p, |- F6 N" r0 ^
  525.     if(can1InitFlag == true)* r# M( ?& z* r1 o3 G4 @0 n
  526.     {8 k/ A/ l# S: G5 S/ R' M; E
  527.       return RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg);& e6 A8 N- C5 e2 N8 Q( ]  w
  528.     }) c8 u/ |8 ?, d. ~: A/ g
  529.   }
    - v' r3 v. A5 n; i

  530. # U' U+ _& g  s3 A% m( a+ a
  531. #ifdef STM32F10X_CL. t3 b$ r" H& e- T/ v' D1 r0 h/ i2 w
  532.   if(CANx == CAN2)
    ; {9 H* y" X$ v1 z' O/ F
  533.   {) o* J6 x% n1 i4 O; m3 o' u
  534.     if(can2InitFlag == true)
    + d1 O: F9 i+ Y  Z% a4 S1 g
  535.     {
    ' E! ]) e+ U9 u- o# w; P
  536.       return RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg);! A# `* ]7 }2 d9 R
  537.     }: Z$ i$ Z( Y& x! N# C% g6 A4 I
  538.   }
    2 p# y, p' `  S3 B, Q
  539. #endif /* STM32F10X_CL */6 G+ H5 T+ g2 m; V  u% ~
  540. 6 c3 R# R8 E% I& z/ U( O) {
  541.   return 0;+ G' A% f) l  C& [7 D/ I2 X  Y
  542. }
    + ]6 b  X" ~4 C$ g- g; @

  543. 2 D" k% F0 R- v0 w6 G4 \3 X2 ^
  544. /**
    5 P8 J4 ?& w/ }' h
  545.   * @brief  Get the size of the CAN transmit buffer unused.2 J2 A5 G2 D3 D/ X3 R* C. {
  546.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.$ S$ J  O- m1 [- S
  547.   * @return Unused the size of the transmit buffer.  Z  d: V. f) T6 D9 G+ X9 S! x
  548.   */
    7 h7 n1 {4 S7 e' _( e3 ]1 P
  549. uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx)1 ]: W' o& I4 {3 i9 o/ E% y2 q9 O
  550. {  N' a4 J0 b% o4 D2 O& c# P  `
  551.   if(CANx == CAN1)
    " a+ I2 A# u' I. N+ ^
  552.   {
    ! z) Z9 b" L' B* @
  553.     if(can1InitFlag == true)/ Q1 W& x3 D% b- P: T
  554.     {
    " S/ y7 Z3 @" I2 o) z
  555.       return RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);0 k& V9 M- t7 @; J/ ~
  556.     }
    1 q+ X* Q0 q- L5 O, P
  557.   }
    . e- m! Q% Q4 E$ T# N
  558. 8 d5 l8 i1 ~4 `  _2 q
  559. #ifdef STM32F10X_CL- J, V9 P) L0 p0 [; G* f# Z; W
  560.   if(CANx == CAN2)1 P2 U) H* u1 l2 |
  561.   {9 ]- ^0 u6 a& e
  562.     if(can2InitFlag == true)
    3 A" D6 l2 }0 _! k8 @
  563.     {
    " v1 \" O' h' }1 Y+ D; c
  564.       return RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);
    1 p( ]1 N9 p+ b1 E/ C
  565.     }& E8 `$ U8 c! i; F! r
  566.   }
    " X3 k: Y2 U5 K: Z" _4 g* i
  567. #endif /* STM32F10X_CL */" v" e: S, n1 @" U; W" L' q, q

  568. 0 h2 m! B* n8 h! I4 D
  569.   return 0;% N1 i) F. @+ }: y1 f
  570. }- p$ B+ p9 R3 ^" f
  571. 1 P7 ?2 |0 `. |
  572. /**7 C4 _6 L9 ]0 l: F# ]
  573.   * @brief  Get the size of the CAN receive buffer unused.
    4 I) q! U! E) X& q8 ^% w# b
  574.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.; J- C  t5 i' N6 u/ w
  575.   * @return Unused the size of the receive buffer.
    3 g, p: X+ o3 T) X. r" j+ [% E
  576.   */) g- R& j5 E  p
  577. uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx)
    8 r5 g) w9 P8 L8 [4 R) D% {3 F0 p  L1 b* e
  578. {
    ! D: k; D7 R' G. ]8 A
  579.   if(CANx == CAN1)5 q: I9 d% f' k9 {8 T" l
  580.   {
    1 F/ n3 a) i* T, Q
  581.     if(can1InitFlag == true); g4 \( z& d" K
  582.     {
    0 Q( j* m5 M: Y# k' O+ ]0 Y
  583.       return RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg);- ~* j" |' r  k5 v$ Z3 t
  584.     }
    0 Z0 Z$ w# L( J) Y+ ~: F) G
  585.   }* @) |; u$ }0 u/ R( m  ?
  586. % G/ P; {* U! s; @0 G8 h5 j6 V
  587. #ifdef STM32F10X_CL
    - |. J# A7 M0 W. u7 [& W. B
  588.   if(CANx == CAN2)0 o! R. @1 i& b- p5 t
  589.   {+ L3 @+ r4 j% i: P9 K5 p9 Y
  590.     if(can2InitFlag == true)
    3 }1 y: e& w# c, G$ P* b2 Z* _
  591.     {
    / }; c+ a& g& \9 ?+ r# E
  592.       return RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg);3 J) w8 O! L9 y3 I+ _
  593.     }
    & N( g+ c% ?; C  X# P
  594.   }
    2 T9 J3 |5 V& t
  595. #endif /* STM32F10X_CL */* h# c1 n" Y4 k' Q
  596. # U- i( e% }% _: a% q
  597.   return 0;. \1 o0 u0 R: K2 w$ v: }
  598. }2 a* z& k9 q* T9 s
  599. 0 A/ p  m( {# g; Q0 F  j. R
  600. /**
    - b$ c- |: f; u. j
  601.   * @brief  Is the CAN transmit buffer empty?, @  G5 |! u& |% s$ g
  602.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    7 e% F5 s0 z8 P, z! D5 \, e
  603.   * @retval true:      The transmit buffer is empty.( u4 }' F% |9 z( y5 C
  604.   * @retval false:     The transmit buffer is not empty.. b% j# ~% Q' ~6 R
  605.   */9 P: G, M% T8 e, ]2 F  {! S! [; ]
  606. bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx)' K0 p% s, ]6 k# [* |) T& M: x
  607. {2 `  ]. b. p+ O
  608.   if(CANx == CAN1)
    * j* `6 R; e: a! S+ z4 F1 e/ ~
  609.   {
    $ s8 u8 n2 a3 ^; U8 [
  610.     if(can1InitFlag == true)
    # ^# e( P2 l5 ]" t5 s) ^# d- _8 v
  611.     {1 r% \+ K' I- ^) T
  612.       return !(RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg));7 u$ m# e) l# Z) q
  613.     }* [5 R9 X/ |& [6 H. d2 V9 S
  614.   }
    3 {1 K3 K6 p9 q+ L0 x$ ?; d

  615.   E4 S0 V: F& M+ y, i) ~
  616. #ifdef STM32F10X_CL2 M1 q* m- m/ a# G& X4 B
  617.   if(CANx == CAN2)
    4 s: L  a* s& M2 k
  618.   {3 a* W9 E- J% S; g* ^8 j% \, i
  619.     if(can2InitFlag == true)
      y# k0 ^+ Y8 \" O: S! f% }" V- U
  620.     {
    - N- \0 m8 {1 ?; B% Q
  621.       return !(RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg));8 b" q+ r, _2 X7 L. H1 D; ]
  622.     }
    ( Y- J  I# p- g. T+ O% f& r
  623.   }, h  l$ z) T% u# {& p3 |
  624. #endif /* STM32F10X_CL */
    : e& H. p6 d- ~6 B$ I

  625. 8 [! y4 R- X, p- K5 o
  626.   return false;
    0 S- t6 D2 g2 k3 o7 o
  627. }
    5 }7 E5 l2 k: U: L- p  b, q6 J

  628. 7 U; ~9 ]8 r. n4 H& T
  629. /**
    0 K9 e% ~0 ?$ w* `2 u& d. P, k
  630.   * @brief  Is the CAN receive buffer empty?7 z+ z# u4 r. c9 i( A$ `& B
  631.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    * g' d. s% H3 ~
  632.   * @retval true:      The receive buffer is empty.
    # Z  B# T  g' P7 `% S. p0 j' H
  633.   * @retval false:     The receive buffer is not empty.
    ( x9 o7 g0 P# k: c4 l
  634.   */
    1 [5 V- D7 {# t' k" @4 ]/ }, [# F
  635. bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx)' ^# ^3 `: U. t3 B0 i
  636. {$ u! \) t) B( X5 N, I
  637.   if(CANx == CAN1)/ h2 p7 t8 n" H3 r8 C: t- D6 V3 i+ I
  638.   {: _. n, M& J  Z( t
  639.     if(can1InitFlag == true)
    5 r' O/ G* b; n. O* t
  640.     {
    9 t/ p+ m8 o+ S* H% Z2 l
  641.       return !(RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg));  M: P5 e5 M; ^+ F% \
  642.     }
    6 |- k9 h0 b3 T& W% }$ {
  643.   }) v( r9 b/ z" d: [
  644. ; K- ?3 \9 ~& g$ B
  645. #ifdef STM32F10X_CL2 z7 B! }5 G+ E" G: C( \
  646.   if(CANx == CAN2)
    - F3 p) u: S# H! @7 W
  647.   {( s4 m* n4 Y/ G! X+ T
  648.     if(can2InitFlag == true)
    1 a. h+ a0 R0 E7 }
  649.     {" A9 F3 b- G6 @2 E" _
  650.       return !(RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg));2 t8 \3 `: S' o8 g! B2 `/ k
  651.     }% z8 Q1 ~" ^% P; {  J
  652.   }: O. U( i) Z6 J& L- p( v
  653. #endif /* STM32F10X_CL */- ?. P3 q" f  ?4 G* N  z  g
  654. ( g9 ?0 A3 q# r
  655.   return false;
    , ^2 |' r: J6 `. G3 O" I% M$ u0 ~
  656. }
    0 j1 g( e, r* d3 p$ m+ H

  657. ' A- Y! d* O7 P2 y
  658. /**
    2 m8 O- t6 ?  {2 X% Z" |
  659.   * @brief  Is the CAN transmit buffer full?1 b0 b8 W( X- k6 ]  A+ Z& W# y
  660.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.2 G# R$ j" n5 ?& t  S$ y8 M- j
  661.   * @retval true:      The transmit buffer is full.
    * ^7 C5 X' R% O. @8 k  u& O6 s
  662.   * @retval false:     The transmit buffer is not full.9 o7 ?" e4 v, \7 E  l* t
  663.   */
    2 I! U+ s3 _$ t% v  [
  664. bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx)
    0 S3 t3 I. x. N  b0 n
  665. {, O6 m7 c) G/ _/ D/ w/ z
  666.   if(CANx == CAN1)
    5 |- v5 ?* [/ f
  667.   {- }# t" p; q1 W! H/ \) }) e- [
  668.     if(can1InitFlag == true)' \7 M1 D8 D4 f3 z
  669.     {$ M( B: N1 ~9 |' S
  670.       return !(RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg));  s, l9 k0 e. l# {2 R- T* _" ?  T6 y
  671.     }+ L2 U! _* A+ u' @' u* O. Z
  672.   }
    5 g1 t( A3 G9 T4 Y

  673. - \, k# O) L: _
  674. #ifdef STM32F10X_CL
    ) I+ |1 {7 G5 u  S$ e
  675.   if(CANx == CAN2), x) K) A$ y# F' s% c
  676.   {
    6 a- Y5 p! \1 M& j5 z) f% v% L
  677.     if(can2InitFlag == true)0 W$ z, R! O' R; |* c9 e
  678.     {
    9 d+ s/ i7 c# s- j) D
  679.       return !(RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg));6 T$ W* D6 y* |  ~' Z
  680.     }
    . i8 X5 P6 P. a0 t- E
  681.   }
    % h/ v5 I$ S1 ]# c8 _
  682. #endif /* STM32F10X_CL */& k5 V: I. C4 d" A2 e& d8 d- j

  683. 4 z3 W3 W* m3 u/ c3 h7 \
  684.   return false;, D# P/ X1 w( R, ?5 a( e
  685. }
    - C% A! x5 M- G% ~' U

  686. 3 N6 s8 p  I4 E' V' s( Y. x9 B; _
  687. /**% n: k" I) D: r# C8 L- Q
  688.   * @brief  Is the CAN receive buffer full?
    2 M4 \- A' }) y5 N4 Y; E* a5 ?6 `& N4 E
  689.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.. X: b3 p( |6 {( _5 K
  690.   * @retval true:      The receive buffer is full.
    . d# o& a  `$ D  j! F2 {0 `( c5 y
  691.   * @retval false:     The receive buffer is not full.8 n9 h/ E8 E  f
  692.   */' H8 O+ C" c4 k9 i7 u
  693. bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx). {+ H! j0 o# P- }
  694. {! Y& w0 j( \- |0 {. }
  695.   if(CANx == CAN1)
    ; `. e! y; }7 z6 r9 B- P
  696.   {
    9 c* @9 w. ^+ W1 g! K$ T7 T$ t
  697.     if(can1InitFlag == true)* Q7 q! [! C! w- S& ^
  698.     {  O% }6 u8 L1 m% t, l
  699.       return !(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg));! M2 Y  N5 h6 h  i/ E3 Q& {
  700.     }9 x4 N0 W2 B. Q* [9 C
  701.   }
      o3 t# G) R+ }, a" c) ~
  702. + _5 V7 r  i7 ~4 q& N4 O
  703. #ifdef STM32F10X_CL
    . t3 e6 L1 `9 e' O3 _$ Y3 J
  704.   if(CANx == CAN2)
    % f8 A4 ^3 R. a4 G+ C8 Q4 A
  705.   {) q  E: o' \( S- G) h
  706.     if(can2InitFlag == true)
    0 y4 F( H4 e9 ]2 o& Q
  707.     {
    3 R: B: O# d1 F
  708.       return !(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg));
    + k* }/ V0 f' {' p% z4 u# F. {0 }
  709.     }
    9 g! c5 a- q/ t& J9 k
  710.   }* l. c8 B1 ^1 T8 o' l( m& F; b$ ]) y
  711. #endif /* STM32F10X_CL */9 K, h+ D, c2 O0 h' J
  712. + M; w6 B; s* d9 M+ L* `7 J
  713.   return false;
    / g) u# h4 n' r6 i
  714. }& y# i, @8 t" g

  715. 7 \; h* B+ X9 u  x% \# N! A
  716. /**# h/ K. i/ e' M. J* A
  717.   * @brief  Clear the CAN transmit buffer.  H# Y3 C: E  o
  718.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.8 y% m) {4 d4 m' X2 i
  719.   * @return None.0 ]* }* B7 I6 _+ N; I
  720.   */6 h0 D( T3 G0 G" g4 p4 [3 J
  721. void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx)
    ' a  J% X$ f$ `+ m" _
  722. {
    , O, }$ |2 ]) P2 ~  s1 r2 p
  723.   if(CANx == CAN1)
    7 u' y5 P! q+ |5 o
  724.   {
    - @, c1 \' _6 T- Z% O$ e6 Z
  725.     if(can1InitFlag == true)
    4 A0 B  T! I4 W
  726.     {. |/ Q; G0 \' U) \/ J/ _
  727.       RingBuffer_Reset(can1TxBuffer);
    : y; l- ]4 ?8 u. R8 k
  728.     }0 e, ?5 y- P5 U: ?- W2 v
  729.   }
    9 {7 L3 n& x" {- h
  730. & G8 x( B: L7 S
  731. #ifdef STM32F10X_CL
    4 w4 ]# S; u% w* R- f2 p
  732.   if(CANx == CAN2)) K6 M% P- Y0 B" U2 D1 @1 }! a7 |
  733.   {! \! r& J6 A) Y+ A
  734.     if(can2InitFlag == true)- O4 [/ H0 ^; h* y% j% ^9 [
  735.     {! P6 R8 a, q! b# b/ m; y
  736.       RingBuffer_Reset(can2TxBuffer);
    2 l, A. e1 y) {7 m$ p
  737.     }
    * N$ o- P9 J6 M% H$ b8 I
  738.   }: Z3 L! b& E' y# p
  739. #endif /* STM32F10X_CL */; A& v5 A$ V9 l; i% y! w8 f  n& l
  740. }- N3 z% _) E% s8 u% B5 f3 K

  741. - r5 T7 X0 j. l/ P  |" r+ {
  742. /**
    : {0 w9 v' S, D( o+ N% W
  743.   * @brief  Clear the CAN receive buffer.8 g. w: Q3 k  o/ q3 y) g2 C  i
  744.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    9 L8 c6 F3 W. [; n" Q) m! E, l/ y
  745.   * @return None.5 ]' r1 q) l% i" M2 h$ C
  746.   */. z* }8 \' `; |& l
  747. void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx)# y6 W+ `. O# E" }! P3 K' Q& ~
  748. {
    4 C( g9 Y2 D* T2 m+ p
  749.   if(CANx == CAN1)# x! ^* \. T, c0 F- p% p1 o
  750.   {% z4 d: [7 V3 C; w6 d
  751.     if(can1InitFlag == true)" R5 ^  @! l! e1 i* s% @7 o
  752.     {: Y6 s  x1 z( Y3 X/ t9 J
  753.       RingBuffer_Reset(can1RxBuffer);
    % ?5 d, N- n$ R( L  F& r* e
  754.     }+ A: p% O& ]! z5 y5 Q& @9 g- [7 G% ?
  755.   }3 E: r6 {2 _( ^' B/ D5 a( x

  756. # @# p& [/ n( n& P7 e4 q" K5 t8 S
  757. #ifdef STM32F10X_CL
    ! ~' I; I% z4 |
  758.   if(CANx == CAN2)
    - M& S1 I% N4 q* Q( o7 N
  759.   {- f% |) q+ b, v# z  Q
  760.     if(can2InitFlag == true)5 x$ ?" C. ~- e5 t8 N1 p  w" v/ }& I
  761.     {
    ) g% ~7 f+ ?# z
  762.       RingBuffer_Reset(can2RxBuffer);% T3 I0 J* `$ N; _, K! X" L; g
  763.     }& J0 i3 b# J4 j+ X! R3 }
  764.   }8 U. e0 @! r/ A( p* I  O1 S
  765. #endif /* STM32F10X_CL */
    % [# W  j# \5 t
  766. }5 {3 V) \4 [9 m% ^# P! ~  P
  767. ' Q! B6 d2 m" a# w3 f9 ?0 N
  768. /**
    . }& d8 O; T8 b' y- F: A
  769.   * @brief  Is the CAN transmit a message?
    6 `" Y4 C! y: w) b# u* f9 v7 b
  770.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.$ V6 O, s% g$ f7 M' L1 w
  771.   * @retval true:      Is transmit a message.; {( f: \  }9 ~& w
  772.   * @retval false:     Not transmit a message.
    : ?" Z: Q! R) S) E
  773.   */
    0 w. i( o. w) {3 S$ V
  774. bool CAN_IsTransmitMessage(CAN_TypeDef *CANx)
    . w- H4 J9 t0 h7 V" N/ E
  775. {
    + ?! g+ r5 @( k
  776.   if(CANx == CAN1)0 s7 n) |2 [& _5 \
  777.   {
    + Z+ \4 \! l) I; r7 s
  778.     if(can1InitFlag == true)
    ! t$ `/ ^/ N+ S) {" b$ j/ G# Q
  779.     {
    * t  ~! @; O3 Y5 `  i# t$ [1 ~9 X; f
  780.       return can1TransmitFlag;
    : F- T  h' z2 J, O* m# p
  781.     }' q# ^5 J. U5 o" ?7 a1 v) g
  782.   }
    * E8 q/ D/ [2 c5 j+ S; X4 J
  783. ' f& [2 a6 \. w
  784. #ifdef STM32F10X_CL% P/ Z$ ^% P2 t
  785.   if(CANx == CAN2)
    8 _7 r3 A# d8 h+ Z  o3 N: z  j
  786.   {
    8 A& s, ^* K& K+ H7 S
  787.     if(can2InitFlag == true)4 w- F2 ]( [0 B6 G4 L
  788.     {
    ) Q5 c% z8 \$ |& t! p- n
  789.       return can2TransmitFlag;& }$ R' m1 U+ k: r4 o
  790.     }
    9 Z( C) E- \. }7 s$ I9 K
  791.   }
    % F% g! s8 u) g, K  s; T: ^7 D  q
  792. #endif /* STM32F10X_CL */
    - X1 u) S$ O* g0 R) S
  793. 4 W$ D  {  D) k; G
  794.   return false;- m/ r: f5 [# m! L
  795. }- _9 g5 q: C/ e# ]6 @
  796. # d8 e" k3 Q9 z3 `+ z, k8 j2 h+ S$ `
  797. /**$ a2 p2 l0 W) R: M1 ]) k
  798.   * @brief  This function handles CAN1 TX Handler.& I1 J2 L( J& X. O2 R" s
  799.   * @param  None.5 c  f; v! `' M' e, u2 [7 l
  800.   * @return None.' Z+ j6 |* j0 q! N3 j4 U& T. v
  801.   */' N& r' J$ M# Q: P
  802. #ifdef STM32F10X_CL
    / ^! \* t' b! B, z: p1 {' z. W
  803. void CAN1_TX_IRQHandler(void)
    % \1 j) J& O' k5 s
  804. #else
    8 b& d- X: O- [4 G) y: {
  805. void USB_HP_CAN1_TX_IRQHandler(void)
    8 T' x  s) l2 l: _+ h- M5 B& }
  806. #endif /* STM32F10X_CL */
    + a7 }, n, G4 `/ l* A
  807. {
    " ~5 j9 T" k+ n4 A
  808.   if(CAN_GetITStatus(CAN1, CAN_IT_TME) != RESET)  {* E2 W$ `, {* H
  809.   {  F% V2 b" U; V2 m) [9 X+ |% s
  810.     CAN_ClearITPendingBit(CAN1, CAN_IT_TME);
    7 Z0 u. Q8 L: v
  811. 3 r8 {6 }, c2 R  V) F* N3 a
  812.     CanTxMsg canTxMsg = {0};% v1 r: A! t! y/ `
  813.     uint8_t  number   = RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);
      k8 X4 h% F% n. E

  814. ! e" S: t; F/ l+ _! [! `" g1 M. r
  815.     if(number > 0)
    + U4 V7 T! M1 [1 V: h
  816.     {
    / k! @; P( Z" {/ K
  817.       CAN_Transmit(CAN1, &canTxMsg);9 V/ T8 O( `  j2 t& s
  818.     }7 s( X; l: W6 D7 s( B/ p) K! T
  819.     else
    $ p8 k/ ?) Q3 y% _: D
  820.     {( t& T5 @/ j- V; `* q- _1 p; \, n, P/ P) k
  821.       can1TransmitFlag = false;
    0 A( v: B$ H9 P3 L. r% P  X

  822. : n% \9 w6 ^: o
  823.       if(can1TransmitFinishCallback != 0)
    + t" q' M- A# T! O& t; y
  824.       {* A; K* p' b, q) o* n; _
  825.         can1TransmitFinishCallback();
    9 ]8 Y  \* ^8 ~  Q
  826.       }2 s. ~8 t. k6 U7 |
  827.     }
    : `% s: r3 h, e- O5 B1 |
  828.   }
    , E; b& X: f$ Y
  829. }
    * a& h* d$ B+ b- I' H( D

  830. / T4 i  U$ N2 k# W  q" l* Q1 ^1 x( x
  831. /**& @* _" F+ f1 t- Q' ?: r" t
  832.   * @brief  This function handles CAN1 RX0 Handler.
    ( l0 |: {6 `8 z! N+ B1 a8 m
  833.   * @param  None.  E" f  s6 Y/ J$ _1 s0 n! G
  834.   * @return None.  v2 Q) K3 W1 h4 J1 k2 O
  835.   */; s* P3 N( ~$ y2 H( E6 L$ U
  836. #ifdef STM32F10X_CL2 \, O% \3 A( K' e4 {( C
  837. void CAN1_RX0_IRQHandler(void). i! j8 {+ G8 T7 i8 m" S
  838. #else
    . T7 G7 p8 j; m
  839. void USB_LP_CAN1_RX0_IRQHandler(void)5 W9 V2 C+ _8 T
  840. #endif /* STM32F10X_CL */& T. m! L4 w5 y3 x. T4 |! R  t
  841. {
    8 B; c( \, x/ u. [
  842.   if(CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET)2 Q7 T6 V$ p# O. T* o* i8 L
  843.   {4 x- _4 q0 R# B) {. U
  844.     CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0);
    2 Q% c5 t9 j/ B& D0 x
  845. ; z7 g6 k. s8 J! ~; s; n
  846.     CanRxMsg canRxMsg = {0};
    + `* W7 k6 i. A  U& d) o) K  H& ~  _
  847.     CAN_Receive(CAN1, CAN_FIFO0, &canRxMsg);. G* D+ R4 ]" a7 m; k6 M% {

  848. 8 g: i; ]' w% l7 o1 G  p& z! L) z# ?
  849.     if(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg) > 0)
    . ^/ c5 h; S- I7 A
  850.     {  m4 B3 u# N- l+ U) j; L# `8 g0 }
  851.       RingBuffer_In(can1RxBuffer, &canRxMsg, sizeof(canRxMsg));
    ' F3 ~4 _5 M0 \, ?0 N# v7 C# s
  852.     }2 K) _. G3 @5 _1 H- D! n" S
  853. 2 |5 m4 Y5 y$ C& Y9 z3 ?- |
  854.     if(can1ReceiveFinishCallback != 0)( i& L" P( U2 n; ^7 J
  855.     {
    ( A4 Q" U' a$ S: ~
  856.       can1ReceiveFinishCallback();
    2 P: o; h( B9 c6 i
  857.     }
    & `- C; g# ?& o1 c& w
  858.   }
    8 j' H# ^" q) @/ `; a7 P2 Z0 r
  859. }
    1 Q8 w# \7 h4 o* v* }

  860. 7 V8 V% B& ?8 N: h8 C) L6 I
  861. #ifdef STM32F10X_CL* a, b0 ^3 E, a: Q
  862. /**
    , {7 Y8 c4 ^+ e* w8 n
  863.   * @brief  This function handles CAN2 TX Handler.+ d7 X1 T) G! g
  864.   * @param  None.
    % e$ o+ d& w. s& v
  865.   * @return None.2 r7 W4 x! P! r$ P
  866.   */
    2 _  [3 q( R. V+ `* C! g1 h& |
  867. void CAN2_TX_IRQHandler(void)
    : C. T3 \% `' i
  868. {% ~. F( Q- B/ W2 Q0 O# _4 x! C
  869.   if(CAN_GetITStatus(CAN2, CAN_IT_TME) != RESET)$ D' @( r( f2 B6 M
  870.   {( w! q5 f0 h2 u
  871.     CAN_ClearITPendingBit(CAN2, CAN_IT_TME);
    ; O/ \5 b. Q7 B& w4 s3 R

  872. + l& M6 s+ y* s) O6 X& W+ \9 r
  873.     CanTxMsg canTxMsg = {0};0 r; ~( ]4 @+ \8 e/ W: \
  874.     uint8_t  number   = RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);) F7 T/ u( P6 G0 |0 I0 k: a* v' \6 I

  875. " a5 U4 Z- u$ a" w( D  j5 q
  876.     if(number > 0)
    & D9 h6 ^( i& m# x' J/ z3 P
  877.     {- v! T! a/ {% h1 w  g* r
  878.       CAN_Transmit(CAN2, &canTxMsg);! i& S' a7 k/ x+ P9 H
  879.     }  z) ~$ J( G) r( i" W3 E
  880.     else
    ) W6 o$ ]7 b; x6 b- n( _
  881.     {
    : }( i3 y2 A9 v- E0 e+ h( E
  882.       can2TransmitFlag = false;
    7 \3 O9 E9 g: ~: [9 E1 H# Y- ~

  883. 0 U1 \/ R# A2 A$ G( t
  884.       if(can2TransmitFinishCallback != 0)4 \/ _1 q6 J- M0 \+ G
  885.       {: Y7 T2 T. ^$ p' T" l1 Y+ c
  886.         can2TransmitFinishCallback();
    8 O5 s# B/ v. @: ^+ {9 h
  887.       }
    8 [, f  O  P* o5 Z, V
  888.     }0 M% k7 B& D6 S6 b* N. p$ J
  889.   }
    9 v% z" Y1 t# o" h6 S8 k' k4 [) K' ^
  890. }: s5 E1 [. g! l( s8 l# V+ ]7 q+ {
  891. / {" ]! G  _& Y) @
  892. /**
      d7 p6 i" X3 i! z
  893.   * @brief  This function handles CAN2 RX0 Handler.) K) v" q- R' r* m1 D
  894.   * @param  None.- b$ i5 c5 q9 ^" B
  895.   * @return None.
    * A; m- n9 [# B) _. q
  896.   */2 a- m& R8 c9 x! V* }
  897. void CAN2_RX0_IRQHandler(void)1 B  L" X% n* K  n0 m
  898. {
    * M9 [& l2 j2 A/ Y/ s7 {
  899.   if(CAN_GetITStatus(CAN2, CAN_IT_FMP0) != RESET)
    * C3 b( q$ `* _* j
  900.   {' x  s( ~, k/ b5 F! d- L3 U
  901.     CAN_ClearITPendingBit(CAN2, CAN_IT_FMP0);
    . K# F; @" g) f% ]/ S

  902. / y3 [$ ?: ]- h! s3 X
  903.     CanRxMsg canRxMsg = {0};& }6 A8 _" F! t1 }2 [+ c/ Q
  904.     CAN_Receive(CAN2, CAN_FIFO0, &canRxMsg);9 Q- R# i' V9 d( o

  905. ; K" f2 t( A4 `8 I! h8 U
  906.     if(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg) > 0)6 N' i2 U! ]* g% `3 @
  907.     {
    1 a' t. j9 n6 _$ m, [7 y
  908.       RingBuffer_In(can2RxBuffer, &canRxMsg, sizeof(canRxMsg));
    & R. O8 S+ J( h# k. Z8 T; z% ?- V
  909.     }) x2 p3 I. e* _7 \8 M8 y# c
  910. : k, R2 O( @" d8 L, F2 m9 r! U
  911.     if(can2ReceiveFinishCallback != 0)
    # G) b' G. w7 h2 g, P0 o& k
  912.     {5 \& H; k( e5 f. D1 n0 B6 I8 d' `7 _
  913.       can2ReceiveFinishCallback();( I  q* H, v2 z! t/ D
  914.     }5 `* A# ]  i/ b8 R
  915.   }+ d/ K+ I2 e& m" M2 a  E
  916. }
    1 W" U8 {0 Y# Y' d1 Z. T2 K4 b. B3 @
  917. #endif /* STM32F10X_CL */1 k; o& {* b: p4 _( Z% b: d, N
复制代码
; D9 J0 N4 J* o/ m, g, U0 J
, g  L4 E" b8 X0 Q
main.h 文件- s$ E- C; j" Y. n" ~
  1. /**: B9 C: l' f/ \0 s5 D5 }3 L
  2.   ******************************************************************************
    ! b! \! n! P- c4 F
  3.   * @file    main.h! h9 u3 `, d1 J9 [  s8 p2 u
  4.   * @author  XinLi
    ; z# J- N2 W1 ?% I# z+ v
  5.   * @version v1.0, k8 |1 w7 }9 \+ f! I0 R9 ~; m. L, v
  6.   * @date    24-June-20180 f, ?5 O. p4 x8 G% |5 G, r
  7.   * @brief   Header file for main.c module.
    ( `/ ?8 s) D& v& J+ r
  8.   ******************************************************************************& p7 I1 q( M6 O
  9.   * @attention9 Y* P0 p  q$ ~! [# W  c/ E
  10.   *) M- \# q" j2 K9 `" G
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>* r8 a- Z4 J: L( N2 R4 n
  12.   *
    8 [3 b( C* }9 h: X' H' H/ v2 m
  13.   * This program is free software: you can redistribute it and/or modify
    " z, B6 s( t+ O" u& U6 q$ ]
  14.   * it under the terms of the GNU General Public License as published by! a3 U1 i; y7 B# F6 w; I
  15.   * the Free Software Foundation, either version 3 of the License, or4 Y# D9 }) x' Z( \+ ?- R
  16.   * (at your option) any later version., }& n0 q' T. o, Z# p% C
  17.   *
    9 J; v9 J, A& P0 D+ }
  18.   * This program is distributed in the hope that it will be useful,$ Q$ N. I' w$ r+ a) G
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    # L8 `# o4 f3 v3 t' P
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the# b. F' m  f9 p# Z
  21.   * GNU General Public License for more details.7 \" K7 t  n( ^4 M0 m2 y
  22.   *
    0 n* H. r; i6 \- Z3 R# j) H& K- F
  23.   * You should have received a copy of the GNU General Public License5 C' z, ^+ f# ?  ^3 K2 B: w; t5 \
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    % O1 {6 j; m' W0 O+ d
  25.   *
    % @0 n6 b. t0 g- {* C
  26.   ******************************************************************************
    5 B5 f0 Z) N2 v4 h. G1 K4 h) k
  27.   */
    , S. ~( n" I+ [9 Y- Y

  28. / F' }' M9 F, e
  29. #ifndef __MAIN_H* c! L5 a% L+ ~7 H
  30. #define __MAIN_H
    0 Z4 L# P9 p4 R3 U  s- m; t

  31. " S: W3 L2 I) t3 f
  32. #ifdef __cplusplus, p7 r# J5 t% x: k
  33. extern "C" {. }5 ]" Q! }# Z& S& o) H& V
  34. #endif
    % J5 t% [1 v, `! t' G, `
  35. ' }2 p/ a& }6 q0 \
  36. /* Header includes -----------------------------------------------------------*/
    , [1 }* q+ d( }  m) v: l
  37. #include "stm32f10x.h"
    ; K$ Q3 h5 E8 p/ M- B
  38. ( G; b" p" |. \% u2 E+ N5 W2 p
  39. /* Macro definitions ---------------------------------------------------------*/
    + z* N3 D' b( F0 Y, l
  40. /* Type definitions ----------------------------------------------------------*/% l: _7 E$ X" W7 b
  41. /* Variable declarations -----------------------------------------------------*/
    ! U1 B5 l- O. ~# U% T, k* ~1 K
  42. /* Variable definitions ------------------------------------------------------*/# ]3 g. u" [9 \: n
  43. /* Function declarations -----------------------------------------------------*/
    8 G& T  Y; m$ l" s% @1 R
  44. /* Function definitions ------------------------------------------------------*/
    , l- _( w4 {" Y0 q, f" a. j/ p
  45. 0 y+ ]! n. ]4 S/ ]5 K
  46. #ifdef __cplusplus
    , F# N. @9 `) x- @9 b( S* K
  47. }
    7 F9 ?# {( r2 _* l
  48. #endif7 ?" Y, n8 i8 s) z. q' z1 y. p; e
  49. $ j7 m# W$ W3 f5 z7 K3 q3 ~
  50. #endif /* __MAIN_H */
复制代码

* [9 @/ C3 M) M9 c3 ?7 ?1 S9 _# \3 V; {8 ~2 p3 T
main.c 文件
# |5 I& c8 ~8 a8 D
  1. /**% p! i* W: @6 O
  2.   ******************************************************************************/ f' F  Q; }9 d. b# z+ ~" O7 e
  3.   * @file    main.c: M( o& y" x% u5 z  Z6 x# q1 G1 u) W
  4.   * @author  XinLi+ G. b9 l& C! o, P
  5.   * @version v1.0
    . j' ]$ \  g# v) c3 M9 O
  6.   * @date    24-June-2018
    $ w6 X+ p/ F; k; w; B
  7.   * @brief   Main program body.
    & _% [1 D- h5 u3 ^
  8.   ******************************************************************************9 ^9 f$ f+ i$ b* E( G
  9.   * @attention. z: b% z- d. I% ~
  10.   *3 ?) q& D6 t* P- ?
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    7 u9 K9 N$ Q; c/ ^& h' T
  12.   *
    ; A2 Q! v* }5 N' C
  13.   * This program is free software: you can redistribute it and/or modify
    ; o: _& e& i" c1 M4 C
  14.   * it under the terms of the GNU General Public License as published by  I6 g1 c) h7 O9 Q1 X7 n  {) k
  15.   * the Free Software Foundation, either version 3 of the License, or
    - f' m4 [1 l( }% B. M) }
  16.   * (at your option) any later version.% ?1 _3 w  ~& j6 l* w. C
  17.   *
    ) k/ M- y6 n' J* N
  18.   * This program is distributed in the hope that it will be useful,0 t$ |+ b2 t6 _, T+ }
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    7 s& u) S1 L. G6 ~% e. B2 A
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the; |$ e4 n3 \- D
  21.   * GNU General Public License for more details.
    ; r6 Y: o$ o6 G  ]
  22.   *  y0 ?% P, Y9 h6 @1 f
  23.   * You should have received a copy of the GNU General Public License
    5 R; a; ]& a" N* O8 \7 B- d$ x
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    ! r. \: {3 D! `( |- J5 ^; Y6 f4 C* C
  25.   *) z! T7 q9 \0 k" i
  26.   ******************************************************************************  G! D: k9 n0 p9 _
  27.   */
      h) }* I7 T# Z1 H5 H

  28. ' B" D- ?# q3 C( f
  29. /* Header includes -----------------------------------------------------------*/) U( e: m! K$ u+ \
  30. #include "main.h"4 \+ r- u$ e3 k; n! _" m" k, Y( g
  31. #include "CAN.h"0 M4 c) d* b/ b4 ?: Q9 M: r
  32. , n7 Y! _; O, ~. S! T
  33. #ifdef _RTE_8 i" S' A2 H) i! T  A) s
  34. #include "RTE_Components.h"% E( q% h% y# n" h* R3 |
  35. #endif
    7 C& r  S' c* w" l

  36. ) S- g8 m6 Y  b8 G
  37. #ifdef RTE_CMSIS_RTOS2
    + e! g$ v( i7 u/ z1 W
  38. #include "cmsis_os2.h"  c/ m2 Z0 T3 `1 D: @" y* B4 W
  39. #endif6 y, P/ ~- `2 H" c5 _' k" s, c
  40. , y7 J2 i; w2 U. A) y; \& |
  41. /* Macro definitions ---------------------------------------------------------*/
    2 i0 d  G# a  h$ l, ]
  42. /* Type definitions ----------------------------------------------------------*/  d; z0 S* ?/ k0 o+ F. h0 s/ H
  43. /* Variable declarations -----------------------------------------------------*/$ t% @# w4 I6 D
  44. /* Variable definitions ------------------------------------------------------*/
    % [8 F4 v8 e/ e. Y" E7 c
  45. static CanTxMsg canTxMsg = {0};+ ?1 @6 }! m# D: [
  46. static CanRxMsg canRxMsg = {0};) ?( ?+ b! I. a' W, A; s

  47. 2 `4 d2 b# X$ Z+ F3 s. \
  48. /* Function declarations -----------------------------------------------------*/
    ! X# |( i8 f3 i" _" ~* M) r
  49. static void SystemClock_Config(void);: f3 U0 w3 o# q
  50. 0 V1 o. \/ m7 a! i0 q. s
  51. /* Function definitions ------------------------------------------------------*/
    9 j2 T6 l& L+ {) ~; s

  52. 6 }' C8 \$ K4 i- e- M& J) w
  53. /**
    1 d3 h2 ~% B6 s9 }7 c. \" Q$ g4 t
  54.   * @brief  Main program." `3 e& }* L- i. M7 L7 c
  55.   * @param  None.. k1 L0 a! H, G! y1 ?: M% @' d
  56.   * @return None.  K0 }$ ?7 M  x; K
  57.   */
    8 O" Z3 o: ^/ v  S3 B
  58. int main(void)
    - k- R6 h( F' c$ T0 @) k9 ^
  59. {! u( x1 s4 p2 F, ?: r
  60.   /* Configure the system clock to 72 MHz */
    % k8 ]; {, q; i
  61.   SystemClock_Config();
    + u( S2 M- f6 j- o6 e1 B
  62.   SystemCoreClockUpdate();
    2 W4 F: A! J' H* Y6 g! P& w2 J
  63. : p6 g. }+ I+ a& @( D( \: h
  64.   /* Add your application code here */8 j, ^" t3 ^. {& M
  65.   CAN_Configure(CAN1, CAN_WorkModeLoopBack, CAN_BaudRate250K, 0xAA55, 0x55AA);
    / z3 N- x4 a  ]/ W
  66. & {1 A+ ?4 W8 i# L' U3 @
  67. #ifdef RTE_CMSIS_RTOS24 d. r6 @" ~; m2 Y$ G+ x" Y
  68.   /* Initialize CMSIS-RTOS2 */
    1 X" w# h8 f& G  W0 G# f% `/ L
  69.   osKernelInitialize();0 z6 M% n: e, x1 _
  70. + g- {/ G: V. w( y" n2 v9 @: e
  71.   /* Create thread functions that start executing, 5 }/ O9 ~+ V3 S
  72.   Example: osThreadNew(app_main, NULL, NULL); */
      l: y/ ?/ S2 ?" H# ]2 l

  73. 5 u% b! {/ A; B  @2 ~  A# L: y
  74.   /* Start thread execution */
    " P, W, W. {3 M0 x  v# W
  75.   osKernelStart();3 j" |4 i0 I" z& ]  ?9 P8 l
  76. #endif
    + W+ Z9 Y  o1 S! D8 y. L2 s

  77. 8 G2 A. U& m1 X/ G4 U3 R
  78.   /* Infinite loop *// @- r1 P. ?' S; z
  79.   while(1)8 i" j+ Q/ S( V9 t: P  |
  80.   {
    9 ?" P2 ^7 F8 J5 s8 G! a( L
  81.     canTxMsg.StdId = 0xAA55;# m" Z1 G' a8 w' P& X
  82.     canTxMsg.ExtId = 0x55AA;
    - c7 x. ~2 {- e( x; h: J  ~* F/ i; a
  83.     canTxMsg.IDE   = CAN_ID_STD;5 [7 P2 e1 ~  e, D
  84.     canTxMsg.RTR   = CAN_RTR_DATA;" H+ M3 V; V. o1 w
  85.     canTxMsg.DLC   = 8;
    8 S' d8 h: g7 E8 P' F
  86. ' k# r3 E$ U  N5 o
  87.     canTxMsg.Data[0]++;
    8 d8 b; p/ A" c/ E- @5 Y
  88.     canTxMsg.Data[1]++;
    ) U) U# T9 _4 y
  89.     canTxMsg.Data[2]++;
    9 Q0 ~7 I/ t0 R# L, @8 z) K( ^8 }
  90.     canTxMsg.Data[3]++;, C, ?) y- X* f8 A( k3 o1 x
  91.     canTxMsg.Data[4]++;* a8 T8 v8 v" e6 r. x" h* g% D
  92.     canTxMsg.Data[5]++;
    . K) z9 \2 B( L" V$ R
  93.     canTxMsg.Data[6]++;
    ! D7 f) Z$ g' Z. E6 Z  a: v+ c6 N
  94.     canTxMsg.Data[7]++;4 Q6 Q, ~: J' R; @0 _
  95. 2 m) F' ~/ |9 E! z9 @0 f2 |
  96.     CAN_SetTransmitMessage(CAN1, &canTxMsg, 1);" X% k: v4 |4 S
  97. : L$ h8 F+ G4 @: \4 }( ~
  98.     while(CAN_IsReceiveBufferEmpty(CAN1) == true);
    # f& O- V* E5 w2 I; T/ O) }9 n4 P, a
  99. : E. O( C# y! u" G5 d' S
  100.     CAN_GetReceiveMessage(CAN1, &canRxMsg, 1);
    & ^6 Y4 I/ ?1 H& c1 O6 x
  101.   }3 h( v/ _& f' B+ S
  102. }2 P0 y: Z1 X/ N( I2 l8 K9 P
  103. ) T: q( _1 m+ @0 `3 L
  104. /**4 Q8 ~7 {* m" d: h+ C1 V2 b9 `
  105.   * @brief  System Clock Configuration.2 Z, v# ^$ Q0 F; }
  106.   *         The system Clock is configured as follow : 5 g! t* \- l) ?- K1 e4 L
  107.   *            System Clock source            = PLL (HSE)
    ' Z  f$ [: ?! @- j" T
  108.   *            SYSCLK(Hz)                     = 72000000
    5 L7 v: @  i0 C* D* j
  109.   *            HCLK(Hz)                       = 72000000
    ) V2 Q( ]% R: ^% k4 Y. w
  110.   *            AHB Prescaler                  = 1
    9 n5 _9 i: B5 R8 Q. |
  111.   *            APB1 Prescaler                 = 2
    : x! R" P& n/ s
  112.   *            APB2 Prescaler                 = 1
    / W; [4 u" }+ }3 i
  113.   *            HSE Frequency(Hz)              = 8000000' t( g1 \0 J1 G5 D$ c
  114.   *            HSE PREDIV1                    = 19 _9 H9 Y! k3 j
  115.   *            PLLMUL                         = 9/ N% \' f$ i. C" e3 e2 c6 l1 h+ h) O
  116.   *            Flash Latency(WS)              = 27 x4 n5 P& J) y% s# J& _' Y
  117.   * @param  None.+ Q  ~3 f% ^& K) c: i
  118.   * @return None.! ~* {4 N# n( U8 I
  119.   */( i. M2 O, P9 ~6 w
  120. static void SystemClock_Config(void)
    ' e5 V  m4 K2 \6 m2 W- }* N' G/ s! J
  121. {4 f% J4 r5 l. G% M
  122.   /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration */
    2 X  w7 Y; G, Z- C
  123.   /* RCC system reset */
    * o) i; p- U$ |5 j6 L9 R
  124.   RCC_DeInit();
    / f: |. C5 ~1 s

  125. ! o3 E1 K6 V- k2 }
  126.   /* Enable HSE */7 n' ?( K" E1 [  B5 @# _
  127.   RCC_HSEConfig(RCC_HSE_ON);7 L' P/ y( W. k, x: a; E6 e

  128. 1 Q# s1 Q) \' N" I
  129.   /* Wait till HSE is ready */
    % E$ Y! L1 N3 o( N* n6 r
  130.   ErrorStatus HSEStartUpStatus = RCC_WaitForHSEStartUp();0 i# g0 O" G9 p! b4 K3 I% F3 [

  131. ; C# }, K& N. u0 q! r
  132.   if(HSEStartUpStatus == SUCCESS)6 N0 v1 ^/ t6 q0 \, \# O7 A  K# _/ O
  133.   {, _; O- e, I( H% V8 k3 T
  134.     /* Enable Prefetch Buffer */
    * z# u+ p+ b' T1 G/ O2 ?! t: y
  135.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);0 {) }0 `$ F9 R0 M
  136. / N1 e1 ^+ f+ i0 G! c8 i4 |: y
  137.     /* Flash 2 wait state */
    " |+ l- V/ C2 u0 r2 `
  138.     FLASH_SetLatency(FLASH_Latency_2);" d) u  R  Z) \) l: Z
  139. ' h$ k/ h0 E! K' x7 w7 ]
  140.     /* HCLK = SYSCLK */  R1 y/ t% m0 l% M
  141.     RCC_HCLKConfig(RCC_SYSCLK_Div1);
    - Y2 v. F& o# {4 Z" \. w, r2 m% k

  142. 4 t% I; l' w! X
  143.     /* PCLK2 = HCLK */6 g+ I7 b( z0 L+ @3 o( j
  144.     RCC_PCLK2Config(RCC_HCLK_Div1); ) S; f& r& V# v5 P# j
  145. 9 z; F" C% C, m" I
  146.     /* PCLK1 = HCLK / 2 */
    * w7 N5 ~+ L% N
  147.     RCC_PCLK1Config(RCC_HCLK_Div2);
    1 @' s6 _6 y8 e( J; n+ o
  148. ! R  {3 i) S4 E  M! Z8 U2 y2 b
  149.     /* Configure PLLs */  [& z2 J. A. |  v& q
  150. #ifdef STM32F10X_CL
    ( f) P1 y; U) [
  151.     /* PLL2 configuration: PLL2CLK = (HSE(8MHz) / 2) * 10 = 40MHz */
    , a% e" e+ @# V5 _% {" W" i. |
  152.     RCC_PREDIV2Config(RCC_PREDIV2_Div2);
    4 _5 e/ |5 U( V" @
  153.     RCC_PLL2Config(RCC_PLL2Mul_10);
    4 s4 C0 \/ O% w! y
  154. 0 E2 P0 Q- W, ]1 P5 R! g
  155.     /* Enable PLL2 */
    0 W1 N2 l6 A) J
  156.     RCC_PLL2Cmd(ENABLE);" U- H" H8 P# D6 ~' N

  157. - z, a: a; @9 `8 G0 e
  158.     /* Wait till PLL2 is ready */# h  I1 @/ \; U# @. J, f; M2 L
  159.     while(RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET);
    ! v8 n7 U9 n9 g& k+ ?
  160. * K( U9 @2 d8 f$ y# e# C5 M& D  s
  161.     /* PLL configuration: PLLCLK = (PLL2(40MHz) / 5) * 9 = 72MHz */, d4 |' v& V$ F5 s
  162.     RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div5);& L5 I+ B3 L* }5 R3 n7 Y9 V1 P
  163.     RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);6 c. b' T4 }& U7 O
  164. #else
    % \% i) R+ V1 {9 B
  165.     /* PLLCLK = HSE(8MHz) * 9 = 72MHz */
    7 T' b/ _$ B  t* j$ D# G$ G2 y- M
  166.     RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
    ! _8 `0 @* K+ A+ m) a
  167. #endif
    & u) R7 T( c: W* C# M

  168. / f0 r6 ~5 `7 E9 D
  169.     /* Enable PLL */
    1 d: N6 G3 h, d7 m8 h( ~$ o  \  U
  170.     RCC_PLLCmd(ENABLE);3 {# F/ i* o0 b) O

  171. 5 F: Z8 p' f& I0 f+ }) V' u- J5 ~
  172.     /* Wait till PLL is ready */4 A2 w: l7 e/ p. \" |! [: T$ r+ `
  173.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
    : `4 v8 [. L( {! E0 _' `

  174.   f5 D( {7 k, F/ e
  175.     /* Select PLL as system clock source */. ]" P0 v0 q' K+ {+ ?$ O9 F
  176.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);" f! |6 Y, z. B% H- Q2 e$ l0 q) P

  177. . m0 U& S/ S+ B6 E
  178.     /* Wait till PLL is used as system clock source */
    ) P% {1 C. D- y
  179.     while(RCC_GetSYSCLKSource() != 0x08);
    & q, [" E- `6 {- o3 w/ d: O' N& R
  180.   }
    % e' _6 i$ y# a7 E! r
  181.   else
    . Q/ N" x$ ?( e6 E3 _$ R* I
  182.   {  I! j5 P4 Z( L, Y5 ?9 s
  183.     /* Disable HSE */
    , r8 z' U7 M3 O' w# k/ c
  184.     RCC_HSEConfig(RCC_HSE_OFF);- v) c, O: ]; C. F/ ]* L2 ?5 i

  185. . c& q1 O) V. }( T
  186.     /* Enable HSI */# L8 A- C& O0 i# [* y
  187.     RCC_HSICmd(ENABLE);  V3 h9 N( ^# T, M, V4 U9 }" L' s- D
  188. , N, Z, u- Y1 b1 ^  P
  189.     /* Enable Prefetch Buffer */
    " O2 f, m" _" s% L$ D
  190.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);) F) `* e& ?. y
  191. 3 b' G5 j; Q; e! e3 }$ d
  192.     /* Flash 1 wait state */$ A  u! r5 t2 y
  193.     FLASH_SetLatency(FLASH_Latency_1);
    4 G$ C* E! K1 D( \) Y

  194. % f" H+ ]& x6 O% \$ {! b/ c
  195.     /* HCLK = SYSCLK */
    ' W6 p3 [+ ]" V
  196.     RCC_HCLKConfig(RCC_SYSCLK_Div1); . U+ p, m5 r$ O! L4 @
  197. * _, l3 N* H: ?1 [; }
  198.     /* PCLK2 = HCLK */6 L( s" o  ~, G- J
  199.     RCC_PCLK2Config(RCC_HCLK_Div1);
    3 i9 x" d* q# l* b% k( M3 L  R

  200. + G5 A0 B9 S5 v$ y$ K* u6 N2 z
  201.     /* PCLK1 = HCLK */
      O1 g/ Z* y# ^$ \) r0 B  {
  202.     RCC_PCLK1Config(RCC_HCLK_Div1);; v2 A7 b: r7 j) c" \
  203. & A5 E8 c$ Q2 w3 ?  r1 @. w  N5 W
  204.     /* Configure PLLs */3 e  p9 `' l4 L, o  U
  205.     /* PLLCLK = HSI(8MHz) / 2 * 9 = 36MHz */$ H% c/ o' m8 A: [* o% ^9 I9 ^
  206.     RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_9);
    ) S( Q" G( `/ [6 \, j" M

  207. ! N% W7 z6 P$ t3 W
  208.     /* Enable PLL */. J! U3 Q. z$ g/ h
  209.     RCC_PLLCmd(ENABLE);! ]+ x! `" z: A
  210.   `* K1 l1 T3 g$ }+ S, Z
  211.     /* Wait till PLL is ready */
    $ m% v' w9 o( K9 o  k
  212.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
    ! \, R3 x2 _/ B9 Q+ d! e( o. B) w
  213. 9 o( P6 v) d- w  U2 w
  214.     /* Select PLL as system clock source */; V* r* E7 E; G5 q: q
  215.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    0 i/ j$ v1 G- l; Q

  216. 7 [% t7 d8 L5 \7 k& K* y( p
  217.     /* Wait till PLL is used as system clock source */
    2 f6 h: I  B! ^) U
  218.     while(RCC_GetSYSCLKSource() != 0x08);
    $ W- n' B: m3 ~
  219.   }
    ( Q% K& a1 Q! X1 v6 c  K
  220. }
    1 R; G. c8 ?  G
  221. ; O6 I! `  c' ~# Z
  222. #ifdef USE_FULL_ASSERT
    ) Z( _- o7 b: b, f5 {" d
  223. /**' l" j" {8 w3 J% a
  224.   * @brief  Reports the name of the source file and the source line number1 k9 q. b' J9 [9 L/ b5 L
  225.   *         where the assert_param error has occurred.+ r$ S7 ?' u* z
  226.   * @param  file: pointer to the source file name.
    - \; |2 ]" P) s5 E7 W
  227.   * @param  line: assert_param error line source number.3 \3 @1 w" c5 X/ }
  228.   * @return None.7 K3 o$ X" Y% ?5 a8 `! E
  229.   */
    5 R$ u2 `3 Y& ~5 v& k3 ^
  230. void assert_failed(uint8_t *file, uint32_t line)
    + U& I$ p! t) o  c" U
  231. {3 |1 g, ^6 j2 [* @9 I. F
  232.   /* User can add his own implementation to report the file name and line number,8 P3 Z0 V: _; ?0 {3 b) F
  233.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    " Q8 z' X! s% B. `8 `' }
  234. ( Z4 v2 t" D# S
  235.   /* Infinite loop */" X- [% M- S/ k1 C; Q
  236.   while(1)8 I1 w+ ?1 n8 Z5 w% j  B
  237.   {! v' r4 m# C0 M. A- Q& ?
  238.   }
    . p  F0 \" u" y) z+ }* l
  239. }+ G5 N8 y  `/ Z. t5 E7 t6 y
  240. #endif
复制代码

& I+ l. `- {/ v( a* Y3,注意
0 l; x# ]9 M) P1 d
  X. F1 D/ h+ W6 o' M% V8 _CAN 消息发送缓冲区和接收缓冲区的大小,可以根据应用的需求进行修改,缓冲区使用的是堆内存,需要根据缓冲区大小和应用程序中堆内存使用情况进行配置。, \8 M/ M3 S) X8 @5 ^" D
, L; y: s3 H0 a) H  y
1 M: `2 ]; _- c9 F) O. z% T

9 R8 E: u; ~' t% G7 _: c$ k5 N
收藏 评论0 发布时间:2021-11-26 17:00

举报

0个回答

所属标签

相似技术帖

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