|
EDA365欢迎您!
您需要 登录 才可以下载或查看,没有帐号?注册
x
F282xx/F283xx自身带有I2C模块,但受限于TI的官方例程中使用了fifo,其深度为4,在写EEPROM时,读写地址16位,占了2个字节,最多只留下2个字节存储数据,使用很不方便、实用性也极差。有不少网友在这一块碰壁,甚至逼的没办法使用IO口模拟I2C,放弃使用I2C模块。最近一直在测试28027的I2C模块有所获,可突破发送/接收长度限制(非fifo模式,当然这个长度也要和I2C器件匹)。本查介绍查询方式下的I2C模块使。
3 Y# h0 ~$ v* J" K$ ? z1、宏定义I2C模块操作参数
1 U2 l# T7 c w# y8 O) K3 u8 K#define I2C_SLAVE_ADDR 0x50 //器件地址不含读写位。以24Cxx系列为例,器件地址应为:(0xA0>>1),即0x50
5 Y% F; u5 C$ R4 ?& k& F#define I2C_NUMBYTES 10 //发送/接收数据长度9 S8 v, m" I6 g
#define I2C_EEPROM_HIGH_ADDR 0x00: h8 M1 y/ \5 q( N& x+ j
#define I2C_EEPROM_LOW_ADDR 0x00
- T9 Q( q% M+ i# t' }0 r' x1 r4 K5 d; p) E) }& e4 Z
2、设置相应GPIO引脚用作I2C引脚。 修改F2802x_I2C.c文件中的void InitI2CGpio()函数。
, b$ X1 P' I/ Z/ ?! C' E3、初始化I2C模块。) O# g& H7 u/ D3 E/ v5 i% g
void I2CA_Init(void)
& F3 C& G% L7 T. M+ J; o{
) s+ Z; [4 S: \3 k // Initialize I2C5 S9 y3 S# X# W. }9 ~$ C+ y
I2caRegs.I2CSAR = 0x0050; // Slave address - EEPROM control code( _4 g, I$ q3 e: p$ Y3 e
5 z7 M# x8 O7 V$ y' E; L% i! }$ Q // I2CCLK = SYSCLK/(I2CPSC+1)/ P/ ^$ D5 D: e e; L$ M
#if (CPU_FRQ_40MHZ||CPU_FRQ_50MHZ)& |# R, |5 I7 F: b
I2caRegs.I2CPSC.all = 4; // Prescaler - need 7-12 Mhz on module clk$ y+ J2 n, k+ N5 B! j4 R7 e+ h
#endif
# f# l7 I2 a2 s
. l$ a4 w" T& B# w( Z7 b/ K( } #if (CPU_FRQ_60MHZ)( ~9 s9 B2 L( h: P( \& q3 W3 e8 a7 z
I2caRegs.I2CPSC.all = 6; // Prescaler - need 7-12 Mhz on module clk1 \8 t& U( O2 \* h
#endif
+ |) g! @/ U% V; U0 X, c b/ P I2caRegs.I2CCLKL = 10; // NOTE: must be non zero
- x4 {# t( D" ?3 c2 C6 I I2caRegs.I2CCLKH = 5; // NOTE: must be non zero. W7 E) R5 `( w3 Y
I2caRegs.I2CIER.all = 0x00; // Enable SCD & ARDY interrupts
- n }. Y, |! Z, w- K/ c
{5 q( A5 M R7 y! r I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset
) B) j* m; L/ {6 l // Stop I2C when suspended
! w+ o& O8 {' z( E, @$ f6 x& ^! q7 ~ K2 A l: K; z: t
I2caRegs.I2CFFTX.all = 0x0000; // Enable FIFO mode and TXFIFO
4 r0 x. c% @: c I2caRegs.I2CFFRX.all = 0x0000; // Enable RXFIFO, clear RXFFINT,
$ Y! h8 I5 d( p9 m
: k& \8 z. S2 H0 ^( Z* X7 B return;2 G. A% E% J+ a0 b1 ^; [" V
}
7 q! @, K$ H3 r. ^- w4、执行I2C模块接收或者发送。; P7 E1 r# T; k" `
//I2C模块发送数据到I2C器件。; L* v. }" q" y& Z; I7 H6 K* [
void I2CA_SendData(void)
8 c D, F% z0 z{
3 L. B D. F; i% a* }3 Q( ~ Uint16 i;
9 e4 J8 V* l+ Y6 s: O ~4 G I2caRegs.I2CSAR = I2C_SLAVE_ADDR; //Set slave address" M1 t( T& x# J7 `% X! n
I2caRegs.I2CCNT = I2C_NUMBYTES + 2; //Set count to 5 characters plus 2 address bytes, H; k+ U' s4 |3 `9 H9 w. s
I2caRegs.I2CDXR = I2C_EEPROM_HIGH_ADDR; //Send eeprom high address/ a5 Y$ a3 A3 ~% k& d n
I2caRegs.I2CMDR.bit.TRX = 1; //Set to Transmit mode
# P. e1 w. x1 W" i I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode
+ J; e3 m0 B- x T* J3 }2 \4 h I2caRegs.I2CMDR.bit.FREE = 1; //Run in FREE mode8 r' H6 i# P$ p; @6 v3 N9 }
I2caRegs.I2CMDR.bit.STP = 1; //Stop when internal counter becomes 0
% u7 }! N' M+ ]* w/ P6 j( { I2caRegs.I2CMDR.bit.STT = 1; //Send the start bit, transmission will follow
& Q# `" Z* j8 @% z: f; w# c while(I2caRegs.I2CSTR.bit.XRDY == 0){}; //Do nothing till data is shifted out
- Z# g8 F$ ?7 q1 z I2caRegs.I2CDXR = I2C_EEPROM_LOW_ADDR; //Send eeprom low address
+ O' f1 ?1 _7 m! o
+ d$ s% k: ^+ t3 o* e/ I for(i = 0; i < I2C_NUMBYTES; i++){/ @8 h7 A6 i# u6 ~
while(I2caRegs.I2CSTR.bit.XRDY == 0){}; //Do nothing till data is shifted out
( M) p. |& j6 k4 A8 D+ {9 z- u I2caRegs.I2CDXR = TxdData; //Send out the message
/ Y# g: }4 u/ ^. e: p. [# S0 v }2 V P) C- m5 R
}
- }5 C, T$ m$ R3 v. \$ C//I2C模块从I2C器件接收数据。0 i( U6 l: ^2 r' `8 C* d
void I2CA_ReceiveData(void)
* h! M/ z( V2 Q* ^7 ~3 |# W{
# m" o( H" _" _2 q$ U Uint16 i;' z! a M' j4 u) l: _ D. L& A# Y. r2 z
I2caRegs.I2CSAR = I2C_SLAVE_ADDR; //Set slave address9 @. V& n/ M: @( e
I2caRegs.I2CCNT = 2; //Set count to 2 address bytes! Q+ j$ }, y$ Q& F8 t; ~6 `
I2caRegs.I2CDXR = I2C_EEPROM_HIGH_ADDR; //Send eeprom high address
) O6 z/ }8 f1 y I2caRegs.I2CMDR.bit.TRX = 1; //Set to Transmit mode
7 J- Q1 `" Q; D" F' n o7 U- y B% Z0 s I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode/ u6 M2 c+ [7 {7 S$ b
I2caRegs.I2CMDR.bit.FREE = 1; //Run in FREE mode
# w5 R( m& |- a; [. K I2caRegs.I2CMDR.bit.STP = 0; //Dont release the bus after Tx$ r; r3 x0 g4 ^% d# M' ]
I2caRegs.I2CMDR.bit.STT = 1; //Send the start bit, transmission will follow9 O8 I& H2 R. E% c8 ?
8 C& e9 u2 i6 _" _- X while(I2caRegs.I2CSTR.bit.XRDY == 0){}; //Do nothing till data is shifted out
+ `( R7 H; w7 g" E8 y( v$ c I2caRegs.I2CDXR = I2C_EEPROM_LOW_ADDR; //Send eeprom low address
, {! I8 t5 G' S- b) Y3 B# [1 i. z I2caRegs.I2CCNT = I2C_NUMBYTES; //read 5 bytes from eeprom3 U- |4 V" y( k! V) h2 \! H
I2caRegs.I2CMDR.bit.TRX = 0; //Set to Recieve mode2 p/ b7 R+ \% X& f$ g$ ]
I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode# N e8 l7 Z0 _7 l% ] k& H1 s" \8 s
I2caRegs.I2CMDR.bit.FREE = 1; //Run in FREE mode0 i6 x' X+ J1 y! k# _+ }
I2caRegs.I2CMDR.bit.STP = 1; //Stop when internal counter becomes 04 H; Q/ O: i4 N( r$ k; C( R
I2caRegs.I2CMDR.bit.STT = 1; //Repeated start, Reception will follow
4 r) N5 \5 j0 s' U, p for(i = 0; i < I2C_NUMBYTES; i++){
: u- L3 K6 i5 Z, s: k2 O while(I2caRegs.I2CSTR.bit.RRDY == 0){}; //I2CDRR not ready to read?
8 B; P+ Z# l% Y7 z7 ]) T RxdData = I2caRegs.I2CDRR;
3 K- n3 `9 L6 E }' e+ C N ? }$ H# X. x) _$ I2 v7 P. |
} |
|