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