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