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

【经验分享】STM32F1(CAN)

[复制链接]
STMCU小助手 发布时间:2021-11-26 17:00
1,开发环境, t# _. h' s6 J0 C3 n
$ n: J& V: a) C
1,固件库:STM32F10x_StdPeriph_Lib_V3.5.0" |2 p+ `1 v  V- R0 D) A% V  S0 W

0 T; C$ r: T% T9 l4 |0 `2,编译器:ARMCC V5.06
& A2 `( X% X; y
( J& \0 o2 t0 k3 T. m$ a" E3,IDE:Keil uVision5
, Y$ x$ t: e& j/ V/ k' X8 v9 n. ^2 O8 V
4,操作系统:Windows 10 专业版) q0 B9 G3 P2 V4 `% ]
, w! W* g5 c1 _  A9 C

- @/ y- w1 ?2 A! Z  n* M2,程序源码
1 X/ z+ C+ [- B, _& J. M- }2 b, |
! r9 f* k3 v8 ?* L* ERingBuffer.h 文件. h, x% B0 t: G$ L% A- m4 D7 r( K9 Y0 A
  1. /**
    , F( M& r% F( ~0 f
  2.   ******************************************************************************
    . \$ ~: |# x$ Z% {
  3.   * @file    RingBuffer.h
    " q7 s- r* K+ Z! v
  4.   * @author  XinLi
    / a4 q3 G( k4 V# @: ]
  5.   * @version v1.1; y# z2 w7 C7 U- {
  6.   * @date    15-January-2018
    9 Z/ u, X" K& i  S" g3 d, c4 ]+ l& l
  7.   * @brief   Header file for RingBuffer.c module.- K, v! s( u4 H$ z
  8.   ******************************************************************************8 E. h3 q" I: d4 ^6 Y
  9.   * @attention0 ], U% I0 ]2 z- b9 Y  _# H
  10.   *
    8 L. r. v+ A; {' G3 v; R
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    / W( `5 ?- ^$ v# `( N( ^
  12.   *  l' T& |1 e% z. Z
  13.   * This program is free software: you can redistribute it and/or modify
    % ?9 R0 B3 K1 {/ H
  14.   * it under the terms of the GNU General Public License as published by/ b, ?2 c+ k/ K. {! u( K2 R
  15.   * the Free Software Foundation, either version 3 of the License, or
      P* m. b1 [% ?" s( ]5 U
  16.   * (at your option) any later version.
    9 |, D1 s5 e& s3 s5 M! d  Y
  17.   *3 d/ ~3 o) v1 ~0 E% G& t
  18.   * This program is distributed in the hope that it will be useful,
    / ]; J1 v, m' h3 v. _# y: a
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of( ^4 m/ T6 M  b5 Y3 m! `, t
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the6 z8 f- K) ]; x5 C
  21.   * GNU General Public License for more details.
    - V9 ?) u5 l/ _" t2 u& u
  22.   *: ~$ t) c# ^& Q0 A! p
  23.   * You should have received a copy of the GNU General Public License
    8 T2 |0 Z% ?& D: o  }+ O9 h2 d
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    # e3 Y$ ~; g$ Q& k: ^3 {
  25.   *) m" c* ?& t! `. t
  26.   ******************************************************************************* M% `" z9 C" d9 P, t
  27.   */  ~8 Y7 X' c5 P7 A* L; E
  28. : f3 _# r7 y2 V. _
  29. #ifndef __RINGBUFFER_H. P6 t7 F8 {" {; f! ~
  30. #define __RINGBUFFER_H7 p/ ~1 b  s: r$ m" @/ ~1 |! p  l/ ?
  31. 0 u% u8 ~- n0 [/ X) m3 F7 I/ P* c
  32. #ifdef __cplusplus
    7 a) `* K, N9 k' U4 P, D
  33. extern "C" {
    ( k/ s- w! l: S6 g2 c4 Z. J! f1 Q
  34. #endif8 x1 K& |; h" @
  35. / F3 d0 F0 I4 p/ d/ @; u
  36. /* Header includes -----------------------------------------------------------*/8 C3 ?6 X4 h& p8 z
  37. #include <stdint.h>0 V3 p6 y& ?5 a* R. F0 E, \2 X
  38. #include <stdbool.h>5 u: t2 K3 l- E! o" R
  39. #include <stdlib.h># l8 S" C% x  y! b4 K  M+ m

  40. ! {* q; Z% X- V; W* m
  41. /* Macro definitions ---------------------------------------------------------*/
    5 o3 ]- Y# C5 t+ m( T8 Y3 P! S6 s
  42. #define RING_BUFFER_MALLOC(size)  malloc(size)
    7 L; A, s* C' @+ ?
  43. #define RING_BUFFER_FREE(block)   free(block)
      V$ d/ B! S/ `/ O* K/ U% ^
  44. 2 s! G7 ^) u! R" R* a
  45. /* Type definitions ----------------------------------------------------------*/
    $ u4 L; o+ M+ }2 z, E! X7 `
  46. typedef struct
    / z) q/ s7 ^, ?# k% r3 s
  47. {
    ( g. c- ?8 `1 e/ G2 Z( ?/ ^9 L  R
  48.   uint8_t *buffer;1 R& ]6 @: J" U3 W) N
  49.   uint32_t size;
    : g% c  B+ G' \5 j3 o* ]
  50.   uint32_t in;  ]' s+ ~7 j% k: `! R  k  {9 V( S
  51.   uint32_t out;3 s6 o6 a: O6 L  X8 W/ g  `) l
  52. }RingBuffer;
    5 K5 N& Z9 f5 n" ?  j
  53. ! M* d0 m' c+ R* i' t* V
  54. /* Variable declarations -----------------------------------------------------*/
      C2 H3 f& {* C, h$ L/ z5 v
  55. /* Variable definitions ------------------------------------------------------*/
    4 ~" Y+ e& q' k
  56. /* Function declarations -----------------------------------------------------*/8 \: P6 n/ T5 i; S( M# r
  57. RingBuffer *RingBuffer_Malloc(uint32_t size);& {% B& h- j0 [
  58. void RingBuffer_Free(RingBuffer *fifo);
    & m3 I4 r  l7 |1 i% r

  59. 0 e  P5 U6 Q5 @) M( `
  60. uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len);5 f$ k1 e5 [6 D9 d) `
  61. uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len);
    ( _  s7 W' ^5 t

  62. & o9 V; q% V4 d# W' P. {) X
  63. /* Function definitions ------------------------------------------------------*/
    4 f2 e5 O' {, j. G% i/ T- h

  64. 4 F  B) K4 R' q  z9 z" ^2 m* K
  65. /**
    3 {: K. l8 n) x% `1 B
  66.   * @brief  Removes the entire FIFO contents.
    # K5 ?. k8 _9 Q- J; i% z8 v  V, H
  67.   * @param  [in] fifo: The fifo to be emptied.4 p& p* L( L# y) D) J4 w9 [
  68.   * @return None.' p; ?. L$ Q) }5 _; y2 X
  69.   */
    % r$ b' _+ G3 @. b3 O
  70. static inline void RingBuffer_Reset(RingBuffer *fifo)
    3 I% I/ d' d5 ^1 E* G9 s0 M) ?* T3 v
  71. {+ i+ Q' i; |; M! v  Y2 n( `; b4 \
  72.   fifo->in = fifo->out = 0;
    * M: C  k$ P& q( q  R
  73. }
    # R; [8 M8 X/ V2 k/ W

  74. . Z. ~  E; }! G& V
  75. /**9 A+ M( Y9 _- i- x
  76.   * @brief  Returns the size of the FIFO in bytes.
    0 v* T& V: k% q$ n# P: d% f
  77.   * @param  [in] fifo: The fifo to be used.; t+ {$ d; ]/ p( f4 }+ l
  78.   * @return The size of the FIFO.5 L( y+ Q$ O3 Q+ x. ]) h! s  w
  79.   */( N7 c. y6 }) O9 t8 X
  80. static inline uint32_t RingBuffer_Size(RingBuffer *fifo)
    # m+ ?/ u: ?4 H  k4 E
  81. {+ [/ f( x! s1 X
  82.   return fifo->size;
    9 z: @  N2 F2 I% U7 u# v% P/ g8 r
  83. }1 F9 L' x1 K7 u% r8 d9 ]
  84. - H: @8 G* y1 E' o
  85. /**% Z1 y4 ^6 ?6 k) x
  86.   * @brief  Returns the number of used bytes in the FIFO.; [2 b, A. N# ^: n/ a  V
  87.   * @param  [in] fifo: The fifo to be used.2 o/ i! B% c  `1 t4 z. g
  88.   * @return The number of used bytes.# G$ P" l8 r) d$ d! C) j" C) O+ J# C
  89.   */: b- k$ E5 ^. b: E
  90. static inline uint32_t RingBuffer_Len(RingBuffer *fifo)
    3 M* S6 ?/ H) W7 t+ O
  91. {
    3 v: e5 [2 u7 T' R$ C- P
  92.   return fifo->in - fifo->out;
    * U7 C" P, A% v* k% h
  93. }
    ) ?% ~) x; ?" A, o1 |: t  w* g

  94. 7 |( G  p# Q! k
  95. /**0 u( t/ x% L7 p+ `" M  I' C0 n; D) F
  96.   * @brief  Returns the number of bytes available in the FIFO.  t& r/ `  P* f# e" g# ]  l
  97.   * @param  [in] fifo: The fifo to be used.1 L+ Y, S+ u( R8 q1 [) E
  98.   * @return The number of bytes available.+ D2 q4 {8 t3 Q! n
  99.   */
    0 S9 A& w9 p$ ]: S" y
  100. static inline uint32_t RingBuffer_Avail(RingBuffer *fifo)
    0 Q* H9 ^( ]! p$ ?
  101. {* k! K. e$ D+ E! r
  102.   return RingBuffer_Size(fifo) - RingBuffer_Len(fifo);" q5 C/ \1 [( I! _% b
  103. }
    2 {, Z4 e- v; Y  c' S3 W' ^4 X( Q

  104. % Y, ?3 i  k  Q2 ]& W3 t0 V
  105. /**( z" a2 Y3 P( d
  106.   * @brief  Is the FIFO empty?
    % Z$ \( y# T2 l( T* d0 o
  107.   * @param  [in] fifo: The fifo to be used.
    # |: U6 a8 c! i+ k. W
  108.   * @retval true:      Yes.; N& k3 n2 J# ~7 j& @5 G( \2 r+ H
  109.   * @retval false:     No.
    ; w$ R: e+ u5 N' P* I2 d8 k
  110.   */, R: @1 E# R1 Y/ R
  111. static inline bool RingBuffer_IsEmpty(RingBuffer *fifo)- m. `) O5 ]+ V- D" n6 j" M7 p" l0 e, z3 r
  112. {# T5 i% G$ f) I" p2 }
  113.   return RingBuffer_Len(fifo) == 0;6 |2 k4 ?1 o/ f- b
  114. }6 \) L, r" @1 I! C
  115. 4 ~$ H, |8 g5 y/ W5 Z8 {
  116. /**
      y0 E, c* i" ?& g( }6 b4 b  R
  117.   * @brief  Is the FIFO full?2 L, p3 ~  L" U; O' B& S1 }
  118.   * @param  [in] fifo: The fifo to be used.
    6 G( G$ ~5 a, K  P( }+ A+ W2 P
  119.   * @retval true:      Yes.) {! U6 M! X# k( ?" Z3 h' g9 d
  120.   * @retval false:     No.8 v9 D5 t+ |; Q" L, C- f
  121.   */
    2 \  T4 A3 m' A) }
  122. static inline bool RingBuffer_IsFull(RingBuffer *fifo)
    5 d& V* L9 b: Y/ e/ D/ I# M
  123. {
    % C- w! P, ^! j' {: A
  124.   return RingBuffer_Avail(fifo) == 0;% m% {6 K! ~9 B1 J" t8 C/ L# m3 S' g
  125. }. j- v2 j% {  E2 C

  126. : N3 E) `) u  {  k/ }2 c
  127. #ifdef __cplusplus4 t$ e- ?8 \! A; q
  128. }
    4 M% _1 e7 I, }# w
  129. #endif
    - N( W4 y0 O3 X& k9 r0 a% q/ E

  130. 8 q& w8 p) m1 l
  131. #endif /* __RINGBUFFER_H */
    & {0 A3 B: _9 |" b2 D$ O% m( i
复制代码
+ B8 B$ \; I) u$ B( ~$ E

9 {* n# T2 g: i  RRingBuffer.c 文件
: c8 V% B% u# Q' B; k9 f
  1. <div>/**
    9 x6 K0 A* q7 ~% Y; e7 h4 l
  2.   ******************************************************************************
    2 w/ o) A) g+ S% M# r
  3.   * @file    RingBuffer.c1 o- B/ ^3 M+ i& y% v
  4.   * @author  XinLi
    3 n% X4 l  E) m$ y$ x! x0 K
  5.   * @version v1.1
    2 e  e5 I& @/ u* h  Y+ v- ^
  6.   * @date    15-January-2018
    ! l$ S4 D- n- @( `/ K
  7.   * @brief   Ring buffer module source file.0 w3 m' F$ a8 a5 B% Q
  8.   ******************************************************************************9 v# z3 p: U5 {4 I
  9.   * @attention% v* y3 g) j2 }$ X- b
  10.   *
    0 a0 y6 u- g. |+ U- C' `- O4 _2 m. k
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    5 j7 D2 }5 S; Q+ k- p' _
  12.   *. z# f4 `5 p3 U# x$ ~
  13.   * This program is free software: you can redistribute it and/or modify0 ^. _7 g9 x2 c# D4 W# I( n5 B2 F
  14.   * it under the terms of the GNU General Public License as published by
    4 x+ s: r6 ?4 O3 L* g
  15.   * the Free Software Foundation, either version 3 of the License, or
    ' {) _0 H+ I5 b' u
  16.   * (at your option) any later version.
    " R; G5 E0 k- \$ X  `# U# ]
  17.   *
    - ~. ?  o2 N. h# `$ [$ C5 h
  18.   * This program is distributed in the hope that it will be useful,, s3 f* S4 ^% q3 j( M2 ?
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    + R3 S% Z: d& r+ Q1 [' Y
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    6 M, l' Q5 a. k' T3 i0 e
  21.   * GNU General Public License for more details.8 U' J/ y& }% n9 ]# ]" g! f0 d
  22.   *1 |' s( c3 E8 z( p  l' _
  23.   * You should have received a copy of the GNU General Public License8 l6 V7 z0 H9 t5 U! O/ X. C
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>, j) p/ N, p: p7 \/ Y0 @
  25.   *
    ! d2 S0 \& S4 n  z: K9 Z
  26.   ******************************************************************************
    9 k6 a* o. L" c: W: Q
  27.   *// i/ T3 F8 p+ \) V% z4 l& K

  28. 7 G; b  X4 V0 H8 u! N2 m
  29. /* Header includes -----------------------------------------------------------*/8 d9 d' o6 o; F7 _- Q8 ]
  30. #include "RingBuffer.h"
    6 d" G% f/ d  [+ T% Q
  31. #include <string.h>
    4 |. e, J- F& f( a
  32. / ~% K3 |) o, r' d4 j; U
  33. /* Macro definitions ---------------------------------------------------------*/
    & z+ L% |7 S5 }1 `& x
  34. #define min(a, b)  (((a) < (b)) ? (a) : (b))- v% U+ W; _6 [9 x* R3 {& C) H7 Z3 W

  35. : |) A) Z+ B  `: {" Q  E9 T
  36. /* Type definitions ----------------------------------------------------------*/
    + [! ]' X( y! C* b+ C  v2 G! ^, N
  37. /* Variable declarations -----------------------------------------------------*/
    2 d4 u2 A7 {- C$ C
  38. /* Variable definitions ------------------------------------------------------*/1 R7 u$ Z: B7 B8 J
  39. /* Function declarations -----------------------------------------------------*/* ^3 y: W7 h6 T* m
  40. static bool is_power_of_2(uint32_t x);
    1 |2 _  S" E$ L. A
  41. static uint32_t roundup_pow_of_two(uint32_t x);6 v) _4 X- Q. W+ ]+ [' O

  42. ; H& u; u2 h3 m: c: C
  43. /* Function definitions ------------------------------------------------------*/
    # ~2 |+ o: D3 R: k* {! k/ d( G

  44. ) E0 w+ L+ r  G- X- a
  45. /**1 d0 @, W- ]  v+ Z
  46.   * @brief  Allocates a new FIFO and its internal buffer.: T1 H* t/ ^" N+ U! w; z
  47.   * @param  [in] size: The size of the internal buffer to be allocated.
    ( A6 t4 b. K- K" t, H; ]" r5 ~/ F
  48.   * @note   The size will be rounded-up to a power of 2.' c; j1 }" b$ b; {) G  Q4 D" H
  49.   * @return RingBuffer pointer.
    % ]4 k$ i# P5 H& `4 o
  50.   */
    7 ^4 E( Y) D+ r- B* W
  51. RingBuffer *RingBuffer_Malloc(uint32_t size): o! L( a2 w5 ?# l
  52. {+ N* ~/ j' J3 F( v$ K
  53.   RingBuffer *fifo = RING_BUFFER_MALLOC(sizeof(RingBuffer));  G5 H  G+ H8 {# V* L' V# k  S
  54.   Z6 k( t* t' b2 l: D2 [
  55.   if(fifo != NULL)
    7 c% B0 W+ e; r; d/ g
  56.   {
    1 J( g) Z7 ]9 y0 X
  57.     if(is_power_of_2(size) != true)
    : U+ n8 Y' E8 A4 j9 X
  58.     {
    1 a5 M4 T) w& a' W' k
  59.       if(size > 0x80000000UL)
    0 V# G4 v: R- ~3 I5 ^7 d
  60.       {- l1 u! y& B" L5 ?0 D# d+ ^
  61.         RING_BUFFER_FREE(fifo);
    : I& g8 u% S- p5 `
  62.         return NULL;
    ) w9 k: H- X( s/ P
  63.       }
    9 s: V% B% i( Y& E: R
  64. 9 `. O) E, U5 k2 |' e  u; v
  65.       size = roundup_pow_of_two(size);
    - ~; f) [/ a5 {) w/ J- E
  66.     }8 m' \" a, [. R3 q" {( f1 U( V

  67. * }* R3 U# s, w/ b" S3 c
  68.     fifo->buffer = RING_BUFFER_MALLOC(size);  a& h4 j; f( o7 P+ Z

  69. 1 a0 r# z+ X! J3 A( K
  70.     if(fifo->buffer == NULL)! |! E1 [: i, X: E6 E0 Q9 _3 c% D
  71.     {2 x1 w* u4 |5 K, J9 n
  72.       RING_BUFFER_FREE(fifo);
    : t, o& o; R' m( F) \) I+ M
  73.       return NULL;6 I6 J: c3 d- @0 i
  74.     }
      Q' j. {) E! n, d* f0 K6 r

  75. 4 C0 S, k# O; t
  76.     fifo->size = size;
    6 J+ O2 _- U/ N0 I
  77.     fifo->in = fifo->out = 0;
    3 p8 v# j$ p5 C- p$ d
  78.   }
    & t0 {% ?9 }. Z  X9 E

  79.   D! ?' N0 |0 b8 t; c
  80.   return fifo;0 j" G0 q4 ^; q% O; @
  81. }
    2 g3 X& J& Q" g+ y

  82. . o( C$ O1 I! |' h, A# N! R
  83. /**
    0 C. K  l/ P9 \/ i
  84.   * @brief  Frees the FIFO.
    8 R' U& j; P5 h  ~. `7 v7 C
  85.   * @param  [in] fifo: The fifo to be freed.
    % D4 K1 L& r$ i4 N1 P
  86.   * @return None.
    3 p0 e' A8 q1 S' T* V- x* H: [& j
  87.   */
    ( g, _, ~6 z/ x6 G& }! r; v
  88. void RingBuffer_Free(RingBuffer *fifo)8 p4 o+ U% ]: ?- ^) ]# v
  89. {
    - D4 X2 C: [) s: ]  Q3 l
  90.   RING_BUFFER_FREE(fifo->buffer);( Z6 E5 e* X9 ]
  91.   RING_BUFFER_FREE(fifo);
    * L1 ~* H3 A- W7 A2 w0 y, I
  92. }" v* x* f# \! C4 {: Q
  93. : ]4 [2 b/ A. m+ g
  94. /**+ }3 [, X( l6 w( d8 k: j- U# H7 p
  95.   * @brief  Puts some data into the FIFO.
    ( u) f5 q6 Z8 p5 N. b4 t- u2 i
  96.   * @param  [in] fifo: The fifo to be used.
    2 e2 }% p: [" s
  97.   * @param  [in] in:   The data to be added.0 v$ F) M' N2 R5 b0 ^
  98.   * @param  [in] len:  The length of the data to be added.3 d) c4 F3 Q- z1 k  g: i
  99.   * @return The number of bytes copied.
    # O- t8 ^( |: G9 c' w5 U
  100.   * @note   This function copies at most @len bytes from the @in into, x' G9 p9 \- z( W
  101.   *         the FIFO depending on the free space, and returns the number3 P& S+ l% J1 i% ?
  102.   *         of bytes copied." @5 g4 M5 D" S) t% y: F% O6 ]9 m2 a
  103.   */
    ; D, ~% Q* H$ q- o% K% X" s
  104. uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len)2 I7 l  X/ ]$ v
  105. {0 ~3 S, W/ P+ {
  106.   len = min(len, RingBuffer_Avail(fifo));
    , o! t- L- M# d2 z/ ?4 n
  107. 6 k/ w" G7 H8 x8 O" O& `# d
  108.   /* First put the data starting from fifo->in to buffer end. */7 n2 E: Z" o4 Q+ O$ S# T
  109.   uint32_t l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));5 p- z' V, W* j6 ~* [+ ]
  110.   memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), in, l);
    9 @' x2 e9 r, L! c! o

  111. ; J% ]; O; ~* j( o9 `; h% h
  112.   /* Then put the rest (if any) at the beginning of the buffer. */) _* f  m) S# O
  113.   memcpy(fifo->buffer, (uint8_t *)in + l, len - l);2 _- e3 o5 @/ m) G6 g& X1 O3 n
  114.   b% K% |+ Y2 ^$ u+ C1 v! p0 Z
  115.   fifo->in += len;: p# m! O' l) p1 B' P( e

  116. 2 E9 \' r' N/ |. @( T
  117.   return len;8 m$ ?( Y* K: A( r  x0 u  G
  118. }
    5 [, W1 O9 h8 ~7 b
  119. : v0 J0 E3 c& x! q8 n: v  S/ |
  120. /**6 w" ~1 G) C5 |9 F5 H& C
  121.   * @brief  Gets some data from the FIFO.- x. O) U9 |2 [; i4 a6 Y
  122.   * @param  [in] fifo: The fifo to be used.
    ) t  a% z/ L6 b' V0 Z
  123.   * @param  [in] out:  Where the data must be copied., n6 i; N. I& ^
  124.   * @param  [in] len:  The size of the destination buffer.- r* e) L% e# R! j( O
  125.   * @return The number of copied bytes.
    2 |+ h) k( G* c0 w' s5 \- H
  126.   * @note   This function copies at most @len bytes from the FIFO into
    - r  u8 t' i6 Z/ m1 Q6 p  C) O
  127.   *         the @out and returns the number of copied bytes.7 _, l" F4 E( Q! F( K! u6 H0 M
  128.   */6 ~# n% t  `$ p  b( q' B( d
  129. uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len)5 u% _  a' O' v3 @. c
  130. {
    6 D( T9 k# p! k
  131.   len = min(len, RingBuffer_Len(fifo));2 d* w: Y0 }9 v+ w
  132. ' V3 s4 F0 B+ r8 U
  133.   /* First get the data from fifo->out until the end of the buffer. */5 Q" A2 o( B5 S) P* M' ?5 J3 B" b
  134.   uint32_t l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));$ h5 t' \& x& t) Y9 X' R
  135.   memcpy(out, fifo->buffer + (fifo->out & (fifo->size - 1)), l);
    # m/ r- R1 J# H6 z% H4 z
  136. 6 h  x- i6 B5 J% Z3 H2 F/ E' q
  137.   /* Then get the rest (if any) from the beginning of the buffer. */
    / t- X  {. a  H
  138.   memcpy((uint8_t *)out + l, fifo->buffer, len - l);
    % o* F2 X: V: Q, r
  139. 0 \  f( U% s! X% ]) K7 ^6 x# Y2 [
  140.   fifo->out += len;/ k! r: F; E/ ~5 C$ V, k# W

  141. ; E; p) e+ _3 q6 D, @+ a
  142.   return len;
    6 c8 Q' p" z1 Z- X5 z1 k- g! x
  143. }
    # ?( t  `; s/ N/ g, I) x

  144. 4 r9 \# a/ v! S7 i2 U1 s
  145. /**
    $ y- T9 ^" I. W/ y1 q; ~6 m
  146.   * @brief  Determine whether some value is a power of two.
    - C& E- P# \& x0 d  ]/ v- M( h8 I
  147.   * @param  [in] x: The number to be confirmed.
    - @, }* ?3 q: A
  148.   * @retval true:   Yes.
    . ?. j' M9 [) a6 ~' l: K
  149.   * @retval false:  No.6 f4 s9 x% m5 [: Y
  150.   * @note   Where zero is not considered a power of two.
    2 Y% O' W: h9 e4 y% u
  151.   */- b  |' r3 i; D3 W9 L
  152. static bool is_power_of_2(uint32_t x)$ o$ M2 ?, y1 I# d
  153. {
    ! k: a! U5 q6 y1 A0 w0 O" m$ D
  154.   return (x != 0) && ((x & (x - 1)) == 0);
      t4 [: h4 v5 R3 ^, E2 i/ O9 O  Z
  155. }
    $ d- p" Z$ L3 R- O; w# }
  156. 1 A, Q) M" U- {
  157. /**  `$ o+ n/ K9 }0 B- w; E7 @/ z, V) P
  158.   * @brief  Round the given value up to nearest power of two.+ l- H* r$ ?9 u/ s5 Z
  159.   * @param  [in] x: The number to be converted.
    7 m0 i. n, ^' d  b
  160.   * @return The power of two.; K7 ~8 G$ g  v/ i' F5 {# v
  161.   */. V- }, U* F- n
  162. static uint32_t roundup_pow_of_two(uint32_t x)1 |* h* ^" B( A  T. V6 L
  163. {
    1 B' f+ t: w$ X; g
  164.   uint32_t b = 0;
    3 ]8 @" M& o' ?
  165. ) [0 ]" `# x& c# }' N8 ?3 R
  166.   for(int i = 0; i < 32; i++); E. m. F0 X: N& {% Z4 d7 o/ j2 @
  167.   {8 _1 `' i$ i$ M) m8 O$ \
  168.     b = 1UL << i;9 Q7 j+ Y( X4 h+ q, g+ n% ^+ S* H, B* A

  169. 1 Y8 c6 e) b( H* r3 f
  170.     if(x <= b); y; ^* t8 K2 t! ]) n1 a& l
  171.     {
    ! n& R# ~8 p7 [6 L  V
  172.       break;4 h6 }  Z6 `7 X# K  H
  173.     }4 O* ]. N8 y, }: o
  174.   }( {; n- B  M6 ], L
  175.   d7 g; z' x* w7 Q
  176.   return b;4 c' Z) b, R: r' ~  I9 _* I2 i- C
  177. }</div><div></div>
