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