01. I2C简介
1 A" H: Y% ?9 P3 [0 v! E0 Z lI2C(内部集成电路)总线接口用作微控制器和 I2C 串行总线之间的接口。它提供多主模式功能,可以控制所有I2C总线特定的序列、协议、仲裁和时序。它支持标准和快速模式。它还与 SMBus 2.0 兼容。
x, N6 ^: f8 W2 Q% T
) o W: x% }/ }它可以用于多种用途,包括 CRC 生成和验证、SMBus(系统管理总线)以及 PMBus(电源管理总线)。
; p# t/ g5 y3 s( `$ F% G2 o# \2 d/ j$ |. @
根据器件的不同,可利用 DMA 功能来减轻 CPU 的工作量。% K, `' [+ x* Q4 }8 e, A
/ @& \; s/ Z) n* M2 i; W, Q2 |% n# t
02. 相关类型
) [7 }* `; K7 |' @2 V2 m9 V$ }- hI2C Init structure9 p' s! b& N, g: a/ b2 Q$ {% b0 |
8 W4 @' E* r% {' n
- /** % x( o1 W& e+ u8 a L2 Y
- * @brief I2C Init structure definition " b& I+ B" |0 t5 }; }
- */& q0 R3 ^- n' g1 F) f
3 a% z2 S1 Z# ?8 N! w- typedef struct
- b8 g g5 {1 r. B - {* l7 d+ X/ x6 ?5 n( Z1 q4 l
- uint32_t I2C_ClockSpeed; /*!< Specifies the clock frequency.% ?$ O r& h. {
- This parameter must be set to a value lower than 400kHz */: `& l! [; d1 s G
- : O+ a& X; D. H$ @8 Y
- uint16_t I2C_Mode; /*!< Specifies the I2C mode.
+ q$ ~" h' j' o - This parameter can be a value of @ref I2C_mode */
( x3 [( t. x. t- a% [* Q - 3 e& i/ g% d- A$ ~# W! g' P/ r
- uint16_t I2C_DutyCycle; /*!< Specifies the I2C fast mode duty cycle.5 o) d; y/ }( y. U ~( O
- This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */
; e& t& e! {, D; q" t& H7 A - 6 U. p1 S* s7 g N) j
- uint16_t I2C_OwnAddress1; /*!< Specifies the first device own address.2 @: A6 X/ ?+ c! i2 c( u% b
- This parameter can be a 7-bit or 10-bit address. */% I; ~4 k' _5 e8 H8 K
. _. i8 A% z- h9 r- uint16_t I2C_Ack; /*!< Enables or disables the acknowledgement.8 H- [# V1 r& [" h; @
- This parameter can be a value of @ref I2C_acknowledgement */$ D4 f) W( A! m( o
& c, a! V+ @3 ?: D8 _9 Q- q- uint16_t I2C_AcknowledgedAddress; /*!< Specifies if 7-bit or 10-bit address is acknowledged.9 N* g: N$ y4 o% @
- This parameter can be a value of @ref I2C_acknowledged_address */ Q( Z8 z* ^: ]$ H' d
- }I2C_InitTypeDef;
复制代码 - ]) K. E% B. m6 Y1 Z N6 ^
I2C_Exported_Constants4 h2 d" l! M( A7 p; M
$ f" c5 \, U5 y, Q$ K3 w1 H
. D# A* ]( g) I8 D- /** @defgroup I2C_Exported_Constants
0 |/ X: A, V( I& \- ^$ a( \% K - * @{+ S) S, j& k) Q# }( U+ e3 T. H
- */" K* u% t. L5 R. X5 D( l% X
- #define IS_I2C_ALL_PERIPH(PERIPH) (((PERIPH) == I2C1) || \0 E; Z5 m# f, S+ X/ \, B" K* B
- ((PERIPH) == I2C2) || \
% e6 T$ {! g$ S) j; j, }8 M, y% n - ((PERIPH) == I2C3))3 f2 A: k" G) c" L a3 C6 L) o7 T
- /** @defgroup I2C_Digital_Filter- x; W1 Z! z6 L; V" g
- * @{
' Q5 G, v1 ]* N5 W - */. e a+ X/ }3 k9 S% V4 K/ e9 }( R
) T0 ?* J( t# f" J- #define IS_I2C_DIGITAL_FILTER(FILTER) ((FILTER) <= 0x0000000F)
6 a/ g/ d, B/ D& X4 w& ~ - /**
% G$ R8 Y% _6 W6 s - * @}" O; \1 B1 z3 ^% O
- */
复制代码 & Y1 M# B$ V2 D5 [* Y9 M
I2C_mode- /** @defgroup I2C_mode & m1 Y$ s# Y) Q- F/ i% K
- * @{
( e8 B9 I0 L4 L! j: }; {2 t - */
% W5 O: }3 @! ]( ~8 h - / `. p+ [8 M& S9 l1 C6 p
- #define I2C_Mode_I2C ((uint16_t)0x0000)
( D M% t. H$ O, P T# p' u - #define I2C_Mode_SMBusDevice ((uint16_t)0x0002)
: K, l3 K. `0 v% k - #define I2C_Mode_SMBusHost ((uint16_t)0x000A)
" ^7 ^- k. o+ f) Q3 } - #define IS_I2C_MODE(MODE) (((MODE) == I2C_Mode_I2C) || \
, f8 q/ W: o& @) Q - ((MODE) == I2C_Mode_SMBusDevice) || \
/ t @' h0 C$ t# [ - ((MODE) == I2C_Mode_SMBusHost))
复制代码 Q/ s q; N8 e
I2C_duty_cycle_in_fast_mode
" z& l8 M$ [6 C1 d5 `; h
9 I- o2 H+ [$ q1 \- /** @defgroup I2C_duty_cycle_in_fast_mode / R' `9 x, a& B% B, P* U
- * @{* d/ U8 g! ~9 s" l m
- */
7 [5 m, l* V5 E/ \
! W4 y4 P& J' ~/ {( O' x- #define I2C_DutyCycle_16_9 ((uint16_t)0x4000) /*!< I2C fast mode Tlow/Thigh = 16/9 */
: V$ |9 {- j8 Q) x9 `: U- K - #define I2C_DutyCycle_2 ((uint16_t)0xBFFF) /*!< I2C fast mode Tlow/Thigh = 2 */
* d7 l. w# m7 t b5 V+ {; ?4 ?6 L9 B - #define IS_I2C_DUTY_CYCLE(CYCLE) (((CYCLE) == I2C_DutyCycle_16_9) || \# U1 Z( p4 B) a4 \! [( ~) J
- ((CYCLE) == I2C_DutyCycle_2))
复制代码
f% N0 R' j, p7 j: MI2C_acknowledgement0 q$ j0 s! t3 |
% {+ C2 L2 N1 z5 S0 w9 C# @ z
- /** @defgroup I2C_acknowledgement' }# X# }, p: t. C7 {% I
- * @{
" u2 C# F5 C" O9 h, }$ y - *// v6 ~ y; T: d1 x
- 7 R0 N0 s' G+ O
- #define I2C_Ack_Enable ((uint16_t)0x0400)0 S7 [+ v5 v' W# }' z
- #define I2C_Ack_Disable ((uint16_t)0x0000)7 S* e+ M6 ~& _5 o' d8 i( ~
- #define IS_I2C_ACK_STATE(STATE) (((STATE) == I2C_Ack_Enable) || \' Y- }/ R ]7 D; N
- ((STATE) == I2C_Ack_Disable))
复制代码
. \9 ~$ x! Q$ C z1 V& dI2C_transfer_direction
5 ?: n; v0 A l8 W3 Q
Q4 V% M& Y, k: o- /** @defgroup I2C_transfer_direction . I9 o9 H2 q2 o) m
- * @{
3 R3 c6 }0 ~ ~; p4 z; c* f - *// E }5 @: b/ H5 X! s5 l
; C" s7 X# k* O$ b: x* }- #define I2C_Direction_Transmitter ((uint8_t)0x00)
9 e. k- b/ a6 h O - #define I2C_Direction_Receiver ((uint8_t)0x01)6 H+ G5 J1 C4 h- |% U* A% |/ ~
- #define IS_I2C_DIRECTION(DIRECTION) (((DIRECTION) == I2C_Direction_Transmitter) || \
" o; ]# H2 p* Y/ p6 m. G - ((DIRECTION) == I2C_Direction_Receiver))
复制代码 3 X/ l2 d6 T" R2 b: m" B; [ R
I2C_acknowledged_address
% a/ s& K9 c: P. Z- L: d8 Q( k) X4 f0 p, B
- /** @defgroup I2C_acknowledged_address
, V8 {+ T" y6 g! f& h# q - * @{4 f+ g& |' n& e% @3 t1 X# w
- */" `$ N6 V7 s8 k; F! X( E
! ^7 @6 c: o7 d, }- B* H- #define I2C_AcknowledgedAddress_7bit ((uint16_t)0x4000). J1 S! F' ?" ?6 L. P0 p8 M
- #define I2C_AcknowledgedAddress_10bit ((uint16_t)0xC000)
, P, t* d; P' D% s& a0 ?: L; ?+ T - #define IS_I2C_ACKNOWLEDGE_ADDRESS(ADDRESS) (((ADDRESS) == I2C_AcknowledgedAddress_7bit) || \9 p/ i" y8 m# i4 c7 p9 \# R4 q
- ((ADDRESS) == I2C_AcknowledgedAddress_10bit))
复制代码 8 T; I4 |7 g, o
I2C_registers
# K( w# K7 G% H, r5 J. k
' _: F- T; B+ A! x! }: L2 }/ N/ u- /** @defgroup I2C_registers
1 f$ `8 Q) Q5 [ - * @{. F, }$ W3 n# W. m7 F
- */+ q* O4 f- Q3 n0 ?. @
- % K: B7 d: P, M+ q
- #define I2C_Register_CR1 ((uint8_t)0x00)2 ~7 q. S& A I/ y5 |
- #define I2C_Register_CR2 ((uint8_t)0x04)
% Z! U( I( `$ { }# v& k - #define I2C_Register_OAR1 ((uint8_t)0x08)3 J+ f5 `$ v# X% d6 o3 }
- #define I2C_Register_OAR2 ((uint8_t)0x0C)" ^6 \7 R) f C3 K
- #define I2C_Register_DR ((uint8_t)0x10)1 i3 a5 q: u5 @- ^ d) z0 L+ W
- #define I2C_Register_SR1 ((uint8_t)0x14)' J! A" Y& _* d# g
- #define I2C_Register_SR2 ((uint8_t)0x18)& ^. L4 j4 x6 K4 u7 p) a
- #define I2C_Register_CCR ((uint8_t)0x1C)) D" Z% t: m7 ^/ j# m. l2 U1 j
- #define I2C_Register_TRISE ((uint8_t)0x20)7 t, X8 y8 o. M! k6 N: i: D$ ^
- #define IS_I2C_REGISTER(REGISTER) (((REGISTER) == I2C_Register_CR1) || \8 P) |7 x# R! |0 h l& B5 e
- ((REGISTER) == I2C_Register_CR2) || \& Z1 G" U' [- ^8 D
- ((REGISTER) == I2C_Register_OAR1) || \
) K) S r: K; U4 ^' n - ((REGISTER) == I2C_Register_OAR2) || \
2 Q( i- m5 h$ z* s - ((REGISTER) == I2C_Register_DR) || \
( C' P3 T- P" O1 F - ((REGISTER) == I2C_Register_SR1) || \
% x5 A! \& \ e" T - ((REGISTER) == I2C_Register_SR2) || \/ A( M/ X2 ?& U1 E% h: K
- ((REGISTER) == I2C_Register_CCR) || \
$ O& f/ [/ K: f' e6 h - ((REGISTER) == I2C_Register_TRISE))
复制代码 ; p* G4 ~' a0 N1 U+ v
I2C_NACK_position: W, A6 [/ S$ o: e9 V
9 g0 C5 k' _4 s8 U+ n- /** @defgroup I2C_NACK_position
3 ^) f9 t: _: P1 F* _# R - * @{! B+ t3 w2 f, h( M3 A7 V
- */; w5 s5 B l8 i7 n: u1 q
- ' W- M" S# y# p, f4 [8 z
- #define I2C_NACKPosition_Next ((uint16_t)0x0800)6 c( z* f" d9 s% W
- #define I2C_NACKPosition_Current ((uint16_t)0xF7FF)/ R6 C& P" v9 g0 c
- #define IS_I2C_NACK_POSITION(POSITION) (((POSITION) == I2C_NACKPosition_Next) || \" _/ D: r+ d) z8 e& ]: ~
- ((POSITION) == I2C_NACKPosition_Current))
复制代码 . T% z7 O# |% e) Z. N8 I
I2C_SMBus_alert_pin_level
; t& s( n5 h9 R3 `$ Q/ L4 O) `( V. f0 }! Q
- /** @defgroup I2C_SMBus_alert_pin_level : l5 d9 O/ P- |/ K
- * @{" z* z; n5 Z" w1 f
- */$ B6 S8 j5 s1 a' Z7 H3 O- W* x
; b# k+ I# j5 R! g( {- #define I2C_SMBusAlert_Low ((uint16_t)0x2000)
( B) {! q3 c0 f - #define I2C_SMBusAlert_High ((uint16_t)0xDFFF)
2 \& P( F- g9 X; f. D: k - #define IS_I2C_SMBUS_ALERT(ALERT) (((ALERT) == I2C_SMBusAlert_Low) || \
+ T" k' j* B3 s* B# |" R - ((ALERT) == I2C_SMBusAlert_High))
复制代码
$ l1 {6 b1 C9 v8 W8 U7 VI2C_PEC_position+ m( }6 C2 |3 J c/ o) r
7 k7 ?. Z; k4 \ V- /** @defgroup I2C_PEC_position
' H7 z" ?1 w7 ?" e - * @{0 I C6 l# Y) Q5 p/ a4 H! i
- */
n! H7 [. _; A/ ], S& ~
/ W' d5 W, w, x* [8 |- #define I2C_PECPosition_Next ((uint16_t)0x0800)
% M8 D& t& x/ i, b/ r$ b5 E7 X - #define I2C_PECPosition_Current ((uint16_t)0xF7FF)6 H5 V+ r$ ?4 U, A2 I
- #define IS_I2C_PEC_POSITION(POSITION) (((POSITION) == I2C_PECPosition_Next) || \
# w" L+ m" D M0 I0 R" ?4 J& Y6 r" K - ((POSITION) == I2C_PECPosition_Current))
复制代码
$ _: j+ T7 K+ T6 U* TI2C_interrupts_definition
3 ^# g7 \0 C- h8 z. j# F o: k7 Z4 C2 |* b
- /** @defgroup I2C_interrupts_definition ' P" ?9 ^9 Y# R' {0 h/ Q; g4 h
- * @{
# H4 h$ U- u. ^ n5 d; }8 R, M - */- w/ [8 M8 c6 N% @3 E
' v* X+ _# x7 y% b: `$ y, O" _. B0 c- #define I2C_IT_BUF ((uint16_t)0x0400)$ P4 J& j6 Y. g" z! Q! U
- #define I2C_IT_EVT ((uint16_t)0x0200)
) K" z" n- B( H. U. F% v7 R - #define I2C_IT_ERR ((uint16_t)0x0100): { L- s' A0 n/ C
- #define IS_I2C_CONFIG_IT(IT) ((((IT) & (uint16_t)0xF8FF) == 0x00) && ((IT) != 0x00))
复制代码
- I/ @7 j, N3 G" qI2C_interrupts_definition
7 |+ ]8 q( K. w- s0 q6 Q9 V' p' B/ A: E5 |5 y
- /** @defgroup I2C_interrupts_definition 7 }* R" ?& u' K# o5 ~( Y% z
- * @{8 m' l; D( E7 {" R: s* E5 e" e8 I
- */0 _7 d- s( ?! Z- p0 \
/ e1 S, f5 q G1 n) w( n- #define I2C_IT_SMBALERT ((uint32_t)0x01008000)5 F5 H: E' l& ^- }
- #define I2C_IT_TIMEOUT ((uint32_t)0x01004000)) c! _! U# ?+ x/ w% H
- #define I2C_IT_PECERR ((uint32_t)0x01001000)" i: w2 |3 |" F* Z% B* G& G
- #define I2C_IT_OVR ((uint32_t)0x01000800)1 k/ \5 ?+ p9 x5 k. F' q8 p! y ^
- #define I2C_IT_AF ((uint32_t)0x01000400)
8 x6 C) L" i+ l( ] - #define I2C_IT_ARLO ((uint32_t)0x01000200)
8 r7 R( _0 [+ L - #define I2C_IT_BERR ((uint32_t)0x01000100)
6 U' \ E9 n; @- g: B% |' ^3 G n- X+ K - #define I2C_IT_TXE ((uint32_t)0x06000080)
# N6 l( A+ [* ] - #define I2C_IT_RXNE ((uint32_t)0x06000040)" ~% N+ d7 x1 D! p$ W3 J2 K6 P
- #define I2C_IT_STOPF ((uint32_t)0x02000010)4 x9 N. t' K" p) C6 ^' d
- #define I2C_IT_ADD10 ((uint32_t)0x02000008)
+ Q- T& q. }: Q - #define I2C_IT_BTF ((uint32_t)0x02000004)5 B( R) U! U* a, r" r- S; |
- #define I2C_IT_ADDR ((uint32_t)0x02000002)/ w% W$ L3 f' q {, y
- #define I2C_IT_SB ((uint32_t)0x02000001)
3 S3 D2 D7 z: q( G7 H - ; ]# d' u }( Q4 M
- #define IS_I2C_CLEAR_IT(IT) ((((IT) & (uint16_t)0x20FF) == 0x00) && ((IT) != (uint16_t)0x00))1 C: i' C) P" O( }# [, y
i# B6 ^5 s. y0 F1 c8 c1 F% n+ _- #define IS_I2C_GET_IT(IT) (((IT) == I2C_IT_SMBALERT) || ((IT) == I2C_IT_TIMEOUT) || \6 I1 N, ?8 }' x" Q" x
- ((IT) == I2C_IT_PECERR) || ((IT) == I2C_IT_OVR) || \ {. F8 ]" S+ [# k0 H4 C) S$ x8 i" G
- ((IT) == I2C_IT_AF) || ((IT) == I2C_IT_ARLO) || \
( A: e- t' S2 X4 ~7 y& D - ((IT) == I2C_IT_BERR) || ((IT) == I2C_IT_TXE) || \
2 o) d8 T `, k% u - ((IT) == I2C_IT_RXNE) || ((IT) == I2C_IT_STOPF) || \
$ u" n7 |1 b4 i, l0 u: ^6 z# y. ^7 V - ((IT) == I2C_IT_ADD10) || ((IT) == I2C_IT_BTF) || \
0 m; I4 P" ~9 T: o8 C$ r" X' @ - ((IT) == I2C_IT_ADDR) || ((IT) == I2C_IT_SB))
复制代码 % a, v0 u4 E* H' x A
SR2 register flags. h( @, X L" e- K# I, e9 n3 L
" Z" B4 ~$ q1 K+ Z! [2 w0 D' v/ J
- /** ! d2 b9 y# q Y) _' d; e
- * @brief SR2 register flags 6 e' {- i7 ]" a. [! U8 u8 t
- */
2 \/ l. Y) |; t - . Q2 e7 j6 N1 U1 Y. P
- #define I2C_FLAG_DUALF ((uint32_t)0x00800000)9 o! ?- ^4 J4 j! ]$ b
- #define I2C_FLAG_SMBHOST ((uint32_t)0x00400000)
% r2 ]& |. g3 ? - #define I2C_FLAG_SMBDEFAULT ((uint32_t)0x00200000)' S. g$ ?, n) R' I
- #define I2C_FLAG_GENCALL ((uint32_t)0x00100000)0 u2 o8 m) V( k5 I) a
- #define I2C_FLAG_TRA ((uint32_t)0x00040000)9 T+ x' G, k4 Z, a. a3 e
- #define I2C_FLAG_BUSY ((uint32_t)0x00020000)1 X1 t: ] Q X2 I0 ^
- #define I2C_FLAG_MSL ((uint32_t)0x00010000)
复制代码
8 [: p2 c; ]3 K3 _) qSR1 register flags1 A% n$ Z# z6 X6 n( H. O: @
) N, t6 y0 v; H3 Z$ h7 O5 x- /**
/ v! U% t: I4 o% ] - * @brief SR1 register flags ; w( G& |8 t$ M, y" q
- */8 [ P6 A5 N7 e
- + \( r! ^/ s. Z7 Q% f! V4 s+ Y
- #define I2C_FLAG_SMBALERT ((uint32_t)0x10008000)# v- p/ f/ A3 ^" r
- #define I2C_FLAG_TIMEOUT ((uint32_t)0x10004000)% W Q. @, T, O, G
- #define I2C_FLAG_PECERR ((uint32_t)0x10001000)
8 }6 a+ j6 K& {" S* F8 }4 H - #define I2C_FLAG_OVR ((uint32_t)0x10000800)
' B! h+ _) u7 T7 [7 E - #define I2C_FLAG_AF ((uint32_t)0x10000400)
& H$ q4 t7 C: k/ c - #define I2C_FLAG_ARLO ((uint32_t)0x10000200)
' @& X5 o8 \2 a; S3 q3 j - #define I2C_FLAG_BERR ((uint32_t)0x10000100)
$ a* j+ N6 v5 b( J; t [ - #define I2C_FLAG_TXE ((uint32_t)0x10000080)) H; b: T# K! b) u) T+ o6 P5 v4 f
- #define I2C_FLAG_RXNE ((uint32_t)0x10000040)
# R8 b" u7 F4 e* c% N/ F3 _3 f7 @) w - #define I2C_FLAG_STOPF ((uint32_t)0x10000010), Q* h8 Y/ u4 s- g9 V5 C3 J
- #define I2C_FLAG_ADD10 ((uint32_t)0x10000008)
- q: g. {2 B- B. y. U, g - #define I2C_FLAG_BTF ((uint32_t)0x10000004)# P3 p' F8 b, B4 @6 S+ ?2 A+ C4 W1 i
- #define I2C_FLAG_ADDR ((uint32_t)0x10000002)+ ~# _: w6 ^. O5 {% r8 D5 X- W
- #define I2C_FLAG_SB ((uint32_t)0x10000001)' d0 w' ]" h9 q6 Q0 o# |
- , v: e, R3 A H5 s1 R' Z$ B- Z3 g
- #define IS_I2C_CLEAR_FLAG(FLAG) ((((FLAG) & (uint16_t)0x20FF) == 0x00) && ((FLAG) != (uint16_t)0x00)). ~# C" n4 E* c8 k( L1 |
( i% o8 x7 i' V0 U, Y4 U, u- #define IS_I2C_GET_FLAG(FLAG) (((FLAG) == I2C_FLAG_DUALF) || ((FLAG) == I2C_FLAG_SMBHOST) || \, ^8 Q$ @% _4 C$ j S" r
- ((FLAG) == I2C_FLAG_SMBDEFAULT) || ((FLAG) == I2C_FLAG_GENCALL) || \
. o2 ]% Q Q; y$ }- { - ((FLAG) == I2C_FLAG_TRA) || ((FLAG) == I2C_FLAG_BUSY) || \
6 j' s- O) v& G3 ^/ o. T - ((FLAG) == I2C_FLAG_MSL) || ((FLAG) == I2C_FLAG_SMBALERT) || \
8 w& K1 W4 k) X9 V+ T0 K! ] - ((FLAG) == I2C_FLAG_TIMEOUT) || ((FLAG) == I2C_FLAG_PECERR) || \7 I3 p9 ?# Z/ i0 F9 ~" P+ J
- ((FLAG) == I2C_FLAG_OVR) || ((FLAG) == I2C_FLAG_AF) || \
2 O( s% g- H' X - ((FLAG) == I2C_FLAG_ARLO) || ((FLAG) == I2C_FLAG_BERR) || \
4 k# o. m# f* f$ @0 q1 W - ((FLAG) == I2C_FLAG_TXE) || ((FLAG) == I2C_FLAG_RXNE) || \
; K" o0 N; D; u8 z @7 R& F - ((FLAG) == I2C_FLAG_STOPF) || ((FLAG) == I2C_FLAG_ADD10) || \
7 v9 k1 ]0 W4 f% ~% v; T - ((FLAG) == I2C_FLAG_BTF) || ((FLAG) == I2C_FLAG_ADDR) || \9 h' K7 _* |3 B! @
- ((FLAG) == I2C_FLAG_SB))
复制代码
$ ~; R( } {9 G* \* Y- f) h03. 相关函数
& R& p0 i2 j3 G- /* Function used to set the I2C configuration to the default reset state *****/
( h; F; p+ {" Z( i/ }9 w1 j9 D - void I2C_DeInit(I2C_TypeDef* I2Cx);; f$ w1 u4 J, D! \2 I
- 3 l) A# Q5 h% n9 r, a, u
- /* Initialization and Configuration functions *********************************/
6 i5 R; @4 q: e6 u - void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct);
& t7 u7 `; O( D. D, r. X - void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct);
E# c: R, s$ S; V% V4 q - void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState);* Z/ p" ]5 J1 G" {" Y, ]3 q. g
- void I2C_DigitalFilterConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DigitalFilter);
, a4 l _* _# _; ^6 e7 { - void I2C_AnalogFilterCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
" Q3 y2 {2 R; j - void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState);7 V9 F; E% J3 f) Z7 F* I
- void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState);
1 T9 B7 g( v3 O1 a, J - void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction);
% m: q$ g6 ~+ J1 U' V; Y* b - void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState);
# N# P6 b' q9 L9 s - void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint8_t Address);
5 A5 b; |* Y: r, q8 W - void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);8 y6 r9 Z& l/ ~. U- n4 {5 ]5 d
- void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
! R7 G5 P. U' `- d- [ - void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);( r! f5 J2 d4 w- L7 F
- void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);; J8 {' d( x ~3 R' Q2 A
- void I2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DutyCycle);
# _' G& a; p' b l+ N - void I2C_NACKPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_NACKPosition);
) U8 Z: b. P, Q$ F: ^" ` - void I2C_SMBusAlertConfig(I2C_TypeDef* I2Cx, uint16_t I2C_SMBusAlert);: T" M% h9 r7 o. ]# ~0 o
- void I2C_ARPCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);% T+ F3 x* z* B- A
+ X( P$ q; g/ o1 `- /* Data transfers functions ***************************************************/ : O. e/ k+ h- K
- void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data);
5 u, R" E" L1 \# h - uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx);
: S2 J/ N0 x+ X$ U6 D - 7 Y5 Z/ t2 Q, R' ~, U
- /* PEC management functions ***************************************************/ ; L4 [5 U# c7 w$ {' }
- void I2C_TransmitPEC(I2C_TypeDef* I2Cx, FunctionalState NewState);
; ?% N* @; @5 e) S6 C# {3 c - void I2C_PECPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_PECPosition);
: ^+ p# q V9 |7 F - void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState);
# K5 J; z5 A6 P$ K: E! J - uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx);
" M1 B. a" k$ m$ s: g; ?
2 _& d7 r k4 {: `- /* DMA transfers management functions *****************************************/
3 Y4 L8 J; X9 Y$ ?8 E! _* a - void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
/ j% p2 l( ?, C/ o1 }4 y6 W - void I2C_DMALastTransferCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);4 l& A2 s- G T! L% B* u# Z
- 3 V/ e% [6 J- Y
- /* Interrupts, events and flags management functions **************************/4 Y1 R' `, s2 w" \% d& c
- uint16_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register);, m' n9 D$ }: l: J! o
- void I2C_ITConfig(I2C_TypeDef* I2Cx, uint16_t I2C_IT, FunctionalState NewState);
0 u& G: _4 P/ _ [" A: A
) B% m- q" R7 R' F0 u' A- /*
6 p3 T9 ^( V/ K4 k. i4 D- @ - ===============================================================================3 [( X; N$ `9 d2 E4 D% o9 ?
- I2C State Monitoring Functions/ a* `7 s! @- r5 b3 b: h/ N! ^
- ===============================================================================
/ G$ t+ _+ I7 r* q - This I2C driver provides three different ways for I2C state monitoring/ k8 f5 j& P" x% ]3 @1 a$ P+ D
- depending on the application requirements and constraints:# b4 \7 O* Q7 z- N/ Y# a' V: M8 N
- 9 s0 Y2 O9 y% U7 t" C( e
- 6 b% u8 n: i; F7 Y( W, {
- 1. Basic state monitoring (Using I2C_CheckEvent() function)2 O+ ?5 u8 e5 B' i3 S: T3 ?
- -----------------------------------------------------------
0 ~+ F. M4 |+ ]4 o* m7 b' \6 p - It compares the status registers (SR1 and SR2) content to a given event
; c5 g% G! M, c Y2 u3 s% l. L7 K - (can be the combination of one or more flags).8 p& t( U/ X& ]# J% C" {0 Y
- It returns SUCCESS if the current status includes the given flags
2 l+ q" o2 V8 c3 | - and returns ERROR if one or more flags are missing in the current status.
: A6 e0 y. a7 B - 6 k7 g8 K4 `# G! b2 @* v0 `
- - When to use7 ]/ R% H; P; B( l7 X
- - This function is suitable for most applications as well as for startup 2 h5 H9 m/ c/ y8 _1 T6 \. P0 s. i
- activity since the events are fully described in the product reference ) Y! Q# s% L! \' l% W1 [( g
- manual (RM0090).
% m* p1 g: f7 r; ~3 \- ]0 f! A - - It is also suitable for users who need to define their own events.4 N" k, |/ z. [! H" T1 Z# `
- 3 Z- g8 u* P8 U' v
- - Limitations- |* R; }2 D/ z) d7 H$ Z
- - If an error occurs (ie. error flags are set besides to the monitored
6 }# n/ u) f7 f3 [( m! l+ l - flags), the I2C_CheckEvent() function may return SUCCESS despite 5 j* {6 N. C8 Y6 H2 c% B
- the communication hold or corrupted real state.
) l% K' `& M6 c5 R2 H3 d8 a+ F - In this case, it is advised to use error interrupts to monitor & R; z* S: e$ ^5 h
- the error events and handle them in the interrupt IRQ handler.
+ s3 ?' s8 X5 n
8 W9 z7 O# q. W- B5 r1 e! ^- Note % Z1 W3 D- t+ _ y% S
- For error management, it is advised to use the following functions:
3 t( f( s; x1 D0 ` - - I2C_ITConfig() to configure and enable the error interrupts (I2C_IT_ERR).; {" H% ]+ Y' |. o% `" h
- - I2Cx_ER_IRQHandler() which is called when the error interrupt occurs.
0 l# D2 ~: f. n( T+ Z w - Where x is the peripheral instance (I2C1, I2C2 ...)2 {* P+ P V/ ~: M$ I5 w- p
- - I2C_GetFlagStatus() or I2C_GetITStatus() to be called into the
9 R% ~8 D6 T. c5 G: W8 X! x - I2Cx_ER_IRQHandler() function in order to determine which error occurred.& M2 g z W; m0 Z. `( d' i( D
- - I2C_ClearFlag() or I2C_ClearITPendingBit() and/or I2C_SoftwareResetCmd()
6 q/ Y6 O: Q0 j9 g8 G9 @ - and/or I2C_GenerateStop() in order to clear the error flag and source K+ k' z A+ X0 Z6 e2 w1 G# R ]
- and return to correct communication status.4 L' ]2 F9 s( I: C, c3 T4 D
- 4 l: Y: g6 ~7 D. g1 J
- 9 c) C8 b1 r& j K
- 2. Advanced state monitoring (Using the function I2C_GetLastEvent())6 |+ Q3 Q% N% }
- -------------------------------------------------------------------- : J/ J. q% X6 f% F
- Using the function I2C_GetLastEvent() which returns the image of both status
1 T# _+ |6 a, D3 Y - registers in a single word (uint32_t) (Status Register 2 value is shifted left
$ }0 f; M3 h. Q6 x - by 16 bits and concatenated to Status Register 1).9 u2 ?% p; W. n" U0 h) K6 u& \
! y$ p4 _4 E V! i* X- - When to use
% b1 [' n& z1 ?8 N1 x6 ?7 s) z - - This function is suitable for the same applications above but it - j1 t8 F# a7 M: V$ k" B6 C
- allows to overcome the mentioned limitation of I2C_GetFlagStatus() ' j5 [( U* V" f* t5 ]- b
- function.0 V: Z% X5 {# z4 L% v F; R* N
- - The returned value could be compared to events already defined in
: d8 r3 O7 O0 C - this file or to custom values defined by user.! ^4 d5 y1 ?5 S: y* V( q
- This function is suitable when multiple flags are monitored at the
9 ^7 f5 R8 h+ U4 {5 W - same time.
, v7 M, y7 o! b' g' q - - At the opposite of I2C_CheckEvent() function, this function allows
9 f- ~) w* w7 D6 Q% G1 o: R4 w - user to choose when an event is accepted (when all events flags are 3 Q, @/ i) n# ?
- set and no other flags are set or just when the needed flags are set - i: C t a: @9 }7 Z- c
- like I2C_CheckEvent() function.
& d7 C6 a* A$ s4 p
% y( o( U7 `# R4 j) L! G- - Limitations/ p, M* ^- c& L; a2 g( \
- - User may need to define his own events.' }7 n8 E$ @0 ]
- - Same remark concerning the error management is applicable for this ! T, v) K( X2 P) S; t% l( P6 a7 {- J
- function if user decides to check only regular communication flags + \ [& P; q5 n) D# x
- (and ignores error flags).
' G, T6 @+ j( ]8 f3 B6 S2 V
+ H! c; p k% h" m7 ^1 p: n/ S
! p2 [( p# G$ ?' |: K- 3. Flag-based state monitoring (Using the function I2C_GetFlagStatus())5 \" A2 w A+ B5 p, ^) I' v: A8 }6 I
- -----------------------------------------------------------------------
R& }# t! F" K* `, F+ c( k - * O( f3 A7 c+ }( f0 d ~
- Using the function I2C_GetFlagStatus() which simply returns the status of
, n5 f$ m2 j. B2 P - one single flag (ie. I2C_FLAG_RXNE ...). . }$ i1 E7 [5 G+ ?+ [$ B2 s! @4 V
* D. d$ G; Y* @ k) @5 _3 C- - When to use: m+ I& o, b, W) z7 `
- - This function could be used for specific applications or in debug
; R+ S6 G# I: r - phase.
6 [0 t4 d$ C. V# ? - - It is suitable when only one flag checking is needed (most I2C " [" A; ]& z0 E) I2 Z
- events are monitored through multiple flags).
9 R0 H+ W3 o0 g, F) n# v - - Limitations: + A! M: m2 B6 _& P0 Q; Y# Y
- - When calling this function, the Status register is accessed.
: Y/ q- K; { ~7 K- a v - Some flags are cleared when the status register is accessed. ( x/ W n: K M) J+ r! {! x
- So checking the status of one Flag, may clear other ones.) h7 @6 o V( T/ C: u1 `
- - Function may need to be called twice or more in order to monitor ; T9 u8 i) E A) [4 B: A& R X
- one single event. ) X3 E3 F6 u3 h3 T
- */3 o: V( Z5 U% J, [# p9 G2 f- x
$ `4 z0 [# M/ t- j; W7 B* G0 A! U- /*8 \; |) n w; `$ s- J7 E; A& c4 d
- ===============================================================================
3 K3 ~: W! s# M& w2 q - 1. Basic state monitoring
* C1 h7 Q2 x0 M# H3 l: ^6 n! V# Q% e9 P - ===============================================================================" p- i" t! i, k( V
- */
, Y1 l* S8 Z# _, q - ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT);% {, i' H6 Q! R+ l
- /*
. s" V, B, C) E: [9 [ - ===============================================================================; _4 p8 n7 M% {0 z* ?5 G
- 2. Advanced state monitoring( ~6 b H# p* x b7 Q
- ===============================================================================9 Y/ H/ F5 s$ Q% B
- */
1 _' D. C6 a* C2 t( l - uint32_t I2C_GetLastEvent(I2C_TypeDef* I2Cx);
8 N+ l& Z/ I3 G O3 X' ^ - /*: U" E6 h6 P# W) l+ j; \6 a
- ===============================================================================4 J% A4 b& w4 @. L5 J
- 3. Flag-based state monitoring) E; @8 K, W: u( i$ v9 X& L# \, t
- ===============================================================================
+ r- h, Z! Q: P$ e* v - */
, P5 S7 C1 }5 } s - FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG);* K5 C: d# q, A
! ~3 ?5 K' g6 B% j( W- , B9 X% h. A( T! M1 j0 y: N
- void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG);
$ k1 N" b7 R1 G" m" a - ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT);
4 _, w; B/ w" O1 O8 S$ A - void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT);
复制代码 A* J2 O7 N# t4 J8 x- U
04. 结构体封装
( f. P1 L$ M2 D0 U$ W0 J+ f- /**
* L; g% v0 a6 {1 f: {: x- m - * @brief Inter-integrated Circuit Interface
( a) X! ~" a7 K) x( I( `* Q/ r - */
8 @2 U& x; e0 g. m, _
: _( u2 o) M! `2 C& s- typedef struct1 ]$ d8 P. }, L: t; M. k; I
- {7 i% v& i# i5 @) U- I8 K* \
- __IO uint16_t CR1; /*!< I2C Control register 1, Address offset: 0x00 */
% ]! H& C+ M1 S5 ~( s - uint16_t RESERVED0; /*!< Reserved, 0x02 */
% \$ R- B# [) c# o# S8 i1 B - __IO uint16_t CR2; /*!< I2C Control register 2, Address offset: 0x04 */& s2 S) x" |( @1 }
- uint16_t RESERVED1; /*!< Reserved, 0x06 */
; N* G z- ]& l! e$ j - __IO uint16_t OAR1; /*!< I2C Own address register 1, Address offset: 0x08 */
: s0 P! r! q: j c: o1 @( d - uint16_t RESERVED2; /*!< Reserved, 0x0A */- D) `6 g; M B
- __IO uint16_t OAR2; /*!< I2C Own address register 2, Address offset: 0x0C */# I* F2 o& p0 G9 [$ Z5 F
- uint16_t RESERVED3; /*!< Reserved, 0x0E */
/ I* q4 B& o1 o- N5 ^+ O - __IO uint16_t DR; /*!< I2C Data register, Address offset: 0x10 */2 E' B D4 x5 i# F4 N% [5 m+ p
- uint16_t RESERVED4; /*!< Reserved, 0x12 */
1 z: P: }; w5 Y# h p. O0 Z: K- ] - __IO uint16_t SR1; /*!< I2C Status register 1, Address offset: 0x14 */! [* X3 J2 z( J3 p7 A
- uint16_t RESERVED5; /*!< Reserved, 0x16 */# d) f n6 D9 w
- __IO uint16_t SR2; /*!< I2C Status register 2, Address offset: 0x18 */8 w0 f5 c& l7 w2 ]: W3 v# q
- uint16_t RESERVED6; /*!< Reserved, 0x1A */
/ Y" R; `$ O' c9 K" p3 J; J - __IO uint16_t CCR; /*!< I2C Clock control register, Address offset: 0x1C */
' h3 m! o0 a3 ^$ n& I6 T$ e7 C - uint16_t RESERVED7; /*!< Reserved, 0x1E */
$ Y0 j5 A. R' U0 R/ o4 ? - __IO uint16_t TRISE; /*!< I2C TRISE register, Address offset: 0x20 */
; y! s( r) J5 p8 a- r8 d) c - uint16_t RESERVED8; /*!< Reserved, 0x22 */
% o& S9 S0 q+ q& q) N; } - __IO uint16_t FLTR; /*!< I2C FLTR register, Address offset: 0x24 */
% ?+ a4 T6 G; {3 g. }0 M - uint16_t RESERVED9; /*!< Reserved, 0x26 */
& C/ A( Z& W% S; r2 ~2 [; c+ S$ C! ` - } I2C_TypeDef;
复制代码 " Y1 N3 G& A, e
# Z+ g# i$ a- M
" M. T% T9 w$ i5 o9 C4 ~, H: Z! A. i, t& d
|