复制代码
0 Z& J$ D' [6 I% f
( R2 d# _8 s% Q: O. ^( M
CAN.h 文件/ ~5 g8 S/ i/ u0 m7 W
  1. /**. M9 u; ?) X3 R' R
  2.   ******************************************************************************
    ! g2 D4 I6 K6 T
  3.   * @file    CAN.h
    $ I: }$ }, P$ J# ]* ]
  4.   * @author  XinLi
      q% e/ u/ S! V% p# t
  5.   * @version v1.0+ N  `; C* o2 P. ?3 d% T8 Q
  6.   * @date    24-June-2018& ], X6 l& C  r8 d
  7.   * @brief   Header file for CAN.c module.6 W: B# A4 l  m: m
  8.   ******************************************************************************
    4 _8 J3 i0 u8 o6 i( K* J2 s
  9.   * @attention7 Z0 ~& f0 R7 ~) t
  10.   *
    0 S6 M4 l/ V- j# X
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2># f/ ?" B% L5 F( u0 C& ^1 F; Q+ O
  12.   *8 H4 Y- h# w8 U$ @# B7 D* i; r) ^; E4 m
  13.   * This program is free software: you can redistribute it and/or modify+ J  a9 ]# G, B$ r* K
  14.   * it under the terms of the GNU General Public License as published by
    4 E+ Y  S' Q. e7 {, r6 \4 c- l
  15.   * the Free Software Foundation, either version 3 of the License, or$ ?0 g" n! m% z8 e
  16.   * (at your option) any later version.* x# G0 t9 A3 R! x3 r
  17.   *) |/ y8 ]* w9 h; b9 w
  18.   * This program is distributed in the hope that it will be useful,+ I) D- X! Z" \
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    % _9 ]& \  d: n" g1 K$ v/ D
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    : A7 R2 v% r3 H, k0 w  e( l
  21.   * GNU General Public License for more details.1 O  b; s0 v6 `3 ]
  22.   *
    ; ^" X; b( ^9 [4 v
  23.   * You should have received a copy of the GNU General Public License4 o# J5 t' s$ Z4 A6 M3 F! @' V
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a># Q* V7 p( t( Y  _; T7 ~
  25.   *
    9 h! G* Y& k) A5 j; \5 T
  26.   ******************************************************************************' j$ _# C. A; t. v% n2 c
  27.   */$ I. j# Q* E" ^' ?- a! {0 Z7 p

  28. 7 \8 U. J' _" j+ I4 X# R. V
  29. #ifndef __CAN_H, m9 v4 l# a0 u/ W" G: \/ ~
  30. #define __CAN_H; w8 x4 |5 J3 c3 t6 D7 M

  31. # R( y4 u# {/ B6 x  W' o$ i$ F
  32. #ifdef __cplusplus" T/ q& b1 _0 n+ L( t" c. s7 i
  33. extern "C" {, B8 J+ q/ {1 u( F' ]1 Q
  34. #endif
    1 S  x" o! J& H" M- }) b

  35. 2 r& p5 @( q- y* L7 e0 }3 y2 n
  36. /* Header includes -----------------------------------------------------------*/6 o3 S4 ?/ H/ ?0 ]
  37. #include "stm32f10x.h"
    1 z6 ^- H4 O* M/ I0 z
  38. #include <stdbool.h>
    7 \. M4 d# T6 j8 |  j
  39. 4 @( C: X" d- A2 {. S
  40. /* Macro definitions ---------------------------------------------------------*/
    9 t: [: N1 t  m) @! C

  41. + P7 K( m( U. w8 ~; q
  42. /******************************* CAN1 Configure *******************************/
    . Y0 @4 S9 |3 B; K/ `4 {* F4 ?
  43. #define CAN1_TX_BUFFER_SIZE        (16); w7 v  K' g2 N% ~& s) K
  44. #define CAN1_RX_BUFFER_SIZE        (16)
    4 z+ p0 _- M' j# Z% \
  45. ' e! V) o1 o+ x. u8 w; a, f
  46. #define CAN1_TX_GPIO_CLOCK         RCC_APB2Periph_GPIOB7 z* w2 Z: e( E/ K; |
  47. #define CAN1_RX_GPIO_CLOCK         RCC_APB2Periph_GPIOB6 {. Y& d: s- J1 |8 D

  48. & u: j6 ?- i% n: l
  49. #define CAN1_TX_GPIO_PORT          GPIOB
    # v1 A( q- ~& W$ ?& H7 V/ i% ?6 P
  50. #define CAN1_RX_GPIO_PORT          GPIOB. I+ b9 b. s  d' ^6 S  h) E

  51. 9 O$ _9 D1 ~7 s3 C6 Q( C
  52. #define CAN1_TX_GPIO_PIN           GPIO_Pin_94 N& Q! k3 G0 r  s: w; i
  53. #define CAN1_RX_GPIO_PIN           GPIO_Pin_8
    # q5 D* W7 W. p. M/ a( @

  54. ( m3 x3 p+ I% Z! O
  55. #define CAN1_IRQ_PREEMPT_PRIORITY  (0)
    + Z5 ?+ t6 h1 T
  56. #define CAN1_IRQ_SUB_PRIORITY      (0)
    7 n1 ^- k/ z1 J# U+ X
  57. ( Y9 Q8 s. m# X% b7 d
  58. #define CAN1_PORT_REMAP()          GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE)% Q( [5 @! x- P/ z3 ~6 v0 ~' w* _+ L
  59. /******************************************************************************/
      ?$ U3 ]) F" e1 \5 H
  60. , H2 I4 I. H7 T$ Z# m& `" r
  61. #ifdef STM32F10X_CL6 G6 i, n% @4 F* _( v
  62. /******************************* CAN2 Configure *******************************/
    2 D8 q6 S: {/ l9 H* Z" c# K
  63. #define CAN2_TX_BUFFER_SIZE        (16)
    . e7 n$ D2 C# o7 p# i$ W" c. L; ^
  64. #define CAN2_RX_BUFFER_SIZE        (16)
    - P- H- I$ q7 s' |9 z$ N

  65. / q/ x6 n8 ?5 D$ b
  66. #define CAN2_TX_GPIO_CLOCK         RCC_APB2Periph_GPIOB
    ! o, A8 y; W( X: R& ]5 [8 T
  67. #define CAN2_RX_GPIO_CLOCK         RCC_APB2Periph_GPIOB' m: D$ a' n# Q  E* W) c2 p

  68. # L- m4 U9 k0 V  o' |* I: W8 A: |7 F) A9 P
  69. #define CAN2_TX_GPIO_PORT          GPIOB! z& z% I8 r$ c% e0 {
  70. #define CAN2_RX_GPIO_PORT          GPIOB
    ! n* }  b( ^+ E& p1 J. `7 X
  71. / T' }4 N- c' z
  72. #define CAN2_TX_GPIO_PIN           GPIO_Pin_13
    $ o5 L6 ^8 X$ y& Y  H. W
  73. #define CAN2_RX_GPIO_PIN           GPIO_Pin_12
    7 @, g: g: G: }. p$ h

  74. 1 \( r+ q% t3 M3 x. q
  75. #define CAN2_IRQ_PREEMPT_PRIORITY  (0)
    + H" \! h! H& r
  76. #define CAN2_IRQ_SUB_PRIORITY      (0)
    ( P/ p3 a1 r- m

  77. . q) g. k+ V- F' e! X+ n+ N$ \
  78. #define CAN2_PORT_REMAP()          GPIO_PinRemapConfig(GPIO_Remap_CAN2 , DISABLE), m( x6 f( m; B# n% T: H8 l$ c
  79. /******************************************************************************/
      d) e9 ]& C8 G# a* s3 o$ M, {; t
  80. #endif /* STM32F10X_CL */
    ; l, |# r6 P* M  H& V

  81. 6 s) ^/ N( {$ V3 T
  82. /* Type definitions ----------------------------------------------------------*/0 X* N' b; o4 k3 s
  83. typedef enum
    ( _+ N$ x% {) A  t
  84. {" ^2 G5 K5 t# R5 K: p
  85.   CAN_WorkModeNormal   = CAN_Mode_Normal,7 A9 p0 C5 x" X5 Y( ~
  86.   CAN_WorkModeLoopBack = CAN_Mode_LoopBack
    0 \( I1 e* K, `$ l
  87. }CAN_WorkMode;
    5 V- ]) C# l9 Q/ a6 h/ z/ \

  88. ; ?! Q# ]1 x: Y1 W
  89. typedef enum
    - k% y. l1 e6 _3 y5 ?
  90. {
    6 D7 b5 R" e- H( [5 |
  91.   CAN_BaudRate1000K = 6,
    ( E5 |/ [% H3 _6 |) W5 ^
  92.   CAN_BaudRate500K  = 12,
    9 [! c5 O/ B  r8 i& Z* h0 O! j- a
  93.   CAN_BaudRate250K  = 24,
    9 h4 `* s7 H* V  a- _
  94.   CAN_BaudRate125K  = 48,, k% _4 E. B& e8 ~2 ?: b* d
  95.   CAN_BaudRate100K  = 60,
    ; ]% l; Q& P! ?
  96.   CAN_BaudRate50K   = 120,
    - f% s1 z0 n4 _9 M* m  h
  97.   CAN_BaudRate20K   = 300,
    % ^2 }) n2 M6 I$ |% w2 ]  l( M" V
  98.   CAN_BaudRate10K   = 600
    ( k. t5 y4 ?8 Y$ C: \2 p+ M
  99. }CAN_BaudRate;: Z4 f+ Z5 d+ g, t; C4 b
  100. ) R1 N- \  k9 C7 I( y
  101. /* Variable declarations -----------------------------------------------------*/, v1 W4 q& ?+ ]) ]) {1 A, o
  102. /* Variable definitions ------------------------------------------------------*/
    9 i3 j6 F( n9 ^  [9 `0 N$ q
  103. /* Function declarations -----------------------------------------------------*/+ ]/ G: q1 E8 m" B" F
  104. void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId);
    6 m  Q3 |9 m6 p4 ~6 a% q
  105. void CAN_Unconfigure(CAN_TypeDef *CANx);
    % Z) ~- Z& G; F4 @& c

  106. : l& f# n: r; ~
  107. void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));
    , l5 Q, a- X/ v4 H) I
  108. void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));. M  D: F+ V/ W6 `. k/ W. d

  109. 8 n# h, l5 p* L4 f, t
  110. uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number);, M) S; r; x- c; P# Z
  111. uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number);) g- a' G" B  Z; B$ i3 F8 u) x: N

  112. 3 m  q4 o  D: \7 f5 x1 n; q
  113. uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx);# u5 s- \4 R( D2 ?
  114. uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx);' F& ]) y, U7 s+ l1 C
  115. uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx);- _; i' c7 n$ ]% v2 q' P
  116. uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx);
    : g2 K6 X& U$ Y+ }

  117. . ?9 V8 z( z# y; d' n! W
  118. bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx);
    + P. d& L( h# T- t1 J
  119. bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx);  G( ]: |. }( S( [* k
  120. bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx);1 L. K; `( g9 G1 x% w4 ^. N
  121. bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx);
    & _1 E- X5 |8 q5 i  X+ @1 X- E2 {

  122. 6 n. s3 A8 R3 D( K7 ~3 K0 t; I$ F1 e
  123. void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx);' S+ X$ O( Y% H: A4 \+ _
  124. void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx);" T1 a9 J& j* W' `, U

  125. - j+ o3 F2 I1 {7 I0 I, I6 F7 ?4 P( u" I+ S
  126. bool CAN_IsTransmitMessage(CAN_TypeDef *CANx);
    0 C# z9 @' X2 r5 o$ y9 r

  127. ; t! J( Q  R+ Z3 q# A) G$ T! j9 o
  128. /* Function definitions ------------------------------------------------------*/0 E2 i$ B" {' ^" X8 z4 b

  129. 4 [+ ]# y8 W* E* u6 ~$ O
  130. #ifdef __cplusplus' W! E  k3 q# Q& e
  131. }9 T7 R! n" P: T* [
  132. #endif2 H+ P. X4 a1 C
  133. 0 B1 G. h+ o" R6 e- o# Y1 A# Y
  134. #endif /* __CAN_H */
    ; x2 Q  x8 Y; ]/ o5 l; d* V
复制代码
2 }  G3 @8 u, r2 p
; f/ a0 ^- Y. b$ x

