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