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