+ x/ n- h5 R. HCAN.c 文件
' L1 h4 j/ _# ]" |0 X* `1 Z0 T9 N: D/ U9 m& z$ j9 D  \
  1. /**
    ! s% L* o3 `' w1 W1 r
  2.   ******************************************************************************' I' n: l5 Q" U# e" d' s6 a
  3.   * @file    CAN.c
      b' ~$ C5 J. U. d
  4.   * @author  XinLi
    , j! t4 e; b- }; F0 ?! L  Y0 y9 [) v& Q
  5.   * @version v1.0
    . w( ~  g, h8 q) D. A1 r! K6 o) k
  6.   * @date    24-June-2018
    7 G5 T/ I& k) v/ I+ V" C/ G. M
  7.   * @brief   CAN module driver.+ d/ \/ W% A$ M1 b$ ~- j
  8.   ******************************************************************************  p) c6 z8 s/ z- K* v) @4 U/ c
  9.   * @attention
    . k0 v% a1 O9 `/ L) a7 n* D
  10.   *  ~& m3 x: ?% J9 E9 e
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    - Y/ L& h: Z4 W" V
  12.   ** P) I* V0 W! x) B9 ^  v
  13.   * This program is free software: you can redistribute it and/or modify) V2 W+ g4 N. s4 @+ O4 ]2 i- s- Y
  14.   * it under the terms of the GNU General Public License as published by
    & g7 ?$ X  ^. J2 i& \4 r
  15.   * the Free Software Foundation, either version 3 of the License, or
    & K& [7 `. y; f% ]5 i6 u0 i
  16.   * (at your option) any later version.
    8 S4 |, X3 k8 c3 V* |
  17.   *
    . j2 D+ ~8 M; n* {0 H# {' n1 Q
  18.   * This program is distributed in the hope that it will be useful,% |- b* @) K: D4 v$ m# k; b
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of: g5 X  p8 r3 I/ Q
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the1 F2 s. I4 {3 \/ f) U  z1 s' L% c
  21.   * GNU General Public License for more details.# ?% u  Q$ Y& x3 X% D+ P
  22.   *8 o* I$ A% ?0 Q; y1 I
  23.   * You should have received a copy of the GNU General Public License# F/ R3 P% `2 Y* N
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>0 n. c6 n: {- r! K( A- I( h
  25.   *; T. e; q* K2 J: u: ~
  26.   ******************************************************************************
    9 d9 B4 S9 G+ Y3 P8 V
  27.   */7 \5 R% o* [1 e" v. Y8 q+ t

  28. ! d4 y6 h, t) a+ ~" X8 B
  29. /* Header includes -----------------------------------------------------------*/% S. E) n* C/ k9 s7 a3 d
  30. #include "CAN.h"+ e9 N/ e" F9 z. [$ P
  31. #include "RingBuffer.h"
    / g& j: p" N3 z2 D) x

  32. 7 i  ^. w( B$ M! f3 V
  33. /* Macro definitions ---------------------------------------------------------*/; v3 o- _" }  m1 k7 b
  34. /* Type definitions ----------------------------------------------------------*/
    6 P2 m: }, a( x/ I) L
  35. /* Variable declarations -----------------------------------------------------*/
    # j& c: ~8 Q3 E1 A
  36. static volatile bool can1InitFlag     = false;  V" k" c% j  R$ |0 Q" T
  37. static volatile bool can1TransmitFlag = false;  V) b1 ~2 Z* o7 V% ^$ ~# E8 o2 [

  38. & @! e- D% P" _4 q0 A
  39. static volatile void (*can1TransmitFinishCallback)(void) = 0;/ [/ f, I9 E4 y5 Q6 M
  40. static volatile void (*can1ReceiveFinishCallback)(void)  = 0;; f8 G  l6 j0 m1 I$ L. e2 O. M

  41. 1 g! r2 F- _7 t
  42. static RingBuffer *can1TxBuffer = 0;; I0 j( C, {) W  o2 g5 K& v
  43. static RingBuffer *can1RxBuffer = 0;% q( H2 q; J' `- @

  44. 4 `# E9 ?: h% h- Y" H
  45. #ifdef STM32F10X_CL
    # x* T+ ~, m% O) q
  46. static volatile bool can2InitFlag     = false;
    # p# ?# ~/ H% {! ~; n* s9 f
  47. static volatile bool can2TransmitFlag = false;
    + p, j# X' N( X: z

  48. : I: A2 c/ l) ?' N# q6 S6 T
  49. static volatile void (*can2TransmitFinishCallback)(void) = 0;; R; ^5 @7 F! V" H7 {, P- J
  50. static volatile void (*can2ReceiveFinishCallback)(void)  = 0;
    ' x# Z3 H1 J9 v2 _+ o
  51. 7 J3 x6 M, _! y  w. D: |. c6 b
  52. static RingBuffer *can2TxBuffer = 0;' Q( t' C- t9 u' ~) n2 R
  53. static RingBuffer *can2RxBuffer = 0;# t$ D( c& `( B+ K8 `3 C
  54. #endif /* STM32F10X_CL */7 W. L3 v0 q$ v4 J' {  g

  55. 5 a, ?' i; ^6 f0 k4 `
  56. /* Variable definitions ------------------------------------------------------*/
    ) C9 g; v2 k8 l* z3 g
  57. /* Function declarations -----------------------------------------------------*// [4 b; j' C; o! I8 j& t: r
  58. /* Function definitions ------------------------------------------------------*/( }) i2 y- n; q- B5 S5 p: Z- b
  59. " _+ I5 j2 [& v, i4 Y, `( W/ y
  60. /**7 C7 t) i  b# }4 b1 ]$ @' e1 t
  61.   * @brief  CAN configure.
    ! G4 Q2 K5 n6 l. G) l
  62.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.
    # R: ]( N& y: ?5 j  g* D% D0 h
  63.   * @param  [in] WorkMode: Work mode.2 Q) p- _( e0 `) i. J7 b
  64.   * @param  [in] BaudRate: Communication baud rate.4 G0 E! N7 H, D! Q8 }" s! Z
  65.   * @param  [in] StdId:    Filter standard frame ID.& `+ _" T- s  v' M
  66.   * @param  [in] ExtId:    Filter extended frame ID.
    $ o7 |3 e" k3 w3 O; Y1 F0 X$ _7 S/ c
  67.   * @return None.
    ) R4 x+ i2 l& \9 `
  68.   */
    ) P  H2 x/ X0 h1 c
  69. void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId)
    7 t3 B; i$ O$ Y# ~+ g
  70. {0 @1 q1 V) ^# l) H% f
  71.   GPIO_InitTypeDef      GPIO_InitStructure      = {0};( ?# R9 X' Y3 @# z+ v! z
  72.   CAN_InitTypeDef       CAN_InitStructure       = {0};9 W+ |) W9 w/ p2 ?+ W# j
  73.   CAN_FilterInitTypeDef CAN_FilterInitStructure = {0};. F. M* |0 V4 F# }
  74.   NVIC_InitTypeDef      NVIC_InitStructure      = {0};9 H6 B( ~9 ~  D; P9 }
  75. 9 H% f/ ]: H2 H. J6 M% i# V; e) e
  76.   if(CANx == CAN1)
    % O5 |  R; x8 U
  77.   {0 {/ o2 r! f% l) I- w* b+ b
  78.     if(can1InitFlag == false)6 ~  v- [5 b$ Z5 U& k/ j/ b4 B
  79.     {
    . g$ u) B+ k% s* ]) C
  80.       can1InitFlag = true;7 ~& n& |7 d$ l0 ?2 u

  81. , k/ U8 ^0 b/ w7 F  V6 P
  82.       can1TransmitFlag = false;" E! E$ b. C* E7 p) M
  83.   u/ u) X% ^( u: K8 o! a: S
  84.       can1TransmitFinishCallback = 0;
    + o, C. U: A- C- {7 q
  85.       can1ReceiveFinishCallback  = 0;* v& M4 V2 O; i

  86. - U1 Q6 d4 B8 R, P
  87.       can1TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN1_TX_BUFFER_SIZE);
    9 V% g! I0 P& V$ l# W( J( x9 E, n$ F
  88.       can1RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN1_RX_BUFFER_SIZE);
    9 L9 E: z* X" V4 ^0 \3 f5 g

  89. / R* V1 U0 y: w
  90. #ifdef STM32F10X_CL
    . u8 I& k- d) z- \4 I3 u
  91.       if(can2InitFlag == false)% d; r  K& M4 S: O! U" L! R
  92. #endif /* STM32F10X_CL */7 V$ e7 l( Y9 J  Q6 T, v8 n
  93.       {
    7 o  k1 L2 V% Y; L/ e9 h2 G
  94.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
    9 L* u* i! `6 z, C0 J/ i# a
  95.       }9 q1 F7 S1 W$ W5 j( ?
  96. 8 T) _8 n. [' H) b" I9 z
  97.       RCC_APB2PeriphClockCmd(CAN1_TX_GPIO_CLOCK | CAN1_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);
    4 M6 N& o0 C% d. Q
  98. 6 Y5 q$ J+ T' c, G4 I* i9 }
  99.       GPIO_InitStructure.GPIO_Pin   = CAN1_TX_GPIO_PIN;8 i" R: t' E. c+ N: {5 Z
  100.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;+ L; q& @+ q( J: p5 ^5 h
  101.       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;6 z. j/ {* o& H$ U' u: E* X
  102.       GPIO_Init(CAN1_TX_GPIO_PORT, &GPIO_InitStructure);
    - d+ M$ L$ }! f: j* y' s
  103. 5 d, v+ f! t& b: A( ?/ G6 m
  104.       GPIO_InitStructure.GPIO_Pin   = CAN1_RX_GPIO_PIN;6 R  }6 p5 P, O' ]7 U4 S8 D
  105.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
    # r: d  R6 |* C3 [
  106.       GPIO_Init(CAN1_RX_GPIO_PORT, &GPIO_InitStructure);7 l' g7 l- k8 Q6 c' g, Z

  107. 4 {4 u4 p0 h0 r/ J3 ?/ o
  108.       CAN1_PORT_REMAP();- t( p3 o, U+ t$ z  |# J" U; u

  109. / y+ M1 q# |+ @, X# \
  110.       CAN_InitStructure.CAN_Prescaler = BaudRate;: D: ]2 |0 N$ e/ c( o9 A
  111.       CAN_InitStructure.CAN_Mode      = WorkMode;
    8 \0 `# `/ y& q  \0 f+ ]
  112.       CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;. ~- u9 Z& h. z2 i: E  F7 Q* x
  113.       CAN_InitStructure.CAN_BS1       = CAN_BS1_3tq;/ W2 ~  N# E3 ^
  114.       CAN_InitStructure.CAN_BS2       = CAN_BS2_2tq;4 w. G, d+ E% b4 s4 ~, @
  115.       CAN_InitStructure.CAN_TTCM      = DISABLE;" g- G/ m+ p# Y3 d: _
  116.       CAN_InitStructure.CAN_ABOM      = ENABLE;* x6 T( b" V8 L8 @8 Y4 E. X9 o1 I( K
  117.       CAN_InitStructure.CAN_AWUM      = DISABLE;. v: p8 T. h8 g. C
  118.       CAN_InitStructure.CAN_NART      = ENABLE;
    / G5 ~9 c0 ^; L! h: ^0 S
  119.       CAN_InitStructure.CAN_RFLM      = DISABLE;
    ) S9 r8 U- p- E1 B
  120.       CAN_InitStructure.CAN_TXFP      = ENABLE;
    % E$ M+ p; t6 c" P) W
  121. ) p* M( o$ N: t7 s" R8 N
  122.       CAN_DeInit(CAN1);
    $ X1 T4 I% f2 G- K( q
  123.       CAN_Init(CAN1, &CAN_InitStructure);
    . ~/ v( d" y& F
  124. 5 ^  T- R) c0 E! K/ M
  125.       CAN_FilterInitStructure.CAN_FilterIdHigh         = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);
    : t: F( Y8 \. {( |# s
  126.       CAN_FilterInitStructure.CAN_FilterIdLow          = (uint16_t)(((StdId<<18)|ExtId)<<3);4 \. l3 u& ?* n. O7 ^
  127.       CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;
    " f' T$ o4 ], `# C+ H. v
  128.       CAN_FilterInitStructure.CAN_FilterMaskIdLow      = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;" ~- z( [3 B# ~- n. Z7 ?/ z* B$ o
  129.       CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;  i+ T9 D1 f! ~( A6 M( f
  130.       CAN_FilterInitStructure.CAN_FilterNumber         = 0;
    7 P, M8 Y. t9 d% k$ ^1 h0 x
  131.       CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask;4 D/ S4 a  U$ T5 g# @2 e
  132.       CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit;
    7 x: T) W  n! I* J0 i9 y4 p$ O( S) r
  133.       CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;0 N& ?8 `/ p$ l
  134.       CAN_FilterInit(&CAN_FilterInitStructure);9 R8 M; n' o; i7 y

  135. ; B: c0 ~- w2 q! o
  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 |
    & _  A# s) X( d0 Z9 F* U/ ^# z
  137.                          CAN_IT_WKU | CAN_IT_SLK  |CAN_IT_EWG | CAN_IT_EPV  | CAN_IT_BOF  | CAN_IT_LEC | CAN_IT_ERR, DISABLE);- w: n+ [8 M1 [% Y8 @' T7 k
  138.       CAN_ITConfig(CAN1, CAN_IT_TME | CAN_IT_FMP0, ENABLE);
    3 W! o3 p! R' t  J& Q1 c; ~+ |. j
  139. ) W. @  W. O$ C# E) ^8 q
  140. #ifdef STM32F10X_CL+ {  ?; U( u; M9 @" a
  141.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_TX_IRQn;
    * ^. _% j0 ]" H& B
  142. #else
    ( o' v; R) d1 h  N
  143.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_HP_CAN1_TX_IRQn;) l; f, D# x- P3 Q# v1 v+ s: G
  144. #endif /* STM32F10X_CL */3 ~- @2 `6 ?6 E; Y* z

  145. " S* s* ?$ o% o  l7 z1 I
  146.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;7 j' R9 S; b* Y9 p; A0 L# ~+ c2 m
  147.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN1_IRQ_SUB_PRIORITY;
    - X3 \  O* ?1 r
  148.       NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    ' o2 a0 l: s& ]0 |  s
  149.       NVIC_Init(&NVIC_InitStructure);( r( z( O' I* _/ B7 K# O. ]
  150. & L: z7 v* @# Z8 w4 k' m
  151. #ifdef STM32F10X_CL8 q% U1 n5 x1 n: Q7 E9 R$ K
  152.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_RX0_IRQn;
    $ }) Z/ r. |- D9 }. R! j7 \
  153. #else
    5 }* b1 T5 _& L% r& y) O) ?
  154.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_LP_CAN1_RX0_IRQn;
    1 `8 o9 s9 E: W7 ~( J) R0 s/ |
  155. #endif /* STM32F10X_CL */
    * m2 C- F" o( q2 n

  156. 8 h( U  k# t/ k& v
  157.       NVIC_Init(&NVIC_InitStructure);
      j3 M& F- L2 U
  158.     }( u: }4 b, ?& d
  159.   }& c& O: F; A) g+ w2 p

  160. , c$ Z/ B5 |' z( c
  161. #ifdef STM32F10X_CL& K# ?. W* j1 g0 L# ]4 L
  162.   if(CANx == CAN2)# N/ L: p* v8 B5 b5 M( n
  163.   {) i4 a1 @* H& I  D
  164.     if(can2InitFlag == false)6 P9 U. u2 O5 N$ L0 c
  165.     {
    1 U& v+ R% b- `1 ^
  166.       can2InitFlag = true;3 }+ w& G3 x' v4 L3 r9 n
  167. 1 ?1 i. ^7 m2 r% J. v
  168.       can2TransmitFlag = false;
    # H& [1 }% G! R: P2 r

  169. ! K4 m: g1 B, @
  170.       can2TransmitFinishCallback = 0;
    - i7 z  i; S! _: H; U. O  U& |
  171.       can2ReceiveFinishCallback  = 0;/ g4 a4 a7 [- s' m0 _& f" h) r! u4 O

  172. ' j6 V9 r. D, D- J9 R6 c( T
  173.       can2TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN2_TX_BUFFER_SIZE);
    0 ?7 R( J4 Z( ^
  174.       can2RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN2_RX_BUFFER_SIZE);
    4 d3 X3 \+ B, Z) u, B5 a6 l! X

  175. 4 Y' Z" m0 z& d, _6 w: V! u: x
  176.       if(can1InitFlag == false)# x+ L. W- U0 b: y( g
  177.       {* Q6 L# D0 |# W" c, T1 B' }" a; u
  178.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);- b; g9 Z3 R: {9 k' ]% C
  179.       }
    ( K' o/ S& ?9 Q/ O2 i

  180. 0 K( x& x( I2 A6 Z
  181.       RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);
    # v! P  A, h7 y2 w" `; l+ P
  182.       RCC_APB2PeriphClockCmd(CAN2_TX_GPIO_CLOCK | CAN2_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);. o+ K3 n( \: `) H  q6 d- z& K

  183. - S$ U4 c! S* C
  184.       GPIO_InitStructure.GPIO_Pin   = CAN2_TX_GPIO_PIN;3 l# ^% G. l0 t
  185.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
    9 [4 z7 G. p! j; e6 ^" F
  186.       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    & x' Y" j- [& K; r) }1 e( l; T
  187.       GPIO_Init(CAN2_TX_GPIO_PORT, &GPIO_InitStructure);0 }9 e& @4 }, }

  188. 2 L: P5 p* _8 [4 O
  189.       GPIO_InitStructure.GPIO_Pin   = CAN2_RX_GPIO_PIN;0 R% ]+ y* B& w
  190.       GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
    7 W4 g8 f9 [- \0 \) R
  191.       GPIO_Init(CAN2_RX_GPIO_PORT, &GPIO_InitStructure);0 @) _6 P! j# K5 q2 k# }$ S
  192. + w: a* ]9 {/ l0 [  x: I' z: M
  193.       CAN2_PORT_REMAP();
    ' r9 X( _! ]  J; {! @7 _/ D
  194. % i& V  V2 ]- o  j
  195.       CAN_InitStructure.CAN_Prescaler = BaudRate;
    6 W3 O8 E+ ^. f
  196.       CAN_InitStructure.CAN_Mode      = WorkMode;
    ! ], Y* P) |2 E! q5 G4 n7 I6 r8 P, Q2 K. p
  197.       CAN_InitStructure.CAN_SJW       = CAN_SJW_1tq;, X- Q( e9 L; K/ Z6 q4 x4 {: x- N% C
  198.       CAN_InitStructure.CAN_BS1       = CAN_BS1_3tq;
    1 j8 e% T3 ^4 F: z
  199.       CAN_InitStructure.CAN_BS2       = CAN_BS2_2tq;  a" Z1 W! M7 o3 ]) U' [
  200.       CAN_InitStructure.CAN_TTCM      = DISABLE;/ D8 P( k! }' \9 E7 ~2 C
  201.       CAN_InitStructure.CAN_ABOM      = ENABLE;* O- `8 n- R3 O4 T
  202.       CAN_InitStructure.CAN_AWUM      = DISABLE;
    $ x4 {+ g" Z# P( L) e8 ~6 I( `) q
  203.       CAN_InitStructure.CAN_NART      = ENABLE;
    ) r3 J' O) L: E' R0 W7 t
  204.       CAN_InitStructure.CAN_RFLM      = DISABLE;
    7 Y7 h( R" t* q! P  t8 G) w
  205.       CAN_InitStructure.CAN_TXFP      = ENABLE;$ r5 H) J; k: E# |5 y9 D6 G2 a

  206. 0 H5 C/ K, \) E+ H) A* T
  207.       CAN_DeInit(CAN2);
    ) B6 p4 k4 |" D: X1 s5 Z
  208.       CAN_Init(CAN2, &CAN_InitStructure);! ^$ e$ [5 C# d5 m4 V9 r! }
  209. ; I: |" z$ f0 L2 O) Q% [- R
  210.       CAN_FilterInitStructure.CAN_FilterIdHigh         = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);/ y+ N# V$ z5 C+ q. N
  211.       CAN_FilterInitStructure.CAN_FilterIdLow          = (uint16_t)(((StdId<<18)|ExtId)<<3);
    . c9 b, q! G" Z2 ~1 V" ~
  212.       CAN_FilterInitStructure.CAN_FilterMaskIdHigh     = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;
    ! r5 o$ R  Y% l
  213.       CAN_FilterInitStructure.CAN_FilterMaskIdLow      = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;
    % y6 ^3 R: i+ M# Q& l; t3 C$ o5 G: J
  214.       CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;/ o8 U+ i+ l$ c. |
  215.       CAN_FilterInitStructure.CAN_FilterNumber         = 14;
    ; {9 ~. `8 O' o6 e7 J$ i! Q, F$ F# n0 z
  216.       CAN_FilterInitStructure.CAN_FilterMode           = CAN_FilterMode_IdMask;. X6 P9 |6 T6 J5 O
  217.       CAN_FilterInitStructure.CAN_FilterScale          = CAN_FilterScale_32bit;7 R0 Q! p- y+ o. b  X/ w
  218.       CAN_FilterInitStructure.CAN_FilterActivation     = ENABLE;
    2 E2 F$ ]7 W0 C+ |  J  _; x5 O% |7 M
  219.       CAN_FilterInit(&CAN_FilterInitStructure);$ C: G- Q0 l, Y
  220. 8 S, d; j- M% O$ c- |
  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 |7 [" S: m$ Y5 W" H' y
  222.                          CAN_IT_WKU | CAN_IT_SLK  |CAN_IT_EWG | CAN_IT_EPV  | CAN_IT_BOF  | CAN_IT_LEC | CAN_IT_ERR, DISABLE);
    ( S, R6 H) L6 D5 M0 B
  223.       CAN_ITConfig(CAN2, CAN_IT_TME | CAN_IT_FMP0, ENABLE);
    ! ?6 J4 f9 W$ ?; [
  224. 8 N2 [& q0 F9 p, @
  225.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_TX_IRQn;
    / O  ~: K0 |. Z  U
  226.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;
    5 Y9 W, n# P0 a
  227.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN2_IRQ_SUB_PRIORITY;* q$ k; v5 _9 O7 F$ T1 X
  228.       NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    3 \2 A& }, X" w& w. [& R5 e
  229.       NVIC_Init(&NVIC_InitStructure);  |! R4 M0 u0 ?( s" ~. W
  230. 6 a' [' M& w/ v3 X, f+ i2 z
  231.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_RX0_IRQn;
    0 q8 o; m. n+ y# A' l
  232.       NVIC_Init(&NVIC_InitStructure);5 S# ]) `3 T5 Y0 A8 G2 r! Q7 C
  233.     }) u+ W# T7 T7 L  l# [, c7 @5 B3 M
  234.   }( ~) m4 h! Q2 m! `4 h
  235. #endif /* STM32F10X_CL */: H/ f; V: A% M, Q  N
  236. }
    8 j% f# U( y( w& A6 d$ g

  237. : W/ F$ g# E' S
  238. /**
    " M  @) z! G, K* v4 Z" n/ e
  239.   * @brief  CAN unconfigure.3 E$ [/ X7 W7 _5 u& v2 q. u
  240.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.+ I& i( ?9 d# c( e8 F7 H' u
  241.   * @return None.
    0 w) ?/ R* a+ p3 |1 l$ X7 l  Y
  242.   */% H. ]& s% A+ _) c0 ~  Y* Z' }
  243. void CAN_Unconfigure(CAN_TypeDef *CANx)
    ) o$ \- I* B  a" W0 z
  244. {$ ~9 B5 w3 R4 j6 N
  245.   NVIC_InitTypeDef NVIC_InitStructure = {0};
    2 c- Y4 b9 W* W( I+ B& F& [% z1 e

  246. ; _( e' }. ^1 \5 ^% j! `: q3 r
  247.   if(CANx == CAN1)* R0 j" P6 g5 j5 u3 c8 Q
  248.   {
    + F: p0 ]* e) {% {2 G
  249.     if(can1InitFlag == true)7 `* P5 O/ m/ Z9 F8 K- c( n
  250.     {
    $ n. k  _! V2 B" o1 ]6 L( w3 l/ R
  251.       can1InitFlag = false;5 L% H9 X3 r% h
  252. % k$ G1 p4 \5 H, _6 \; e& q2 ^
  253. #ifdef STM32F10X_CL9 U+ d# q4 z3 N5 V& a; P4 L
  254.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_TX_IRQn;9 S8 s3 G6 H8 A; _% E; R# B' @
  255. #else' j8 m2 l# _, @  Z- K+ G( U
  256.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_HP_CAN1_TX_IRQn;9 @$ @2 F" b# w  q$ o
  257. #endif /* STM32F10X_CL */
    " A# C6 N" P& f! @4 p! N
  258. 0 j2 Z3 a/ A* |3 \2 F
  259.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;
    + J: D  Z, r% b4 m
  260.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN1_IRQ_SUB_PRIORITY;  L% A5 o6 P+ D, x
  261.       NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;3 J/ b5 i! P8 q/ p: g0 ?2 p* t. k
  262.       NVIC_Init(&NVIC_InitStructure);
    0 g: i3 O' e- u1 E6 v
  263. ) R2 O+ t* [7 t3 t
  264. #ifdef STM32F10X_CL
    9 u% N3 S( q+ K( z
  265.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN1_RX0_IRQn;# H5 _! a0 W3 q: ?3 a% g2 \& j
  266. #else: i( Z/ G8 s: n8 Y$ Z6 s
  267.       NVIC_InitStructure.NVIC_IRQChannel                   = USB_LP_CAN1_RX0_IRQn;
    + S) s/ h8 ]) e& Y) ^
  268. #endif /* STM32F10X_CL */- J- f7 D4 c8 R4 T! q! m# s& y5 ?' e
  269. ! h; l, C4 C1 i6 G/ m+ L
  270.       NVIC_Init(&NVIC_InitStructure);5 W$ P: t: F8 N6 h' h# @  i8 M
  271. * {( \  Q7 v# j' s3 y" I) b
  272.       CAN_DeInit(CAN1);1 Q: r' J' N+ C9 H
  273. ( H6 ?$ G4 q7 [/ B
  274. #ifdef STM32F10X_CL* X0 X" c0 [) f
  275.       if(can2InitFlag == false)4 U, `' B% R( @1 H6 O- Z
  276. #endif /* STM32F10X_CL */! Z0 I1 U8 T% E- ?4 e4 t
  277.       {2 T4 }: ?6 C8 t1 `3 }9 A) U7 _
  278.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);& B8 m% S/ c+ q9 e9 ^6 f
  279.       }
    $ P! b9 l+ b$ }1 i% A1 i: r
  280. " C/ X, b+ l: ~5 k; k# h+ K
  281.       can1TransmitFlag = false;
    0 ]/ u7 ]& I) l: G* v. B

  282.   j- B& H' n; f0 t8 n" B" f' K
  283.       can1TransmitFinishCallback = 0;
    ) o* `& g, [" m/ Q
  284.       can1ReceiveFinishCallback  = 0;& y* d% q! V! d9 v7 r- X3 I' W: r

  285. 6 M2 w; T4 F$ [# Z) v5 I
  286.       RingBuffer_Free(can1TxBuffer);" B- G/ O. p+ K; P6 s/ N2 ^- T( L) r, _9 ]
  287.       RingBuffer_Free(can1RxBuffer);0 |/ J/ M" @4 l9 O# ~/ h
  288.     }3 O; `( q( |% i$ R' @) y8 Y( u
  289.   }
    6 P. W; Q( K4 k' n" O* j# v+ }
  290. 0 m+ N- r' o* @0 H" d. M4 j
  291. #ifdef STM32F10X_CL
    0 ]  }: I( B2 b4 o. i3 h( x: X
  292.   if(CANx == CAN2)3 r5 g* I$ ]: r* i
  293.   {& [* ]  u1 G  }
  294.     if(can2InitFlag == true)1 ]8 {! P, t* e- e
  295.     {
    ( W5 @3 u8 t2 D
  296.       can2InitFlag = false;
    ! P% p- m) F4 w

  297. ! d9 k% g5 Q" n
  298.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_TX_IRQn;
    # h6 O' }. ~! ?: q4 P( F* g
  299.       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;
    7 `- h' x! G& f6 p9 }. M4 @
  300.       NVIC_InitStructure.NVIC_IRQChannelSubPriority        = CAN2_IRQ_SUB_PRIORITY;
    5 [( K: D( r! U' s* q, s
  301.       NVIC_InitStructure.NVIC_IRQChannelCmd                = DISABLE;
    , H4 M% w6 X& t6 w. t+ U* q& Y
  302.       NVIC_Init(&NVIC_InitStructure);3 ]8 a- Y7 h/ g

  303. . {7 \8 Q$ t8 a0 Q( C
  304.       NVIC_InitStructure.NVIC_IRQChannel                   = CAN2_RX0_IRQn;! [# ?1 p* |6 r  \; {( v5 I$ ?
  305.       NVIC_Init(&NVIC_InitStructure);0 v- \5 h$ D4 ?3 E2 b

  306. & ?% R; c% t2 j/ U$ O
  307.       CAN_DeInit(CAN2);/ V* Y+ q8 j  U/ Y8 P
  308. ! a0 U& Q3 j  F+ {# s3 m( j
  309.       if(can1InitFlag == false); f6 f) e4 N1 z$ E' V+ `5 A; V' E
  310.       {
    , L1 @! P: i5 ]* ?! ?' S) A7 U. Z
  311.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);
    ) a# s) R) C6 \
  312.       }
      @6 U+ ~( o2 }% M4 _

  313. - {% Q0 K- m7 p, L7 i
  314.       RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, DISABLE);
    : ]  L0 V: r% m% z- d: k% J# ~

  315. - L. X- k4 e! N( A
  316.       can2TransmitFlag = false;
    + t! H: ?8 u* M; y6 f( B- R! K

  317. 5 D! i) E% T2 W: a8 \" O
  318.       can2TransmitFinishCallback = 0;
    ) b  g. i7 @% l# b
  319.       can2ReceiveFinishCallback  = 0;) l! O7 y4 H9 ?% ]" K* I
  320. ( \8 H8 T8 D6 N% W5 D
  321.       RingBuffer_Free(can2TxBuffer);! |5 [- b. @5 a) I* b- ~; f. Q# _
  322.       RingBuffer_Free(can2RxBuffer);& \% ^' c, D2 ^! k! L% L. J# H
  323.     }7 ^% {" H  |9 U7 S' E8 f! o
  324.   }
    1 k( o0 N6 O1 f+ G6 j" D
  325. #endif /* STM32F10X_CL */
    7 Q# K: w. I/ _6 n7 r: l" N* f
  326. }9 F" d6 V* m9 z+ q$ q

  327. * V( [0 q$ r% T9 n& a' z
  328. /**
    * a3 f1 x# ~2 K. p
  329.   * @brief  CAN set transmit finish callback.7 N* C2 n2 y, }5 E7 r
  330.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.% r. X; v6 [# _5 P2 L" a2 K5 L
  331.   * @param  [in] Callback: Callback.
    / L) o. H2 y& \9 N  ^; U- ^" |3 r
  332.   * @return None.! Z, \8 e9 x$ E
  333.   */
    & p! w0 z' `8 |
  334. void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void))
    * k- k  F2 U2 N( L4 O; B4 F5 S
  335. {+ K1 _( [, w/ d1 S- ]
  336.   if(CANx == CAN1)
    8 z4 z9 N: c* K; ^8 _  f5 ^$ |
  337.   {
    3 ^3 s) N  e  Y; Y
  338.     if(can1InitFlag == true)% f/ Q5 o: P" ~7 q: d6 ]1 M
  339.     {9 g+ S& R# H" `& C3 e
  340.       can1TransmitFinishCallback = (volatile void (*)(void))Callback;: r9 [/ N3 X, o5 Z7 o# Y3 J8 z; w
  341.     }. @4 i2 b3 t/ b; I3 {" W
  342.   }
    0 R: @. [% S0 R7 R  B
  343. 8 R5 k) a1 I+ K7 C0 c
  344. #ifdef STM32F10X_CL
    / o- U) ]5 d; O- F7 X0 l
  345.   if(CANx == CAN2). p( f5 b2 O) Q+ O
  346.   {
    ! R/ o2 a/ w, @$ E
  347.     if(can2InitFlag == true)
    9 [' T6 p& A8 z' S' v  q3 |, A3 ^- S
  348.     {4 u9 d0 z% A7 @& ^, K0 T
  349.       can2TransmitFinishCallback = (volatile void (*)(void))Callback;3 W* K' l  h9 N& l  N
  350.     }
    . w0 J$ |; j3 C- @# L& V0 Y
  351.   }
    : Q' P* v6 u# T$ }( h5 [
  352. #endif /* STM32F10X_CL */0 m( P( a: N9 _6 [4 T) }2 w1 v7 Z: z- J
  353. }" V6 G( X& c3 G4 h: R3 q8 Y. X

  354. 4 r# c. {; K! z; O$ \
  355. /**
    ( t/ S" S& I6 j( e, U5 V1 |; n
  356.   * @brief  CAN set receive finish callback.' A! d) Q' `1 y; Y
  357.   * @param  [in] CANx:     Where x can be 1 or 2 to select the CAN peripheral.
    * E0 b: U; s3 `, s, O7 n" |
  358.   * @param  [in] Callback: Callback.) n8 ^7 s$ ?" h( v  V7 v) @! b
  359.   * @return None.+ |0 J& |+ d/ Y! \8 I9 o
  360.   */
    1 h: u$ h% {' V; }/ h
  361. void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void)): h( T; K( C6 o
  362. {
    4 I2 G' k5 j: |  e; ~
  363.   if(CANx == CAN1)% y' G  s* Y: G
  364.   {
    ( X2 W' ?- N7 ]( V" L
  365.     if(can1InitFlag == true)* z; s0 b3 q5 a
  366.     {2 b8 q+ I3 m+ Z! v3 ~% [
  367.       can1ReceiveFinishCallback = (volatile void (*)(void))Callback;( j" d2 @- a6 p6 J0 |
  368.     }- }/ q8 T$ o- u* S
  369.   }5 r5 l9 l) I$ W
  370. 5 Q" c  Z6 c$ i
  371. #ifdef STM32F10X_CL
    % w- Z  |) `3 n7 A0 F; V8 ~5 D
  372.   if(CANx == CAN2); m# k2 h" v9 ^+ n7 y0 B5 g
  373.   {& ^  f. P) t, G, {4 }
  374.     if(can2InitFlag == true)
    * r+ y8 e' q  z: C$ ~
  375.     {: [& l& x# Z: o9 q- x
  376.       can2ReceiveFinishCallback = (volatile void (*)(void))Callback;
    # ^2 O/ t0 j: a' B
  377.     }
    2 L, R" }( l' k7 c/ D  x
  378.   }+ M; S8 Q! w) n% j
  379. #endif /* STM32F10X_CL */- D* V2 j  ^7 ~! J8 y
  380. }
    ' L/ o" ^4 W( @4 B5 f
  381. * M5 G; K3 q. _- c* }2 ]7 s* [
  382. /**% u) q5 e6 i1 r* b# z; ~
  383.   * @brief  CAN set transmit message.# V3 t: j9 S) n/ U9 e
  384.   * @param  [in] CANx:    Where x can be 1 or 2 to select the CAN peripheral.8 `4 }  M! J" u9 j) s7 J
  385.   * @param  [in] Message: The address of the message to be transmit.( z! F" o: W/ k0 }7 ]
  386.   * @param  [in] Number:  The number of the message to be transmit.
    / J5 p8 g# \2 E& I  t
  387.   * @return The number of message transmit.1 X5 [8 Z( _; g: X7 l8 [
  388.   *// o9 h# A$ F3 H6 Z- \/ c" g
  389. uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number)
    / x4 N7 w; [0 ~# ^3 i; h
  390. {' H5 n4 l3 @0 q% S; z8 b8 c
  391.   if(CANx == CAN1)/ I: |0 w) B' e1 t8 {
  392.   {, w$ V/ F5 d3 p7 F7 V. y; L. v" M
  393.     if(can1InitFlag == true)
    5 C2 H( q  y8 L
  394.     {% {; N' V2 J$ t
  395.       uint32_t available = RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);
    $ a% p, Y- r9 b- V7 `. |
  396. + f# j2 z1 D, i+ b# |( B
  397.       if(available > Number)
    1 V0 I1 j' S- t8 c2 H, Q* r, x6 ]
  398.       {
    ; C8 |8 n) E, I0 p
  399.         Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);" I) @3 W* ], Y6 Y: K
  400.       }
    * ~& x/ P* U( J
  401.       else" \: j- j! k4 i6 o/ |
  402.       {( N5 ~/ P8 H5 O, ]7 {
  403.         Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);" A1 h5 g5 p1 k+ J# h8 V
  404.       }6 O; A( R3 O2 ?7 [1 R8 C3 i$ v

  405. ) k. z8 T' k: z. ?  d) F$ t' z
  406.       if(Number > 0)
    & g. b4 E8 L$ p  y' q! I
  407.       {$ x& x7 c* M6 _
  408.         if(can1TransmitFlag == false)
    ) I% y8 v+ J* N% s
  409.         {
    6 m" U8 d7 \' F# F7 U
  410.           can1TransmitFlag = true;' U, T( H1 Z/ S5 \+ R4 |3 \3 r* V

  411. + V, x( l& g3 }; y
  412.           CanTxMsg canTxMsg = {0};
    3 g2 H) {. D$ _- o# C$ i
  413.           RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg));
    ! r& Y7 ~, a# I( A3 Q0 x4 V
  414.           CAN_Transmit(CAN1, &canTxMsg);
    $ v* ^* A) v6 Y7 q& z
  415.         }
    1 }3 T! b8 _) h
  416.       }% o6 o  a8 ]/ Y" r

  417. 3 d. g7 N9 F, r$ j
  418.       return Number;
    - ?: y, G& ~, a; ]# a8 U" k3 d
  419.     }# n/ _1 Q$ e$ H* e9 E
  420.   }
    % f+ g9 h( I% L1 x+ |. e9 E* Z
  421. 8 e6 a- v% @1 v: ]1 O2 N
  422. #ifdef STM32F10X_CL, H  b4 A% w) V8 `: ~
  423.   if(CANx == CAN2)
      m0 c% |2 |7 Z8 t5 W8 e# ?. f" |
  424.   {) d6 j6 }7 s1 p! f/ g6 P
  425.     if(can2InitFlag == true)/ w: S$ E0 r; z8 X8 S' a. o% H2 t: G
  426.     {9 Q% m# t8 V3 @/ F/ w# C3 K  G
  427.       uint32_t available = RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);
    : d3 ~. A( F* P: T, c( P+ o
  428. ; O' r6 U. Z4 k5 Y6 l2 ?! P
  429.       if(available > Number)7 m/ E, F# l: _
  430.       {
    - V' G: e- z$ y6 X* t) i
  431.         Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);
    3 g  Q' a% _$ T
  432.       }, m! z# w6 M+ v# Z/ ~" U" m
  433.       else
    6 R6 \% M2 P, u( P
  434.       {
    * Q% W2 _. M) T% n% o5 [. J! P, ?# X
  435.         Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);
    + o) p+ |+ c! ?9 S0 a( |1 S
  436.       }/ F6 Z4 }1 M6 Q3 J- ~% i
  437.   B5 B" l# h1 S3 x7 Q
  438.       if(Number > 0)
    ! [* v% x0 ?! p* a* Q7 ]
  439.       {
    % W3 h+ s; ]0 g) `9 q' _4 X
  440.         if(can2TransmitFlag == false); Q2 e& {" C. T3 V7 {1 L: X+ E1 \8 H5 ~
  441.         {
    * }5 J5 L1 R/ y5 j# Q( a3 \
  442.           can2TransmitFlag = true;9 u; w5 K" r* V! ~4 B

  443. 6 H" a3 V& E* S5 J6 Z
  444.           CanTxMsg canTxMsg = {0};+ x5 _* E8 M% C/ `% V& a% N
  445.           RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg));
    5 [* r2 B% M" ]/ b/ B6 y2 L; S, d
  446.           CAN_Transmit(CAN2, &canTxMsg);) d% w; O. m5 Y1 K5 Y7 D2 O, N
  447.         }
    1 Z- L3 v6 B2 v! X1 o# w1 [: W. _0 |
  448.       }& M) L6 W! m/ R  n  T

  449. & o# X3 A% T& O  j( C2 I! ~: b9 m
  450.       return Number;0 J) t9 s" ?5 a6 s- o
  451.     }
    ) \0 Q! f8 \! v9 u' D% K! e
  452.   }
    9 O0 f+ ~. \- c- W3 b, _+ ?$ N
  453. #endif /* STM32F10X_CL */
    - q. w7 z0 T5 Q, t5 U' r  r$ A2 A9 D1 d
  454. 8 z: T" F% ~0 ~6 R* p
  455.   return 0;
    ) j1 c; s4 x3 f3 o/ |. F2 R
  456. }
    % q1 V& B! g  ]9 [7 q( K9 S

  457. ! A. u2 C# W: j0 z0 r" ]' `
  458. /**
      s/ I# I7 R; Y5 _1 J2 I) b
  459.   * @brief  CAN get receive message., g% O" M2 g; K: t. f0 I
  460.   * @param  [in] CANx:    Where x can be 1 or 2 to select the CAN peripheral.
    1 |" ?) v5 o1 w2 }
  461.   * @param  [in] Message: To store the address of the receive message.7 b( q4 Z2 t0 ^: Y0 u; l  ?
  462.   * @param  [in] Number:  To read the number of the received message.- I' F% G; O' \0 g# s2 r
  463.   * @return The number of message obtained.
    , t& @1 t( V% |/ ?4 m
  464.   */. w) A) a- C. @, J1 k2 ]$ u
  465. uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number)6 S$ Y! m- ~  B9 t7 v0 t* v# }
  466. {
    . D2 x/ I: F7 v# k! ?/ P  N/ d
  467.   if(CANx == CAN1)
    - y/ \. ~/ K* m$ Y, n% b8 b* ^
  468.   {* p' B9 E( {  `; i! [
  469.     if(can1InitFlag == true)! g, S1 U3 c  Q) C1 a
  470.     {
    ! n) c8 t. Y) K9 ?
  471.       return RingBuffer_Out(can1RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);
    8 }. s7 u: l$ [7 ]9 \
  472.     }- K( b1 y& b# c; a5 T
  473.   }
    * b2 Y9 s4 b' v9 M
  474. 7 B7 n; V" ~9 O8 p9 b" A
  475. #ifdef STM32F10X_CL, a  h7 ?/ ^1 s6 s6 a3 C  N) H/ |
  476.   if(CANx == CAN2)5 [9 i% }- G6 J( S
  477.   {
    * F0 d6 T9 S) B( D) K
  478.     if(can2InitFlag == true), ]9 k. m' Y8 W9 q* Z6 Q( O
  479.     {
    ' W( c: k- U9 N( y& i8 M7 n+ U4 ?
  480.       return RingBuffer_Out(can2RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);
    ; L- a: ]" s8 D0 v9 y- U
  481.     }
    ) ]: I5 e( P' j* Y0 d
  482.   }
    ( e. J7 M. q4 J; V0 b' u
  483. #endif /* STM32F10X_CL */
    0 v6 }7 `# \8 \- h8 m# a

  484. " J9 x# c% {& x+ }( V, o' Q
  485.   return 0;5 P) A! ?: l& U5 _6 L* p+ K
  486. }
    , l! K1 R* _  l3 B* _/ s% g1 C

  487. ( N$ v6 }% c! f* P1 N
  488. /**
    % F' I" P# H8 d6 A4 ]
  489.   * @brief  Get the size of the CAN transmit buffer used.
    2 F+ Y* k8 V) l$ L
  490.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.0 x$ w) m4 S/ @9 v4 y+ g9 L% h
  491.   * @return Used the size of the transmit buffer.
    5 R$ l1 _1 e" g. G1 d
  492.   */, r' y( R6 E( K5 g
  493. uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx)6 m7 i: D# U5 a! D
  494. {" W" }+ \$ M& y) Z; a  v
  495.   if(CANx == CAN1)
    # e! f, t! e& b3 ^* n
  496.   {  D. l3 l; V; M
  497.     if(can1InitFlag == true)7 y( z0 @2 r/ R1 u3 [$ t
  498.     {: h/ z8 [: C- Y6 D
  499.       return RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg);
    ; L+ b% O" J8 T) O/ j
  500.     }
    3 y) S& B' b% h6 `1 n: T
  501.   }5 ]! I$ z3 A$ n' ^- l& X

  502. 5 h$ @' o. o# Z# S" H4 I4 L
  503. #ifdef STM32F10X_CL
    + Q5 i, w6 E5 f. \( E7 n5 G
  504.   if(CANx == CAN2)
    ' H" P' f. m/ k" }- P
  505.   {
    . z( j: l- X5 N3 x" `
  506.     if(can2InitFlag == true)8 M1 D) g  g6 y
  507.     {; K4 f: F% [- F: }- l) U
  508.       return RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg);
    7 u; L7 K% `, g6 F
  509.     }
    & y: _/ d! w1 P5 b  X
  510.   }
    5 V$ l3 u! F5 s7 J) _, d
  511. #endif /* STM32F10X_CL */
    ; s' v; B3 G% F
  512. ! L6 Q7 j( h0 u4 g2 W/ O
  513.   return 0;
    - i) Y: h  T: U, s. i
  514. }% e! Z) u% {* k8 {( [

  515. # c. M: m  M9 {! p1 w/ I- E3 L- L9 g
  516. /**
    ( n, i" @/ k- B
  517.   * @brief  Get the size of the CAN receive buffer used./ |6 J- s1 {( M9 P/ j2 L
  518.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.# ~" n/ ~! I$ H) A) Y
  519.   * @return Used the size of the receive buffer.
    $ T6 I/ @! c3 o2 u
  520.   */
    4 F7 c7 C; v- o' t2 j* Y
  521. uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx)5 {2 P( M8 b$ ~" {& {3 ]
  522. {/ B1 G- P/ T# j9 {: }, I
  523.   if(CANx == CAN1)
    : C/ q* \- B$ U/ b) k1 \. Z5 u
  524.   {
    * m, x6 K" v' v' {! |2 y
  525.     if(can1InitFlag == true)9 r9 B$ n, G8 y( u* {8 d1 D
  526.     {
    & ~5 ~) |+ z" H! \6 g
  527.       return RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg);
    : M- P6 A0 B; Y% q0 N8 l  G
  528.     }; Q5 e) S2 [  W
  529.   }
    + y* A, s- l4 n; U" M

  530. 9 |) m5 R4 f  X7 O8 w3 q
  531. #ifdef STM32F10X_CL
    : O3 U# @. ?8 a! T4 R8 h" A
  532.   if(CANx == CAN2)& C; I- M8 k/ Y& J6 j: m
  533.   {2 I; ~4 e" Y6 Y
  534.     if(can2InitFlag == true)5 ?8 I! q2 [4 x$ f: G
  535.     {* m5 E+ o, R, t( p
  536.       return RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg);0 n3 s" e9 g0 s  ]( v; l
  537.     }' ^6 a6 ^0 T1 n8 @: D
  538.   }
    0 Y9 c4 b: p" K2 w
  539. #endif /* STM32F10X_CL */. y' d0 U: P: K5 ^: q. v" f. A
  540. 8 k4 p$ N: v6 j
  541.   return 0;" b2 U$ @, W" B
  542. }' T% [( ~. @2 e/ O' W+ b
  543. 8 f% ^. ]7 v: g" y
  544. /**
      ~: `; w+ g8 J
  545.   * @brief  Get the size of the CAN transmit buffer unused.- }/ M' G! f+ C+ |% {6 T; K0 E
  546.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.2 W* J0 ~6 w5 n/ R/ p1 q  X; ^
  547.   * @return Unused the size of the transmit buffer.
    6 [9 h( N1 f3 M3 G# _+ Q' L2 ]
  548.   */
    4 ]3 P. c. i7 F7 M+ O% `
  549. uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx)
    ) B  e9 F5 ^  Q" L6 t
  550. {
    7 ]% b# m& b6 x& S, q4 d3 Z
  551.   if(CANx == CAN1)
    . P2 y0 V; y& |: c8 p- e
  552.   {) s" F1 s8 S& g& @6 b) j6 D- W
  553.     if(can1InitFlag == true)9 m1 ^. K. {: t3 {
  554.     {1 G% m# l$ t. A8 g3 `! y1 {5 Y
  555.       return RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);. `( [4 Y, Y7 E5 s# |: n3 S! ]
  556.     }2 R8 x4 O8 v8 b( l( t/ @
  557.   }. p$ i# H5 f4 d4 v

  558. 6 ^# ]! m) Q" m' V; ~8 a. d# Z
  559. #ifdef STM32F10X_CL8 m" v9 V! I# }0 ]' ^& p% y
  560.   if(CANx == CAN2)
    % W' O7 l9 d4 H# B% z! T8 v5 P3 N
  561.   {) m: [" K- n' W5 Y" E; N" Y8 X6 L6 s
  562.     if(can2InitFlag == true); E+ P! W. U: h" q7 F' _! ]
  563.     {& z% Z$ z; w; y" z6 N' S5 Y' n9 o
  564.       return RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);) x9 G; j+ G5 O7 l! i  o
  565.     }
    + z4 S) T1 a+ f
  566.   }( |$ A2 j/ u# U$ ~- s1 J( j6 ^
  567. #endif /* STM32F10X_CL */6 x* M, Z. c; o$ h
  568. + J3 Z9 M; {: P/ ?. O  w
  569.   return 0;+ h6 o- Z  f2 e$ i
  570. }0 N6 w6 O- o. D$ Z* R

  571. " y+ j' s) b6 k0 v8 \
  572. /**
    7 {: x# G. q7 w1 g* K
  573.   * @brief  Get the size of the CAN receive buffer unused.
    % D: E+ w& [. c. H- S0 `/ v2 K
  574.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    % S( @/ _4 I7 ]' o# [5 k2 X
  575.   * @return Unused the size of the receive buffer.! q0 S) a6 X  ~+ L
  576.   */
    : E+ V% L0 ?3 t9 F1 Y
  577. uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx)
    6 R9 V) u) c- \
  578. {
    5 R- P% m; t5 T9 k( K
  579.   if(CANx == CAN1). E/ w% F4 ~% X3 t( ~
  580.   {
    8 G& [- @$ Y0 f! f
  581.     if(can1InitFlag == true)
    6 [) |4 l; m5 ]7 Z
  582.     {4 o( c* n2 f2 e+ Y4 R. H
  583.       return RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg);; C- w1 j6 V& v. f0 G
  584.     }
    " Z' f- k  {$ G. n7 V
  585.   }
    - m' v' S# k. B" E1 ~# s0 L
  586. 1 a) u  X6 ]9 G& E* J, Z9 g
  587. #ifdef STM32F10X_CL
    7 X9 k, @. O7 n. u
  588.   if(CANx == CAN2)5 z3 [" T4 \' q2 u' N$ D
  589.   {+ A" s9 F! k. x- g. }
  590.     if(can2InitFlag == true)/ J7 h# e3 ^5 C0 n' m# j
  591.     {; i# H# i7 J+ s# R: n) t1 a
  592.       return RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg);
    8 M2 m* `% D0 D# q" v$ k
  593.     }
    - ^' M; R+ R- z" T4 x
  594.   }5 W. r: {! R; |- b, l: Z/ H
  595. #endif /* STM32F10X_CL */: N# J8 |) x8 ?8 ^1 O2 y

  596. . H9 p, `+ v- e, b( B
  597.   return 0;8 x; y/ r/ j; p. s# y8 K
  598. }3 L) {5 q4 B6 q- b3 |0 O

  599. 0 c3 H9 ]$ n/ D  b% U8 y( ]
  600. /**; w8 c- O# k% F7 u8 b! T: `
  601.   * @brief  Is the CAN transmit buffer empty?
    & B- W' L$ f" Z) P
  602.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    $ H) d6 n7 J" g$ }  {
  603.   * @retval true:      The transmit buffer is empty.
      l3 r$ W7 y! C9 ^7 ~
  604.   * @retval false:     The transmit buffer is not empty.
    6 ?* ?) \( _7 z  z, F
  605.   */
    - N$ Z: B- \" Q5 C+ k4 Y' _; M
  606. bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx)
    2 q, y+ e: Y1 ]5 h, b# {8 T
  607. {
    " k  T$ Y$ U  U. A) Q# K2 o1 t# ?3 V9 E
  608.   if(CANx == CAN1)4 `# L% l- a6 i
  609.   {
    + E  r  w/ o& B5 q
  610.     if(can1InitFlag == true)( W  v8 M  O7 f2 g
  611.     {# e" N# b; {( I5 _+ J/ |
  612.       return !(RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg));5 I6 a( i& E+ n8 `( J2 m
  613.     }  _, {. C+ x3 D
  614.   }2 `# w- Z( O3 t; F6 v8 o
  615. ' }6 E4 M0 [6 `* y( J8 L$ L
  616. #ifdef STM32F10X_CL. `  r& N$ k4 J& A2 E2 F/ t1 _
  617.   if(CANx == CAN2)
    + d9 Y: X) e" ?4 r/ M5 g/ W
  618.   {: e6 w/ ^) a5 K0 T3 n, ]/ K/ c
  619.     if(can2InitFlag == true)
    5 [7 n  m, v  ^' \# a' X4 g
  620.     {
    + x  G) O! Y3 g0 H5 n# S  ]' `7 M
  621.       return !(RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg));
    / w) A1 ~% I+ I) N  d" U9 B! b
  622.     }
    5 v/ N! D/ K6 L% \* v1 y
  623.   }# J1 H0 g, _1 L
  624. #endif /* STM32F10X_CL */0 H0 b# V6 J3 k+ c
  625. # I3 I, _; E# u; t4 q/ T8 S
  626.   return false;$ L6 v5 w+ D" K, {
  627. }
    " w. y$ x' ~' g
  628. 1 L5 U6 O! j  H3 F
  629. /**+ `& o1 k* Q# [
  630.   * @brief  Is the CAN receive buffer empty?
    % o2 A& X0 G2 f; K3 c4 [* l4 i& p
  631.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    - W4 b  Y3 I$ Z% p( ^# Q1 ]6 |, w! Y
  632.   * @retval true:      The receive buffer is empty.  g- n& u$ U) R9 d8 G
  633.   * @retval false:     The receive buffer is not empty.% F1 s( r  p) N( p: B5 u8 [
  634.   */! V! Y$ _$ T" `4 e% x
  635. bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx)
    6 n+ T; D9 D  e! ^+ a7 O, I
  636. {7 T5 w( `: w1 x7 K2 ~
  637.   if(CANx == CAN1)5 N& u: k) |. y% c3 Y
  638.   {
    : K" w; e# _6 ^
  639.     if(can1InitFlag == true)
    ' D% i" f  `: k* [/ }$ ]
  640.     {
    . D3 {& m! b+ p: q/ z5 ~" G
  641.       return !(RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg));
    " M4 U7 V9 D( K$ h& P& [, W1 W5 n
  642.     }4 v4 U. r% M& ^2 s3 r) F5 o1 [8 l
  643.   }
    " F! h" Z5 X; |* {

  644. ) }6 W! V' G5 w9 G
  645. #ifdef STM32F10X_CL* C4 t3 D+ h/ D- I. ^* o
  646.   if(CANx == CAN2)5 G. b& y! k5 }2 P3 V6 y2 }2 _
  647.   {
    # d6 v# r4 ~7 \! j
  648.     if(can2InitFlag == true)
    8 Z# y. l4 p3 _% v5 C6 n) M, A! {
  649.     {
    . x4 ?( V, s* ]. P$ c! Q8 q
  650.       return !(RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg));
    ) `$ h! N5 f& w  k/ Z( O
  651.     }
    7 `' A9 r2 ~  Q6 c  o: \* v. G
  652.   }
    0 D, h* H4 E- |9 W/ f1 h
  653. #endif /* STM32F10X_CL */9 ^! |+ p+ `+ e) d
  654. 2 T" S- a1 _* _3 v
  655.   return false;
    8 H1 n$ h: D' f4 _
  656. }. ~$ c- \; y4 k3 j

  657. , K# ~  u4 v% j& e' ]
  658. /**
    ( n8 c% h5 e+ \& }* x
  659.   * @brief  Is the CAN transmit buffer full?0 E8 `6 D' s5 y
  660.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    ( {6 {7 f/ }; e$ m
  661.   * @retval true:      The transmit buffer is full.
    / n8 f+ L" a0 @, i8 }. C+ E4 j- e
  662.   * @retval false:     The transmit buffer is not full.
    % o! u; ]9 k3 t3 w* S
  663.   */# [/ X0 w; ~2 m# K
  664. bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx)" V! h- n7 W' j, z! ^
  665. {" T" E( v8 P( |# v" i0 u& N% \. R' q) X
  666.   if(CANx == CAN1)( y9 d1 H2 K1 W3 }- U
  667.   {: a; u: L% }9 P9 s4 U- N, G
  668.     if(can1InitFlag == true); u7 ]4 ?$ H; Z6 p! d
  669.     {- H& z# J, i" x5 A- h( p+ @
  670.       return !(RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg));
    & l8 `+ q1 y  O. ?+ ?- A
  671.     }( r! {! p# D  c! L, M
  672.   }
    7 r+ l7 R7 m$ H1 J- }1 a# l; T* I
  673. 6 d- d2 e5 {! s8 U) D' @* y
  674. #ifdef STM32F10X_CL
      o' P( t! q, V9 K4 J
  675.   if(CANx == CAN2)- U8 h; o* [2 U' ?+ c% Y1 o& X
  676.   {/ M, K, I* Q! S* u+ Q' N
  677.     if(can2InitFlag == true). D/ e( h6 }% \' _
  678.     {
    2 r4 ~7 C5 F  r6 w
  679.       return !(RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg));
    " v2 I9 \0 a9 i9 |( w( G9 h2 ?
  680.     }1 @$ }2 g$ e3 ?
  681.   }
    1 R0 M5 k- C6 l) t9 y  L) ^
  682. #endif /* STM32F10X_CL */
    ' ^. o4 ^5 A4 q

  683. 7 L( O' n/ z& f6 H% I! G- z
  684.   return false;5 P& }6 a  n, l) L7 ^
  685. }
    9 f9 }8 ^& W* ~6 g2 n; m& u; e
  686. ! Q* Q# w7 q2 i7 U9 h8 s
  687. /**! t# y7 O( |- R5 V" K
  688.   * @brief  Is the CAN receive buffer full?
    - I$ f6 e2 L. Y& u( l/ n0 Q
  689.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    ) v, D9 c" n6 X9 r3 F5 X
  690.   * @retval true:      The receive buffer is full.8 g" E/ w6 b  p
  691.   * @retval false:     The receive buffer is not full.2 x/ e; D4 P+ p
  692.   */2 p5 {4 Y1 g; s- p) B+ e0 j
  693. bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx)$ x5 O! |" _5 |, m& z7 Q5 H
  694. {" Q3 Q  c0 X% \3 z
  695.   if(CANx == CAN1). a' G- t& ~' |, d$ [
  696.   {
    0 E- y9 g  }3 t' [( y
  697.     if(can1InitFlag == true)
    8 j3 W- Q5 u& x% Q$ V% p! K
  698.     {- N, y% |4 I" `- {! D( N' {$ s0 q
  699.       return !(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg));
    2 N  B/ W$ R. N8 t# F3 f1 H
  700.     }
    $ Y  a! ]+ r! C! ^2 s$ b2 A
  701.   }
    5 S. N) M+ f. W- l" C" m) e/ @: u

  702. : V9 r$ `& J% v
  703. #ifdef STM32F10X_CL
    0 {" Y1 p2 [  u% Y, f, C. Y! i
  704.   if(CANx == CAN2)
    3 F4 [5 v) W3 O+ l& h
  705.   {
    , |9 O# G# M8 C7 Q5 D
  706.     if(can2InitFlag == true)7 }* Z; {* d5 l; I4 T: L# t
  707.     {- H% G8 y$ l  T+ q$ W" c4 _, f
  708.       return !(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg));
    ! O5 c" i/ _5 d& a
  709.     }
      k" Q- h  l; O9 D- R
  710.   }
    4 s/ n( U- K7 R5 i$ L
  711. #endif /* STM32F10X_CL */
    - C! |: c, Y' b8 l! B* f' A
  712. 1 Y" O5 q( w3 Q/ G
  713.   return false;  J$ [5 z+ M) @6 R5 g5 w
  714. }
    6 t/ q# s' `; K7 E* ]

  715. 9 t) B6 N/ `: r
  716. /**8 Y* d( q9 ~  @1 a: V/ l
  717.   * @brief  Clear the CAN transmit buffer.! ?' _" `8 n& y4 N
  718.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    ) R/ d' w3 C# B2 Z1 d
  719.   * @return None.. w3 }- j  I' i9 Q9 o& J
  720.   */& \6 D& w! ~. C4 m
  721. void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx)6 p/ a" s+ |+ u3 h3 u1 f6 a7 @* @
  722. {8 C; o) W+ C  g" V
  723.   if(CANx == CAN1)
    , ~  z4 T5 |: {5 [( w
  724.   {
    + A& A1 q, |0 x4 f0 n* |# q* P
  725.     if(can1InitFlag == true)% ?$ w8 o; W$ V. q1 `
  726.     {
    - D2 @# g1 r! W0 g4 J( _; g
  727.       RingBuffer_Reset(can1TxBuffer);
    2 P9 a! _# \- k  ^( p/ e
  728.     }9 y) X! H5 K; a- _- H
  729.   }
    5 {: B' [8 B0 u! ^  [" o

  730. , e! T- ^9 B5 _6 V0 a4 _" _
  731. #ifdef STM32F10X_CL
      v: N( R3 J9 d) w9 }! ~
  732.   if(CANx == CAN2)
    2 @$ H! }2 T  Y* _$ b3 q3 [- q$ y
  733.   {
    9 O( v8 }/ u0 S. m/ C3 T  v$ W, f
  734.     if(can2InitFlag == true)
    5 i" f0 H  a% M  ^
  735.     {# I/ v1 [- M' }) i9 O- h9 x
  736.       RingBuffer_Reset(can2TxBuffer);9 Q# v- i5 f9 l3 C/ W& @
  737.     }
    5 o5 D! ?- t$ [# ^
  738.   }
    & C. q1 Y) ^% k0 S2 Q" m" o
  739. #endif /* STM32F10X_CL */
    - V4 Y, i  Z+ o! j. o7 |" Q
  740. }! H5 j% a3 \* h  J4 z: L% C
  741. + }  T: [  z* J' d8 @: Z1 h
  742. /**; O1 L' P( {. p- u8 D
  743.   * @brief  Clear the CAN receive buffer.: o+ v9 z. t0 T/ x5 K  B) I: @: {
  744.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
    4 R' s: \4 c/ y3 I8 i- q* \
  745.   * @return None.$ |: s% ?" t! V& I5 k5 d6 n
  746.   */( k5 d- r$ ]  C; C
  747. void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx)
    : w4 A$ X5 K2 s, z& y
  748. {; S' P, W6 }8 X2 J  p5 a
  749.   if(CANx == CAN1), M7 u) b0 _' }
  750.   {8 e4 X# L1 {( z  K
  751.     if(can1InitFlag == true)
    1 \& Z" h+ i/ _5 I+ ]- i$ x
  752.     {* {( A$ H* n- S2 y7 E& t/ X
  753.       RingBuffer_Reset(can1RxBuffer);" E' Q' F% B0 G. o2 Q& d
  754.     }
    3 C8 o8 C& X2 Z, X4 J: O7 R
  755.   }
    0 I" Q% [6 U; E+ m0 R* y( O

  756. 7 L, Y9 _! j# r
  757. #ifdef STM32F10X_CL' n- X+ N9 |6 y: B: V; a1 o+ c  y# T
  758.   if(CANx == CAN2)
    9 l; U: I* `+ I1 I* _
  759.   {
    - q# A2 \; f3 J3 Q
  760.     if(can2InitFlag == true)
    7 {6 k7 o9 m& B; z9 X; ^' b* F
  761.     {
    - D$ o4 c0 i, L  B/ W5 z& c
  762.       RingBuffer_Reset(can2RxBuffer);) y9 Z  u5 O, S7 i. d- g
  763.     }
      A* `. t; t2 p. D
  764.   }  x: ^, Q7 E& x) i5 _% b! d# P
  765. #endif /* STM32F10X_CL */: j, C7 r, E/ S7 r( p, d5 q
  766. }
    5 O. ^9 @) ~9 z4 D, I  ~6 v
  767. . F( ^' \) n4 X% x
  768. /**
    ! J+ Q2 m0 D& [, u% y5 K8 a4 p
  769.   * @brief  Is the CAN transmit a message?
    6 A# k' }. H: S1 N0 p* G7 y
  770.   * @param  [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.) K/ }) T: d+ }" c- G
  771.   * @retval true:      Is transmit a message.) k0 F! {6 E. t6 }+ Q
  772.   * @retval false:     Not transmit a message.
    ; z2 j; c, |* V* ~) P
  773.   */. C& _, }. [6 _, n( G
  774. bool CAN_IsTransmitMessage(CAN_TypeDef *CANx)$ [9 {$ [: J( P, c1 s2 W: @
  775. {
    ( \& z& x' @% A5 [0 n3 U0 ~
  776.   if(CANx == CAN1)
    . ?& V. J2 X" i& X+ p7 Q. i
  777.   {
    & m: ]6 s9 o. z0 r5 Z! R
  778.     if(can1InitFlag == true)
    4 i# c$ J. }2 ^4 ?; H7 D
  779.     {
    4 `8 J# W) u6 R8 S
  780.       return can1TransmitFlag;
    ; B' }1 w0 a! F: |) n
  781.     }
    # o( w" q6 b; G
  782.   }
    , ]7 d. n% Q4 ~1 _( r8 C
  783. 7 M2 K4 X* G1 W! J( s7 R
  784. #ifdef STM32F10X_CL
    / Y. h' ]. q9 K6 D  E
  785.   if(CANx == CAN2)
    : H# l; |# u: U
  786.   {5 v# m" u+ l8 A5 ?" ^
  787.     if(can2InitFlag == true)
    ( x4 `0 F) V" E" a( g* i
  788.     {7 ~% f1 L4 ^3 \( M1 g9 R7 T+ K
  789.       return can2TransmitFlag;/ Z" r! l2 B" q5 P
  790.     }7 q$ A( U0 o1 w( Q, |# @: y
  791.   }
    ! b, G+ @- Q7 d" W3 F3 R( Z, l
  792. #endif /* STM32F10X_CL */, t- M5 p5 Y* p+ Z, @+ Y& Z
  793. & e1 O& g4 }5 u, N9 Z' S! b1 J
  794.   return false;6 R  H9 z7 K; g+ I" v2 |4 W
  795. }
      s# q6 M1 m1 t* ^* a
  796. 3 r; b2 e- |$ u5 T0 n& e
  797. /**
    ) |& T4 e4 M) E! `: |. \
  798.   * @brief  This function handles CAN1 TX Handler.
    5 z2 o/ P& E% g% i" @' W
  799.   * @param  None.
    9 u- k7 {3 @& r0 @$ G# d
  800.   * @return None.0 p$ y: a% B) w- e" M! H5 J
  801.   */3 l  }$ \" p3 ]2 C
  802. #ifdef STM32F10X_CL* N2 N1 O2 l% I1 ~4 I+ S6 h- A
  803. void CAN1_TX_IRQHandler(void)2 k$ w( k( i) [4 C+ t. l- H
  804. #else
    : O: b$ u! L( q, H' @
  805. void USB_HP_CAN1_TX_IRQHandler(void)2 V; ^& d# Q4 X( C7 d* W
  806. #endif /* STM32F10X_CL */, x5 t: P, d2 p% ?! Z3 c0 S
  807. {
    4 G) R$ C5 a0 I% j0 L
  808.   if(CAN_GetITStatus(CAN1, CAN_IT_TME) != RESET)0 y. V+ c- A$ a+ k
  809.   {
    7 L5 f0 V; e6 {+ M
  810.     CAN_ClearITPendingBit(CAN1, CAN_IT_TME);
    4 T! n, V. k* Y- p6 T: a+ m, i

  811. . \  w# M- S6 U2 x7 F' w
  812.     CanTxMsg canTxMsg = {0};' K7 {; b: z6 E, X5 S- {4 l3 \
  813.     uint8_t  number   = RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);, z  x! S0 R5 o  \4 @  |" J) ]$ ~! i

  814. 9 M" x8 Q' Q2 ?+ _" I8 K- B/ P
  815.     if(number > 0)
    6 i) ~( R  w2 ^5 m1 z
  816.     {. k5 I( ~% @* Y. D4 g
  817.       CAN_Transmit(CAN1, &canTxMsg);3 _( d8 ?0 l0 w& m% L
  818.     }
    $ n/ j! H& ~$ _  w$ m( o1 o
  819.     else
    + \( j4 Q1 k8 H# i/ z0 G
  820.     {! f, T7 m" J" m7 @# C) ?/ U
  821.       can1TransmitFlag = false;
    * j3 q1 o9 v# N' P; Q
  822. # W! l7 T& p0 m
  823.       if(can1TransmitFinishCallback != 0)% n# V4 Z+ o# @" h; Y& K- z
  824.       {
    ) E* ?1 i+ o1 g- x( ]
  825.         can1TransmitFinishCallback();7 W9 |# F& g$ `& ~
  826.       }
    ) r* c* M" K& p% m' G5 o2 F3 x
  827.     }
    " @8 u* j" N1 V' e7 ^
  828.   }
    4 S/ |5 M" q1 w
  829. }
    2 A# R( S! s8 P, J/ q

  830.   W  c7 K" {: Z" `4 e8 _: P: Q7 d
  831. /**7 D) H4 m; V) q$ U& z: I: C
  832.   * @brief  This function handles CAN1 RX0 Handler.
    1 h" E8 A( }0 w# k& E5 I) q
  833.   * @param  None.: S- V* _! o7 j
  834.   * @return None.8 r7 p  v2 Z' y! q
  835.   */0 t, d, e$ i+ p( m! ]
  836. #ifdef STM32F10X_CL
    7 Z3 E. B2 H/ d: W4 U  e
  837. void CAN1_RX0_IRQHandler(void)
    ) H/ j3 W& T9 }' {" q& ]2 e" z
  838. #else
    ) `. c6 E) t% h( g
  839. void USB_LP_CAN1_RX0_IRQHandler(void)
    ; ^; Q8 i: v3 t5 k) k+ X# T3 m4 y1 g
  840. #endif /* STM32F10X_CL */) c- v# s- f; w/ I; w% c& k* A
  841. {
    . ~  d/ a7 Z% x9 U. ]; s& S
  842.   if(CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET)# e/ ]% B" @9 g
  843.   {
    * {( a* a; f0 X2 ^2 n
  844.     CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0);
    0 Z0 D; u4 B# B" |
  845. ( Z1 H% n$ T0 v. T% l
  846.     CanRxMsg canRxMsg = {0};
    / E8 M1 {  D3 ?$ r. \# K2 {- ]
  847.     CAN_Receive(CAN1, CAN_FIFO0, &canRxMsg);
    & b# a  [1 f% [! J6 x4 J  ?& o
  848. 6 k6 I# k# H' T! b
  849.     if(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg) > 0)
    $ o; V" A7 ^& _
  850.     {# j* j4 S. l; `" i6 k5 }. T( I
  851.       RingBuffer_In(can1RxBuffer, &canRxMsg, sizeof(canRxMsg));7 s- V, i, X' }. ?% ]1 N4 v% B( f
  852.     }6 j/ C% O( w1 C% h

  853. ) p' j4 U$ d  I* d
  854.     if(can1ReceiveFinishCallback != 0)0 S* z: e. L0 m7 w: h+ U
  855.     {
    6 g3 U$ N: J- A+ \
  856.       can1ReceiveFinishCallback();. N# n& B4 |/ t  l5 h
  857.     }
    5 W& }  X, L3 ~
  858.   }
    3 G0 i7 \) T2 P& d3 N! l5 y  }9 g
  859. }2 _# F( x/ w* J* H) e0 o. D) D$ A
  860. 6 }7 {# ~, h1 ]
  861. #ifdef STM32F10X_CL3 m" C% S- a5 ^* Y& l/ j- l5 p) Y
  862. /**+ m* d' [' m- T7 F
  863.   * @brief  This function handles CAN2 TX Handler.5 A! A9 u1 X6 J. z4 E  v
  864.   * @param  None.
    + g- b+ `' i' ]) l9 J$ i  M( Q
  865.   * @return None.. [1 }/ A" p1 d( V4 T
  866.   */1 Z- f3 j2 e4 N! l5 q$ O
  867. void CAN2_TX_IRQHandler(void)
    ! ]6 p2 O: b0 g8 k( R, l
  868. {
    7 Y9 o; {9 m* @- ?% c  A
  869.   if(CAN_GetITStatus(CAN2, CAN_IT_TME) != RESET)4 l! z: Z! ], k6 c2 x
  870.   {
    + G/ g6 Y4 N) J8 t4 j& Q
  871.     CAN_ClearITPendingBit(CAN2, CAN_IT_TME);
    # \6 ^* _+ q0 a9 c
  872. ' X0 j# s2 f4 U* a9 V" e+ x% S+ G, \
  873.     CanTxMsg canTxMsg = {0};
    8 g6 O6 s6 a7 A3 h& v4 Z+ `2 z
  874.     uint8_t  number   = RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);3 r$ ^' d: R9 y& g1 Z
  875. 9 G7 h( z4 D) |. U
  876.     if(number > 0)( d3 `( h* {) o& x* B4 Z
  877.     {) u7 t1 _7 v5 K& h' Y0 g
  878.       CAN_Transmit(CAN2, &canTxMsg);) h( t% N4 h) }% W* y
  879.     }0 ^& l0 }- |2 t% I3 V" G
  880.     else
    6 ^& J- z9 @2 C6 x0 }7 F
  881.     {9 R( Z/ ^2 v8 x0 e
  882.       can2TransmitFlag = false;5 R6 Q: n8 l8 P4 o

  883. * k+ n5 U% P  M7 G0 y
  884.       if(can2TransmitFinishCallback != 0)
    8 f& o4 s  }  ?% D- Z5 K
  885.       {
    0 r7 A: A5 M, l5 @- D, w: j
  886.         can2TransmitFinishCallback();: b: ^  ^! Y7 J, N
  887.       }+ _9 b" b5 o7 z$ u
  888.     }
    + h  k2 M! `+ T( {1 A+ q- S
  889.   }
    9 g' f  R6 B4 E2 |+ V5 M
  890. }  N* M% x" x& P
  891. : }; Z1 [5 r3 r- R1 A* `) X! z3 k
  892. /**
    2 d, K3 K9 K( P
  893.   * @brief  This function handles CAN2 RX0 Handler.& O& `( [9 o* r( _! n
  894.   * @param  None.
    ; _. ^: @/ P; I& v- M
  895.   * @return None.4 R$ T0 g( B+ g* f
  896.   */  P9 w  c! n+ s) Y7 F, l
  897. void CAN2_RX0_IRQHandler(void)4 P% ?. ]' v" L; s% [, n: O
  898. {+ \; Z0 @# M( A) l
  899.   if(CAN_GetITStatus(CAN2, CAN_IT_FMP0) != RESET)
    4 q- q7 `# ~  W$ N" q- V
  900.   {
    4 y7 M9 Z7 [# L
  901.     CAN_ClearITPendingBit(CAN2, CAN_IT_FMP0);; t6 j+ p. x( o* |' \

  902. 5 r+ V0 L, x$ q1 l: i( o2 V
  903.     CanRxMsg canRxMsg = {0};9 I$ ]" F4 c, h
  904.     CAN_Receive(CAN2, CAN_FIFO0, &canRxMsg);1 V1 U% l- P5 j, a
  905. ( i+ d: z5 J/ k; u7 _6 x
  906.     if(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg) > 0)% \; l+ a0 m( W, B: V
  907.     {
    9 [8 `. C' F& k9 X/ y; T' P
  908.       RingBuffer_In(can2RxBuffer, &canRxMsg, sizeof(canRxMsg));6 W+ `* z1 @5 t; r  f
  909.     }; w+ g: T" G( {! C

  910. ' y8 p  U! U0 d; v
  911.     if(can2ReceiveFinishCallback != 0)
    5 H5 J* M7 g( g  \. Q# d4 T( K; M
  912.     {* L( }1 D) s5 g
  913.       can2ReceiveFinishCallback();
    0 n0 `% j# r! p" A1 n' L
  914.     }$ O9 s' P2 t2 e! {6 i" h
  915.   }* |8 N: i9 |6 f( D* a1 d. z
  916. }
    5 d8 S( s) z5 g. ]; n
  917. #endif /* STM32F10X_CL */) q$ C- k# }# j; N
