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