|
EDA365欢迎您!
您需要 登录 才可以下载或查看,没有帐号?注册
x
F282xx/F283xx自身带有I2C模块,但受限于TI的官方例程中使用了fifo,其深度为4,在写EEPROM时,读写地址16位,占了2个字节,最多只留下2个字节存储数据,使用很不方便、实用性也极差。有不少网友在这一块碰壁,甚至逼的没办法使用IO口模拟I2C,放弃使用I2C模块。最近一直在测试28027的I2C模块有所获,可突破发送/接收长度限制(非fifo模式,当然这个长度也要和I2C器件匹)。本查介绍查询方式下的I2C模块使。
: B1 f- @$ a" {! |$ t7 ^1、宏定义I2C模块操作参数$ x( g1 _8 S8 z! i0 ^/ s
#define I2C_SLAVE_ADDR 0x50 //器件地址不含读写位。以24Cxx系列为例,器件地址应为:(0xA0>>1),即0x50; k) ?8 F: Z. C% G# a- ]: p
#define I2C_NUMBYTES 10 //发送/接收数据长度; S9 B9 [. d6 z* ?
#define I2C_EEPROM_HIGH_ADDR 0x00. y0 E4 \+ C n- r/ S6 T
#define I2C_EEPROM_LOW_ADDR 0x00
0 K. }9 v- O4 d
( u0 w) c/ d$ K2、设置相应GPIO引脚用作I2C引脚。 修改F2802x_I2C.c文件中的void InitI2CGpio()函数。9 b% q1 O2 ?, g5 |+ [( q$ R6 {2 I, _
3、初始化I2C模块。3 A; \' w6 }3 o% L
void I2CA_Init(void)
9 C1 Y* t. { Z8 I9 y{
4 g6 C4 D( }- E% X0 z! i // Initialize I2C; C- o' [- \) Q/ [+ P2 t
I2caRegs.I2CSAR = 0x0050; // Slave address - EEPROM control code
: P5 a5 W8 e% q2 ^- e8 H6 S& ?
// I2CCLK = SYSCLK/(I2CPSC+1)
2 q( G! x. H1 a% m/ Q% C$ ] #if (CPU_FRQ_40MHZ||CPU_FRQ_50MHZ)! a4 t" @( N, `* B9 t- \9 t
I2caRegs.I2CPSC.all = 4; // Prescaler - need 7-12 Mhz on module clk* N7 ?1 ^( K$ K$ h' q3 b
#endif- s2 k! |# y, ?1 N: \# \3 g
- U6 c$ w- s c) _8 `. h U #if (CPU_FRQ_60MHZ)" }, [# K3 \7 N
I2caRegs.I2CPSC.all = 6; // Prescaler - need 7-12 Mhz on module clk
! t1 p* j) e0 I0 n. G #endif
& R# m( [9 l4 k$ g! t I2caRegs.I2CCLKL = 10; // NOTE: must be non zero! |3 r I. ^+ |3 U# ]
I2caRegs.I2CCLKH = 5; // NOTE: must be non zero
# `3 u8 O( \: s; e I2caRegs.I2CIER.all = 0x00; // Enable SCD & ARDY interrupts
3 c! X, s7 E5 {* r" j) q- Q' |
7 h5 O% @) a6 ]& P1 h8 s! h6 _ I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset+ P2 @9 C5 U$ p S4 I* i
// Stop I2C when suspended
/ G8 K, @: ]; V
9 @: `* m) V: I5 V( _ I2caRegs.I2CFFTX.all = 0x0000; // Enable FIFO mode and TXFIFO, l# Y& ~& l1 z2 c4 W
I2caRegs.I2CFFRX.all = 0x0000; // Enable RXFIFO, clear RXFFINT,
/ u' n- m( D3 o$ S7 }2 k* u$ i* m; h, X1 _
return;
. b) }8 u3 H; W. R" b3 d}9 S( S' A' d8 m {$ I) z+ ^8 J
4、执行I2C模块接收或者发送。1 l2 e( }! v& z
//I2C模块发送数据到I2C器件。8 p: n z% f! |
void I2CA_SendData(void)
0 N# r$ ^1 ^! \7 h+ s{
3 Y8 t, J$ P; M Uint16 i;& N9 @! z6 r# P, A( n2 Q: n
I2caRegs.I2CSAR = I2C_SLAVE_ADDR; //Set slave address( ^& y& E7 e( J" s% }8 t" y9 D/ `
I2caRegs.I2CCNT = I2C_NUMBYTES + 2; //Set count to 5 characters plus 2 address bytes9 n) p6 c+ }$ X, K
I2caRegs.I2CDXR = I2C_EEPROM_HIGH_ADDR; //Send eeprom high address3 `5 ?% r) z! Y k5 T, a7 p
I2caRegs.I2CMDR.bit.TRX = 1; //Set to Transmit mode$ U; C6 Q4 n9 C$ @
I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode
' x% M: M( X u/ e) f* c$ j I2caRegs.I2CMDR.bit.FREE = 1; //Run in FREE mode6 x; F2 C* G5 G+ c
I2caRegs.I2CMDR.bit.STP = 1; //Stop when internal counter becomes 0( u3 [% K/ P) `) Q* k. ^: \. R9 |
I2caRegs.I2CMDR.bit.STT = 1; //Send the start bit, transmission will follow
& L2 U0 v0 ^' K1 M! X while(I2caRegs.I2CSTR.bit.XRDY == 0){}; //Do nothing till data is shifted out5 ~$ L7 I3 {/ j$ A! N
I2caRegs.I2CDXR = I2C_EEPROM_LOW_ADDR; //Send eeprom low address% I1 I. s) n m6 A
1 y, T4 K& J8 M, W/ U1 v for(i = 0; i < I2C_NUMBYTES; i++){$ l9 Q. \, A/ p# R8 \
while(I2caRegs.I2CSTR.bit.XRDY == 0){}; //Do nothing till data is shifted out
5 O3 v/ \6 v1 a I2caRegs.I2CDXR = TxdData; //Send out the message
$ U4 X7 k* ~8 T+ \ }2 t+ L: J9 l; ~; b
}! c3 s6 X" M T0 h0 _
//I2C模块从I2C器件接收数据。
, e. f- Y' Z. D4 e9 k) S( nvoid I2CA_ReceiveData(void), d3 w4 U, P- R# I
{
' X: n) c* n" ?6 U0 ]% _0 E! P4 ? Uint16 i;( L. y9 Q$ ?' v7 B5 j6 q
I2caRegs.I2CSAR = I2C_SLAVE_ADDR; //Set slave address
0 `, t3 e" s7 m6 r* B9 k8 | I2caRegs.I2CCNT = 2; //Set count to 2 address bytes; j3 |% j# z4 L6 u2 J* | ?) s4 P4 E
I2caRegs.I2CDXR = I2C_EEPROM_HIGH_ADDR; //Send eeprom high address
' B& L) C0 Y. H% B" D- g I2caRegs.I2CMDR.bit.TRX = 1; //Set to Transmit mode
: T8 }7 X' u, G: X; E I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode
/ ~" ~! T- c, f6 i: Q/ S* h I2caRegs.I2CMDR.bit.FREE = 1; //Run in FREE mode. G2 r$ f/ _+ B" f
I2caRegs.I2CMDR.bit.STP = 0; //Dont release the bus after Tx
) [4 Y: o) D9 u' Q+ E; x& B I2caRegs.I2CMDR.bit.STT = 1; //Send the start bit, transmission will follow
( e) B2 V) t/ K! m7 S: p7 p7 N! X* u" `4 e( D( S
while(I2caRegs.I2CSTR.bit.XRDY == 0){}; //Do nothing till data is shifted out5 w9 d3 S% |9 i$ g+ m
I2caRegs.I2CDXR = I2C_EEPROM_LOW_ADDR; //Send eeprom low address
" q( ]* _8 [) Y I2caRegs.I2CCNT = I2C_NUMBYTES; //read 5 bytes from eeprom
& G8 x: u, V+ j v I2caRegs.I2CMDR.bit.TRX = 0; //Set to Recieve mode
& i5 Q& \) [# @0 W I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode
, Y* p& l4 S4 O( }2 B) I I2caRegs.I2CMDR.bit.FREE = 1; //Run in FREE mode
/ \2 [/ H9 I: k. ?/ o, {4 J I2caRegs.I2CMDR.bit.STP = 1; //Stop when internal counter becomes 05 P. n. W" E- T$ d" Y
I2caRegs.I2CMDR.bit.STT = 1; //Repeated start, Reception will follow
, f: l+ ], k" K4 p3 P. e for(i = 0; i < I2C_NUMBYTES; i++){
. j) S9 P* \7 Y& ^ while(I2caRegs.I2CSTR.bit.RRDY == 0){}; //I2CDRR not ready to read?
4 r: q% J9 |- ^6 D( N RxdData = I2caRegs.I2CDRR;
' c$ f" H/ L% L0 f4 L5 ~! I }+ ?% f8 p, h( K; C5 v
} |
|