复制代码
5 ?! y4 G, T5 P' ~* _

& p* z, I8 T2 c% z0 Lmain.h 文件
8 S  z3 f) [3 v) {1 a$ X
  1. /**7 a# w' T# R& \$ w; Q
  2.   ******************************************************************************
    ( _% |" m4 Q7 `' J
  3.   * @file    main.h5 C! x: x, p5 n! ?
  4.   * @author  XinLi
    . T, Q& j+ D7 \, r1 w
  5.   * @version v1.0- }0 C, O2 v* ~+ r6 o$ |
  6.   * @date    24-June-2018
    ( Q. a1 E4 {$ E6 |6 W! ~
  7.   * @brief   Header file for main.c module.
    ( Z6 N1 V4 s+ B8 B/ [
  8.   ******************************************************************************
    ' d; P" U9 G5 J) w- v$ r' h
  9.   * @attention. n" t. F: Y) C3 w" L& p
  10.   *
    ) Z8 L; E; K/ }6 Z+ D! e4 T9 y
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>
    ! q) T( D: m' Y4 h3 q: z3 I; N
  12.   *
    9 [  I7 }& O5 s  W$ Q
  13.   * This program is free software: you can redistribute it and/or modify
    + F/ c& u# Y; s9 W1 ~' A- Q
  14.   * it under the terms of the GNU General Public License as published by
    8 o9 P1 s3 S0 S
  15.   * the Free Software Foundation, either version 3 of the License, or
    + m7 M# v+ o  v* }# H$ N
  16.   * (at your option) any later version.5 w! W$ w0 F" P+ x
  17.   *" F: b$ L2 T* `  N9 B
  18.   * This program is distributed in the hope that it will be useful,0 p- u% {, c4 S9 m. W
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    8 Z7 U4 O: M2 G1 l$ c& [1 r
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    # i; B% u2 p( ?, z+ X
  21.   * GNU General Public License for more details.& ?7 E. P! v2 G1 ^
  22.   *6 \: C7 ~! T* C" P; }. y) F
  23.   * You should have received a copy of the GNU General Public License5 n1 `; P- c- |/ [
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    ) _; _0 Z6 u% ]* x1 Y; t( r  e' y6 a
  25.   *6 V" K5 Z( q9 e, E8 h6 _
  26.   ******************************************************************************
    . g* E: t: H- i( c  n
  27.   */* j# r" [9 b# t  |7 ?/ T
  28. 2 _- D( R4 S9 P" C# x/ \9 L
  29. #ifndef __MAIN_H) }8 ^6 Z1 W) K  y0 D6 P: b3 a3 |7 |
  30. #define __MAIN_H
    6 v: F# \5 s( I$ c  V. k8 e
  31. 5 S1 d% s" x) b7 s) ]5 H
  32. #ifdef __cplusplus( B7 x8 a4 U) U& L2 \: N8 l
  33. extern "C" {
    4 q( n5 w' t7 S, s
  34. #endif
    : f6 x1 n) G; t
  35. + p6 O: b8 k9 z; x- n" s
  36. /* Header includes -----------------------------------------------------------*/
    6 B  a6 S& f9 [4 t
  37. #include "stm32f10x.h"# l7 H( K& }  X4 S
  38. : D! B1 I0 z$ t# A/ h, E
  39. /* Macro definitions ---------------------------------------------------------*/. L% M1 N5 |- m# b, n
  40. /* Type definitions ----------------------------------------------------------*/8 Q  n! G3 b* f5 G  ?
  41. /* Variable declarations -----------------------------------------------------*/
    ( ^& L3 B6 \1 I2 Q+ X" J
  42. /* Variable definitions ------------------------------------------------------*/
    . P- R3 s; U& h( t
  43. /* Function declarations -----------------------------------------------------*/
    * h$ e1 H% [0 d: x4 z! X3 T
  44. /* Function definitions ------------------------------------------------------*/
    # @8 n" a1 k! D) p: H1 k9 T6 \

  45. 0 y6 S- b4 v/ r( ~2 D- Q2 G
  46. #ifdef __cplusplus
    * ~% c2 {+ }; Y/ _% ]  B
  47. }% U2 O+ v3 k& W: b6 r6 _- j* ]3 f- H
  48. #endif' M% S4 ~- ]: d0 k' S6 [/ q. G
  49. 0 p! ^. X( |/ s6 v" n
  50. #endif /* __MAIN_H */
复制代码
; K: ^: e- a! a( Y7 F) f
0 z: F2 C  f0 |2 Y7 O
main.c 文件
  s6 T# j) W6 ]
  1. /**1 h( Z/ u! G/ n, L
  2.   ******************************************************************************$ K( H# y  S5 J+ q0 J" W
  3.   * @file    main.c
    + H3 k& H6 l3 n9 D/ H; U
  4.   * @author  XinLi7 a$ n9 y) t) d2 C! V
  5.   * @version v1.02 D. t1 M7 j% _) }; B5 j! s
  6.   * @date    24-June-2018
    7 v$ M! u; k# d3 w  q; r- b  U
  7.   * @brief   Main program body.+ P% H2 _* T& `8 X+ p8 ~% [% G% h
  8.   ******************************************************************************
    $ r! Q. O$ c, l6 n% {8 _8 H6 r
  9.   * @attention
    " q8 \( N6 |% ^" y
  10.   *
    / ~  y+ \2 y4 m5 D/ V' m
  11.   * <h2><center>Copyright © 2018 XinLi</center></h2>, @5 ]- e8 F( V+ g( Q$ W* \: I: c
  12.   *0 N: N% J' R1 s
  13.   * This program is free software: you can redistribute it and/or modify
    + T/ h3 ~/ k: _3 G
  14.   * it under the terms of the GNU General Public License as published by  ^- Y* l3 o& a5 K8 R1 B1 @1 n
  15.   * the Free Software Foundation, either version 3 of the License, or
    % y. N. @& g- p2 k. m
  16.   * (at your option) any later version.
    ! C2 f- X  R. V. F7 k
  17.   *0 m/ A, P6 }2 i7 x
  18.   * This program is distributed in the hope that it will be useful,- d0 ?% A! c- x1 u( v; c
  19.   * but WITHOUT ANY WARRANTY; without even the implied warranty of8 ~; t7 |6 s+ z. S* l6 B! T8 a
  20.   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the- j7 t  |1 ?9 Q; {
  21.   * GNU General Public License for more details.
    ' A; l: r" p  ]( w1 w( s( s
  22.   *
    * E1 p' G9 _1 N. K+ Q
  23.   * You should have received a copy of the GNU General Public License
    1 J6 n$ t) e$ U
  24.   * along with this program.  If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
    3 o& G( _1 n- w. E9 W. k( G
  25.   *
    & ^4 |8 Q+ t$ \4 n* f! a
  26.   ******************************************************************************" W# e  @) o# O3 K  V8 ~
  27.   */8 l, {6 L  ]2 n% Z0 v) O  ^

  28. 1 q! t+ Z% L% n* g8 q$ o
  29. /* Header includes -----------------------------------------------------------*/8 _( ~) J+ b+ a+ f/ l& l1 |/ G1 F
  30. #include "main.h"0 ?  _  O1 U/ {7 O
  31. #include "CAN.h"8 R5 c1 w! K3 e3 ^6 z% q, C1 b
  32. 3 X7 N+ w, _3 t: G9 g' k
  33. #ifdef _RTE_
    % P0 S8 |) c, i! h7 e
  34. #include "RTE_Components.h"3 p; n) q' W" i& s* j. R% `
  35. #endif
    ) A8 M, Z# L1 X& [. R+ K
  36. ' x' f; a% T; s: ]5 {! W5 e# C  c/ b
  37. #ifdef RTE_CMSIS_RTOS2  z6 m0 v7 m- u8 q
  38. #include "cmsis_os2.h"
    : H3 T4 y- v( X" k1 r0 w
  39. #endif
    ) ^0 I% s5 a; r3 E2 T! |

  40. ( {1 ~; `" [# A0 `$ _
  41. /* Macro definitions ---------------------------------------------------------*/9 y- z' S$ B8 p9 _: U9 ~0 N; t
  42. /* Type definitions ----------------------------------------------------------*/
    + {4 ]9 v5 e- @+ |
  43. /* Variable declarations -----------------------------------------------------*/, J. |" e3 P5 |  G9 @5 w0 k2 t
  44. /* Variable definitions ------------------------------------------------------*/
    - f, z' q0 e+ H* S0 I9 e8 ~! T
  45. static CanTxMsg canTxMsg = {0};
    ( L7 s' o  e" p8 T; F$ Y" ^4 I
  46. static CanRxMsg canRxMsg = {0};7 Q* H; K. l$ `+ n& m4 X

  47. " i' ~8 x2 o& j
  48. /* Function declarations -----------------------------------------------------*/' ^) C  t& }# n( {
  49. static void SystemClock_Config(void);
    , i# ^* B" Y" s0 m9 J4 b& `6 O

  50. % G7 S) A1 X% Y" T" ~$ Y
  51. /* Function definitions ------------------------------------------------------*/9 ~9 s  u' H  l  P  K& ^
  52. ! S9 d' v6 k5 k$ N; Z  b9 l
  53. /**4 N2 V+ J& u; g  ]& u+ o& _
  54.   * @brief  Main program.
    * v, I4 L. F$ l! K, y4 z% I3 J
  55.   * @param  None.
    , l$ T3 z! B1 d; D
  56.   * @return None.
    0 j! S! b* q7 H! b( H- A
  57.   */7 j* Y, o. g9 n4 v
  58. int main(void)$ v8 J8 \& a' Q- a* O
  59. {
    $ K, @4 z7 \0 I7 t' R7 }) z. \
  60.   /* Configure the system clock to 72 MHz */2 x+ z6 N" D2 N' n! F' h$ u1 b( G
  61.   SystemClock_Config();0 g# T- E5 r6 o. ^4 f3 g
  62.   SystemCoreClockUpdate();% X9 Q2 l8 \8 H( F7 H
  63. + c' M$ G6 o6 c$ d) h2 O- e
  64.   /* Add your application code here */7 m; t8 b- ~+ m% c- |- f
  65.   CAN_Configure(CAN1, CAN_WorkModeLoopBack, CAN_BaudRate250K, 0xAA55, 0x55AA);
    & R0 T5 e6 ^( O, Q0 ~- o0 k

  66. # B& y+ {. M! M. j# Z
  67. #ifdef RTE_CMSIS_RTOS20 B6 F& G  r1 A
  68.   /* Initialize CMSIS-RTOS2 */6 X% o" `# U) h: Z
  69.   osKernelInitialize();7 M9 n3 U2 t+ @, L: a6 U
  70. : G+ r3 f# l! {2 H* ~$ S
  71.   /* Create thread functions that start executing,
    6 Z* k$ U2 F7 Q1 U4 B4 ]
  72.   Example: osThreadNew(app_main, NULL, NULL); */, f' ]# J+ u% A3 V

  73. 4 t) q' r: m6 E/ r
  74.   /* Start thread execution */2 e  [5 P5 O1 r6 i9 B* {
  75.   osKernelStart();
    * e: i; g6 l% q
  76. #endif
    9 B4 g" R: }7 ]8 {( d3 K0 j1 K

  77. ! \9 R) a: f# i
  78.   /* Infinite loop */* a+ l; F7 F# d5 q1 t# k
  79.   while(1)- _  d  m) H, {0 p# O( A
  80.   {; c: \/ O! U0 X$ o
  81.     canTxMsg.StdId = 0xAA55;
    , S3 b& Z6 H) m# |: M; [
  82.     canTxMsg.ExtId = 0x55AA;
    / w+ v' r- B4 P6 g
  83.     canTxMsg.IDE   = CAN_ID_STD;
      h! c) U: x8 |4 d
  84.     canTxMsg.RTR   = CAN_RTR_DATA;
    7 l( i8 L4 C% k3 x7 p: v, h/ _9 t
  85.     canTxMsg.DLC   = 8;+ q, K; A' h0 F6 T: [- F0 H, ]0 ]1 r" E
  86. + g  d0 D8 V) B, p
  87.     canTxMsg.Data[0]++;
    4 @6 L% m6 ^2 d/ _  e  e
  88.     canTxMsg.Data[1]++;5 y( l4 p) ^& {+ `. c# l5 B3 k
  89.     canTxMsg.Data[2]++;
      @0 s+ h1 T9 B. f
  90.     canTxMsg.Data[3]++;/ X6 j+ `. }& R0 v
  91.     canTxMsg.Data[4]++;9 q7 Z. V% |8 h5 M
  92.     canTxMsg.Data[5]++;( `& E* k- L( S- a2 M
  93.     canTxMsg.Data[6]++;, d6 ~  E- v; V; u9 v' G
  94.     canTxMsg.Data[7]++;4 e  h3 K  C# C/ {7 A9 b$ m

  95. * s9 P5 W: y9 [; O( c
  96.     CAN_SetTransmitMessage(CAN1, &canTxMsg, 1);
    0 ?: G' `5 [$ s+ A

  97. ) W. e) F' t, H% [3 [, p
  98.     while(CAN_IsReceiveBufferEmpty(CAN1) == true);
    * ?' N1 E; B$ D% c  i
  99. ; `  R* [1 Z4 q2 V/ \
  100.     CAN_GetReceiveMessage(CAN1, &canRxMsg, 1);) ?4 K  r1 P2 i$ V
  101.   }9 p# C: ~5 x# w: ?  a1 [' ~" Z
  102. }# J  S4 i. z$ @( K$ R" J5 j$ ?

  103. 2 f; o* ?2 R7 @6 C
  104. /**
    2 O  W1 \% r9 n( r% i0 M
  105.   * @brief  System Clock Configuration.8 x- w3 Z  E) G' w
  106.   *         The system Clock is configured as follow : $ J. l" K- T" I  c5 E
  107.   *            System Clock source            = PLL (HSE)
    : p1 Y! O8 L( O4 Y
  108.   *            SYSCLK(Hz)                     = 72000000+ U4 q+ a( R) B$ W
  109.   *            HCLK(Hz)                       = 72000000
    # Z" m: q# d% }* F/ b. F- i
  110.   *            AHB Prescaler                  = 1; @4 T# V8 b. R" e
  111.   *            APB1 Prescaler                 = 2) g, G7 t' g. H# P
  112.   *            APB2 Prescaler                 = 1; q  u4 T8 W2 _" A# P8 g) E" R
  113.   *            HSE Frequency(Hz)              = 8000000
      n4 o2 k) _: V: g
  114.   *            HSE PREDIV1                    = 1' \5 e/ O2 ^6 ]1 E' l* m, i
  115.   *            PLLMUL                         = 90 F, }& `' F6 k6 h( R* K" o) e, c
  116.   *            Flash Latency(WS)              = 2
    2 A1 i+ n* V9 S9 |) ~  w
  117.   * @param  None.5 K' w% ~8 r0 _% ]9 G, f
  118.   * @return None.5 x9 i$ D2 y' Q1 q6 }
  119.   */
    * f9 {8 I$ E. ]1 X. e
  120. static void SystemClock_Config(void)$ i+ a: q7 X: g8 p
  121. {
    0 w. g7 {. V: O/ x6 D' i+ R$ M
  122.   /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration */
    * h6 q9 t1 E" p4 P. I
  123.   /* RCC system reset */3 i0 b4 a( [1 d
  124.   RCC_DeInit();4 b" m, Q* w3 Z: z+ j+ p; g
  125. - _' O* `5 @; ~- S
  126.   /* Enable HSE */
    + L; t! J1 e" o/ S- z
  127.   RCC_HSEConfig(RCC_HSE_ON);3 G. f! R6 e! N  c

  128. ) q! @; `8 ?$ ?1 j9 t$ t* ?
  129.   /* Wait till HSE is ready */, f0 h; m$ g/ X! ~5 k/ V
  130.   ErrorStatus HSEStartUpStatus = RCC_WaitForHSEStartUp();
    , |" M7 g2 c- L  r! l
  131. 8 A0 w/ X  h! N: t5 t3 e
  132.   if(HSEStartUpStatus == SUCCESS)
    4 M: L% p/ ~, |( Z
  133.   {* Y/ m3 `  X  ^
  134.     /* Enable Prefetch Buffer */' f0 Z% T' |& n( o  u! ]
  135.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);5 r7 [$ D" }$ p* a$ r$ w

  136.   V$ t% M7 _& R9 R2 H! S
  137.     /* Flash 2 wait state */
    * L7 F; l- R" u
  138.     FLASH_SetLatency(FLASH_Latency_2);1 W3 i+ ?9 i2 m3 A3 g1 n
  139. * H) c+ m' p7 z. F
  140.     /* HCLK = SYSCLK */
    4 M0 ~8 x( Z* G4 X6 b# Q' B: i
  141.     RCC_HCLKConfig(RCC_SYSCLK_Div1); 0 G8 N2 q6 C% ^4 U/ b4 S; o2 M% T& \

  142. ; C! }7 N7 I+ E0 g# D8 P
  143.     /* PCLK2 = HCLK */  X. M; e- t0 I4 v2 m) {- Y7 {/ Q
  144.     RCC_PCLK2Config(RCC_HCLK_Div1); , @0 C6 @& B) r' `0 N8 N% O

  145. 7 R: ^$ Q4 b8 B9 K
  146.     /* PCLK1 = HCLK / 2 */
    ' S, B3 N* P8 |
  147.     RCC_PCLK1Config(RCC_HCLK_Div2);
    + r( P  W6 U3 p: H5 ^

  148. & z! A% N8 e; p: W
  149.     /* Configure PLLs */
    4 B3 q+ [+ B6 P5 a/ D
  150. #ifdef STM32F10X_CL0 y' ^3 J, N, {& m
  151.     /* PLL2 configuration: PLL2CLK = (HSE(8MHz) / 2) * 10 = 40MHz */
    , o! a* E' z9 j
  152.     RCC_PREDIV2Config(RCC_PREDIV2_Div2);/ [' S0 k0 e9 S, |) I
  153.     RCC_PLL2Config(RCC_PLL2Mul_10);
    ; @, O0 y0 d1 |; {

  154. 9 N4 j: ^& F, p5 x6 q0 W7 y
  155.     /* Enable PLL2 *// g" P  D! @9 K  H5 I' u
  156.     RCC_PLL2Cmd(ENABLE);$ z" G: D8 `: Q  A& Y" M

  157. % `  J1 |4 |9 {# O
  158.     /* Wait till PLL2 is ready */. w' E6 L  z/ j. e
  159.     while(RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET);
    2 T* q" X$ |5 I, I( D

  160. 5 w+ v- P( t% E& n9 k5 [
  161.     /* PLL configuration: PLLCLK = (PLL2(40MHz) / 5) * 9 = 72MHz */( z; R$ C4 ~/ F' a/ X( b! f9 E
  162.     RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div5);
    / c/ I5 g* e. f$ x, D2 T- N
  163.     RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);
    . Q0 o2 A* R- e, ?$ S) r1 ~
  164. #else
    2 w! _  ], Z9 W. @' Y( h5 k- h* \# K
  165.     /* PLLCLK = HSE(8MHz) * 9 = 72MHz */
    8 @  Z5 A7 f6 O8 Q6 a  ~4 y! K
  166.     RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);' v) `# w/ v; _5 ^$ Z
  167. #endif
    4 J7 L6 H( `1 U$ k5 b. T7 T: w/ e! n

  168. 2 c/ q4 s/ @+ T( Y6 V/ G. S
  169.     /* Enable PLL */
    4 v! K; ~/ C: x/ D6 w* v
  170.     RCC_PLLCmd(ENABLE);
    / R1 `! G& S9 d6 `4 X# p7 q

  171. 5 N7 x- J5 l; `4 h2 _: {3 ]/ H
  172.     /* Wait till PLL is ready */3 N( u9 `8 K8 Y; u3 A
  173.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);( F8 B! m" ~# p' `# b

  174. - O, X% ^( B' g" a
  175.     /* Select PLL as system clock source */
    - z  h. @0 D8 f& w% i
  176.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    * y2 p4 C* x% L

  177. " c, C7 _' B+ |- z
  178.     /* Wait till PLL is used as system clock source */$ V0 e8 f" q! s' ]7 |5 [
  179.     while(RCC_GetSYSCLKSource() != 0x08);4 T/ h4 G- F/ w4 D# K/ V9 {* M
  180.   }
    " O; H) `4 A4 w0 V8 F' s4 v5 ?( {* H
  181.   else: d6 a1 G- \- i( Z, y
  182.   {- ^9 q" X6 j" T" Y7 y
  183.     /* Disable HSE */* Y+ f$ s1 o3 N3 w% ^8 T* T% g) z
  184.     RCC_HSEConfig(RCC_HSE_OFF);
    4 _) z! b# R3 e% n: a# h0 ]  H

  185. $ P- A& ?2 Y. ~: n* k
  186.     /* Enable HSI */: P. m0 B  Z  l) M  t+ U
  187.     RCC_HSICmd(ENABLE);
    . t  A! Z& H  G7 u5 ?

  188. / b7 W: P8 D( u3 u! H
  189.     /* Enable Prefetch Buffer */$ M7 A# m; S: u. o; `" A
  190.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
    & z2 B, @- Y' p3 E

  191. 9 {% ?0 O+ o" {) w2 ]+ |. M
  192.     /* Flash 1 wait state */1 D; _. C$ T5 K$ L# R' e- u
  193.     FLASH_SetLatency(FLASH_Latency_1);
    5 {9 p# z0 r3 \' v: N/ o) T4 S

  194. ; Z0 X' d, _- U2 z* g& @# T" D
  195.     /* HCLK = SYSCLK */' N4 a( {( `: M3 \8 E: w
  196.     RCC_HCLKConfig(RCC_SYSCLK_Div1); / Y. r7 `( s% R% }

  197. 1 ?' E6 A0 @) {- j3 R8 M
  198.     /* PCLK2 = HCLK */6 }9 B6 r; Y& x* h/ m
  199.     RCC_PCLK2Config(RCC_HCLK_Div1);
    % v5 F, l* m) g; V: H
  200. ! u) x5 C& Y) `9 @9 S; X& i# u4 M% k) q
  201.     /* PCLK1 = HCLK */! v0 c3 y/ N( E
  202.     RCC_PCLK1Config(RCC_HCLK_Div1);% @/ r7 R5 V7 F; q& ~8 b
  203. ) T2 I( A" c+ p; C
  204.     /* Configure PLLs */
    . f' ]' |- I7 c7 s4 G/ l
  205.     /* PLLCLK = HSI(8MHz) / 2 * 9 = 36MHz */
    ; \# f9 s* c9 w7 g
  206.     RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_9);
    2 @* d' q/ y4 X* _

  207. ; \  U* z6 I4 w8 m* }
  208.     /* Enable PLL */
    . P9 [. ]# d* e8 d: G" d0 P
  209.     RCC_PLLCmd(ENABLE);
    ; w5 R) ]* q' E5 W/ X# e: w
  210. # O4 h! t% Q: E6 R/ `- u
  211.     /* Wait till PLL is ready */
    , v+ F1 `/ f) O1 U" s
  212.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);  S2 u8 A" z5 n4 ~/ j

  213. $ n9 r8 F" K+ J' K, _
  214.     /* Select PLL as system clock source *// j. ]# b% ?3 x. _# w
  215.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    3 Z# T; S5 }0 H: A

  216. ! l3 W! j4 L3 P1 A+ Y9 s& r
  217.     /* Wait till PLL is used as system clock source *// W9 d5 Q& H9 D9 t5 U# C
  218.     while(RCC_GetSYSCLKSource() != 0x08);
    $ o: `7 K0 D  c3 i4 a7 u! t: W6 @
  219.   }6 H6 G( B& u" a: `" X/ d
  220. }
    ( u( g- V& Y8 u. o

  221. ; H5 W* U# E, @' G
  222. #ifdef USE_FULL_ASSERT
    : F# X. {& T- V9 w
  223. /**7 U0 p* M8 y. O9 Q; h/ p* o2 [
  224.   * @brief  Reports the name of the source file and the source line number
    9 u; {- J: `2 l
  225.   *         where the assert_param error has occurred.
    $ F4 }+ {$ @( l9 b' A  L! y; E( V
  226.   * @param  file: pointer to the source file name.
    4 @- m" m+ F) }
  227.   * @param  line: assert_param error line source number.1 c+ I8 B' t# h0 e; b& z& H
  228.   * @return None.
    & v( U* m  G% @; L7 P) k* r- `
  229.   */" a  W  d, ~5 E, b( \9 s8 @. b. A
  230. void assert_failed(uint8_t *file, uint32_t line)6 p# w2 [6 }- _5 F0 f" J' o
  231. {
    4 ~  z: m( R) b0 j: d, j8 `' O' U
  232.   /* User can add his own implementation to report the file name and line number,
    4 H% d5 O: W: S, ~
  233.      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */! F- E. t! E* F- F
  234. 5 ?. E( a, q3 ^% X5 Y
  235.   /* Infinite loop */" ], @% `+ [+ i7 r* f3 ~
  236.   while(1)( {+ Z) f1 r1 L% D5 V
  237.   {
    - {- s6 e! k/ }  i0 q1 \
  238.   }6 r  {, D5 F+ A' E. l6 L" z
  239. }
    5 ~& w! ]5 l( }3 ]: l) G
  240. #endif
复制代码

8 q* t1 K+ [# g3 ]+ c) u3,注意
$ b/ t* V" E1 b4 G+ M& X0 Q
6 f9 _; B0 s' w. y! e3 c# R* GCAN 消息发送缓冲区和接收缓冲区的大小,可以根据应用的需求进行修改,缓冲区使用的是堆内存,需要根据缓冲区大小和应用程序中堆内存使用情况进行配置。" ]+ R2 F- G- m0 ~4 f
8 {1 Q; y6 g* ?
2 O( t6 v; B( ?: o2 v

* O0 O$ h/ K1 ~1 O. p; |
收藏 评论0 发布时间:2021-11-26 17:00

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版