|
EDA365欢迎您!
您需要 登录 才可以下载或查看,没有帐号?注册
x
F282xx/F283xx自身带有I2C模块,但受限于TI的官方例程中使用了fifo,其深度为4,在写EEPROM时,读写地址16位,占了2个字节,最多只留下2个字节存储数据,使用很不方便、实用性也极差。有不少网友在这一块碰壁,甚至逼的没办法使用IO口模拟I2C,放弃使用I2C模块。最近一直在测试28027的I2C模块有所获,可突破发送/接收长度限制(非fifo模式,当然这个长度也要和I2C器件匹)。本查介绍查询方式下的I2C模块使。
}( m: E2 h% y: ~+ _! O1、宏定义I2C模块操作参数
' N! V5 p0 v; u1 w6 |1 k#define I2C_SLAVE_ADDR 0x50 //器件地址不含读写位。以24Cxx系列为例,器件地址应为:(0xA0>>1),即0x50
3 k7 o W/ F1 X0 i: v#define I2C_NUMBYTES 10 //发送/接收数据长度
2 S# M* g% h' I7 i% ]0 I2 q& B#define I2C_EEPROM_HIGH_ADDR 0x00
8 h) D* s, P$ a6 K( \#define I2C_EEPROM_LOW_ADDR 0x00
' R/ Z6 s( w* N5 Z; C! ^/ o
2 b( {/ M. e% a: `2、设置相应GPIO引脚用作I2C引脚。 修改F2802x_I2C.c文件中的void InitI2CGpio()函数。- Y$ ?8 w7 s( a: N& {$ k
3、初始化I2C模块。- g/ [% r) t) }: e2 x
void I2CA_Init(void)* e+ o' b" ~1 O( Y* p6 A
{6 j4 |/ g, S& e& _$ p) y$ {5 D
// Initialize I2C
# }4 ]# T3 I) r' ~; Y1 Y* h I2caRegs.I2CSAR = 0x0050; // Slave address - EEPROM control code
$ X0 f: g k1 h/ f) e. s. L" A" p3 n& ]! F' m, Z
// I2CCLK = SYSCLK/(I2CPSC+1): Z5 k0 U2 u0 ?, u- W' v. ^# F/ I
#if (CPU_FRQ_40MHZ||CPU_FRQ_50MHZ)$ W* M- I8 L8 Y1 C. r$ M X
I2caRegs.I2CPSC.all = 4; // Prescaler - need 7-12 Mhz on module clk3 \& }" Y2 A: g& X! p5 q* J& f- R
#endif0 z1 J- O) I& _0 A& @! F! h
: q/ H6 E$ h2 d4 } a7 U/ L* `
#if (CPU_FRQ_60MHZ)$ \2 T0 g$ _' P
I2caRegs.I2CPSC.all = 6; // Prescaler - need 7-12 Mhz on module clk
$ i$ Y3 R/ r: j* O l* D9 t1 j' L #endif
3 b: ^* j/ ~0 W5 x" A- V I2caRegs.I2CCLKL = 10; // NOTE: must be non zero
- F& X8 T* ~4 D8 v5 R I2caRegs.I2CCLKH = 5; // NOTE: must be non zero2 p n$ O% f! c8 C' d
I2caRegs.I2CIER.all = 0x00; // Enable SCD & ARDY interrupts
z) e6 @/ u$ J4 e( j; ~' W! t! ^; Z1 w, y3 s! T
I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset" o7 M/ z! S2 T9 ]
// Stop I2C when suspended. U& |' x1 b9 r6 L6 D) _0 v# u; _
; f0 E; I% O1 s2 _: u5 B I2caRegs.I2CFFTX.all = 0x0000; // Enable FIFO mode and TXFIFO& G. H$ w# f- E; U( D& S
I2caRegs.I2CFFRX.all = 0x0000; // Enable RXFIFO, clear RXFFINT,, a4 Y; b9 t& B2 g
7 i0 j& Z$ a$ q* z9 l3 X# X
return;+ q9 W7 V" Y; \
}
4 M- d) O, B- h k, e$ Z' O4、执行I2C模块接收或者发送。
2 E- Z" S/ N: j+ Y/ f4 A//I2C模块发送数据到I2C器件。
! t! I% {: j+ |' Z: vvoid I2CA_SendData(void)
! Q# a) l$ w% G: z" B* \{, K6 ^5 O6 D4 {
Uint16 i;; o. t6 ^" O" v r4 d9 I7 \
I2caRegs.I2CSAR = I2C_SLAVE_ADDR; //Set slave address2 ?) O: P. q0 c* @5 p V2 H/ m
I2caRegs.I2CCNT = I2C_NUMBYTES + 2; //Set count to 5 characters plus 2 address bytes' f& I5 W( O8 @# z
I2caRegs.I2CDXR = I2C_EEPROM_HIGH_ADDR; //Send eeprom high address$ X# a& B& k+ D$ C
I2caRegs.I2CMDR.bit.TRX = 1; //Set to Transmit mode5 f# S: }6 F/ X7 z
I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode: H' ?4 I2 ~- A4 v
I2caRegs.I2CMDR.bit.FREE = 1; //Run in FREE mode
! u7 b$ R3 o8 a' {$ w I2caRegs.I2CMDR.bit.STP = 1; //Stop when internal counter becomes 0
8 J; s0 p G: m. j I2caRegs.I2CMDR.bit.STT = 1; //Send the start bit, transmission will follow- c% ^) M# i$ v& `* h
while(I2caRegs.I2CSTR.bit.XRDY == 0){}; //Do nothing till data is shifted out
/ n; I2 G4 m K6 h7 k I2caRegs.I2CDXR = I2C_EEPROM_LOW_ADDR; //Send eeprom low address% z8 V6 m. ^5 A; _
7 T- x7 H5 @1 N4 d& f j for(i = 0; i < I2C_NUMBYTES; i++){4 |# D, n0 J# J% m+ U, l
while(I2caRegs.I2CSTR.bit.XRDY == 0){}; //Do nothing till data is shifted out3 ]. j" v: j, I! T
I2caRegs.I2CDXR = TxdData; //Send out the message
" A. b9 o7 Q5 J+ @. O0 V. g }
, ~2 c2 M& N+ l% f6 k; l3 E}
' S+ F- v2 F+ m9 U//I2C模块从I2C器件接收数据。) ?/ {$ L. w! M O' r
void I2CA_ReceiveData(void)
4 K! l6 ~0 L$ z% M$ F0 I{! \; U; c, ^$ I; }
Uint16 i;6 A$ l x& x7 H$ o, T3 c2 }
I2caRegs.I2CSAR = I2C_SLAVE_ADDR; //Set slave address
! A" q: Z7 K% R3 M5 L I2caRegs.I2CCNT = 2; //Set count to 2 address bytes9 O# c Z! c& g$ d
I2caRegs.I2CDXR = I2C_EEPROM_HIGH_ADDR; //Send eeprom high address& q! X: l# L" v% q
I2caRegs.I2CMDR.bit.TRX = 1; //Set to Transmit mode
Z- h' F' R+ r3 J" j* ` I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode
* b$ U" ^1 [. K, t I2caRegs.I2CMDR.bit.FREE = 1; //Run in FREE mode$ s L+ v9 {7 ^$ V _" j$ P0 ]& D
I2caRegs.I2CMDR.bit.STP = 0; //Dont release the bus after Tx
* E$ N& W5 j& R2 Z3 A I2caRegs.I2CMDR.bit.STT = 1; //Send the start bit, transmission will follow
6 Y i' Z% G# Z+ X; j9 v( `
. V, x' e* N+ W) L% _% w$ G7 U while(I2caRegs.I2CSTR.bit.XRDY == 0){}; //Do nothing till data is shifted out$ L/ P( W6 m, p/ \
I2caRegs.I2CDXR = I2C_EEPROM_LOW_ADDR; //Send eeprom low address
1 y! C& U/ h5 F3 f! x5 b Q: [ Z4 ^& k I2caRegs.I2CCNT = I2C_NUMBYTES; //read 5 bytes from eeprom/ u/ w& S" O3 e
I2caRegs.I2CMDR.bit.TRX = 0; //Set to Recieve mode
4 x: m: v/ s6 f) ] I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode5 @# |8 i9 I8 |
I2caRegs.I2CMDR.bit.FREE = 1; //Run in FREE mode
f: h" F. @5 o5 _( b5 p5 t% [1 G' b I2caRegs.I2CMDR.bit.STP = 1; //Stop when internal counter becomes 0! u: H, C$ B5 w- s8 v; ~$ ^( S+ {" x% F
I2caRegs.I2CMDR.bit.STT = 1; //Repeated start, Reception will follow6 D) B' S, p1 i
for(i = 0; i < I2C_NUMBYTES; i++){. d# U' D( t3 w3 i7 R. H6 G; p
while(I2caRegs.I2CSTR.bit.RRDY == 0){}; //I2CDRR not ready to read?
" j* s7 O$ s, s$ `7 c! r+ } RxdData = I2caRegs.I2CDRR;2 f) G% I8 A* X
} L+ u0 w4 {# i3 B6 c; K
} |
|