1,开发环境
; T; F' N8 ~- h
; |% Z) x& J7 h8 n1,固件库:STM32F10x_StdPeriph_Lib_V3.5.0
v$ S5 Y" N, ^7 h% h) G6 a4 i2 O7 P i T. G/ Y
2,编译器:ARMCC V5.06
' |! p+ G3 T1 {: ?2 m
7 _0 P/ T" b9 }+ \8 O. O, |3,IDE:Keil uVision5
$ K. X' v) r8 I5 k( Z. E6 t: Y3 X2 k/ k' _) O* ^! B
4,操作系统:Windows 10 专业版
$ F; v2 X/ s" ?6 g# f7 q7 f
; b: m& V) p( S3 O+ s6 @# V
" `9 }2 `* X6 w% }# C- X8 `2,程序源码
7 }, h' U5 c9 Z h/ O, Z9 P
6 ~4 t: D) |- Z Y7 h8 t: `RingBuffer.h 文件2 j# \9 Q' H! H7 {2 D
- /**# p" z+ @# ^4 ]. o" H- p
- ******************************************************************************
5 Y9 N8 A% u1 G8 V+ K+ c, i# [# A - * @file RingBuffer.h
: \0 n) ^# G, }4 E; ?; g0 b7 P - * @author XinLi5 E* _9 I4 T: i% e
- * @version v1.1
; `- `0 p/ N7 Q4 W$ v6 [- z* _/ ] - * @date 15-January-2018
0 O3 ?& w& M; i - * @brief Header file for RingBuffer.c module.
& z& Z/ D. p3 z8 q: S; h - ******************************************************************************
7 R( ^5 N1 S' y+ B# n! e - * @attention
$ f! Y" _1 ]8 _, G( n# V, n k - *
1 z8 s- o0 U* L, O$ {2 F$ N - * <h2><center>Copyright © 2018 XinLi</center></h2>$ E1 O2 {* r/ h8 x/ l
- *4 C V8 U0 Q. a. [# {
- * This program is free software: you can redistribute it and/or modify) b: J3 ]3 T3 E1 H# Z
- * it under the terms of the GNU General Public License as published by
7 R# T% y$ a8 O5 K - * the Free Software Foundation, either version 3 of the License, or
: f1 b0 t/ Y6 ?4 L: Y+ }6 d0 P( F - * (at your option) any later version.. y% m! f2 ]* |! _
- *
" Q4 `0 O9 C" G- u4 ] - * This program is distributed in the hope that it will be useful,
" v) x. K7 H& b9 A1 O. U - * but WITHOUT ANY WARRANTY; without even the implied warranty of
6 G- \0 ]( f0 s/ m* d - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the A6 A( e- Q0 N, Q) O0 O; {* W ~
- * GNU General Public License for more details./ g( ~! s, I5 i
- *) w) O$ |& O) h* |3 e1 E. N- y
- * You should have received a copy of the GNU General Public License
2 y/ t. Z6 a+ Z3 @7 J - * along with this program. If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
, t/ C/ ~- w% w) G& T - *
" I# f. Q8 I/ W" ^* {9 { - ******************************************************************************3 L9 U7 v- Y" a' q* ]3 I' t5 _
- */9 |3 d' X; y! q+ I' k$ h
- ) U1 C7 I9 n9 ]1 y
- #ifndef __RINGBUFFER_H
7 ]) L3 c7 ?9 i4 f: t - #define __RINGBUFFER_H) T" x& {. f/ F9 Z
- 7 C9 b5 @1 u9 X. N n5 t/ e& h6 g5 f
- #ifdef __cplusplus
7 F. U9 P3 ]4 M0 p" ` - extern "C" {
9 c! Y( r2 q8 |4 J - #endif
4 ?" c8 C; y/ f- B, b
$ F( K8 h" F" ~- /* Header includes -----------------------------------------------------------*/
7 y4 q; x" O, }' A1 |' N - #include <stdint.h>' R1 e- y$ ]' s
- #include <stdbool.h>
/ Y/ _+ O& R4 |2 e' }; U1 k - #include <stdlib.h>
, d7 u1 M0 `4 F/ t$ ^, R - 6 _4 l4 u3 m* `0 Y
- /* Macro definitions ---------------------------------------------------------*/; {1 j3 p# J9 @8 U8 i
- #define RING_BUFFER_MALLOC(size) malloc(size)
2 f4 p l5 K5 m* q& t9 d$ e" O$ K! O ` - #define RING_BUFFER_FREE(block) free(block)
: {! E# N, v8 U$ h3 H6 b# } - 6 ^# k |! h3 k2 T ^- s5 b7 ?
- /* Type definitions ----------------------------------------------------------*/
7 y4 C6 z8 I* q: e! l8 R2 Q - typedef struct
' [, [% M# @9 c+ W8 k1 m) U - {& R' v2 W/ P8 m3 k0 w) F8 z
- uint8_t *buffer;( ^2 }# x9 n) X
- uint32_t size;
) ?9 H7 m- H8 d! @/ n4 I3 Z7 \+ A5 j - uint32_t in;
) l: Y) i* }' R5 d5 a7 G7 F - uint32_t out;
6 ~% T) l5 S: E. x" W: t$ i - }RingBuffer;6 f b2 c% c. H: j; P4 w7 [
# k" r: W2 u7 f- /* Variable declarations -----------------------------------------------------*/
- o1 r+ ?, [) f3 g# N& j! G - /* Variable definitions ------------------------------------------------------*/
9 {' e6 w; {- V* ^; C2 { - /* Function declarations -----------------------------------------------------*/
% V3 a$ G! X+ q5 [7 L - RingBuffer *RingBuffer_Malloc(uint32_t size);8 J6 G$ g+ B0 y, {+ i2 ^/ G
- void RingBuffer_Free(RingBuffer *fifo);3 |3 I. `2 [' ]% X( P; e
- ( w$ w+ R" i z* F
- uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len);
$ [* x0 A) d* Q$ U7 r. d' N, a! A - uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len);
x: e" R$ N% {; D* g8 N - # }1 t8 ~4 Z) u$ G% [' m
- /* Function definitions ------------------------------------------------------*/
# P/ j2 E" a$ o - 0 d8 K2 E- `9 e6 c* Z
- /**, S* @+ Q9 T' c9 A7 }
- * @brief Removes the entire FIFO contents.
' M3 u! s/ S' i" H/ K* S: g, E - * @param [in] fifo: The fifo to be emptied. v2 [6 o+ c. p! f0 |1 \
- * @return None.( l1 [* G; B, k8 \5 D$ l
- */
$ i$ G& Y" s- s% H6 T- [/ ] - static inline void RingBuffer_Reset(RingBuffer *fifo)
. `' K+ p3 I. L! R0 W" H* _! u - {. J: c- s$ V% q( ?: N
- fifo->in = fifo->out = 0;
( u0 a1 k9 z- [# ~1 p$ [ - }
1 g% ~# H' W, `) A# G - 8 W, `9 z: O3 U- B
- /**
a5 {+ z* @/ D) E* w8 n - * @brief Returns the size of the FIFO in bytes.1 I7 V. p$ `6 ^+ E; Y: N2 o$ Y
- * @param [in] fifo: The fifo to be used.( D% i3 r8 N8 F
- * @return The size of the FIFO.2 z; `* r+ B( U7 m- y0 [
- */
& e" z1 T" S1 g - static inline uint32_t RingBuffer_Size(RingBuffer *fifo)6 r6 H! E5 A( o: n/ L% Q9 o: \
- {% i3 f/ m" ?. e! t5 P
- return fifo->size;0 C" A' y; V' ?) ^3 C# `9 p( e& ?
- }
) B$ y+ u, b$ k
- B& r! A# o- i; |* V- /**1 j/ Y8 H+ b* E3 P
- * @brief Returns the number of used bytes in the FIFO.& w9 m l8 f9 ~4 g) p
- * @param [in] fifo: The fifo to be used.5 b& s% V4 y# L( c! P+ S8 q
- * @return The number of used bytes.$ V7 R+ \# y; K4 `
- */
" {5 z: e @+ S n. ~. X - static inline uint32_t RingBuffer_Len(RingBuffer *fifo)7 E3 D. B1 U; ?4 U. ? U; k( l9 r
- {/ @7 L: ]; r+ h# e1 [
- return fifo->in - fifo->out;' k# ~' L7 O" A( n1 t: U
- }" v' l* L5 y* c7 v. m$ L
- # Q6 o7 ]! }- x$ N2 b
- /**
; h4 u' V T, P: d! J - * @brief Returns the number of bytes available in the FIFO." l C% A& |, i8 e* P' L6 e+ f
- * @param [in] fifo: The fifo to be used.
" a5 Z" W0 H& V& W$ S9 M0 F/ ` - * @return The number of bytes available.
z$ x/ F& A8 A6 T1 e - */
. r0 O; m9 Z/ D: y! I8 V( x5 m) ?# k - static inline uint32_t RingBuffer_Avail(RingBuffer *fifo)
/ J( ]! B O- C - {& P0 L V1 i8 b' }2 R+ s5 r
- return RingBuffer_Size(fifo) - RingBuffer_Len(fifo);1 Z' j. R2 V0 B" Z$ C5 H8 Y/ t9 x( b
- }: a7 Z$ ^0 b. F$ Y$ _
- 7 w K+ l( _/ G. m
- /**5 F0 _& L$ n# [
- * @brief Is the FIFO empty?1 w0 h8 s. \0 J8 o: q
- * @param [in] fifo: The fifo to be used.
; U' G$ p) [% k - * @retval true: Yes.9 I. H+ \& F4 {; m4 D5 u
- * @retval false: No.8 E3 G: t# U' L0 e
- */
$ z7 f, k j+ `1 i - static inline bool RingBuffer_IsEmpty(RingBuffer *fifo)' \5 l6 l2 [7 g& m; R* Z$ p7 G
- {
6 z5 T. \* k/ r - return RingBuffer_Len(fifo) == 0;
& ]8 N! m! ?$ I - }' _& c D) }/ `) Y6 `: N: N7 P
1 U8 Q* o# V4 [* h: C- /**0 J* N1 B- y3 e+ |7 [9 o
- * @brief Is the FIFO full?% `; t7 {/ k1 Z7 C. T6 V5 P# l
- * @param [in] fifo: The fifo to be used.
( N) T, Q. ?4 h& K$ X5 r - * @retval true: Yes.' a2 [$ t7 A0 Y
- * @retval false: No.
- @/ c( C$ V- V: ~5 A% E9 n& ] - */
1 R( ^7 M( e/ P - static inline bool RingBuffer_IsFull(RingBuffer *fifo)$ k r( A; N- {' X% \% ~% m
- {
6 U3 a% y: ?. m - return RingBuffer_Avail(fifo) == 0;
6 A1 m4 b8 E" W1 x$ B - }
/ d9 g' i- _; L1 c4 [; T5 y
( r- P2 p! @3 H2 y9 T- #ifdef __cplusplus9 F: d9 G9 Q; w5 Y9 ^, A, [8 o- X Q
- }8 w# h9 ]3 D; `& ~, v& z9 a; g2 H" {
- #endif
L! u( Y/ d# L% U6 J5 t - ( Y* w( w8 e8 N ?& x
- #endif /* __RINGBUFFER_H */* M1 B: }3 w; P& Z: y6 W) B
复制代码 . x7 _: _) ]( a3 o, R6 }/ K8 p, T
$ ~1 K9 G, K* {! CRingBuffer.c 文件9 R6 n3 `* e9 o h
- <div>/**
7 R k* [) q5 d2 R7 q - ******************************************************************************
5 }# H2 ^# F* Y; J* ]3 s - * @file RingBuffer.c. n$ s2 @4 Y q0 `5 K$ C
- * @author XinLi
; T; S& e- i a/ j0 N - * @version v1.1. i8 u' N. n! K' M
- * @date 15-January-2018) l; L2 Y6 a! H. x. Y6 }+ U6 O
- * @brief Ring buffer module source file.6 T% q, o& b! k# S9 s E1 y8 v6 f( V1 j) f
- ******************************************************************************
d3 e6 ~# o& ^, f9 ^ - * @attention6 K# \! |; B6 E2 j( ^/ `% e
- *: x2 _" u! \- r* ?7 T
- * <h2><center>Copyright © 2018 XinLi</center></h2>
) i8 W6 k7 |# x- i9 O - *; }- ~+ }8 z& z" W5 L4 T
- * This program is free software: you can redistribute it and/or modify: V1 C. L5 @1 p/ \0 Q1 y4 |4 z+ x
- * it under the terms of the GNU General Public License as published by
r6 r# ]& } f2 [) G - * the Free Software Foundation, either version 3 of the License, or& u3 {! n* y5 Q6 _- g$ r
- * (at your option) any later version.$ H1 C) q' H% P& h# L% s
- *
* N; k/ C( O" _9 v2 d' [2 C6 V - * This program is distributed in the hope that it will be useful, B; W, A4 j0 X3 y( R' p
- * but WITHOUT ANY WARRANTY; without even the implied warranty of- ~& F% i/ Z% u! M8 S6 r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
: L3 T! _- z0 f - * GNU General Public License for more details./ ~/ l% @; S( v! g
- *
, r3 Y! q- B& Q4 O+ A - * You should have received a copy of the GNU General Public License
& A. j( A( b8 m2 m$ d) r( r - * along with this program. If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
% Q+ w8 K! q1 q2 `9 P; T6 H% \7 k - *: N7 Q) K7 O" _6 Z4 y3 l F. T
- ******************************************************************************
7 i9 E4 f7 ?5 i( B7 o, K$ O9 p - */5 `/ v1 ~( i! }% L& [# P5 G. h/ ~
k0 ^' O. G7 T, ~1 [2 ~- /* Header includes -----------------------------------------------------------*/% {$ D# I( X7 c2 A& B0 ^
- #include "RingBuffer.h"
' U7 y" J' Q0 P0 m5 e/ X4 `% n - #include <string.h>
1 [" M) t* Y0 M/ d4 k/ Z- I1 G - 4 a: X7 F/ y8 }' q' H# t
- /* Macro definitions ---------------------------------------------------------*/0 c6 ~& K7 z, m4 Z: h: l
- #define min(a, b) (((a) < (b)) ? (a) : (b))7 w& p& L$ e6 c- c* e* [- M T
- 3 ^+ t4 w" h: M! |: \
- /* Type definitions ----------------------------------------------------------*/$ I7 i# ~2 ~6 t7 r4 R: v
- /* Variable declarations -----------------------------------------------------*/9 p% `! W' b# @ t8 w" e
- /* Variable definitions ------------------------------------------------------*/6 R2 L) r$ p5 ^; O" G( j
- /* Function declarations -----------------------------------------------------*/5 t, r3 o# X, H
- static bool is_power_of_2(uint32_t x);
% C, Q! J6 `$ Y) ~ - static uint32_t roundup_pow_of_two(uint32_t x);. k6 D3 J: Y1 V9 i5 \5 u! |! z
- . K! K, e7 n( z2 U9 ], Z3 P* L
- /* Function definitions ------------------------------------------------------*/
6 o. I, X7 X; w8 p0 \* O" R G& m1 f
4 a$ M6 q7 w! i+ P3 v+ h% E! S- /**1 } H! W6 M7 v* }/ C# a' z4 E
- * @brief Allocates a new FIFO and its internal buffer.
% o, M8 i/ ]) h" @' D b - * @param [in] size: The size of the internal buffer to be allocated.) V9 T. m" E ~9 _! B
- * @note The size will be rounded-up to a power of 2.
. X6 T% i- N# t- j5 {& A& z+ u - * @return RingBuffer pointer.1 D ?* { f6 S
- */
8 `& k# _& v5 ^, w4 F2 b& V* G - RingBuffer *RingBuffer_Malloc(uint32_t size)
4 f$ D. g' N- A& N+ z& `% [3 a - {
" |. X5 U ~7 i - RingBuffer *fifo = RING_BUFFER_MALLOC(sizeof(RingBuffer));
7 H; \0 M* a9 I
2 m P$ N6 V( Z$ p; a, o# h7 B7 J- if(fifo != NULL)6 Z1 ?/ B* m7 n) T, s' O
- {
: I4 n6 E8 Y- O5 z* E1 I s - if(is_power_of_2(size) != true): T* e* t0 s. Y9 M( `3 l' X
- {
6 \% b; Y2 Q9 ]- G% w5 t% t - if(size > 0x80000000UL)
/ Z# U2 s: t& Y3 Y: z3 d - {: F: f2 P x& H8 t; S
- RING_BUFFER_FREE(fifo);
A# C" }! m: d/ s! ?1 v% b) Y - return NULL;
+ u9 z M3 X3 d( U! F( V% Y - }& I/ `% q1 z: [2 `' V1 @
( r& E j( V$ R- size = roundup_pow_of_two(size);4 D1 m8 p, F [" b2 K) ?) `
- }
7 r9 Z( `2 n3 @- D/ j. q - # O2 ?( c Y% a! E- g A
- fifo->buffer = RING_BUFFER_MALLOC(size);
. f6 i' W W$ F# B8 N
* [* O9 B% d" s- ?- if(fifo->buffer == NULL)
8 e$ t" U- A' `/ o( R; ^1 ?+ W H - {) I% V, b9 [" o& o
- RING_BUFFER_FREE(fifo);1 U& Q, M' C$ s7 N4 }" T
- return NULL;
4 I, t# Z e# S, I3 x - }5 K5 E3 j% ~- L6 P7 Q1 J F
- u3 G2 o3 a8 V/ n/ B: j2 f
- fifo->size = size;
6 }! j6 |6 S8 [! D - fifo->in = fifo->out = 0;% J0 r# g+ N: X9 \
- }
0 ^+ J6 j8 g* S& r# ^, W$ w - ' m* S6 a( i: r, q0 T: \
- return fifo;- O1 p3 D6 ?7 z0 C. ^; X' ?
- }# x: \0 q. O, q" p! K
, ]: n+ ]/ v: Z$ X& d8 H- /**
) S# B2 x# J" _! m - * @brief Frees the FIFO.+ b9 ?# `7 {! ?: @
- * @param [in] fifo: The fifo to be freed.
@" K+ J1 x* r - * @return None.9 U9 d& m0 y1 L G
- */
/ @7 @# w1 j$ G# H" }) ] - void RingBuffer_Free(RingBuffer *fifo)- r* V5 i( W& h& u" T! D
- {
6 Q% N: x& R8 S5 C - RING_BUFFER_FREE(fifo->buffer);
7 A# `$ g [* n4 X" s" q. Z - RING_BUFFER_FREE(fifo);3 E' ~% d; _! m) H1 P
- }
$ X+ |6 ?! V6 U% ~4 V9 n- Y4 ~
; x7 {6 \' C$ N: b) {- /**
' ^) h; w9 ~$ s. [ |* G - * @brief Puts some data into the FIFO.: s. u5 p5 S3 ~
- * @param [in] fifo: The fifo to be used.' q! [( u/ Y% r0 o9 g& I" _7 \
- * @param [in] in: The data to be added. p, W* X2 G/ x2 z9 W( L5 A. l2 T+ j
- * @param [in] len: The length of the data to be added.
7 g$ L3 {: p4 t& P( c - * @return The number of bytes copied." w9 |8 x1 Z$ b( t
- * @note This function copies at most @len bytes from the @in into) v: g. V2 d$ b7 E
- * the FIFO depending on the free space, and returns the number' N4 [9 j# a+ Z4 l0 a" n3 _+ P6 Z4 m
- * of bytes copied.1 Y2 V, r& k. o" Z( F0 u2 F. C
- */
$ a$ U1 n+ v/ d# e - uint32_t RingBuffer_In(RingBuffer *fifo, void *in, uint32_t len). m' k3 ]; k, Q5 O; w7 N4 O
- {
, d( z# x: e( [( ?$ ^& Z - len = min(len, RingBuffer_Avail(fifo));1 e1 O% l( x2 @5 ]- u# V, d
- , H' F7 R3 C! B
- /* First put the data starting from fifo->in to buffer end. */6 R+ b; g9 F+ }$ p- G
- uint32_t l = min(len, fifo->size - (fifo->in & (fifo->size - 1)));" h. u& |- |2 g
- memcpy(fifo->buffer + (fifo->in & (fifo->size - 1)), in, l);4 ~7 Q" ?8 e! w1 ?" y' \
$ B8 a0 J1 ~8 v$ |- /* Then put the rest (if any) at the beginning of the buffer. */
" i; Y9 x5 @' E! ^/ Q+ U. C7 h - memcpy(fifo->buffer, (uint8_t *)in + l, len - l);
- [( @& l" m- ?5 s; P9 K - 1 l% V6 u3 Y( m$ y$ q
- fifo->in += len;
3 G: O3 q" h$ ^0 W2 ^- a
7 |" `/ f( x- r$ B- return len;
: a; r7 u* {2 |5 d$ h8 Q# V - }
. ^; H: z/ g' F$ k% ]/ E
: E* _) ^2 |: ~5 l3 Q* T) R( e- /**0 r7 | Z, x- h' O; Z! i
- * @brief Gets some data from the FIFO.; A! U2 K" F9 c& f
- * @param [in] fifo: The fifo to be used.0 V: w6 r( n3 v3 y5 Y9 c
- * @param [in] out: Where the data must be copied.
5 \* q! c: m% ?8 Y6 c - * @param [in] len: The size of the destination buffer.
9 Y3 p- D4 v/ d- d1 I7 L - * @return The number of copied bytes.
( E) J5 V/ }3 i/ N/ t" L/ c4 l - * @note This function copies at most @len bytes from the FIFO into
0 Z0 w, b: ^3 `9 o4 ~ - * the @out and returns the number of copied bytes.1 I6 l* Z6 g& m! s t- p
- *// R1 e/ A* @5 c* m" Z3 g
- uint32_t RingBuffer_Out(RingBuffer *fifo, void *out, uint32_t len)
3 O. t& O1 M& G: Q3 S) ` - {% L' C$ A5 J/ z( w
- len = min(len, RingBuffer_Len(fifo));- p: D: t8 l- \, N- M# e
- / G+ \, N: S" i
- /* First get the data from fifo->out until the end of the buffer. */
2 g$ r; G; @5 J! A+ E8 n: } - uint32_t l = min(len, fifo->size - (fifo->out & (fifo->size - 1)));, Y8 h% x9 B @$ x, A
- memcpy(out, fifo->buffer + (fifo->out & (fifo->size - 1)), l);
8 {1 @' A. Z9 |$ u) g0 f - ) ~- V* e, T* {
- /* Then get the rest (if any) from the beginning of the buffer. */
9 J' x& x0 n9 i) \0 T - memcpy((uint8_t *)out + l, fifo->buffer, len - l);
3 C& J- U( A. B) L1 Y* V - / n7 X. @# N- |
- fifo->out += len;
- x( B! o3 [, [8 ]# y' j3 l* U$ e - & h2 D+ _' R& s- l# m7 [- r7 h
- return len;
+ G" Q Z& d' A) d1 U* I. [; t - }
0 {2 F1 H! M. m, B( ^2 c
; u0 U. W* F0 J$ }! M9 W: D* F$ Q- /**% t! x8 k. a# O. Q
- * @brief Determine whether some value is a power of two.3 G+ c" p$ |5 f4 v+ _5 V. U
- * @param [in] x: The number to be confirmed.
6 w4 X) \7 _, o - * @retval true: Yes.
& U1 O9 l& O& k- t - * @retval false: No.
( t0 d. T X% J9 I - * @note Where zero is not considered a power of two.
6 v% W" h- R7 Z& ^! k - */# k/ D" V+ B3 N$ I9 F
- static bool is_power_of_2(uint32_t x)
, v9 J) X0 p4 d - {& k4 g. Y/ ? [6 f
- return (x != 0) && ((x & (x - 1)) == 0);& B- J4 U& O2 @5 b0 Z9 k! Z
- }( Y2 Q7 R: D( _% ]7 O
- 4 j/ ~' o' N' T
- /**" H1 Y8 s% l2 ~* r) K9 U
- * @brief Round the given value up to nearest power of two.' e+ ^) a8 K9 L% L9 ?) ]
- * @param [in] x: The number to be converted.
& A4 P1 n. E. n/ [6 [1 i - * @return The power of two.
* Y" _) c! M" Y; d# a$ R6 Q* _ - *// p% K! k- z" u7 @
- static uint32_t roundup_pow_of_two(uint32_t x)
+ E' ?2 }6 M: B$ e* ^7 I - {( [% C; `( ]- y" o. m1 S
- uint32_t b = 0;6 B/ D4 x d+ H. v- Z6 N; s4 l% ]
, E6 [6 l+ A4 {" `- for(int i = 0; i < 32; i++)6 ~, \( U7 q# f1 N! c0 D9 a9 q! }% O
- {
1 v5 N: n4 L4 n& G2 Q) ^. u' ^ - b = 1UL << i;
; {- X$ w0 S/ D1 b: \1 e
1 {0 d, g2 c; f) m9 r U% r2 P4 `3 @- if(x <= b)4 g2 a& |9 s7 o2 R: L9 h* O( k" p6 }
- {% A. f9 P7 M) n4 |) v- i
- break;6 {: d( |: d* B. B- s
- }4 s. U2 m& s4 c4 e9 b) a
- }
. [% }/ A+ \$ e3 B8 r: E3 ?
# I: ]/ i& \ m4 u& z- return b;% R+ D' a! J& d+ t/ ~
- }</div><div></div>
复制代码
: P8 [0 H4 h5 d8 P! e3 m! p+ |" V' n
CAN.h 文件* x3 u/ [1 I0 A
- /**
" R2 l U$ [. G7 Z K - ******************************************************************************
( t, X2 ~. C3 D" Q; _ - * @file CAN.h5 I, @) m: K! N8 c, B. V! F
- * @author XinLi, y5 e! a/ e$ ^: r% u+ m
- * @version v1.0. I4 u% G; W2 i
- * @date 24-June-2018
* k- B' _, {8 y. M4 `& h - * @brief Header file for CAN.c module.1 B& N" n$ T. |4 t1 k" b% X1 j
- ******************************************************************************
# o7 b& _3 Y. m - * @attention. V6 [8 z' D7 I* F3 e, s
- *
D5 E1 g) s- y3 _4 B( P - * <h2><center>Copyright © 2018 XinLi</center></h2>
: [9 H. L$ n7 U4 D9 F - *. d; |' u4 M$ P0 C* M6 F
- * This program is free software: you can redistribute it and/or modify
5 w+ X0 P% ^* h+ f% ~. N - * it under the terms of the GNU General Public License as published by! L/ ^3 M2 ~# K
- * the Free Software Foundation, either version 3 of the License, or0 W% Q, E; {, Y
- * (at your option) any later version.
6 Z" c X t6 z" s" x - *
" S+ c% Y3 [1 h4 U) T - * This program is distributed in the hope that it will be useful,
7 [& g& N9 J+ P! o' y - * but WITHOUT ANY WARRANTY; without even the implied warranty of
1 e1 K8 f+ R6 S2 t ?) G - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the" o" U6 R+ s0 ?" T' R/ O7 B. W
- * GNU General Public License for more details.
+ g( _3 h( r! ] - *
9 W! I- e' S/ W( e: \# q# S2 c - * You should have received a copy of the GNU General Public License
. A3 p/ H# c( V( n9 N+ I: N% p; m - * along with this program. If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>2 C( Y3 @9 M a% R2 `
- *
, ?+ M8 W1 F, |8 I( R: F, z - ******************************************************************************
& v6 h& Z( v7 V9 K$ C7 G, l - */- H* B/ W1 q4 U+ z" a% W6 x! J
) s6 R& G9 H/ X4 k7 B: ?1 L- #ifndef __CAN_H
' G4 _1 N7 u0 o( _: {+ I - #define __CAN_H
7 B9 e. F8 _1 [' q* a7 k! X - 8 P! k" g+ I3 j! ]9 T. n
- #ifdef __cplusplus% Z/ r( ~, M _! d* ?! W! S' }% z
- extern "C" {
6 L Z0 g$ I$ l - #endif |1 B5 @+ C9 w5 ~$ E& T
- " O d# k$ f# P% Y! g
- /* Header includes -----------------------------------------------------------*/& Y* O K1 y% s! ?: r7 u- T, p* E# A
- #include "stm32f10x.h"5 j8 l1 I2 Y0 q/ Z2 ?! s# P9 F
- #include <stdbool.h>
: t$ _/ T( n3 Q. m - 1 }7 `3 I+ _' j) i6 L
- /* Macro definitions ---------------------------------------------------------*/. i6 i+ A, k& Y& \/ y9 u
- ( [, y: Q. A. `
- /******************************* CAN1 Configure *******************************/7 P7 P/ d; e; r
- #define CAN1_TX_BUFFER_SIZE (16)
, T8 g6 W: ^9 t6 c$ j& S) S - #define CAN1_RX_BUFFER_SIZE (16)0 C- T2 V3 p X+ {
- & T( B- l F: w
- #define CAN1_TX_GPIO_CLOCK RCC_APB2Periph_GPIOB
- T5 C! F1 |, J V N# A% {: F! \ - #define CAN1_RX_GPIO_CLOCK RCC_APB2Periph_GPIOB
! ?& y2 }2 n4 q( q/ I - 8 B7 Q. b7 U# {5 x; e/ H
- #define CAN1_TX_GPIO_PORT GPIOB4 E& U) J2 U" v/ H3 Y9 ^
- #define CAN1_RX_GPIO_PORT GPIOB+ b* ~ @2 s/ b. h' E( l8 W0 g
* @& N) c# I, w! A! o- #define CAN1_TX_GPIO_PIN GPIO_Pin_9
, b0 E! g6 U2 w/ n$ W+ D - #define CAN1_RX_GPIO_PIN GPIO_Pin_83 T0 `$ t; z" ]0 T3 J+ k- O
- + o" }' e$ E9 v1 d3 P8 n
- #define CAN1_IRQ_PREEMPT_PRIORITY (0)4 m( V8 N# D r/ F
- #define CAN1_IRQ_SUB_PRIORITY (0)
! z0 h4 R$ A& r - 4 e3 b* J& N$ Z1 `5 Q7 A. I
- #define CAN1_PORT_REMAP() GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE)
& O" y+ `& Y6 o9 O - /******************************************************************************/$ G$ z' _- C8 U1 H% p
! `. z! j. N+ @- #ifdef STM32F10X_CL
1 |1 c! e( q }2 N$ v! V. ` - /******************************* CAN2 Configure *******************************/2 ]6 h, R) O9 P* S! w& ?2 ?+ P
- #define CAN2_TX_BUFFER_SIZE (16)
( U* Z! |) f5 Z* S - #define CAN2_RX_BUFFER_SIZE (16) n S7 N9 ~2 O* y
- 9 X6 O6 y. h) o, @1 h
- #define CAN2_TX_GPIO_CLOCK RCC_APB2Periph_GPIOB
8 p- ]3 p2 H7 Z, S1 |1 }0 K7 \ - #define CAN2_RX_GPIO_CLOCK RCC_APB2Periph_GPIOB
) i- t7 P+ ?2 N( k! J
/ s6 c7 A/ x( p' ?5 K+ O9 u7 [* j- #define CAN2_TX_GPIO_PORT GPIOB
3 P- E1 g8 o9 n3 n: ~- ^8 h - #define CAN2_RX_GPIO_PORT GPIOB1 h+ n ?2 j' \2 J
* R8 y) i/ Z5 Q+ m- V4 @6 m4 m- #define CAN2_TX_GPIO_PIN GPIO_Pin_13+ H- p# b6 \' R4 Y
- #define CAN2_RX_GPIO_PIN GPIO_Pin_12
% k7 Q1 M B: P2 v& k4 H0 O2 [
: o9 L( h1 R! f$ B0 L- #define CAN2_IRQ_PREEMPT_PRIORITY (0)
8 b$ b* E ^$ G - #define CAN2_IRQ_SUB_PRIORITY (0)' y$ E6 }) B' o* m/ W# P2 j8 R
; w# ?/ l' B; q9 y j- #define CAN2_PORT_REMAP() GPIO_PinRemapConfig(GPIO_Remap_CAN2 , DISABLE)
5 N! F4 i a( _" z5 D* q" r' E1 T - /******************************************************************************/# }" U% }( U* \2 T- N
- #endif /* STM32F10X_CL */- W4 H, w, z- n4 M7 ]8 c( j
- ) `1 M+ x D7 c2 p+ f( k
- /* Type definitions ----------------------------------------------------------*/. c2 I7 N! ]! I' e
- typedef enum
6 L, j8 {& T2 K# V2 i f* V7 k - {
8 h+ U# n p9 s. [ - CAN_WorkModeNormal = CAN_Mode_Normal,, x$ H: L$ k: i, b( g: v
- CAN_WorkModeLoopBack = CAN_Mode_LoopBack1 C& b6 Y3 o- R( j" o7 P% h( J! F
- }CAN_WorkMode;) g% o: U+ p1 t& r' a! k+ P
! v2 k9 c7 x4 [" w- f9 [- typedef enum
: m5 |: x( A+ u6 r* ?% i' p - {
2 x) e7 P6 ]; F7 j- V- S! N" \ - CAN_BaudRate1000K = 6,' X' L: Q& M( D" ]
- CAN_BaudRate500K = 12," q! A1 F. B/ Y: q- I- L9 [( T
- CAN_BaudRate250K = 24,
; V* l8 _/ B; v - CAN_BaudRate125K = 48,/ L$ ?3 y) f+ j0 L. r
- CAN_BaudRate100K = 60,
* H5 E7 K+ Z6 k, W+ a, V* ? - CAN_BaudRate50K = 120,
9 o& @6 i: F; Y& ]6 l - CAN_BaudRate20K = 300,+ s e) Y- T! `& N! p
- CAN_BaudRate10K = 600
9 M5 M& S& q+ u p- \- n& i$ }! i - }CAN_BaudRate;4 ?: u3 q& y+ V( t+ z
- 5 T; \- e0 X+ O0 @5 F) F0 k5 X
- /* Variable declarations -----------------------------------------------------*/
7 i. S) N1 M9 D) b - /* Variable definitions ------------------------------------------------------*/* s1 W0 e' w- |# h. Z$ \
- /* Function declarations -----------------------------------------------------*/
4 v# S& r1 |2 e6 O! I - void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId);
1 [5 ]( z+ }. H; l# T( l - void CAN_Unconfigure(CAN_TypeDef *CANx);' G6 R0 y ~+ E' |7 o: W
- , j) i& ?9 w3 c7 L" v& B
- void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));4 O7 v( b {1 a4 u! _! C C* }
- void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void));
9 ~* d9 C& }) \ - 8 Y5 |) S( F3 s" T& E
- uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number);( Z5 h3 q5 N6 j! l x/ `
- uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number);
# G8 G8 ^, I/ n- p) ~ H
, \5 f4 H' T9 h! [, i5 \- uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx);/ Y. S& y" R# [; N* U3 L+ K$ W& v" ^
- uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx);
3 U! @$ P% K* p6 P; ?. m - uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx);
" ?3 K' e! J% U2 O& \ l/ o - uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx);2 N8 a( ]# t' p6 C
y& q, X0 o j! [- bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx);1 ?) J! o3 O3 Z
- bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx);
( W/ g$ { `! J. `& r- {. N& c4 C* p - bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx);
5 [! A* l$ r! H" U' I, B - bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx);
" `2 l7 @) M+ V
+ H1 K; b. ~ n- void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx);
' ~# T8 d7 |' @& W8 [ - void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx);
, k) p/ o6 n0 F. I - . c, J, S4 M) b$ T y0 D0 `
- bool CAN_IsTransmitMessage(CAN_TypeDef *CANx);
1 d9 H1 q7 \1 A) D% s - + Q9 g$ G2 p- L. j% F# r) _) W
- /* Function definitions ------------------------------------------------------*/
* e) q9 `: [# T - 9 t& H' F9 ]' J6 @3 J {6 ]
- #ifdef __cplusplus
5 {# K3 n- v6 O& s5 e8 e - }
* M5 Z7 ?4 |3 p. l% {& { - #endif
8 A; _8 g x. A, A9 a4 ~
+ a- y: g; w8 s0 E, \: B' \- #endif /* __CAN_H */( m/ J- X5 p. H9 P2 X$ x) f) t4 L& f
复制代码 , c9 \$ ~1 d8 l+ S9 ]
1 E, I f, W7 B8 m- F f% N
' u& h }, l- U: u) Q0 a% B% ECAN.c 文件
8 \% |" U6 Y0 A! `* t+ {/ ~7 L# |8 E3 `2 @) r5 Q
- /**' M \( @) q i3 S& R. K* Y
- ******************************************************************************/ U0 s {# a0 }: d. @; m/ j
- * @file CAN.c/ a" C* w9 Z( R
- * @author XinLi
! v7 n* p. E' F2 m- d - * @version v1.0
9 p8 B o) E& X6 z. X - * @date 24-June-2018
" o9 j! o. `% F9 E7 w! J1 W - * @brief CAN module driver.
4 @) j: j6 N$ |$ }3 ^ - ******************************************************************************
+ s4 g( b, J* H4 x3 q5 @$ L% k - * @attention
( a0 |8 K* N9 ?/ F$ s - *$ r4 d+ l. `/ W
- * <h2><center>Copyright © 2018 XinLi</center></h2>
/ E+ q2 E3 h: g - *. M* x( q; l) P# d+ m8 r
- * This program is free software: you can redistribute it and/or modify5 W, h) |4 `. G- r7 d2 R
- * it under the terms of the GNU General Public License as published by3 k5 ?. `' t$ p# P/ o, b( }
- * the Free Software Foundation, either version 3 of the License, or3 {% g9 q) l# z
- * (at your option) any later version.2 H- m" ]! a" d5 Q- }
- *+ v: Y* G% P! o1 M
- * This program is distributed in the hope that it will be useful,
/ W5 q$ k* O* n5 I - * but WITHOUT ANY WARRANTY; without even the implied warranty of7 D9 B! c/ j- d0 l% k. F
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the6 Z2 w+ A- `" Q( e& S; _7 u* ?& H
- * GNU General Public License for more details.4 D5 v+ l- \6 J. ^
- *7 y& U' N6 r. D* Y; S" }) F
- * You should have received a copy of the GNU General Public License
4 }9 R+ K) g0 T3 s9 g r7 m, [. n% X - * along with this program. If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
, w0 r7 c! X9 p2 @ - *
+ j* l8 k, H' O6 l ? - ******************************************************************************" a4 y9 ~- a' C: U
- */
$ u9 ]! O( W! a- L& N6 [9 v - 0 _- o7 _+ b0 F' w
- /* Header includes -----------------------------------------------------------*// y5 \7 G! D) g' @
- #include "CAN.h"& Y8 e- u7 L) A* ]7 [2 e& ]" T
- #include "RingBuffer.h"
' T) E, w% Y3 G - 6 ^! }: t4 m! X# r
- /* Macro definitions ---------------------------------------------------------*/
: F! C& ]6 e* b! F6 c - /* Type definitions ----------------------------------------------------------*/
6 F. c e$ S* \' y# W# u - /* Variable declarations -----------------------------------------------------*/
! N2 w7 T2 P6 s - static volatile bool can1InitFlag = false;5 n5 d( l- m) V; R4 U4 t: c$ h5 Z
- static volatile bool can1TransmitFlag = false;
- m2 L% V0 k4 d, M8 K! m$ Q/ b - Y9 ~. @: D4 ]7 t! n; T2 e; H$ m
- static volatile void (*can1TransmitFinishCallback)(void) = 0;# j# G, [" Z. T( A2 T6 h2 d- m5 J
- static volatile void (*can1ReceiveFinishCallback)(void) = 0;" w# {) ^- ]) B: B$ m0 W
- 3 k$ A3 u& Y r4 Q
- static RingBuffer *can1TxBuffer = 0;
. l, A3 U/ z6 a j% M - static RingBuffer *can1RxBuffer = 0;! y/ j& C! e+ L G! I1 q& H a/ C
- , P* O" M0 B+ o& F4 S3 T
- #ifdef STM32F10X_CL; ]2 O. r3 p( l- W# Z) y
- static volatile bool can2InitFlag = false;
. u$ Q* W3 G4 x* B0 W( q - static volatile bool can2TransmitFlag = false;
/ l* X/ s% i; U' Y9 j$ C
% c2 s" b! v/ L& \& ?- static volatile void (*can2TransmitFinishCallback)(void) = 0;! @$ e8 i$ Y/ y+ W
- static volatile void (*can2ReceiveFinishCallback)(void) = 0;* e" ^! F" u3 s$ W/ D& ^ K
- ' v: n9 U1 V) u( j/ w' g: ]# r
- static RingBuffer *can2TxBuffer = 0;
, U- a' @$ e& F ? - static RingBuffer *can2RxBuffer = 0;
9 o4 E/ |9 ?1 e$ O3 ^2 Q - #endif /* STM32F10X_CL */& p% e" j" u$ r
- # J- |# m" m6 t: N
- /* Variable definitions ------------------------------------------------------*/3 @) O7 u6 b) Y/ M) B! d2 ^
- /* Function declarations -----------------------------------------------------*/
+ V( t/ g" R, {! R7 ` - /* Function definitions ------------------------------------------------------*/
J3 t" G) E* C* `& A/ C0 r - " d: f4 M, {" I" d. \6 c0 i) D
- /**
- H! t7 z T( A0 J - * @brief CAN configure./ q* X O% w! C( i
- * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.1 G1 [2 y5 L# `% V8 r& ~$ i) c
- * @param [in] WorkMode: Work mode.
; a+ h& q2 w* V0 R& C - * @param [in] BaudRate: Communication baud rate.
. S2 ^1 a$ @' f7 K& m* O" \ - * @param [in] StdId: Filter standard frame ID.3 _* x" ?0 Y3 t( p; J6 e. j4 Q) v
- * @param [in] ExtId: Filter extended frame ID.
' U: X; p) K3 `# L; x! F4 J) V - * @return None./ W. N. K) m6 v2 l) O8 G
- */ F7 {$ P' R" i. f
- void CAN_Configure(CAN_TypeDef *CANx, CAN_WorkMode WorkMode, CAN_BaudRate BaudRate, uint32_t StdId, uint32_t ExtId)
, a7 U5 J6 V; _1 J - {% |5 r6 V/ z7 n- A& ], Q
- GPIO_InitTypeDef GPIO_InitStructure = {0};
* T2 L5 v4 w1 |! n2 r - CAN_InitTypeDef CAN_InitStructure = {0};# |/ A# P: q) ?# w; d& t: w
- CAN_FilterInitTypeDef CAN_FilterInitStructure = {0};. d: ?/ A( T1 P+ c8 [
- NVIC_InitTypeDef NVIC_InitStructure = {0};
5 h% m# g0 k' Z2 b - * t+ q2 Z+ _ Z! t3 ?2 X6 x
- if(CANx == CAN1)
; k! I6 o; }0 G; @" J - {( Q5 c, S$ V, o8 M7 R
- if(can1InitFlag == false)5 m! C( I! s3 a- m) k1 i
- {! v) ~# O' i s4 T% e! E
- can1InitFlag = true;: L( u1 r- e* c" s
- 0 u; a- f% z7 ?
- can1TransmitFlag = false;0 {" e& }3 X: Q/ A9 a6 D4 k& K* ]" c
( d8 i* R2 K7 A! z* H4 S- can1TransmitFinishCallback = 0;& F7 Y. w5 v s) |4 C
- can1ReceiveFinishCallback = 0;
- M& [) D0 L* f$ w - ! K1 Z" O1 O/ \# k* F- M2 p. b
- can1TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN1_TX_BUFFER_SIZE);
6 `' Z) A1 L" Z1 l3 B/ o, u# o9 N - can1RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN1_RX_BUFFER_SIZE);
, k. G, T! l6 x1 g$ | X) a' k8 j3 f
; s5 I8 ^& r$ `; Y8 C- #ifdef STM32F10X_CL- B( J& z |9 h* { u2 p, w( \
- if(can2InitFlag == false)
6 p& G2 X: _1 C0 U6 e - #endif /* STM32F10X_CL */
9 u% W9 }: b" V - {3 ?) s. R* t: Q
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);$ [; D, P) n, \; L
- }
G+ A: N1 o$ C3 W- E! \
" W! e1 ~% y1 L% W& j* p- RCC_APB2PeriphClockCmd(CAN1_TX_GPIO_CLOCK | CAN1_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);
! A. N) k; U% r0 {% m
$ d* b b3 ]) W- `2 F6 Y- GPIO_InitStructure.GPIO_Pin = CAN1_TX_GPIO_PIN;. C1 Q) b$ t5 F* O) c" ]0 d
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
M# J7 S- C' X - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;! T9 {: ]: p0 Z f
- GPIO_Init(CAN1_TX_GPIO_PORT, &GPIO_InitStructure);
- V1 N3 R) C9 J/ D G8 |- O+ G# y - ; n* D% f! s' I3 E2 |
- GPIO_InitStructure.GPIO_Pin = CAN1_RX_GPIO_PIN;
' V% [/ c+ d; i8 }! v, i. G - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
G# b7 D$ [% |5 l2 c" x8 k1 y - GPIO_Init(CAN1_RX_GPIO_PORT, &GPIO_InitStructure);
, E$ h( l+ {# g; z1 r3 x- F
$ |8 W/ C- A4 T3 n5 Z- CAN1_PORT_REMAP();
4 j& `5 q6 J9 V. ^" W( b - ) n: Y9 @ c# Q$ p8 g O
- CAN_InitStructure.CAN_Prescaler = BaudRate;2 y% X8 H, l+ R5 q, k! ^. Y
- CAN_InitStructure.CAN_Mode = WorkMode;
) V a. A: u- J3 Y - CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
2 Y6 o: U1 n( k7 f2 A - CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
" L2 A$ t* L @ - CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;& @7 o- A0 i s" C& l4 M d! ~, n7 h
- CAN_InitStructure.CAN_TTCM = DISABLE;) {4 @# l, y0 N' A
- CAN_InitStructure.CAN_ABOM = ENABLE;" E8 Q1 _3 ^; @/ ?0 h) \
- CAN_InitStructure.CAN_AWUM = DISABLE;
1 M) V8 Z6 S' o- }4 p. b& |- y - CAN_InitStructure.CAN_NART = ENABLE;
) N& q, H7 B) l4 n- X- p - CAN_InitStructure.CAN_RFLM = DISABLE;; b8 x* `: {# A% w
- CAN_InitStructure.CAN_TXFP = ENABLE;
# ^3 b7 d. m* R - 6 q! l/ X/ {/ B% N! C/ H
- CAN_DeInit(CAN1);
$ c+ y" `3 { W8 v/ v# c - CAN_Init(CAN1, &CAN_InitStructure);0 R" g0 m6 Y; m# @
- * z0 P/ R6 z4 p4 \0 \- Q4 j. c+ |8 P
- CAN_FilterInitStructure.CAN_FilterIdHigh = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);8 M/ K" x; z+ M/ }' G: E2 O8 y3 w
- CAN_FilterInitStructure.CAN_FilterIdLow = (uint16_t)(((StdId<<18)|ExtId)<<3);
* ^, R" `% O# { - CAN_FilterInitStructure.CAN_FilterMaskIdHigh = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;
" E" i* a& e2 K# D - CAN_FilterInitStructure.CAN_FilterMaskIdLow = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;( W" V% E [3 s: y+ ?) d
- CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
* Z( V& [) n4 J - CAN_FilterInitStructure.CAN_FilterNumber = 0; a1 s z3 I. ^$ a8 \
- CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
+ A/ ]9 G, ]: F3 k5 ] - CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
( {4 W0 s- \+ @/ Z/ K- e! A7 u - CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
5 L0 f4 |( i, g( S - CAN_FilterInit(&CAN_FilterInitStructure);
3 W& t. Q. x- a( n1 y6 h2 o& j
0 [- G# b8 P( w0 K% Y+ _- CAN_ITConfig(CAN1, CAN_IT_TME | CAN_IT_FMP0 |CAN_IT_FF0 | CAN_IT_FOV0 | CAN_IT_FMP1 | CAN_IT_FF1 | CAN_IT_FOV1 |
5 X6 X. z! P. ^* k0 T n5 y! K - CAN_IT_WKU | CAN_IT_SLK |CAN_IT_EWG | CAN_IT_EPV | CAN_IT_BOF | CAN_IT_LEC | CAN_IT_ERR, DISABLE);
2 m9 L f- ~3 \ - CAN_ITConfig(CAN1, CAN_IT_TME | CAN_IT_FMP0, ENABLE);
9 ~! _6 u# ~+ @- J8 J6 h" V- V G2 l - , X3 l) k- d; T3 e: k1 L. G' ^
- #ifdef STM32F10X_CL$ U8 _& U. Q1 {, v; Y) {( F9 |
- NVIC_InitStructure.NVIC_IRQChannel = CAN1_TX_IRQn;" e$ Y# P" Y$ c8 f8 e. r
- #else
8 i+ Q% n) u6 o% B; p - NVIC_InitStructure.NVIC_IRQChannel = USB_HP_CAN1_TX_IRQn;
, h( f( ?6 @% g6 _6 y - #endif /* STM32F10X_CL */$ |+ U+ P, `. G% v9 @
- # M) |/ w& T6 _. R3 N) B
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;. ?2 M* Z& n h7 X7 K4 f( F2 E
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = CAN1_IRQ_SUB_PRIORITY;
$ r7 ]% b+ w8 g: y& }, j - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;# |( Q; [+ b, ^7 b8 E
- NVIC_Init(&NVIC_InitStructure);% O; J8 r' Z- M( R8 C1 g
- 3 }, Z' v1 B, b$ M5 Q
- #ifdef STM32F10X_CL- Y) f/ {- D, |" e
- NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;4 a0 j* V* l8 Y: o; J# `- Z
- #else
) ?% w$ r( Y: N, \- E; Q - NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
1 G7 U- `! J, P' g; |1 e - #endif /* STM32F10X_CL */( ^6 g+ W, C. ]! ]- o; G
- ) z, r1 e4 K2 p) U' C( q
- NVIC_Init(&NVIC_InitStructure);
5 I1 q6 Z4 C; ^( i - }* j! T1 ?$ P2 T2 a" J! s7 F
- }
. o' O( L9 G# {9 {! B - 0 q) a6 \# ^6 B' j* s1 d# {
- #ifdef STM32F10X_CL2 k' [' }; t1 r! N
- if(CANx == CAN2)" |% p- k0 j* N+ g
- {
5 S/ d: {; e7 w. J" L# H' n* n - if(can2InitFlag == false)$ \3 F: y3 M; y
- {
# C; Y# G2 r/ @8 b - can2InitFlag = true;
: t& v) E( |# z# o
& x9 Y/ b8 Y- S6 D3 |1 |5 x) E- can2TransmitFlag = false;+ ]. O# U& M, X* @ a' D! u
* z; s$ m' [ C1 U% H% s! R- can2TransmitFinishCallback = 0;1 q& ~0 N. x0 M2 \
- can2ReceiveFinishCallback = 0;
1 P7 P6 z! X1 z# N2 Y! n
2 \1 ?* A2 r- s$ q, j- can2TxBuffer = RingBuffer_Malloc(sizeof(CanTxMsg) * CAN2_TX_BUFFER_SIZE);
1 R7 J3 G7 Q1 |/ {0 j - can2RxBuffer = RingBuffer_Malloc(sizeof(CanRxMsg) * CAN2_RX_BUFFER_SIZE);4 H; v) u( @: `6 {, W
U: C: |8 j. W: D- if(can1InitFlag == false)
3 I! t/ k* l0 W( t - {
8 s, Y7 h" n6 I+ D' y; h/ | - RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
6 n/ E* z3 h2 c, L/ B - }+ r8 T( C2 Q% U9 y n6 X0 s% u7 m
- , n' o! }* ?5 P$ I
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);9 M- S- x; E! o- X/ P
- RCC_APB2PeriphClockCmd(CAN2_TX_GPIO_CLOCK | CAN2_RX_GPIO_CLOCK | RCC_APB2Periph_AFIO, ENABLE);
6 P8 R e1 _5 M V4 b" Z
! ^- @, ^; j7 c i! I- GPIO_InitStructure.GPIO_Pin = CAN2_TX_GPIO_PIN;5 y! D- U3 h9 J2 H! J
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;/ m. q" n7 s* F2 R
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/ b. z. g8 `! | - GPIO_Init(CAN2_TX_GPIO_PORT, &GPIO_InitStructure);9 x. O: L( p) E: y5 W
, ?: v/ S! c( {) w! ~; }7 a' X7 {* f- GPIO_InitStructure.GPIO_Pin = CAN2_RX_GPIO_PIN;
$ @* w" _& F1 f6 q - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;5 X$ ], m$ r- C
- GPIO_Init(CAN2_RX_GPIO_PORT, &GPIO_InitStructure);5 V2 W& E1 z3 t* T8 |; ]* r
- 0 C- e% i) o# L5 X) R
- CAN2_PORT_REMAP();
# Y) }& C2 }% B& [, v+ E! K9 ~ - 4 Z6 q; `& d! B/ R9 d, G, F) M
- CAN_InitStructure.CAN_Prescaler = BaudRate;
# B$ N3 A1 }3 Z0 @" I - CAN_InitStructure.CAN_Mode = WorkMode;* U+ `! P0 }/ {* s& J( b2 t
- CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;3 I& k/ s( r' b$ O, M
- CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;" I5 |* \4 b/ j* r- z3 K
- CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;& E9 W9 p" S+ I# ?
- CAN_InitStructure.CAN_TTCM = DISABLE;
6 v0 d) ]* {" e4 X* p( a: ^/ s5 O; d - CAN_InitStructure.CAN_ABOM = ENABLE;# t% _# D3 m0 l2 O: U
- CAN_InitStructure.CAN_AWUM = DISABLE;
R1 b1 T. \ r$ o+ x0 b - CAN_InitStructure.CAN_NART = ENABLE; I% Z, t9 Y+ H! w2 L* o/ A
- CAN_InitStructure.CAN_RFLM = DISABLE;! { T5 K, }( Y9 ?
- CAN_InitStructure.CAN_TXFP = ENABLE;
- ^9 [) L/ c( m3 m
X) z! }, G6 |7 c- CAN_DeInit(CAN2);( D! b5 n' [+ V. v5 L1 P4 f+ m
- CAN_Init(CAN2, &CAN_InitStructure);5 c! h1 s- O1 |& N! F% S! O7 U
! f" m* x% Y! z: x- CAN_FilterInitStructure.CAN_FilterIdHigh = (uint16_t)((((StdId<<18)|ExtId)<<3)>>16);* l% C4 I3 I3 N: L4 b
- CAN_FilterInitStructure.CAN_FilterIdLow = (uint16_t)(((StdId<<18)|ExtId)<<3);
& K# l' x% g8 G7 ?3 T8 s9 ` - CAN_FilterInitStructure.CAN_FilterMaskIdHigh = (~((uint16_t)((((StdId<<18)|ExtId)<<3)>>16)))&0xFFFF;1 X# u8 X+ C5 a5 I" `
- CAN_FilterInitStructure.CAN_FilterMaskIdLow = (~((uint16_t)(((StdId<<18)|ExtId)<<3)))&0xFFF8;
) ^1 B4 ^0 ?0 h7 Y) b - CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0;
, P5 f7 S! j! U+ h, x% p - CAN_FilterInitStructure.CAN_FilterNumber = 14;
9 ^* a6 s" c1 c3 O3 `/ q# [+ ? - CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;: N: X e) n" K, s6 D; W5 {
- CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;4 c }' F9 V- g8 w5 @
- CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;% c) @% I' c, R1 {1 j
- CAN_FilterInit(&CAN_FilterInitStructure);
* G+ A K! H3 ?6 } - 6 H* L0 }" V% L* E5 l+ A+ b
- CAN_ITConfig(CAN2, CAN_IT_TME | CAN_IT_FMP0 |CAN_IT_FF0 | CAN_IT_FOV0 | CAN_IT_FMP1 | CAN_IT_FF1 | CAN_IT_FOV1 |" }% z3 B! r3 u8 v4 L& t
- CAN_IT_WKU | CAN_IT_SLK |CAN_IT_EWG | CAN_IT_EPV | CAN_IT_BOF | CAN_IT_LEC | CAN_IT_ERR, DISABLE);' G, N. m% M2 E) J$ p
- CAN_ITConfig(CAN2, CAN_IT_TME | CAN_IT_FMP0, ENABLE);; g1 q7 j3 e6 `4 x& C" W
, c7 a* E7 c5 O, a- NVIC_InitStructure.NVIC_IRQChannel = CAN2_TX_IRQn;
7 P6 S- b0 C) \" W - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;
0 j* p# A1 |5 \3 |3 b0 r - NVIC_InitStructure.NVIC_IRQChannelSubPriority = CAN2_IRQ_SUB_PRIORITY;
6 P$ r9 s( D0 c2 r' k# u - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;8 E; U" F6 M0 N8 J U9 m
- NVIC_Init(&NVIC_InitStructure);' y- Z' a4 i5 ^8 q1 W: i9 r5 P/ x$ q
' g7 M1 V y u, b- NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;( M$ T$ N* m5 e/ y2 a ] K4 `' c
- NVIC_Init(&NVIC_InitStructure);; h @6 T) d" t+ g
- }8 G* t/ }9 f- G
- }( I! P+ i, y9 x# c- t0 V( ?6 }
- #endif /* STM32F10X_CL */+ x; W" [7 Q% z' J) [
- }
5 y/ n1 W. y& |6 W( p, I) o - # O0 e, ^9 N8 m. o/ s* D
- /**
7 n2 \! B/ g4 z/ h- p- Q - * @brief CAN unconfigure.+ O2 b! H" L7 F; C# l5 K: {
- * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.7 M; O3 N8 m% A7 R% @/ M
- * @return None.
9 _3 ~& `6 _0 }" M& ]+ y) M2 Z - */
- r7 x% o, E7 y# m" \ - void CAN_Unconfigure(CAN_TypeDef *CANx)
4 v( _; e A9 N. Z - {
" \! Z- W- l5 j+ W4 I - NVIC_InitTypeDef NVIC_InitStructure = {0};4 _' @9 u0 F9 W# I! c* B7 @# X
- 3 G0 k" p4 t4 z! L. H
- if(CANx == CAN1)
# [9 r- z. D+ L1 i, G& R" l - {
0 O- d% @8 A! ^# P* E3 x/ p' V, R v - if(can1InitFlag == true) H6 z' P' T1 {' J" F
- {
s, W6 G7 E5 L* \! h& t - can1InitFlag = false;
- D0 T5 {4 w k
1 P; S( G4 [/ o- #ifdef STM32F10X_CL
y% r/ q# m- W7 M) B - NVIC_InitStructure.NVIC_IRQChannel = CAN1_TX_IRQn;
7 x8 c1 A! l/ E5 P) _) l2 o# M - #else
# b4 H8 W( @4 f- c* }" q - NVIC_InitStructure.NVIC_IRQChannel = USB_HP_CAN1_TX_IRQn;) |/ ~+ U" s: g
- #endif /* STM32F10X_CL */
9 @5 E& f7 z0 e2 n9 p
6 k% n( }4 T$ B. S; T- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN1_IRQ_PREEMPT_PRIORITY;
4 f! U/ i9 u$ f - NVIC_InitStructure.NVIC_IRQChannelSubPriority = CAN1_IRQ_SUB_PRIORITY;: Y+ |# p7 T* ?
- NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;6 {9 Z( s+ n' \
- NVIC_Init(&NVIC_InitStructure);1 I/ g8 h7 K8 m- `0 F( v) t
3 I3 L& o0 k. `- H- #ifdef STM32F10X_CL
7 B/ u) v. J" Q: S - NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;" k& Q, r/ J. o+ j6 `* V4 l- Z
- #else
4 r) P- ^& ]: ?& y% S6 Y/ X8 n - NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
; ~' j4 [" m6 ?$ {% Q% Q - #endif /* STM32F10X_CL */
: x, c) e* ^! P3 T. Z5 W$ D2 |
9 x, H2 Q0 E! @$ s- z; J, f- NVIC_Init(&NVIC_InitStructure);- R, i" R. o( ]' R! n( P# ^% z
6 {2 g. x d" B3 O3 U: F- CAN_DeInit(CAN1);* F: @2 J+ V1 H
- ! Y* ~3 r" C& K
- #ifdef STM32F10X_CL! V5 |$ O! I# m8 x5 [' Y3 C
- if(can2InitFlag == false)
: Y- `+ c' P- q; v- `2 L1 N" ^3 L - #endif /* STM32F10X_CL */
+ C# g& X$ c+ f) I7 A9 e. l - {
/ J( _) R! k- ~ n/ l: x - RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);+ q$ F0 i- N% N/ D, }5 c& k
- }7 t8 _2 J% @1 G6 R* \7 i" V
- 1 Z8 ?( Q. Y! u' `
- can1TransmitFlag = false;
5 [5 g* N. X) `+ F4 z* K - 9 a2 L; @* X' e6 t; i; T
- can1TransmitFinishCallback = 0;
/ y" q4 k5 r" r" N1 q6 U - can1ReceiveFinishCallback = 0;# P/ Y. Z! W+ `8 p
+ i" t* U @ l7 n6 O U- RingBuffer_Free(can1TxBuffer);! V c; F( f g, T7 a
- RingBuffer_Free(can1RxBuffer);$ b6 Q* }. L& u- v y+ k( s& N
- }
2 D8 P3 x( O* W; G, M9 n6 r% I y; ` - }0 l' E! U- h n+ ?& j5 w
1 E* p1 Y; i2 W2 |; C+ E- #ifdef STM32F10X_CL
' P+ @$ L7 K5 u' D - if(CANx == CAN2)0 j0 ]/ B9 }0 A8 g- q
- {) d1 {3 Q7 C9 l# i9 M
- if(can2InitFlag == true)
& E1 ]) E. F9 m, N+ H) y( ]* J$ a - {
1 @ P0 b- }- Q, H, a - can2InitFlag = false;
# }9 ^/ D* V0 x0 {6 s n, x0 K - & o J+ b# n- }. P
- NVIC_InitStructure.NVIC_IRQChannel = CAN2_TX_IRQn;
& ]$ ?3 C( }! p: L! s& E) V - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = CAN2_IRQ_PREEMPT_PRIORITY;! N+ p" O% D( U! y% G3 i! J
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = CAN2_IRQ_SUB_PRIORITY;0 w0 i [# \" D
- NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;3 e! Q _# r% C) M3 f& `8 m
- NVIC_Init(&NVIC_InitStructure);6 R- k6 w! q- u) S" d) |
( M1 T1 d' r% a- k! h& I/ O- NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;$ o* N! i* z2 M9 c! B% O( A
- NVIC_Init(&NVIC_InitStructure);' X; @/ R( G2 q- B0 x0 T+ z
- s% r6 \: ~7 z' ^- CAN_DeInit(CAN2);
% `5 ~2 i1 M t; B- L - 9 R' ]7 q# \/ m2 C3 ^& L) ~
- if(can1InitFlag == false)' {2 l- q9 C6 {+ G; a5 c+ C6 v" m
- {$ @* U+ e, Q4 \! p% \5 q- {
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, DISABLE);, Z# a, m9 V: W V6 O' [
- }+ G" r7 W7 T' d- k# `
+ N4 K5 e- _$ ]; F5 I) l1 ]! { t- RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, DISABLE);- a+ A1 x! I7 }' U' N. @9 C5 P
' c- @' [, q% S( b {) y- can2TransmitFlag = false;" y" A1 p7 A( m. x% s/ a: _
P" q$ w9 {# @# N/ W: }6 Y, E8 |- can2TransmitFinishCallback = 0;
) `! j. h" p5 J7 z1 u2 r, G+ p8 u, S - can2ReceiveFinishCallback = 0;
( l2 L4 g. H, p; M
$ L* B8 P3 x3 A- RingBuffer_Free(can2TxBuffer);
. F+ J8 m( ^" b9 d - RingBuffer_Free(can2RxBuffer);
3 ?/ @5 i' ?9 }7 W - }
% Q9 i/ v, h" [9 Z - }+ x! d! W ^$ \$ h3 I& d1 G$ a6 U
- #endif /* STM32F10X_CL */1 L5 ]) O5 `; |. @0 D
- }
" z6 c# J; G% K; f. r6 S% q - 4 O6 ^& R: F( {% D4 N2 a" u7 y' w
- /**8 }! m- }5 M; l2 }% Q
- * @brief CAN set transmit finish callback.
2 U- @" s O" v6 Y - * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
; R% L, b$ A. R8 H' f& w - * @param [in] Callback: Callback.
7 E( E2 e( G& C1 O - * @return None.
2 y& V$ d8 R( r - */) z" E1 c* T. W$ T' v
- void CAN_SetTransmitFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void))- F/ A$ u+ O9 s+ o
- {- ?- Y$ ^' [) r/ Z
- if(CANx == CAN1)/ c2 S( I# {1 R# n
- {
: b. \9 x8 m. j: G" p - if(can1InitFlag == true)
+ @4 f L3 I% L; L% L: J/ H( W/ C; l - {0 u& z+ u. g* l! e1 ]8 ~
- can1TransmitFinishCallback = (volatile void (*)(void))Callback;
. D% w) W2 G: l- e- P, \3 a% n% g - }
3 n Y/ \9 X! N. m2 Z - }/ y7 p/ h: d! X' v$ K1 {
- , x q$ ^3 G j& z" L0 S' b
- #ifdef STM32F10X_CL! d0 @4 R9 R a9 \0 i0 R& K
- if(CANx == CAN2)
! j! Q' ]: B4 ? - {. }" P! m7 Y4 a1 e9 J: j
- if(can2InitFlag == true)
; M* r9 {% Q+ S1 } - {
, i& p, w) i. t - can2TransmitFinishCallback = (volatile void (*)(void))Callback;9 t* `9 @8 Y0 u
- }
2 r. k U- q( J" H7 u1 @ - }
, P; e$ p$ M. N8 C# ] - #endif /* STM32F10X_CL */
9 B g; ?4 [+ j - }* A r; b; F( w# v E9 y! o
5 v$ j _. ], V# Z9 o- /**
6 `( I1 b6 f/ m; m3 z4 R- I - * @brief CAN set receive finish callback.
/ }2 V! R8 r0 f4 ^: d. v6 \+ M - * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.% T: R- B/ Q0 D
- * @param [in] Callback: Callback.3 m5 N$ V% W0 h9 u
- * @return None.
# g- a% I: O: m; r# K5 w3 s9 t. l - */
$ t, l2 K. v2 n; N+ B; L - void CAN_SetReceiveFinishCallback(CAN_TypeDef *CANx, void (*Callback)(void))% B/ C% R: o. E3 z6 `
- {
/ [% ~" R" s9 g7 O0 e - if(CANx == CAN1)
3 N, O! j, c' l, Y - {
+ e6 o! i! ?, O. |4 n - if(can1InitFlag == true)
% c/ r2 M4 o6 ]5 T - {$ X4 v, Q1 e5 k: H
- can1ReceiveFinishCallback = (volatile void (*)(void))Callback;
1 o |0 G% |0 e0 e) |0 |; k - }
3 Z7 t) j! x7 J9 m* o - }
0 z' l( S) @% X/ N" n - 9 C) }/ n# c. M! w/ ?
- #ifdef STM32F10X_CL
0 b* b% L2 k4 { - if(CANx == CAN2)
( p0 y3 S; Y9 B/ m8 b. l - {
6 q- ~+ B7 G u. }5 b( C - if(can2InitFlag == true)
$ p/ v0 y; d5 U& U6 p5 j - {* T0 L) H- Q Q$ o. H
- can2ReceiveFinishCallback = (volatile void (*)(void))Callback;
* f( H0 f3 y) n( w' T/ T, m { - }7 T6 C* g- X- {* N5 Q* F: g+ n
- }
" n' C6 m9 z- _8 ` - #endif /* STM32F10X_CL */! S8 J! M2 t" G: l( Z& ?; n, [
- }
) Q& A6 @% U" j5 x/ Y- G+ \5 R
( S/ X5 a7 z/ D& ~$ g- /**
$ A% y1 E" a- U8 w4 C+ F6 _% F - * @brief CAN set transmit message.
h! f" C: |. w2 Y9 ` - * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
' Q+ K0 Y1 m9 L4 @0 G - * @param [in] Message: The address of the message to be transmit.+ @( `3 _2 H. W: Y u" U
- * @param [in] Number: The number of the message to be transmit.6 S: w. B w7 {7 [8 F k
- * @return The number of message transmit.
3 t5 i5 s0 H* S* B - */
& x2 V: K5 B4 T. K2 k# J9 X - uint32_t CAN_SetTransmitMessage(CAN_TypeDef *CANx, CanTxMsg *Message, uint32_t Number)
. c, c" H* j7 {1 ]) \; u* `, v - {4 ? u3 o1 S- d2 A" i3 Q1 v8 C4 z
- if(CANx == CAN1)& U+ n: A3 u4 s. r) y4 Z
- {
; c! N/ C8 B& H% b - if(can1InitFlag == true)
* F: f) r4 _* f4 @4 c7 l1 V - {& d$ V3 p7 p6 `. v: ^6 t
- uint32_t available = RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);
. ~& C z+ P1 a( }* [- g: |4 N
' w+ s5 v4 g: d P' u; u- if(available > Number)
6 F0 W- n, N( D, b3 z1 { - {
0 ?& b. L1 K- [ - Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);
% `0 o _7 k& K, |1 }8 C, o - }. ~2 i* B* B* V* r m5 _
- else
0 p) w7 A) T% c: Y. [$ o! X4 n - {
. t! Q$ p/ F! k D! B7 v - Number = RingBuffer_In(can1TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);
; v2 R% D3 g$ K; X. [1 U - }$ y3 V( r; |3 l
& P' H) q' t7 j- if(Number > 0)
/ c8 w4 N" {6 N" H t5 } - {
! z2 R: J4 e4 N - if(can1TransmitFlag == false)
& V1 U. r* o( J( Z3 V - {( x1 k/ T5 x; e' Z( Z
- can1TransmitFlag = true;5 ?5 i, v" K6 X
- ! g2 l* f/ m1 r! q
- CanTxMsg canTxMsg = {0};
- F: [( A7 g+ U N# J9 W - RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg));
9 S- @# E; A, p. i - CAN_Transmit(CAN1, &canTxMsg);
' D! R& V Y. ~' P- o4 ^+ w m - }
, G) L. _ F$ ~0 ~/ r0 g2 k - }5 |: V4 ?0 `9 O& y: e: v, x
- $ c# h( B: \+ _! E/ A8 H6 R: {
- return Number;) L3 I: t2 y5 O( d
- }
# ~3 W: d' _# s, ^ - }* E1 m9 U ?3 ]% h
- ; M) h( O6 e; v, x B
- #ifdef STM32F10X_CL
# _/ L1 m+ o- b - if(CANx == CAN2)" V5 T9 f$ w* G2 d4 p$ G. z k* B: R
- {
+ T% B$ `! _! _$ B# L: u - if(can2InitFlag == true)( c' a- e: g/ E
- {
% M$ ?* w' P) ^' P' L( ?" t- ` - uint32_t available = RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);
# V3 R; ?! {+ H' d, N- N5 b+ `2 ] - ( F! c8 G5 `1 m7 k0 m
- if(available > Number)# \) l7 _; i& j# v$ Y* {2 F. ~
- {
/ L7 e6 f3 ]4 ^* M( q - Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * Number) / sizeof(CanTxMsg);
3 W6 q8 z! S0 ^# E - }- x* Q. i G& a4 C3 m9 C A, P
- else
/ W4 g( m; l% C7 Q" i# Y - {
6 Z& A' ~" i$ |* B: w% D t2 q - Number = RingBuffer_In(can2TxBuffer, Message, sizeof(CanTxMsg) * available) / sizeof(CanTxMsg);
, B. J+ C2 u7 K1 |) ~8 _1 B - }. C' [" W2 g F' W2 @
- - l& w2 m& V' z& @
- if(Number > 0)
4 I; U$ ^) O& W0 f2 h - {6 ?* _4 Y; F( r; c! m: \! ~; s) ~
- if(can2TransmitFlag == false)
- J9 y5 m: Z' K9 G4 W' Q0 r# R - {! V8 ~5 b5 \) ?* T* w6 [
- can2TransmitFlag = true;
+ d; C( _ m, O; R, m - 2 j+ b0 {7 u5 c( k, y* C% Z. E g
- CanTxMsg canTxMsg = {0};
' e5 ^3 D6 S x! |! [. M# x - RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg));
" h! M! e9 H n. S4 h - CAN_Transmit(CAN2, &canTxMsg);
* z6 J8 X5 y: y - }% S9 ~* H. K9 i5 q U% @
- }
2 R4 V9 b& p" X& V% i1 G8 V* L" V1 ]
: [* {. L# g# X. Z$ i+ {- return Number;: h4 j7 W5 M5 O( n" |) {
- }' _* b0 h( {: Q s* v x
- }5 x3 L8 {& M* j- _- w! Z
- #endif /* STM32F10X_CL */
( L4 L; Z! s# h6 G - 4 r7 |" [% L2 ]
- return 0;0 x5 a7 p) R7 O4 [& y1 ?
- }
3 f9 i' S* B# b( R' z
. p' P( f" ^# I- /**
6 U, C5 K9 s, p9 i/ a - * @brief CAN get receive message.
4 p1 d2 ~+ v- l& a$ { - * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.* @/ r$ q/ z# U7 e1 j
- * @param [in] Message: To store the address of the receive message., q2 Q5 f3 l# }- x& C
- * @param [in] Number: To read the number of the received message.7 d) E g! ^9 ?
- * @return The number of message obtained.
% V' U. m+ g* b# f I - */
" Z; H# C; [2 @ X Q% s6 y) | - uint32_t CAN_GetReceiveMessage(CAN_TypeDef *CANx, CanRxMsg *Message, uint32_t Number)
7 c1 h2 l+ [ \& d' T - {
! b% f# K+ d4 _' B: d - if(CANx == CAN1). s# D9 I% G* [" ]6 t" j2 s
- {
7 _1 b6 e. ~' f- z) a& L+ l - if(can1InitFlag == true)
. h0 W% }# X( {5 E, n' ~: b - {8 S8 ]6 @0 X* E( k5 b! ^
- return RingBuffer_Out(can1RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);
( E3 `# Z& C: d( M/ f - }
, t H. |5 X7 k- `8 l+ {: m4 P - }3 e& o1 x' X( |1 v' X' S! _
7 z5 r' ^' V# E- #ifdef STM32F10X_CL
3 o. k4 S5 x* _ - if(CANx == CAN2)
. z" C4 f, m& K( D$ @ - {9 |4 b% \0 ^1 _3 v7 v& P2 I) _
- if(can2InitFlag == true)* U; ?6 P& D/ [( x* i1 M- p
- {/ z$ a* C% L# o0 o4 o
- return RingBuffer_Out(can2RxBuffer, Message, sizeof(CanRxMsg) * Number) / sizeof(CanRxMsg);! k" @5 u' J9 [3 o, r
- }
* G8 ]; n" \* o. I; l5 Q - }
2 O* ~9 r8 r, ~! l6 j0 N( h, {" R; z - #endif /* STM32F10X_CL */
) ^! e) X0 X' D2 k. M9 Y3 x+ X" L - - Y$ \; U% y) }2 \: Y
- return 0;
, w. y8 ]6 L1 s. p# {- I. V* Q1 z - }
% D7 J9 C, h2 L9 M; F
2 K2 o0 e) ~- }7 z [- /**
- M9 |8 L% X7 ^2 ~ - * @brief Get the size of the CAN transmit buffer used.
; v: s8 ]6 h/ j$ Y9 F P - * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral." f0 l d; v" f7 |
- * @return Used the size of the transmit buffer.1 ]5 ?/ q+ r, e) L- J, \
- */$ a8 W* C- \: W) l0 D) Z) ]" l
- uint32_t CAN_GetUsedTransmitBufferSize(CAN_TypeDef *CANx)
* N" J. S7 j& ? - {1 @ o1 o1 g) M& A0 Y+ M
- if(CANx == CAN1)3 K* K C1 ]+ k. n7 Y% C ~! }
- {
+ x0 g, a/ D* N1 v9 r+ E - if(can1InitFlag == true)' o1 `$ b }9 o7 |+ p* n; _
- {% |# j* E8 F& A: W' f
- return RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg);# B* f! s. D n" Z& \1 L
- }4 ]8 y$ j9 w$ j- ~" f% R
- }
7 R; ] B) M2 [! O - ) Z) ^" T2 c3 _* C' z) N8 C I9 v
- #ifdef STM32F10X_CL# H" q/ W$ v$ f; R# K
- if(CANx == CAN2)
0 [% N) O* h# t2 n) a - {
. J1 X) q8 Z6 [# z - if(can2InitFlag == true)
% t% c$ [2 J3 o/ I' W - {
( Q& d7 C3 o; R# q - return RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg);
0 T+ q) C& C: G( p6 Y. ?4 ~ - }
5 F# y$ c+ n* ?$ m% p - }3 j1 O i" Y+ {$ @ C+ u: }! [# f
- #endif /* STM32F10X_CL */
" k3 }' j# C# R9 N4 @
1 O; r& s" g/ M/ x& e1 `2 x( f- return 0;3 F6 i" c# O! n0 h% M+ q
- }2 \8 k( ?5 r4 L& x/ n
- 1 ?7 Y7 d4 b! [
- /**! y9 R, h/ ^. W9 f8 a, p
- * @brief Get the size of the CAN receive buffer used.
$ ^. [8 o6 B# S; l2 a - * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
4 f9 d# z9 ~: ~7 W( o - * @return Used the size of the receive buffer.
7 k. {4 R1 _9 ^& E/ ~7 o' B' r - */
7 n' `' r; K2 }8 P7 c) w3 p( _ - uint32_t CAN_GetUsedReceiveBufferSize(CAN_TypeDef *CANx)% ~. f2 {5 y: P$ r- k
- {
& Z' V' U* U2 S7 `+ Z - if(CANx == CAN1)
. i! A8 `+ _9 `- `" a+ | - {
+ J3 H. M1 O1 r9 U+ o - if(can1InitFlag == true)5 ]' `) t3 C9 g
- {" @) K' }, n3 p* t
- return RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg);
$ }8 }6 E/ H# [- m4 C2 F5 F" F - }
# b, x" Y7 T6 ~8 O4 H8 ] - }. \# L# s) q1 P% c
- . }- I5 e0 {7 R5 G; U' Z
- #ifdef STM32F10X_CL' v( b6 E) U; ^- L% S/ E. p: @' y- v+ F0 d
- if(CANx == CAN2)$ E3 {5 G$ {6 K7 S. G! l0 m% \
- {6 W: [9 H0 ~2 I' o) {1 |
- if(can2InitFlag == true)
" _7 A2 ~2 _6 e7 o - {' ?! j) z1 @9 B$ c& j! }7 C
- return RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg);
* f8 f+ k$ D/ E7 \! ?0 X - }- V5 H1 u/ S' W& |+ y
- }
* i! `4 t! c. \+ A/ V7 N - #endif /* STM32F10X_CL */
" H8 E. ]1 s! S& e9 w; S
2 l: Z* n% d" U0 i5 C8 Z* I1 `* M2 P- return 0;* H) J$ [6 ^6 z- p
- }( @) `) A& a9 S8 U
- 2 u7 w: c! N. F {* [7 v
- /**3 g4 O# [ S- V
- * @brief Get the size of the CAN transmit buffer unused.) {0 m4 E- k. V) P$ E
- * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
y6 y! n# B7 x6 C$ b1 p. Q( I - * @return Unused the size of the transmit buffer.
, Z1 n* U/ v2 U" |6 C: H - */) S% q; L; `5 k p! w6 M0 Y+ q5 a. o
- uint32_t CAN_GetUnusedTransmitBufferSize(CAN_TypeDef *CANx) q8 [7 g6 o3 Z7 q$ h% h" d
- {4 D) D+ O1 Z9 N0 G# F1 ?7 N7 U% X/ m
- if(CANx == CAN1)# h! y7 }3 x( @1 D
- {3 Z4 Z1 H0 I1 k
- if(can1InitFlag == true)+ l8 K' k3 W1 ?- A4 }' ?6 [' r
- {+ A& n: T/ Z; p" b
- return RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg);: V3 m% e0 s/ X! l
- }* ?7 ^! a& Q4 u: P. |, @" R
- }
) @9 h$ b7 ~ j, m6 S - 5 u/ v/ ]7 B' Q7 {# G
- #ifdef STM32F10X_CL
7 t" ?1 h3 n. T {6 |- z* X - if(CANx == CAN2)' ^+ w9 p! U+ i$ |" h( d3 d
- {
3 o8 Q; L) @ q1 J" v) N i3 f. {3 J - if(can2InitFlag == true)# l, V0 P: d0 O3 H- C6 |
- {/ K" i# `& n+ i4 H
- return RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg);
X6 i+ \4 Y) q& J2 n7 P - }& [5 R* G% a$ D! U: Z
- }" Q) g& s" j: f& u2 d) o2 O( S
- #endif /* STM32F10X_CL */7 e0 {% q6 n3 g/ ^* _# K1 C; E3 B
- ! a% U0 ^3 u( A. x$ b" h0 w4 x
- return 0;
* T9 R2 k& M! V3 y$ j! F2 V - }4 D- g+ P( q) `8 P8 Q; D+ Q; ?
- 0 O2 c" J5 E9 s/ h0 L
- /**4 i4 o% i( e- |1 ?7 s! u/ [" Z
- * @brief Get the size of the CAN receive buffer unused.# a! }2 t7 H- K3 u k0 N0 j
- * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.- z, Y- Z) C: ]0 B% G! h. V5 ]( x
- * @return Unused the size of the receive buffer.
8 {* ]$ b+ G/ a6 [, `: H D - */
9 b/ t8 }& p! O5 C+ d8 X+ p* v8 d - uint32_t CAN_GetUnusedReceiveBufferSize(CAN_TypeDef *CANx)
+ S$ u* Q8 N& L$ I0 N v/ D1 I5 U - {
, v# m7 S1 o x$ e - if(CANx == CAN1)
% x, A/ G4 H; C1 t' V6 C+ H - {
$ T2 R! W' W( M8 V6 ^ - if(can1InitFlag == true)
* q1 l, g$ o; n P* T5 ]; V - {
' a* s0 m' n& D- C+ c$ ? - return RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg);' t' }5 a. F9 {- i0 J
- }
* w# E! d/ F% {# L" d0 [ - }
2 i: ^8 k2 i m& [ v9 B
) ]3 ?5 O/ T- Y! B! Q- #ifdef STM32F10X_CL$ s' I H( m! ~+ O
- if(CANx == CAN2)( ~$ I# a! ]4 s+ z. }
- {
g* ]; G4 v6 I: a" N - if(can2InitFlag == true)# _+ ]& R6 j& }" z
- {
& j' J- |( p: O$ u0 t: @/ o: b - return RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg);' j2 @( U/ F) v- L2 \4 e7 L% @
- }9 z& ^5 e$ X" Z9 Y4 O5 y
- }- [ G" S% N3 S4 l1 w! W
- #endif /* STM32F10X_CL */; {$ G) {0 B* h/ N9 {1 z9 M0 {
. f M, s3 a* l- V) k3 S8 H- return 0;! p& a( e# J1 S: E
- }: x6 ?% M% ^* z9 R# e, _! g) K
- 2 c% q/ q1 y; v( k( S9 W& J
- /**
& X3 z) ~9 V0 B$ z9 U9 D' k - * @brief Is the CAN transmit buffer empty?/ D. \4 j4 i1 g5 Z; p/ c" s. O
- * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.% r e1 H6 P, ^0 _/ f
- * @retval true: The transmit buffer is empty.6 ^/ P& R- g+ h) T4 M
- * @retval false: The transmit buffer is not empty.% P% s: K9 W* P# B/ U3 a3 ^" U P
- */$ \& {- J+ n' {/ w$ p1 G
- bool CAN_IsTransmitBufferEmpty(CAN_TypeDef *CANx)
. w* S; Q: b+ y6 Y& u0 [' J; `. Q - {( \1 ^$ \) a( r% R& O" A8 b# t
- if(CANx == CAN1)
, L3 w3 w4 `5 [4 m- S% ~ - {
) X9 j% @8 j, l y. l+ [ - if(can1InitFlag == true)
. k4 z4 o' j. P$ t; @8 } - {4 r" V" b9 I1 V# \" V! a1 H
- return !(RingBuffer_Len(can1TxBuffer) / sizeof(CanTxMsg));
7 v7 _" a" R s) [6 Z0 T* h6 r/ I - }7 x: l. W- k" |2 A* P; D! o+ g/ D& s
- }
! k3 M# N9 r% u" p4 j - : R; X6 \! ~6 H$ k! v
- #ifdef STM32F10X_CL* q, [: P H0 `+ _# H8 G
- if(CANx == CAN2)
% j8 _9 D# Y# R" V2 U/ Q$ i - {( a. L$ p6 c3 x+ R& a6 j9 `9 c7 m! r
- if(can2InitFlag == true)
% h! c9 A& L" J: c n - {
% o0 T; [; U9 k2 V - return !(RingBuffer_Len(can2TxBuffer) / sizeof(CanTxMsg));
& h0 H0 |4 F% J! H- L - }1 V: N* E1 l) t) i
- }
( V3 @2 ^8 J# x M; [/ I - #endif /* STM32F10X_CL */
8 y0 d1 B$ I7 b% w5 ~7 t+ j
, G# n6 V7 O* b3 b- return false;0 _% G1 g% o" I- B% G
- }
7 h2 b k! E, S3 I( f: i - * B1 Z! D3 R$ |9 F: _ K
- /**& T$ i( h+ {+ Z+ z
- * @brief Is the CAN receive buffer empty?
; Q2 d/ ~" {4 |0 p8 A - * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.3 r0 Y5 z- s8 @8 j/ Y1 D }. Y3 U
- * @retval true: The receive buffer is empty.0 M% C% S0 M* ^0 [% [
- * @retval false: The receive buffer is not empty.
( W1 K, @; K" I7 y. E5 b - */
* ~) v- N% u5 N; U - bool CAN_IsReceiveBufferEmpty(CAN_TypeDef *CANx), e2 g# m/ Y' ?2 k
- {1 Q1 M$ w$ r+ R! Y4 \% F; T2 l5 K
- if(CANx == CAN1)
( Y# m6 Y" O3 l% ~* s - {
8 i" q7 u0 r$ [5 a6 y& w - if(can1InitFlag == true)
3 D4 i" A9 _0 e' y+ W7 d - {! G" w+ q: i8 Z$ c
- return !(RingBuffer_Len(can1RxBuffer) / sizeof(CanRxMsg));
8 l2 ^9 u: u, K$ q - }1 g" J& F! n* I( t5 {0 O8 h1 C3 U$ N
- }$ @8 X1 u5 A- u9 v
- ' k3 T$ G, [1 Q# {, E
- #ifdef STM32F10X_CL
# x- J& V. I" z. T0 C. z. u Y- c9 U0 N - if(CANx == CAN2)3 q1 G" Y3 W ^ I2 `
- {
2 Y! @# ^7 u8 T3 D+ d - if(can2InitFlag == true) }& ]% X h, M/ @) e; x2 L
- {2 J" [3 A/ @' F$ j5 e% y8 t" n
- return !(RingBuffer_Len(can2RxBuffer) / sizeof(CanRxMsg));
& s: W' B, q' L, Z' x1 i - }
. L z+ o1 }$ C0 ?7 V+ q' L - }
2 Q7 U8 H5 X7 p6 O, ? - #endif /* STM32F10X_CL */
& u8 k' Z) ~+ R - * p+ a. o# b' Y d) @' A- d5 {
- return false;
/ {6 u* c1 R& R7 l9 d$ g - }* S {% r. C$ F
. J4 ^$ ?1 t; D- @- /*** {) f6 @, z% `1 e% Z5 m* b
- * @brief Is the CAN transmit buffer full?
/ d, Q$ b3 H+ }4 i- |9 { - * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
! E4 j5 \+ ^) n+ g m6 {1 ]5 [ - * @retval true: The transmit buffer is full.
2 R4 d! G' D/ X9 _9 F. \! v - * @retval false: The transmit buffer is not full.
7 F/ J" ?+ i1 d* {! V0 l, Q- ?/ r - */
+ ?1 ~* ~/ m$ M. h3 ~7 f - bool CAN_IsTransmitBufferFull(CAN_TypeDef *CANx)
& y( X1 z4 v, [ - {1 ~1 V1 n$ b' Q, _- X- C
- if(CANx == CAN1)
3 S1 c/ t0 O8 }% t% F7 p - {
5 [! c8 y/ R4 x( z' g8 C - if(can1InitFlag == true)$ d! c7 z) `, m- E% x- W
- {
# l9 A2 {& K5 L# E/ o - return !(RingBuffer_Avail(can1TxBuffer) / sizeof(CanTxMsg));
z4 R. Z/ K3 c9 y - }1 R/ l6 n% q! ^9 L( u8 I4 ]
- }
+ L) C J7 R) h - 6 f4 |( c: h. {! W$ P+ g1 @0 o
- #ifdef STM32F10X_CL
; P# G# S- M5 ?) s, ^# n. \7 l - if(CANx == CAN2)# K, I) z% G- w& M5 T- P
- {# N# Z( J; `/ c7 d! `4 V$ H
- if(can2InitFlag == true)
: Y* I8 F0 N, n% H& @ - {2 n- z9 t: D5 D4 O
- return !(RingBuffer_Avail(can2TxBuffer) / sizeof(CanTxMsg));
I6 W& X2 w/ S# I- B6 I - }
, } f4 w3 U: ^: C - }
2 b+ \0 p0 g5 x2 v2 \* M - #endif /* STM32F10X_CL */
- ~' C( r( [/ U) n - ' `# s M6 ^- h; L
- return false;
2 o& D9 F h( O$ o& u - }
! }' v( C8 n0 y" E# r
+ r Q4 W X) B/ i2 e- /** S# n. Z- S: a9 ]! T
- * @brief Is the CAN receive buffer full?
0 r1 `; O9 z+ V; A5 H# @0 c - * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.4 n6 w6 A! ]9 [: A
- * @retval true: The receive buffer is full. @( N& A. r3 R3 ^
- * @retval false: The receive buffer is not full.0 ~8 t0 y1 H- I2 _: r
- */
2 Z6 p+ b p" w% {* F. D, y - bool CAN_IsReceiveBufferFull(CAN_TypeDef *CANx)
1 y9 d6 j! _7 W9 J; T1 ^ - {
, w$ z& d6 J, e' T$ t1 X - if(CANx == CAN1)# o3 d! s: V+ f% O: O1 C
- {
6 K9 |6 w9 A. q9 J - if(can1InitFlag == true). f, {3 T" Q+ o2 Y4 U
- { T& V- i* m- N6 K+ v( n
- return !(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg));
. {3 B, j. q; s! t: v6 [' E- P/ T - }
" D6 ~2 O5 [+ k! x - }' c' `* @. L8 L9 ^) r
- ( J4 N. y. ]! p5 w! u2 f: `- ?7 g
- #ifdef STM32F10X_CL
3 Z1 I# k7 F; J7 M( J - if(CANx == CAN2)
" [1 U0 \' \* j3 Y/ F% \ - {6 ^, d2 F% \ A; Q. m$ n$ o9 H
- if(can2InitFlag == true)
3 s- k" \! h( r4 R- Y0 M - {
5 D1 z) q2 s- Y( H; g3 ^& J' M4 b8 k - return !(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg));. A0 w( O" q3 Z+ u- V
- }
1 z: x/ c5 F6 s - }- x9 W# H1 ~) A$ N7 O
- #endif /* STM32F10X_CL */
! N o5 n4 R4 j; v" N5 R q- w - * h8 X( {. b3 d* u8 m- Y6 w
- return false;
1 o8 |, _" _5 _2 F% F# U - }
7 ~6 m0 n, {' {# c - % _/ B8 y+ x$ D9 n/ O( n
- /**, T, _+ [" W2 v$ y8 P& @
- * @brief Clear the CAN transmit buffer.7 u! J* {/ D/ D1 @" d* r' _/ R# T
- * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.
- K' x; |. S# A9 K6 h - * @return None., D! A# x9 [1 [2 q; Q' i
- */
) ~- D7 Y, m1 ~" w, L - void CAN_ClearTransmitBuffer(CAN_TypeDef *CANx)
5 A3 ?, }, A$ q3 d, N, m0 A - {4 [! _( L1 d' h! ^0 c
- if(CANx == CAN1) a8 d) s$ T+ G' Q u
- {3 P- ] R" C; X4 h
- if(can1InitFlag == true)) s) h1 g7 _) W+ \1 F* s
- {
7 X$ f' X1 C4 }1 q( Y. q& r - RingBuffer_Reset(can1TxBuffer);
1 R( c% j4 j# A - }. k9 r$ h0 e) d& G
- }4 ^) F. k) H$ P4 m7 b& p7 W% x
4 S9 n; y+ d* m% @4 x. _- #ifdef STM32F10X_CL4 W$ O/ |& R$ G+ K9 J# A3 R( t
- if(CANx == CAN2)
$ ]8 f& E J! Y8 v @) h+ F# i4 P - {
! V3 C( n* Y! u. c - if(can2InitFlag == true)4 x6 V, b1 W* L) r' N
- {
4 s) q+ l7 m% V; ?" C! x - RingBuffer_Reset(can2TxBuffer);
8 Y" a# W3 V5 l. q7 {3 `* c" E3 @! w% A - }
l T* O! v. ? - }
# |+ U; U/ k { - #endif /* STM32F10X_CL */% q' l6 S. W K$ W D& O5 x
- }/ b7 r8 M$ |6 E* P
( f f- Z% G$ \* V U- /**
8 B9 @5 y, M) P9 v' v* M - * @brief Clear the CAN receive buffer./ x' K7 T) E7 K: ?, x8 ^) d
- * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.+ t: k6 k0 ]6 W/ n" g
- * @return None.$ p) W, ?/ [4 K9 x/ i
- */
2 }- S7 w7 q7 S - void CAN_ClearReceiveBuffer(CAN_TypeDef *CANx)- Y- \5 a) u4 ?- `
- {
. v; U! j( y4 B; M - if(CANx == CAN1)
- E/ m1 ?6 M) w6 h$ J - {
+ q- }) z3 f5 e& d7 l4 U9 l - if(can1InitFlag == true)
r) X4 h; T) k- t - {$ x9 C- s" C* }
- RingBuffer_Reset(can1RxBuffer);4 ^! f4 ?& l. o6 Z5 t. ~ H8 k0 [
- }: F) G" \0 w0 x7 T& U6 ?4 S# b
- }
7 z5 S) U$ t9 z+ R8 O) K - 3 X. V7 u1 O# u
- #ifdef STM32F10X_CL
. L+ y( S; G5 a$ z1 A- R; T- N - if(CANx == CAN2)
$ D! Y+ _/ F" R) d; R - {
+ X9 A8 ]8 K2 i+ K1 H - if(can2InitFlag == true)
/ i* K0 [$ g) s - {4 f4 u. r$ u- b1 q, [5 P
- RingBuffer_Reset(can2RxBuffer);
. k. t8 F7 e2 W% Z - }
$ l! P+ ]+ H& N* L( E! a - }. m5 S7 u1 ^! j6 ^( h( ^- B
- #endif /* STM32F10X_CL */( ^2 ] J \) x
- }
0 y6 D/ |4 s+ a; \ V
& K3 |( K" l e9 d/ i, ]- /**7 }3 x* J& ?) w( g
- * @brief Is the CAN transmit a message?
) B9 n7 e, c8 l8 c! S5 J( ~4 u1 Y - * @param [in] CANx: Where x can be 1 or 2 to select the CAN peripheral.6 j% \- M# v" s* U1 n# v. t2 [
- * @retval true: Is transmit a message.
! A3 f; e! u0 @- ] - * @retval false: Not transmit a message.
/ W a2 B; C: o) Q1 N+ d - */" K- S3 Z/ [, l0 {/ u, b
- bool CAN_IsTransmitMessage(CAN_TypeDef *CANx)' G6 V& a: P6 u# J( i
- {
- a2 ^3 R' n3 H4 a- ~) L+ Q - if(CANx == CAN1)2 u5 j' u+ S5 b- C
- {
$ |: o( n7 t4 A1 E6 @ - if(can1InitFlag == true)9 @ r! J4 y/ m% b3 y
- {
- I: t( a/ a6 i6 ]# F+ o. z& ]1 H. V6 x - return can1TransmitFlag;
6 C) w2 E l/ l3 ?4 \' t - }: S7 P1 M! q. x6 k1 J: N
- }
7 }+ r; M L# ]# i* m4 n1 |& _ - b, h5 J9 Q! c: h
- #ifdef STM32F10X_CL+ W( t q1 _% d) q
- if(CANx == CAN2)% Y: j1 ?$ j9 P/ b# f; T! b- Y: X
- {
- `+ \+ w1 X8 E, ~0 j - if(can2InitFlag == true)! G: k: N0 Y* V. R) H: u
- {
* H& t6 B9 y2 L( d% {- K - return can2TransmitFlag;
+ ?' o/ y& |3 t7 g/ L4 e; A; Q - }
: w7 j f* l/ ]' t, Q" n3 L6 F' \ - }
' O7 q: ?. b9 }8 y- Y6 K) a - #endif /* STM32F10X_CL */+ i( C0 I6 i$ a3 f
* v p6 I# F& t; c8 S- return false;
0 F0 P) |6 }' ^$ _, x - }1 i( S6 ~" |) Z: l
1 k& n# H) _3 X. R/ [( i- /**
- n& m# {! B) R) g1 B - * @brief This function handles CAN1 TX Handler." ]5 R' ?" e7 M, f/ S+ W
- * @param None.
' E5 E, ^& _ |0 e0 j - * @return None.
$ X. y1 R, x$ `" d3 |% J: c ~ O4 | - */
$ b; n3 f, i4 G) v4 ` y - #ifdef STM32F10X_CL9 j# X. w4 X+ @
- void CAN1_TX_IRQHandler(void)
) W) V; m9 `8 a) e' H5 C3 C! r - #else6 C+ t% Q; ]. B. N9 ^! y
- void USB_HP_CAN1_TX_IRQHandler(void)( v9 G! N( ~! J
- #endif /* STM32F10X_CL */; Z" ^/ j, n' |# ~7 d# z
- {
" T. c# H- U2 V% g - if(CAN_GetITStatus(CAN1, CAN_IT_TME) != RESET)( v' x- N1 w6 Q7 R) L" S; d0 z
- {
4 x8 _/ b, \* j! Y8 M5 V* w - CAN_ClearITPendingBit(CAN1, CAN_IT_TME);
- t7 _4 W' H$ c2 \( n - ; K" b& f+ J% Y' F$ W
- CanTxMsg canTxMsg = {0};& U' h7 Z( O# O$ E; a* j8 y
- uint8_t number = RingBuffer_Out(can1TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);6 x& n( w" Y+ z! Q# F9 m; {. u
! D8 d( S1 m* k" Z- if(number > 0)) X7 \( H; {) [* \* ?# _" H
- {
6 f7 x& ?+ d* h, r4 C5 g% i - CAN_Transmit(CAN1, &canTxMsg);
& N! l0 K: H; B% Z) N n5 { - }- ^/ s3 g }* n# C8 }
- else" N# P! ~1 O* r1 f6 [
- {$ U! G {2 G) `- v! S0 Q) }" }
- can1TransmitFlag = false;& n a# v' \ c W0 v" w1 J
- 0 m, P5 i! Y. e1 a+ r- ~
- if(can1TransmitFinishCallback != 0)6 [; M& {, J, s/ d0 P+ H1 l
- {( e% V/ Z. _* B) \1 y
- can1TransmitFinishCallback();) y! ~" T f2 q2 m! k5 C$ |
- }5 ~' m( Y! g0 ~- Y2 T1 }" v' p: i
- }
# Q) k8 F! \$ ?1 n8 Z$ I# c - }( @+ `1 T. _1 q- z5 Q1 e! b; N
- }$ x) w. J! z4 ]( l/ h+ T$ m2 x( ?& @ H
- / b, k, ]& }) `
- /** F# z9 O9 g! i* z
- * @brief This function handles CAN1 RX0 Handler.4 G7 p0 t- v1 H& F
- * @param None.
9 r( q" {0 Q% R# E# m0 t - * @return None.6 n' I( W3 q- X4 _0 S6 t/ \( r
- *// i f& Y1 |* t# k- x. b$ d$ J8 A
- #ifdef STM32F10X_CL/ p2 L; ~; x4 ]+ s! R' L8 S4 L' ^
- void CAN1_RX0_IRQHandler(void)2 X; J9 j; \4 v; w. Y
- #else
a; i- _5 T% D- w. F& R- }8 V - void USB_LP_CAN1_RX0_IRQHandler(void): v# i) F( P7 U3 b+ h3 E1 ?
- #endif /* STM32F10X_CL */
7 _0 w: m# s/ D, G3 |" c# L1 u - {
: O8 x& O2 H8 y - if(CAN_GetITStatus(CAN1, CAN_IT_FMP0) != RESET)7 Q# B$ { C8 E8 d& g
- {2 N, ^3 |) W' `4 ^: X1 U' F
- CAN_ClearITPendingBit(CAN1, CAN_IT_FMP0);' o4 [0 V: M) e# j/ k. z% Q% n0 y
5 ?9 S+ U) {* p' @% G4 T- CanRxMsg canRxMsg = {0};
6 ~4 E6 c0 \/ Q3 x! d0 ^7 p7 L - CAN_Receive(CAN1, CAN_FIFO0, &canRxMsg);
4 I& m3 l0 ], q
+ O/ n2 |6 H5 u- if(RingBuffer_Avail(can1RxBuffer) / sizeof(CanRxMsg) > 0)
$ ~+ e4 l( v; w7 @4 e% | - {
' {" A) B& T) u5 P2 W - RingBuffer_In(can1RxBuffer, &canRxMsg, sizeof(canRxMsg));% [- {$ Q$ z; W8 S0 u& Z
- }
2 J3 ~$ [9 Q0 m; l: g1 o
+ Q& v x9 T; k& `( z. v. h- if(can1ReceiveFinishCallback != 0)
# Y9 o- C' \ ?. V - {
/ W t. z9 x* N: J* o. R. z8 z - can1ReceiveFinishCallback();
* e; n9 X% z. h - }" [/ t/ s9 }/ ~5 z4 f
- }
. m4 q9 b! Y5 s0 I5 C( n - }9 |- `1 J }# @" Z. o% w0 P, l
- C8 L i, D2 [8 L
- #ifdef STM32F10X_CL/ w- c, o+ J- @3 m' `4 R
- /**
/ V: Q: Z1 f/ U& \7 ^; y' z - * @brief This function handles CAN2 TX Handler.. j, V# k3 p2 [+ h6 H
- * @param None.
) p$ Y9 x1 g3 c5 B3 m7 H) O - * @return None.
$ k3 Y) t' Z7 A) v; o; p - */4 r2 A! n7 t5 c9 K' c0 L
- void CAN2_TX_IRQHandler(void)
, J6 A# `1 \% Y& t7 A - {
7 I0 a- O9 _+ V" B/ Z3 G4 B' D6 o4 A - if(CAN_GetITStatus(CAN2, CAN_IT_TME) != RESET)2 f) {( L% g% l* d3 D% y* J2 ^
- {
- A3 `! b# t3 v( f$ f' O& W& ] - CAN_ClearITPendingBit(CAN2, CAN_IT_TME);
) o; F" V% r: n0 r" w; _# z) M$ _% X - 3 S* K4 _+ Z/ Y6 I( ^: m
- CanTxMsg canTxMsg = {0};1 S' B+ W, k9 O$ n9 B `7 E; Z
- uint8_t number = RingBuffer_Out(can2TxBuffer, &canTxMsg, sizeof(canTxMsg)) / sizeof(canTxMsg);
1 Q# Z8 K+ S5 h% w - 4 B' W& U+ b( `) W; ^- D
- if(number > 0)
4 l: p, j* o8 } - {$ K& d U: j7 E& }* _ Z8 |3 i
- CAN_Transmit(CAN2, &canTxMsg);4 M8 K6 K& F$ j) ~" d. P" }
- }
/ ?0 }& Y1 k5 e - else
% L% o) c$ e' i - {
# D) {. L8 l1 R1 {# u - can2TransmitFlag = false;
- Z8 S& H5 h% S7 F/ u - 8 K3 j6 u) z; m: S- `5 E
- if(can2TransmitFinishCallback != 0)' d* k; G, T: t
- {
4 ^0 c: T- p4 _' N - can2TransmitFinishCallback();
6 n, R6 j; x' y - }
- P' G( x Q7 U X2 ?; e" k2 N$ V - }' ]3 D8 v) T4 e) T1 [
- }; I4 |# O1 Z' `& w9 J( O
- }7 \2 n7 c- e$ D; U {
% I. J) ~& ` l) U A X$ T. V t- /**8 v4 }0 p4 g% l: X5 m
- * @brief This function handles CAN2 RX0 Handler.
~- d. u( p5 F - * @param None.& _% G# e% ` K+ x6 n8 L3 b+ V
- * @return None.9 x. \, D- R: L/ ~
- */
. \7 G1 s" p/ l9 e5 A - void CAN2_RX0_IRQHandler(void)
1 n: P7 J5 {/ O% \: I - {
) x" l [( P. u - if(CAN_GetITStatus(CAN2, CAN_IT_FMP0) != RESET)1 ]. |6 A3 J! ^1 A; w
- {
4 u: Z% b* q. q! n8 R& r - CAN_ClearITPendingBit(CAN2, CAN_IT_FMP0);# q' y8 l7 D2 f, k8 e
4 K( @$ Y& {* o$ A, T8 `- CanRxMsg canRxMsg = {0};9 V- A2 d+ I$ `. t2 u0 P1 V' b
- CAN_Receive(CAN2, CAN_FIFO0, &canRxMsg);
2 ?- E- T/ {0 }; F% A) t$ k
) f; `7 y( B5 s! h- G- if(RingBuffer_Avail(can2RxBuffer) / sizeof(CanRxMsg) > 0)* q" [2 P: a6 W0 F* p7 V
- {2 ?' f0 o( M8 O) g5 M. ^+ r
- RingBuffer_In(can2RxBuffer, &canRxMsg, sizeof(canRxMsg));2 E' l, X( Q% g& J7 k8 ~! j4 x, i
- }
0 D" O+ ?7 |: D6 l5 C* g4 z
- Y7 b# h+ P2 t0 m5 X( r- if(can2ReceiveFinishCallback != 0)
7 l6 Z8 |7 {4 a - {
* e- E0 v+ s+ j9 K& o+ _9 F( v - can2ReceiveFinishCallback();$ Y S" |# i& K, G$ E" Z7 R
- }
7 s+ J0 ]8 D7 g# K$ v - }
* B, {) s6 n* q9 m - }
" P+ ?+ q7 t( r. u1 P6 m - #endif /* STM32F10X_CL */: J) x# t" `% `( H
复制代码 ( h: _* g7 E. M3 g" Q# q( Z! y
# W9 F8 z4 y7 {4 O lmain.h 文件& X. V5 H3 @* W. Q
- /**
: O E. c2 g8 l9 z6 K5 D - ******************************************************************************1 \* Q. Q$ u R3 x
- * @file main.h
6 D0 `2 Y4 ^6 p' C1 @% ~% H - * @author XinLi
; _: ^) t, L$ G% i1 G7 [ - * @version v1.0) a# h7 X: o# ~( S# M5 v
- * @date 24-June-2018
. e( F) U; q" T0 ? - * @brief Header file for main.c module.
4 |- d3 z8 B8 p; a h- P - ******************************************************************************. P, M7 T8 o" j5 a. \
- * @attention/ Y5 D/ N( s3 u8 i( F+ C3 [9 A9 W
- *
4 G* L2 j2 S. i; U - * <h2><center>Copyright © 2018 XinLi</center></h2>
9 ?6 w3 x: e/ F0 b4 U. i) ] - *7 B. c* b @- m1 e, ~
- * This program is free software: you can redistribute it and/or modify, Y/ B/ o. J4 G6 r9 e1 {+ ~- {# v
- * it under the terms of the GNU General Public License as published by
1 Q- M' v( a7 F/ E0 ~1 M" { M - * the Free Software Foundation, either version 3 of the License, or
5 y- W+ e9 y, r/ Z" D: t' I - * (at your option) any later version.
; H! G- y0 `8 X6 |! o# q& i - *" [1 t9 K0 f6 J
- * This program is distributed in the hope that it will be useful,
n: ], r& V1 }2 l) H/ F ~' q - * but WITHOUT ANY WARRANTY; without even the implied warranty of# `7 W. r: m- h) B1 T1 y" r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the z% n6 ?2 ~/ G2 V( i, k8 j+ I) p
- * GNU General Public License for more details.
; t2 v7 P$ x4 l - *
# S/ V5 O0 ?8 K - * You should have received a copy of the GNU General Public License0 `; h: j! y7 \8 `# P6 M
- * along with this program. If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>* M4 k7 q. d. a( ^" `4 ?1 ` g- W5 D
- *
% D5 ^; U) P0 Q - ******************************************************************************
7 [2 \' Q6 q. A! O. f - */+ }5 V; q4 |; C6 d2 D" j
" `' V4 W7 _ \- #ifndef __MAIN_H
) j9 f/ v$ J+ v( h3 s$ A6 ^% @ - #define __MAIN_H
' B2 d+ ^( [* z8 M
2 i! l9 ~0 r' E0 x- #ifdef __cplusplus
1 G7 D: x+ @, z8 l+ h$ V7 N - extern "C" {
+ h2 i! O/ G: H" ~ - #endif
$ Z: P. L" C/ W& ?/ k e9 [, z
s l; F. ^" I/ X* Q- /* Header includes -----------------------------------------------------------*/
9 F# [! U: O6 }/ K. P' @8 u% @ - #include "stm32f10x.h"; H% S; a; g* j
& k' m6 X" H6 ] ~$ I4 r- /* Macro definitions ---------------------------------------------------------*/) ]3 x2 ] w: i+ }. H; m& V) f
- /* Type definitions ----------------------------------------------------------*/2 F; T- @. @9 X( g" N/ U! O Y! ~
- /* Variable declarations -----------------------------------------------------*/' |; s$ H! o; P1 _
- /* Variable definitions ------------------------------------------------------*/
/ j% f6 R$ f R! I" O1 U: E6 X - /* Function declarations -----------------------------------------------------*// Q6 r% l* A W
- /* Function definitions ------------------------------------------------------*/( G% q& h) B% p1 m+ N
- + \! K, A; B' K* D- O2 i1 f
- #ifdef __cplusplus
( }* T* W5 l$ \, K: [& S; d - }
5 Y7 ?8 D1 ] T. Z9 p- g# u - #endif5 [; K# U( F/ K7 N6 ?! V5 O
- $ J* ^' X% V4 Z9 `; }" @* j
- #endif /* __MAIN_H */
复制代码 4 e7 \: J1 d. W- H8 b
* z; r1 Y+ f i. H! |main.c 文件
D" p+ \; D( I" d# [& v: c- /**
5 l6 \1 I3 M+ N: i# g w- R - ******************************************************************************+ ^4 s Q* E% g% d0 K) ^/ s! ~
- * @file main.c
- u3 i3 g1 W7 E1 k' _' R - * @author XinLi# p1 I4 c" T2 k& P. H
- * @version v1.0
6 L# _% b1 Z+ U I# q* Y - * @date 24-June-2018
* f% M+ v& G `2 W6 J/ A. q - * @brief Main program body.% {! `) c1 Y/ I! u$ e0 @. V
- ******************************************************************************
( O2 U/ Q" l# \3 |; f - * @attention. }0 i' H$ Y' J# A. d; l
- *
9 R; Y* H; N2 r; z+ n! J - * <h2><center>Copyright © 2018 XinLi</center></h2>
. @, |9 e" U! U& A+ n8 t - *( S( L' \: y7 ^, X! \. K% z
- * This program is free software: you can redistribute it and/or modify
! s5 s/ f) ^8 c - * it under the terms of the GNU General Public License as published by
# w+ D4 T) F+ U5 z# }0 e - * the Free Software Foundation, either version 3 of the License, or% ~ W. x5 m1 X- R7 t' M3 R
- * (at your option) any later version.
- {) U! c1 N' V' j5 y( |! [3 { - */ B& Y0 I# a$ P+ v
- * This program is distributed in the hope that it will be useful,8 @2 s) A8 q+ I: s2 [9 }5 T* ~
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
S. o% M' E8 o$ w. |0 O& k - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the& B& W5 V5 e& u9 N7 Z! W: |
- * GNU General Public License for more details.
, L4 ?; F, T- v* q) J - *
& S& z4 b; S$ U* t' u - * You should have received a copy of the GNU General Public License) a4 B+ s/ g H1 `
- * along with this program. If not, see <<a href="https://www.gnu.org/licenses/>." target="_blank">https://www.gnu.org/licenses/>.</a>
5 ]5 i9 H8 x4 J) f, k# A$ a: {' N - *
% B* b# X% ?7 P0 c% K - ******************************************************************************
: J6 b) E6 Q6 c7 Y$ q - */. a2 M& }, v) j' ^9 ~' F
- ; N6 u& q' b& s X5 _9 r
- /* Header includes -----------------------------------------------------------*/8 Q+ Z0 E1 {, t$ M7 B5 h
- #include "main.h"
# x4 U2 o! l( j8 Q( \! m# | - #include "CAN.h"
8 p' K! F1 T1 a; ^ - 1 f3 T; ]. L' W0 V* [) i% I. u& T
- #ifdef _RTE_4 Q. Q: F) v; R; K) {
- #include "RTE_Components.h"
* ?0 W% ]: d/ |! G* N' } - #endif
: w! Z. c' B* F0 E/ h. j! V
: ?0 t* V2 s3 x/ g4 r& S- #ifdef RTE_CMSIS_RTOS2
* c# @' H5 f: d) k! t - #include "cmsis_os2.h"1 h) ]: j l. K+ e) w$ j: |
- #endif
- @% S0 I0 D: {( c - # N1 s% [" `8 C5 g: A% {% j `
- /* Macro definitions ---------------------------------------------------------*/
5 F! O! S! l; ?; N' Z- S e - /* Type definitions ----------------------------------------------------------*/, Q* Q9 v8 e7 G6 {
- /* Variable declarations -----------------------------------------------------*/
1 k# s, [ T1 n: o - /* Variable definitions ------------------------------------------------------*/
. g% K! L; I" L3 E - static CanTxMsg canTxMsg = {0}; r- `/ Q }% b% u1 D2 z
- static CanRxMsg canRxMsg = {0};
$ c5 Y. H1 u2 P6 k7 T
, y, J5 M b' m% ?3 r- /* Function declarations -----------------------------------------------------*/$ `& A7 e' h" ], C5 s S0 X* y
- static void SystemClock_Config(void);+ f- C# t- P( C
- $ H% V0 `& }% M. z ]' }& Y2 t6 L
- /* Function definitions ------------------------------------------------------*/
4 [; B* L; U" H3 `& J
# m8 g% D; J( r! z! g, w- /**
2 j) c& \) @: Y; h( W - * @brief Main program.% C1 }( M- z& O, N C& A
- * @param None.. H0 c' s3 `, r9 r! \
- * @return None.2 y$ m4 V* u7 u& t+ [
- */; z$ k' ~# D" I1 e
- int main(void)
1 t* J8 }0 z2 c: k5 q - {( p3 ?6 E# D2 i& A* y
- /* Configure the system clock to 72 MHz */
8 T+ U R' K1 f& e - SystemClock_Config();
" }6 W: [" B: k - SystemCoreClockUpdate();
0 ~% W F5 s) S4 P9 ] - 9 |* } f: \* m5 L# g+ `
- /* Add your application code here */8 [( y# f( a' V# r$ x5 q# S" b
- CAN_Configure(CAN1, CAN_WorkModeLoopBack, CAN_BaudRate250K, 0xAA55, 0x55AA);
4 T! {! Z7 V* |9 h8 q - ( A* s5 q& H9 D, F7 p5 e& s, I* c
- #ifdef RTE_CMSIS_RTOS2
+ |7 e6 S2 G/ J- V+ q - /* Initialize CMSIS-RTOS2 */* M2 r3 n4 H2 b/ @: j$ `! a
- osKernelInitialize();+ U1 p& c7 f8 f" `0 R8 c( d
- + c0 e, d# }% r/ _! `
- /* Create thread functions that start executing,
1 j' b: E3 Q: L; m. z4 P - Example: osThreadNew(app_main, NULL, NULL); */5 I3 H0 c0 w" d
, ^ G7 L* R$ s" H- /* Start thread execution */0 D2 u3 F6 S L: | l$ I6 I# Z
- osKernelStart();
3 {1 N- W) u0 F( W" r E& n+ j2 v - #endif
, a$ G/ ~4 i% f: k. M+ O( K" ? - ( x/ A- j7 m0 X3 j. E
- /* Infinite loop */8 F: y5 Q3 x- j
- while(1). D+ b3 U3 d& Q& C+ Y8 D7 j
- {6 D7 {- d' Q. Z g$ P* O
- canTxMsg.StdId = 0xAA55;/ n" `! T! B) X$ d1 [9 w9 r% o- M
- canTxMsg.ExtId = 0x55AA; ` a d3 d: O4 r, K2 s2 b6 Z
- canTxMsg.IDE = CAN_ID_STD;
5 T0 c: n4 I+ ?% C/ q - canTxMsg.RTR = CAN_RTR_DATA;
) l- H. s8 l; ]% K/ b - canTxMsg.DLC = 8;+ ^0 j& [+ B+ j+ ~
- % \. \4 g' d. J. t/ N
- canTxMsg.Data[0]++;# h0 n( H( T6 ?% u2 q1 V9 ~# i
- canTxMsg.Data[1]++;( R) [+ m ], k8 @0 h2 N
- canTxMsg.Data[2]++;
- F( ?& b1 T0 n- x: B - canTxMsg.Data[3]++;3 S% o/ G. S) z$ ?
- canTxMsg.Data[4]++;0 Z, |/ x, m" q3 m* N
- canTxMsg.Data[5]++;
. P+ [0 Q2 q$ a2 B- |% L0 c - canTxMsg.Data[6]++;
1 b w/ H3 c. ^! x& c. } - canTxMsg.Data[7]++;; c4 j' I9 f# N, M) \
- % r# j, ^& _8 \8 r3 j. @
- CAN_SetTransmitMessage(CAN1, &canTxMsg, 1);
- \5 w' b A# q9 Z9 R0 K - 4 x% }4 Y g) a' C
- while(CAN_IsReceiveBufferEmpty(CAN1) == true);
, p P7 L: O- X# |( F - : `. U. Z' i% e% Y8 H% q
- CAN_GetReceiveMessage(CAN1, &canRxMsg, 1);4 a; @' u/ k1 Z" Q; @# Y
- }+ d# f1 w9 {1 Z$ W! n
- }- Y) d( \: {) L/ f; X
- ; v: E; a+ j) ~# w- {3 S, d% @0 b
- /**+ \1 [! K/ D) i
- * @brief System Clock Configuration.3 M. P8 Z2 Y: z
- * The system Clock is configured as follow : 2 c3 z7 o6 B# s7 j
- * System Clock source = PLL (HSE)
- Q% q8 i% Y* |. V, X - * SYSCLK(Hz) = 72000000
; w; t& A# l/ Y3 ~ - * HCLK(Hz) = 72000000
5 i* k/ y0 f1 ?6 y$ e5 \1 k$ } - * AHB Prescaler = 1$ O4 |5 k! E5 F9 c0 j
- * APB1 Prescaler = 2. h \ P- F- L3 N# f! q7 O6 x8 }
- * APB2 Prescaler = 1
{7 G# J: _2 Q7 a - * HSE Frequency(Hz) = 8000000
6 ~/ ?% [4 R# _& f# F" i - * HSE PREDIV1 = 1
# w- R4 T ]. {2 ?6 l - * PLLMUL = 95 M2 w6 i' ?+ E- S8 s
- * Flash Latency(WS) = 2
/ ^- V- x: V" Y! t: b - * @param None.
) W' ~+ A# C# k" I! }4 i3 ^ - * @return None.4 ]% |& F0 R4 M) j, f2 W0 Q% t
- */
+ J+ P( ?% Q- ]. S7 x5 u7 a1 x - static void SystemClock_Config(void)
, o6 x/ w- [. J( w - {. w+ p4 q/ \% e! Q
- /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration */4 |$ I t( I3 a
- /* RCC system reset */
. S4 [$ }# N1 b ]8 V - RCC_DeInit();
# j# X$ H8 M1 S7 b4 B0 o, a
+ C5 J; V+ L! N: m( D+ p4 \4 d( x- /* Enable HSE */
9 `* F' d" [" o% v2 M+ i% n: H - RCC_HSEConfig(RCC_HSE_ON);3 \' X) ~. J0 r& ^9 p
$ e8 X* b+ m0 ]8 C- /* Wait till HSE is ready */! c4 T% U. T/ M e
- ErrorStatus HSEStartUpStatus = RCC_WaitForHSEStartUp();/ f/ [# D! t! W0 r& s
- # F4 ?7 M7 N. q: Y) Q
- if(HSEStartUpStatus == SUCCESS)
% q2 b+ U% `; ^5 z - {' Y' x, }, ]; {4 ]7 q: L
- /* Enable Prefetch Buffer */
! S4 y- Z/ M: i* S' C - FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
% a% @5 f" j z+ D2 X2 W! ~; m - ; B1 d8 J" R1 E1 f; s
- /* Flash 2 wait state */4 Z) ~, a1 q0 s4 n* u0 d
- FLASH_SetLatency(FLASH_Latency_2);# B ]; n- c/ l6 h3 b, b% t" l
! b' F i4 v% a" b6 Q" u- /* HCLK = SYSCLK */
! }' S" r8 y, A8 R. b. J; N- I - RCC_HCLKConfig(RCC_SYSCLK_Div1); 7 [0 Q! N* W5 m e! v- \4 {% u
8 N2 E3 u" z* D! r9 s, m- /* PCLK2 = HCLK */
, |+ R* X% m9 y3 [9 w6 P - RCC_PCLK2Config(RCC_HCLK_Div1);
9 _% q/ @; m, O( D. \: @
! d% N9 D7 C7 o3 U- /* PCLK1 = HCLK / 2 */. g& Z# P! F H* i2 e$ s2 Y
- RCC_PCLK1Config(RCC_HCLK_Div2);2 z" `( V- ?+ b
- 6 z: D" x5 W1 ^2 U( d/ p
- /* Configure PLLs */3 O" d% T/ A5 z' H
- #ifdef STM32F10X_CL2 a. B! k" c# P* i* h4 q; m; K2 |
- /* PLL2 configuration: PLL2CLK = (HSE(8MHz) / 2) * 10 = 40MHz */! l4 k; a4 M- }; o) Y! v( E8 {
- RCC_PREDIV2Config(RCC_PREDIV2_Div2);: W9 I' L: c: x- C3 D# L
- RCC_PLL2Config(RCC_PLL2Mul_10);2 ~/ E- u: Y1 h3 ^0 \4 ?
( F7 A$ ~1 W7 C/ Q8 X- /* Enable PLL2 */
+ g A6 i( g E+ N# E" N" ]: Y9 |, r - RCC_PLL2Cmd(ENABLE);; C0 b A" a& U
- 8 e. I6 [$ _' F; f8 |, r
- /* Wait till PLL2 is ready */, M, _3 h5 k* ?3 @
- while(RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET);' `4 O) x) Y6 J- g$ ~9 h9 k T! k' t+ l
- # A5 f& j+ `2 C) _
- /* PLL configuration: PLLCLK = (PLL2(40MHz) / 5) * 9 = 72MHz */( g7 A4 |1 [" ^; h. ?& r8 U
- RCC_PREDIV1Config(RCC_PREDIV1_Source_PLL2, RCC_PREDIV1_Div5);
$ Z5 a$ R9 E& I9 q - RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_9);
" Y% M( c" ^' N! _ - #else; f* z, e+ D$ ~5 [; z4 z
- /* PLLCLK = HSE(8MHz) * 9 = 72MHz */; G+ S: [5 d$ w/ @% U
- RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);6 N$ E+ K9 B! P9 `4 p, A& G- n
- #endif
' s, _2 D9 z H% `
4 g: l7 d$ x0 w0 z2 V. ]' X; b2 e/ K- /* Enable PLL */# G2 L' k% T- I
- RCC_PLLCmd(ENABLE);' [) W* H. ~2 \1 e, Y7 u
- 3 l- D" V: M; _7 k4 r
- /* Wait till PLL is ready */' k6 x J7 [# J7 G; @
- while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);. m: Z3 v5 A. M7 U6 q4 _
5 M( Q5 Q0 A# @- /* Select PLL as system clock source */# }$ w, q- g& {1 Z% m @
- RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
: U1 c! y+ L% G - 2 p* J' C4 R9 k: w! [
- /* Wait till PLL is used as system clock source */
$ ^- _0 ? l- I - while(RCC_GetSYSCLKSource() != 0x08);& h" ~- j6 O. y1 ]
- }9 Y5 P$ h2 }9 p7 m2 _
- else0 ?$ Q) U5 k+ {- h3 u
- {" l) C) _$ q: P2 q8 L0 g
- /* Disable HSE */
( [. v! ?% e8 L3 d8 k - RCC_HSEConfig(RCC_HSE_OFF);" ^' p$ e I9 e6 l
5 {8 W" `$ j- n2 c8 K0 q- /* Enable HSI */& w( S% t8 [* ]- ]! w( e: @$ t4 J
- RCC_HSICmd(ENABLE);: R4 N" k2 p, @- p+ e o
2 D" R5 l8 Q% }4 ]- /* Enable Prefetch Buffer */
* s9 o+ p# a6 [$ ~ - FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);& a4 y- L; g/ ]
- # u& H) w& c4 u. [
- /* Flash 1 wait state */2 J- d- ?- B- U: g- w
- FLASH_SetLatency(FLASH_Latency_1);
7 N6 u# e) A( u n6 ^- U7 M
+ i, a' l! _3 c- /* HCLK = SYSCLK */
3 |1 T) R7 S4 }4 z2 m& |/ D - RCC_HCLKConfig(RCC_SYSCLK_Div1);
4 r8 J' ^7 h* |6 _
) n9 m* f, t6 G% U2 E: b- /* PCLK2 = HCLK */- R9 n; l+ P7 R; {$ M
- RCC_PCLK2Config(RCC_HCLK_Div1);
; n. |8 v# Y8 O, D/ F/ z% q' ~
$ n$ R( M) Z2 ?4 E- /* PCLK1 = HCLK */
6 i3 ` F) v8 F( V' q+ Z- u - RCC_PCLK1Config(RCC_HCLK_Div1);% W$ u. L( e6 ]7 k3 D
- / B% K# u' a% E7 o
- /* Configure PLLs */
7 C2 r! m+ b! d& R0 o: q: G - /* PLLCLK = HSI(8MHz) / 2 * 9 = 36MHz */
9 |8 |% }( m& c - RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_9);
" n% D' {5 a! b
$ U. \/ | T# C) k" I/ l- /* Enable PLL */9 T! [: |5 m8 ]! z# w5 q! R j
- RCC_PLLCmd(ENABLE);
' j( h+ u+ R9 ~7 ^7 ~6 S, S( G - 9 D" W7 F4 s( i7 B1 @$ e2 _5 A
- /* Wait till PLL is ready */3 y# }- H$ n4 }' _0 I
- while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
: a- w1 b q) V/ h* ? - 6 s2 j( A2 J# U) V9 J* x" D
- /* Select PLL as system clock source */
4 c+ E a% }0 M& V - RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
3 n. i* y# i! E- I! S% _' I6 }* z' [
! R( I s8 d0 P- M, X+ }2 {- /* Wait till PLL is used as system clock source *// f' ]& T; k6 Z/ J% q
- while(RCC_GetSYSCLKSource() != 0x08);5 A+ H6 V. {, ?( T
- }
! W5 e' z' k7 i0 j/ _ - }
: s) B: K6 k4 I - 9 H" _2 j; A3 x2 H' _! I) S7 |
- #ifdef USE_FULL_ASSERT3 ?8 u3 G3 p1 |# f& n8 [
- /**" \( \7 s8 i& E* `; ?5 [
- * @brief Reports the name of the source file and the source line number
+ _% _* A5 k0 a8 X - * where the assert_param error has occurred.4 n0 ]' B8 i2 f
- * @param file: pointer to the source file name.
) I3 W$ y$ {9 n - * @param line: assert_param error line source number.
: s j; \ R- j+ d+ r, h - * @return None.
# g8 s: k* X" l- b - */7 a/ l0 N5 X) l) v! G
- void assert_failed(uint8_t *file, uint32_t line)
5 m$ X$ O$ B* O# c- a3 ~ - {
" U4 x9 s$ n8 |2 F* S8 H - /* User can add his own implementation to report the file name and line number,% q7 ]. x3 [$ F x/ ~
- ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */$ [# K+ O: h4 o2 \- U3 m M
+ a% M2 E0 D3 L8 e2 v- [: S- /* Infinite loop */9 i- o+ `5 `+ G
- while(1)
) O! L; g9 P" w! k4 Z5 V/ z+ U - {( \8 d3 q) h! [* O- g
- }, k& U3 ^: T5 A1 t. `/ n+ i' _: w
- }
# d) k% I( [: E6 N! \3 X* R - #endif
复制代码 $ S) F- a# t" ]4 c7 B F5 C. N
3,注意 Y' L! U% r8 b, G
& ^8 k6 k4 g8 ]CAN 消息发送缓冲区和接收缓冲区的大小,可以根据应用的需求进行修改,缓冲区使用的是堆内存,需要根据缓冲区大小和应用程序中堆内存使用情况进行配置。! i8 K% v& d( r) i8 ~, f- p' u
2 Q2 |# G9 m I2 n0 Z- D! ?( p
, o8 J$ q6 G r+ k; R' \" v0 s' x# q6 u. Y
|