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