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