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