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