|
在做公司项目的时候,需要用到陀螺仪、加速度、地磁三类传感器,可以知道这三个传感器可以通过IIC总线的方式进行访问,但是中间总是出现各种问题,特别是无法初始化后无法进行启动总线的动作,卡死在查询语句中,经过不断的测试与摸索,终于在网上受到了启发; 下面是我写的一个示例,注意goto语句的用法。 库文件 - <p class="MsoNormal"><span lang="EN-US">#ifndef __HW_IIC_H</span></p>
/ i/ G0 V4 @, w5 G% |) L0 z - * r( _, m8 V$ i; U
- <p class="MsoNormal"><span lang="EN-US">#define __HW_IIC_H</span></p>% A, e% \$ p q
( E$ P. [* g+ h$ a2 X- <p class="MsoNormal"><span lang="EN-US"> </span></p>5 y0 E! ^% @, ?, T9 }
6 ?1 r5 S4 `" h, W' U6 ]4 Y# Q- <p class="MsoNormal"><span lang="EN-US">#include "stm32f10x.h"</span></p>
. M0 R8 U [% m5 |0 I* m; f
$ ?8 D+ S4 J2 N j- <p class="MsoNormal"><span lang="EN-US"> </span></p>
- R3 @/ ]; I6 W, {4 ?1 p; r
2 z. m. v! U- K3 u/ L- <p class="MsoNormal"><span lang="EN-US">void I2C_Configuration(void);</span></p>
: F9 m) W% C1 V3 x - $ A0 v& }3 ?6 m3 u9 _3 F) r1 v
- <p class="MsoNormal"><span lang="EN-US"> </span></p>
4 @% d& S( d( A* ] - $ q4 s! K8 X5 y+ Q& ~ J/ b
- <p class="MsoNormal"><span lang="EN-US">uint8_t I2C_Read(I2C_TypeDef *I2Cx,uint8_t
: X q$ J; L4 I9 z' ^7 x - I2C_Addr,uint8_t addr,uint8_t *buf,uint16_t num);</span></p>
8 k( x2 D; O2 |3 _6 t' }
( H! R' e8 R3 \0 `/ z% g* @! i+ ]- <p class="MsoNormal"><span lang="EN-US">uint8_t I2C_Write(I2C_TypeDef *I2Cx,uint8_t9 D8 ^( v1 M3 ~5 D2 C
- I2C_Addr,uint8_t addr,uint8_t *buf,uint16_t num);</span></p>. {4 w& l5 c t$ W8 N& M% ]9 D
- ; \4 r# N: \8 l8 {; A; p
- <p class="MsoNormal"><span lang="EN-US">uint8_t I2C_WriteOneByte(I2C_TypeDef
- Z% w6 O6 H( j - *I2Cx,uint8_t I2C_Addr,uint8_t addr,uint8_t value);</span></p>" B3 [1 I" _( q. u8 }
- 5 {/ N5 v. u+ t6 @/ D
- <p class="MsoNormal"><span lang="EN-US"> </span></p>0 E0 W$ s8 U9 i; {- }6 [* e& N6 h
- 2 {/ j9 _8 S1 p4 X* K
- <p class="MsoNormal"><span lang="EN-US">#endif</span></p>
复制代码 源文件 - #include "hw_iic.h"
- {6 N' x5 W _2 s1 p - #include "stm32f10x_i2c.h"
8 O8 g/ [# b* A1 z - #include "stdio.h"
8 B7 O! B& `5 c' k' v. w v - #include "delay.h"
7 X' J. L1 _* U) O
2 E2 ]! y3 g4 i' S! d4 m
i& c. o1 X) I+ `/ F0 b- /*******************************************************************************1 R3 d G5 O: T# m! ]/ Q3 O
- * Function Name : I2C_Configuration$ d2 w5 j. p+ T. E1 ]5 m5 M& I
- * Description : : Q! ~0 J/ H' J( T: }
- * Input : None
. Y% \8 P j' s H5 o3 p$ i9 X - * Output : None5 \, ]. O" x: `
- * Return : None! j: g% ~$ M) U% D- W1 e# Y
- * Attention : None
' q" t- x3 g$ R - *******************************************************************************/
. W/ |, T8 z* r% l" \3 U5 h8 N9 o -
( E, j* B" ^5 d% c - void I2C_Configuration(void)- q! Q/ X/ g) U4 Z W6 V& \# Y' _
- {( Y5 z$ U% D4 h+ G8 B0 e- h
- I2C_InitTypeDef I2C_InitStructure;) |" B- |1 X( \6 v, r6 `0 I7 ]; e7 x
- GPIO_InitTypeDef GPIO_InitStructure; ) k: z5 y# a; J+ {$ T7 t/ Z* p- P# h
- 6 h1 W( I6 N% h6 Q
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
$ |! m9 r+ t3 t, K% \: x$ T - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO , ENABLE);$ _# O) }: A1 k3 l) {1 ^2 ]9 z' P6 M$ `
% u- C! x% O. D; {. T- /* Configure I2C1 pins: PB10->SCL and PB11->SDA */% \( a! R8 j4 \9 G( r0 N* y
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;9 M$ R* m% V3 Q2 X- V- H
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; v5 [9 q) L! n* n9 ?
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
v0 N7 F% Z5 O: q - GPIO_Init(GPIOB, &GPIO_InitStructure);
4 g+ t1 n. T* D, l) ~- G. A+ H -
6 P" D3 r' S* f) H" k+ O2 v8 X5 E - I2C_DeInit(I2C1);
/ ` X0 r' o% H B7 g - I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;2 _# }% v7 k$ F8 G3 q; G P
- I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;) `. i) i( `& s
- I2C_InitStructure.I2C_OwnAddress1 = 0x30;
+ M5 b( M. z, a, ^+ \$ k - I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
/ O- D, j$ n# J4 x - I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;) v2 F& r$ w }" ^$ Q3 _
- I2C_InitStructure.I2C_ClockSpeed = 400000; //400K全速; u0 O& G& q/ x2 p
- 0 R7 S' l$ d& A/ C! s( l( S
- I2C_Cmd(I2C1, ENABLE);4 ?; ?* _/ x- _
- I2C_Init(I2C1, &I2C_InitStructure);3 j# L6 L7 Q( u- |8 x% F
; X7 R. V6 ~1 ]- I2C_AcknowledgeConfig(I2C1, ENABLE);
" N ?- L. A/ z6 Y. @. F - }
4 A; Z `1 Y- O# \) J
6 M, m* u4 M9 s' W0 Y
5 r& M$ ~: B5 U9 L, S3 g" O- /*******************************************************************************
( i3 c0 k# o- H+ w; m3 i - * Function Name : I2C_delay) ~8 Q, O' N$ S9 B: B
- * Description :
# y: H" O& U6 m5 y+ N - * Input : None
8 i$ o) L- ^5 x! K$ \. ]0 @5 I0 b2 F - * Output : None
* }$ W7 H. s' Z4 B - * Return : None5 U) |" w' U5 w
- * Attention : None
1 y% c6 |3 l- N7 v: U - *******************************************************************************/4 O# E$ d( w0 |4 @6 g9 S
- static void I2C_delay(uint16_t cnt)
( B1 ?0 k- q# E" R1 N$ t, O - {
+ m: d/ y' f6 n& p' Z, T - while(cnt--);
4 F( w8 T# B" m9 t8 i+ U& W7 P - }
$ T7 {4 ?( b& b4 X* E. s - : I. z+ P3 K6 ]( } f5 g) w
- /*******************************************************************************
* W* z/ ?" v( z; x7 C; B - * Function Name : I2C_AcknowledgePolling; S/ O8 H% E4 W
- * Description :
0 p' S2 n; k2 A1 M5 M+ ? - * Input : I2C_TypeDef * , uint8_t
( ^3 r6 v1 G& D2 `+ k6 _2 U' U - * Output : None& n' U; I5 S4 T& @6 e) i4 m
- * Return : None" e# `2 J2 l1 i6 n
- * Attention : None
2 V1 G$ a- T9 F5 S - *******************************************************************************/
; ^! B5 j; b/ F9 {; O& h& J& i - static void I2C_AcknowledgePolling(I2C_TypeDef *I2Cx,uint8_t I2C_Addr)& z# V: _5 l, M( R
- {
/ [* {. S1 S- U- X* ` - vu16 SR1_Tmp;
) b. v2 i1 I/ k) k$ M) M( @$ K( B0 u+ l - do+ t, ?' o: \' l; x, W6 G
- { , L3 @% a0 f- ] i
- I2C_GenerateSTART(I2Cx, ENABLE);! l3 t. f3 H- g6 u- w2 _: k
- 2 z% g/ E0 c) g4 d8 P
- SR1_Tmp = I2C_ReadRegister(I2Cx, I2C_Register_SR1);; c, i7 @" F3 t
- , j' X! ?# r1 }5 |3 Z
- //#ifdef AT24C01A. Q2 Y3 o* Y! I$ ]& o* t/ @2 I
0 A9 p- G) M) c- I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Transmitter);) j, a. u" ?: Q2 _$ }' i, `
- /*
# }) B7 A i7 ]+ w+ g# \3 r: `% h - #else8 h2 ]4 F. c( _. V6 F5 [! b
- $ [" i# @# T; P4 r6 O
- I2C_Send7bitAddress(I2Cx, 0, I2C_Direction_Transmitter);
. ?$ Q* ]9 ~" \, F$ M - #endif/ {6 e( ~2 Z5 ^3 U# }9 w
- */
* L/ m3 K ~( W9 Y/ \- v - }while(!(I2C_ReadRegister(I2Cx, I2C_Register_SR1) & 0x0002));
, m1 ?% Q& ~* [! ~& h2 _6 V9 W - $ L: L5 C# b1 @2 ~! P1 }8 M
- I2C_ClearFlag(I2Cx, I2C_FLAG_AF);4 v8 D' `9 O8 Q7 e# {! n
- 3 `, s5 j" ^) x! J) k O
- I2C_GenerateSTOP(I2Cx, ENABLE);
+ S3 R8 n: C! {1 a& ]* Z9 |4 D - } P# U3 N' I& J
; J W B: ~$ c+ A) f- " i N. d: Z' J2 f
- /*******************************************************************************
! m0 `3 ^3 u' J0 F. n& t - * Function Name : I2C_Read
l! [& e2 O u8 v" k - * Description :
1 A$ V: \2 M. F- R: k - * Input :
+ p! ^6 z4 [: D% q, K ?* v - * Output : . E! Z, @$ w, V" V
- * Return : * m% t- v/ M D
- * Attention : None# I) F) [5 M& N, }9 ?4 l! x
- *******************************************************************************/
' N* |! h5 p/ e - uint8_t I2C_Read(I2C_TypeDef *I2Cx,uint8_t I2C_Addr,uint8_t addr,uint8_t *buf,uint16_t num)0 H5 a+ n) N) g
- {- W2 v" | M; @5 L8 Q
- if(num==0)
& i5 p( n# k) Q8 R0 \ - return 1;
' F* }, e" O' L5 R% u2 ~ -
- d5 h; H" \" O) b, Y - while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));
8 L+ w4 Q5 b$ l/ d - " Q5 |2 X$ t0 c3 f- R9 k: R
- I2C_AcknowledgeConfig(I2Cx, ENABLE);* a# k! X0 W2 W2 D4 t. l# o$ J( `
- 5 ~0 [) ^$ y$ I& @, z
# o2 `" }6 `( x* p8 J6 k: _4 F7 D- I2C_GenerateSTART(I2Cx, ENABLE);
: S$ w" u {* F" b2 T/ n6 s - while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));1 z' f5 e2 m, ]5 f$ H
: k' X. w& _! m0 X. X$ }7 K# n- //#ifdef AT24C01A : c+ w2 s9 W. _! c
- I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Transmitter);$ f! M. l) f: ^
- while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));% ^8 u6 m U* D0 O. T* u6 R
- ?" q# u0 n ?" G# J- V
- I2C_SendData(I2Cx, addr);# k' W. X* T, }4 i
- while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));; n' V d9 n# v' w ]: L
- # M0 n4 `( \8 h9 z
- I2C_GenerateSTART(I2Cx, ENABLE);
4 C* S8 J$ i2 C. T' x& G9 o - while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));" I6 X2 e2 f- o* z7 l" x
- $ F3 A' w9 W: {9 X) I
- I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Receiver);3 ]# m# l A) c1 d3 h6 Q
- while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));4 E) S/ L" m8 q6 n4 `0 z
- /*
9 x: h! \7 n) H; f2 `3 o - #else " b2 N, @0 o/ Q# {& ?
- I2C_Send7bitAddress(I2Cx, addr<<1, I2C_Direction_Receiver);3 W0 Y8 p/ n! n
- while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
$ [" B( ~2 D; Y& d+ } - #endif/ i. }( H: N/ m1 e; a# ^, X7 _5 s
- */ 0 ? M- \/ ~" K4 g' l
- while (num)6 Y( m. p. h# i3 k: u9 d0 Q; X& i8 v
- {& k1 y; _ }2 {6 O. z. Y$ b! \% Y
- if(num==1)8 M9 V/ D3 \' [( {2 P
- {
8 l; s7 N f4 l5 h+ G! r$ k6 S. S0 k - I2C_AcknowledgeConfig(I2Cx, DISABLE);
/ }6 l0 H- l+ v3 [- w2 |" X! L' s - I2C_GenerateSTOP(I2Cx, ENABLE);
2 T$ e7 V( T F' M0 ]( L: C+ ] - }; S( S; _' v$ b
- ' s. G3 t8 t" K$ T3 F9 [3 Q
- while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)); /* EV7 */- f9 w' N+ H+ N/ D9 c7 H
- *buf = I2C_ReceiveData(I2Cx);6 [; V& h& P; _+ P# Z5 t* I
- buf++;
( N, Y3 }( [4 y! g x- g - /* Decrement the read bytes counter */. t1 ~) @; o, `* P9 c1 O
- num--;
7 h! w* l2 o" f% } - }
0 N- x2 H) u5 g) t% } - " J( N* @% a; d( i* U% e
- I2C_AcknowledgeConfig(I2Cx, ENABLE);
( Z7 v5 l) n+ L
0 ?: m, z0 C# ?# u- return 0;
5 d- S, C2 r5 Z; \ - }
" M1 D! C, \1 O0 f& I4 ?$ Y5 w, G
% N1 X9 `" Y. g( S \6 {' b7 n- /*******************************************************************************
0 T$ y$ z4 I( Z6 M& \6 w1 I - * Function Name : I2C_WriteOneByte
. G& s1 q9 X; l( _. @# I - * Description :
4 F# y9 z+ x7 B- f8 I- t2 H0 c) L - * Input : 7 e$ Z2 C& T( `1 Z
- * Output : None7 k, @9 a) c# k8 V
- * Return : ! ]- G, K4 a0 @( f
- * Attention : None8 l! R5 r4 j( A, }4 N6 ~! |
- *******************************************************************************/7 Z7 Q% c1 a C, t& B, j
- uint8_t I2C_WriteOneByte(I2C_TypeDef *I2Cx,uint8_t I2C_Addr,uint8_t addr,uint8_t value)9 I& j* Y/ S6 b. L7 N- H5 e3 }% u
- {
& ]9 |; }+ P- s - int cnt = 0;# Y; _3 H' ]1 q
- MY_IIC_START_LABLE:" S4 W, B- r9 `$ h2 A
- I2C_GenerateSTART(I2Cx, ENABLE);$ A' T, t! S8 N
- cnt = 0;# P: K- H* _/ L% G
- while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
0 I% C, W5 ?' f; y" O( G+ e - {
' b9 h7 G' B* L5 E: u - delay_ms(10); //必须延时 否则很容易死机1 Z/ S% P. F$ [
- // printf("9XX");, K/ u& W2 ~1 a1 |
- 6 o2 A( ?7 G+ m! W! f, @
- if(cnt ++ > 10)
4 Z& w: ~$ j8 j - {
S- `3 F$ H6 D' S. L. d - cnt = 0;
$ W4 Q$ J b; [ - I2C_Configuration(); //重新进行初始化
" X# l+ f; h4 I7 n8 }; ~ - goto MY_IIC_START_LABLE; //跳到本函数的开头
$ } d1 S* r& I7 e" S& j% F - }+ r& V6 ]/ \( v b( V& w; @: q( h* T
- }
7 C4 Q B) i/ ], A1 a" Y1 F1 z -
: |# J+ J: r- n# H, W -
6 y! i# Y7 U9 M+ E; T9 O - //#ifdef AT24C01A
1 B5 j. s' Y2 t* E5 ~: U - I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Transmitter);
& D4 g9 B( \( B# }0 M9 X - while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
1 O9 e$ Q" `% s* Y: E5 L" {
L, h! W# C# _- I2C_SendData(I2Cx, addr);
" R9 ^# X! n% Y% Z& S2 ^5 j7 h1 @( k - while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));/ Q; u! f/ ~) w# ~4 c/ Y
- /*9 W* e0 |: w2 }( ~% v) l
- #else
" D9 t9 c0 i, ~6 X) @) H$ K - I2C_Send7bitAddress(I2Cx, addr<<1, I2C_Direction_Transmitter);" ?2 Q# K; L! u) L
- while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));% T# Y3 D' z- ^( y3 s
- #endif
3 G* V2 m9 n. h - */
9 u" r1 }( h( O, U - I2C_SendData(I2Cx, value);
, G3 h- x6 K; q! v( N* ?1 } - while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));( `% |1 d; Y, M
- ' @& }" M. W& ^1 K" D5 n' I7 V+ [
- I2C_GenerateSTOP(I2Cx, ENABLE);
. s0 v8 Y5 m2 j( B9 j - . a' L/ i7 A7 |$ I) k
- I2C_AcknowledgePolling(I2Cx,I2C_Addr);
0 |2 }0 @6 m# ^6 _
. Q( y" l6 m! Y- O- I2C_delay(1000);
* f" `, U" i" d( m2 @0 g
+ C3 c# m( f! o& @- return 0;4 r$ e7 s& x" y! ?( Q3 c0 [
- }
+ R" a, { L: K( D
8 P+ T+ h7 ?+ ?" l8 e
5 D: |' r, M3 O2 J1 |% ]) Q; ~- /*******************************************************************************
6 B5 l A* ?5 S: e4 B5 ] - * Function Name : I2C_Write
$ K7 J& |, v1 j% n - * Description : . O8 n" W( E* i4 V7 a3 ~! u: h% @( q- m
- * Input : 4 ?! ]: N: t5 U9 G# Y
- * Output : None
3 A2 Q2 }# L u) b' l" C - * Return :
/ F) x( j( }4 d: A4 p3 O% [ - * Attention : None2 g3 c; R; q* P- }2 E" [
- *******************************************************************************/ E n8 X6 u1 _7 m/ _ d
- uint8_t I2C_Write(I2C_TypeDef *I2Cx,uint8_t I2C_Addr,uint8_t addr,uint8_t *buf,uint16_t num)8 z, T. \: m" k
- {
* `. g$ Y+ I; M( Z" u4 ? - uint8_t err=0;
1 z; u: H" h3 f0 }, [2 } -
, v; N2 J% z: O! e( M - while(num--)8 z0 \9 H; e$ C" a* M" H5 Y
- { c. Z. r3 S- ?
- if(I2C_WriteOneByte(I2Cx, I2C_Addr,addr++,*buf++))1 [# X9 z5 k3 L
- {
) L7 S+ `" _' \; N4 y; V - err++; ^& N* o, z) V; ?4 x/ ^
- }
$ T& S1 r7 n* M1 C/ y1 ~' a - }
, n* q5 U" x S0 c } - if(err)
; `4 F, k8 u* M/ {- A' N* w - return 1;
) x- q- f8 C8 x! m x# C4 h - else
2 Z" G+ K4 Z& o8 U/ e - return 0;
0 L) G& E0 F% Z9 H9 T l/ v' Q - }
! \- N' Z7 a* y/ m6 j
复制代码 4 U7 u4 P$ f' ]3 Y5 H' Z: l
. C, a, Z5 H2 d* V! `8 h
|
你的程序建议最好通过严格的测试,其实理论上讲,在I2C中,使用这种延时是个最大的隐患,一旦cpu因温度、环境电磁干扰等你的程序就挂了。