|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
F282xx/F283xx自身带有I2C模块,但受限于TI的官方例程中使用了fifo,其深度为4,在写EEPROM时,读写地址16位,占了2个字节,最多只留下2个字节存储数据,使用很不方便、实用性也极差。有不少网友在这一块碰壁,甚至逼的没办法使用IO口模拟I2C,放弃使用I2C模块。最近一直在测试28027的I2C模块有所获,可突破发送/接收长度限制(非fifo模式,当然这个长度也要和I2C器件匹)。本查介绍查询方式下的I2C模块使。. G2 Y. L2 C( }( Z9 b
1、宏定义I2C模块操作参数# |$ ^/ n0 h2 q4 w, s
#define I2C_SLAVE_ADDR 0x50 //器件地址不含读写位。以24Cxx系列为例,器件地址应为:(0xA0>>1),即0x50* D* Q( b; k- ^/ G: K. ^
#define I2C_NUMBYTES 10 //发送/接收数据长度
" W2 u$ \' M; m) n8 E% d4 T#define I2C_EEPROM_HIGH_ADDR 0x00
# I$ K$ j/ D: C& ^' h#define I2C_EEPROM_LOW_ADDR 0x00
# a$ {/ ?5 a1 R$ g. t2 |, M, L# t' b' W3 G
2、设置相应GPIO引脚用作I2C引脚。 修改F2802x_I2C.c文件中的void InitI2CGpio()函数。
2 q2 U& s" C9 X9 {4 X3、初始化I2C模块。
# c6 [7 g8 I$ Z: Jvoid I2CA_Init(void)
5 n# Q- n; |9 n' Q: h6 a; d: g8 x7 w{- d8 z5 r) E7 f1 W8 ~6 g
// Initialize I2C
' `( @0 j/ Z( z I2caRegs.I2CSAR = 0x0050; // Slave address - EEPROM control code
; o8 @- w, N$ o* y( f" p3 E+ {
- x2 N% g1 e9 v$ Z6 x& a5 j // I2CCLK = SYSCLK/(I2CPSC+1)7 P# p Q/ Q+ V
#if (CPU_FRQ_40MHZ||CPU_FRQ_50MHZ)
0 r: [1 B# x& { I2caRegs.I2CPSC.all = 4; // Prescaler - need 7-12 Mhz on module clk
$ Q1 |7 ^- w' D8 i, \ Q #endif: N: u; j+ @' h+ {4 z
! A6 c- I1 s7 z& s( h
#if (CPU_FRQ_60MHZ)
* S) I, j# U" F7 _+ p6 n I2caRegs.I2CPSC.all = 6; // Prescaler - need 7-12 Mhz on module clk
$ p; }3 I7 d% S3 E% h! x #endif* p+ O! ]) m3 J0 v1 O
I2caRegs.I2CCLKL = 10; // NOTE: must be non zero' `9 b# N$ x f% V5 I: c" B! F
I2caRegs.I2CCLKH = 5; // NOTE: must be non zero% ?0 j% q3 c* y d) S0 Z& S2 {
I2caRegs.I2CIER.all = 0x00; // Enable SCD & ARDY interrupts: g2 ^ u- q k: }
9 X& s- C$ c) K I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset
# U& Q) Y+ v; {; r' S5 {3 G, n // Stop I2C when suspended
- _9 A5 s' j: g/ i
! ?0 c3 ]8 R! X7 u! V6 p8 x1 I7 \ I2caRegs.I2CFFTX.all = 0x0000; // Enable FIFO mode and TXFIFO
6 K' k2 L4 {7 q' y4 {3 A3 ~% [ I2caRegs.I2CFFRX.all = 0x0000; // Enable RXFIFO, clear RXFFINT,
. N) J H! J, F& {% p4 z4 n1 z, U& n+ C2 t8 w! Y6 M- [
return;
2 G& U& A% J) o2 }9 j- s}
( L$ H) V; {, i$ b: o4、执行I2C模块接收或者发送。- u2 z3 w6 ^( F2 R2 _# I7 E" W
//I2C模块发送数据到I2C器件。. n% L1 y- c# ^) g
void I2CA_SendData(void)
$ @5 ?& `- w; G, C0 a{: A7 L( K. l+ k$ J4 x% e: L
Uint16 i;; ]: N1 T7 E) R% G8 j5 d
I2caRegs.I2CSAR = I2C_SLAVE_ADDR; //Set slave address
/ ?4 U& ?3 e& j" T$ r4 [ I2caRegs.I2CCNT = I2C_NUMBYTES + 2; //Set count to 5 characters plus 2 address bytes
- V+ i% A% H: O* B: n I2caRegs.I2CDXR = I2C_EEPROM_HIGH_ADDR; //Send eeprom high address; F. U( t1 e" v+ w" V0 E6 i+ i
I2caRegs.I2CMDR.bit.TRX = 1; //Set to Transmit mode
# C7 G" F) a" E- {/ u( }8 _+ \+ @ I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode
( f) H8 V; F9 ] I2caRegs.I2CMDR.bit.FREE = 1; //Run in FREE mode: y9 }9 T/ ?7 E$ ]8 z3 g
I2caRegs.I2CMDR.bit.STP = 1; //Stop when internal counter becomes 0; K: a( @4 C9 O. e# |7 S7 q
I2caRegs.I2CMDR.bit.STT = 1; //Send the start bit, transmission will follow
- L& Z' z$ Y- i' n* B" o while(I2caRegs.I2CSTR.bit.XRDY == 0){}; //Do nothing till data is shifted out
9 L5 d5 H n9 b' u* Y6 D% V I2caRegs.I2CDXR = I2C_EEPROM_LOW_ADDR; //Send eeprom low address; q2 E/ ]! T6 _! U) ?+ X
4 j: j! V& ?- N- o4 k2 k) O* }: c for(i = 0; i < I2C_NUMBYTES; i++){+ e/ [! }- w' Y% ^$ Z+ u
while(I2caRegs.I2CSTR.bit.XRDY == 0){}; //Do nothing till data is shifted out, l, m: X/ [# S& m* \# n7 h1 y
I2caRegs.I2CDXR = TxdData; //Send out the message
; Y1 ^' m, d" ^: B }& l8 b0 F3 Z5 X
}. X, O( f% {: v8 I. X% z/ }; N
//I2C模块从I2C器件接收数据。
0 x! ?1 E1 A3 `/ Yvoid I2CA_ReceiveData(void)3 X. p, G$ t8 y5 ~9 b+ N2 A- J+ a0 X
{
" j- w. z: a. _+ M6 U. @( o Uint16 i;
3 X4 ^6 S. I7 ?" l- c I2caRegs.I2CSAR = I2C_SLAVE_ADDR; //Set slave address
$ W H7 v0 j2 p2 H" z0 b I2caRegs.I2CCNT = 2; //Set count to 2 address bytes( z( w- e! ~1 x5 d
I2caRegs.I2CDXR = I2C_EEPROM_HIGH_ADDR; //Send eeprom high address
' x2 K( }* f+ Y* M& B% i: |9 n; I7 o I2caRegs.I2CMDR.bit.TRX = 1; //Set to Transmit mode
0 Z$ [' c6 A! M$ t" ~ I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode6 F* Q7 ?& w1 [" A u8 p' n
I2caRegs.I2CMDR.bit.FREE = 1; //Run in FREE mode2 }1 q3 O4 j: [: h
I2caRegs.I2CMDR.bit.STP = 0; //Dont release the bus after Tx
8 [1 I" Y* R0 T I2caRegs.I2CMDR.bit.STT = 1; //Send the start bit, transmission will follow
8 b3 M( Y" E" g$ F1 L! T' d/ V
8 M5 U( M( g6 f/ m while(I2caRegs.I2CSTR.bit.XRDY == 0){}; //Do nothing till data is shifted out
9 I& D( c8 b3 j5 S7 I1 A, h I2caRegs.I2CDXR = I2C_EEPROM_LOW_ADDR; //Send eeprom low address
* n% R* j" h2 J0 b0 |, a I2caRegs.I2CCNT = I2C_NUMBYTES; //read 5 bytes from eeprom, z* i% i: I5 H7 o
I2caRegs.I2CMDR.bit.TRX = 0; //Set to Recieve mode
9 G, D2 j8 j: X* ^ I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode
: o/ E" |! L; u7 q8 V; `$ p! R I2caRegs.I2CMDR.bit.FREE = 1; //Run in FREE mode6 V: R- }9 C& W! @9 T
I2caRegs.I2CMDR.bit.STP = 1; //Stop when internal counter becomes 07 d: l& p) z+ q+ R1 @; Z: e* N; }
I2caRegs.I2CMDR.bit.STT = 1; //Repeated start, Reception will follow- m1 o4 R- j+ y
for(i = 0; i < I2C_NUMBYTES; i++){
& i3 r r) x) N+ z# ^- [8 g n while(I2caRegs.I2CSTR.bit.RRDY == 0){}; //I2CDRR not ready to read?
( g7 p4 P. \, ~6 {# N RxdData = I2caRegs.I2CDRR;
5 d# Z( ^5 M+ o' H }+ `7 h( L1 _6 S# Z& |. w
} |
|