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