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