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