|
EDA365欢迎您!
您需要 登录 才可以下载或查看,没有帐号?注册
x
F282xx/F283xx自身带有I2C模块,但受限于TI的官方例程中使用了fifo,其深度为4,在写EEPROM时,读写地址16位,占了2个字节,最多只留下2个字节存储数据,使用很不方便、实用性也极差。有不少网友在这一块碰壁,甚至逼的没办法使用IO口模拟I2C,放弃使用I2C模块。最近一直在测试28027的I2C模块有所获,可突破发送/接收长度限制(非fifo模式,当然这个长度也要和I2C器件匹)。本查介绍查询方式下的I2C模块使。+ g/ | N) ]- m+ M: B
1、宏定义I2C模块操作参数$ W0 e; c. }' n' T9 q! O0 s! ~3 G9 r
#define I2C_SLAVE_ADDR 0x50 //器件地址不含读写位。以24Cxx系列为例,器件地址应为:(0xA0>>1),即0x50
+ K3 r, l- `, e* x* i- u#define I2C_NUMBYTES 10 //发送/接收数据长度/ T1 h9 W# u% ^3 `8 k6 N; e
#define I2C_EEPROM_HIGH_ADDR 0x00, n9 S z( X/ T; z7 J# K
#define I2C_EEPROM_LOW_ADDR 0x00
4 Z8 Q0 o# ]- a) o# h6 G/ K4 {
0 N6 F# b- F9 v; n9 ^9 }2、设置相应GPIO引脚用作I2C引脚。 修改F2802x_I2C.c文件中的void InitI2CGpio()函数。
5 Q# C# h+ ~( s. B; f3、初始化I2C模块。% g* i, X5 w0 k. v
void I2CA_Init(void)
8 m+ @! W. T9 c{
0 `8 y5 L/ c! \5 f# J // Initialize I2C9 N/ u) N& ]! I8 y5 U. V+ x
I2caRegs.I2CSAR = 0x0050; // Slave address - EEPROM control code. L" g& } G# F' s) e. ^
$ S8 |% R( Y# ~, A
// I2CCLK = SYSCLK/(I2CPSC+1)+ x8 a6 P' s- A/ K: O: z
#if (CPU_FRQ_40MHZ||CPU_FRQ_50MHZ)1 ^7 H( }3 @# O- J$ v8 X& L
I2caRegs.I2CPSC.all = 4; // Prescaler - need 7-12 Mhz on module clk m: _& w. Y1 p& k: f' R
#endif
2 I3 j9 m; R- G# q+ [6 B0 v/ r: n% m( `# `' B3 F& N
#if (CPU_FRQ_60MHZ), N# c" Q7 [/ k/ {) r; w8 B
I2caRegs.I2CPSC.all = 6; // Prescaler - need 7-12 Mhz on module clk
' f- S a, Q' p+ k+ K #endif
! N' C* s1 h7 E; k$ A/ L" x I2caRegs.I2CCLKL = 10; // NOTE: must be non zero
3 K. l2 C" K# _/ c% v" y1 Z- y I2caRegs.I2CCLKH = 5; // NOTE: must be non zero7 m2 Y M+ O& r( N2 ]
I2caRegs.I2CIER.all = 0x00; // Enable SCD & ARDY interrupts- o! }$ b2 |; U% |9 k
( i, J3 ?) E5 O. l2 U; O% B I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset
6 x$ _3 a' C& w0 h# m+ h // Stop I2C when suspended
+ a$ J) I/ S* y' v, v1 F5 V; b! X9 L
I2caRegs.I2CFFTX.all = 0x0000; // Enable FIFO mode and TXFIFO
+ A. o, a8 N0 Y; k0 {: Q I2caRegs.I2CFFRX.all = 0x0000; // Enable RXFIFO, clear RXFFINT,
1 H! H* M) h3 ~9 s+ l$ f+ J% b, x6 S' M
return;) V: z- Q: L! o$ E( s& w
}
" y/ _( _* p/ l: E4、执行I2C模块接收或者发送。
# v, C. d2 [0 r+ ?! ~/ g//I2C模块发送数据到I2C器件。* ` x9 J h9 Q/ z# T3 B3 E" M6 D' [
void I2CA_SendData(void)9 O- W/ c- M, Z, C# J4 @
{. N; O: N8 o7 r$ n
Uint16 i;
7 P. D! K) k% V" v4 H) | I2caRegs.I2CSAR = I2C_SLAVE_ADDR; //Set slave address
o0 s, { I, g, c I2caRegs.I2CCNT = I2C_NUMBYTES + 2; //Set count to 5 characters plus 2 address bytes
4 b2 K( K4 a, P. d( O" b0 p/ ]. d I2caRegs.I2CDXR = I2C_EEPROM_HIGH_ADDR; //Send eeprom high address
+ ^* t% v- F) [ x. L+ ]7 O9 b I2caRegs.I2CMDR.bit.TRX = 1; //Set to Transmit mode; M" |- L0 u3 D" J5 A( `
I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode
0 |! \1 L" I6 U I2caRegs.I2CMDR.bit.FREE = 1; //Run in FREE mode5 Q( N6 Y5 S- o0 P3 [0 o
I2caRegs.I2CMDR.bit.STP = 1; //Stop when internal counter becomes 07 I/ w. D7 }0 [8 @) y4 R8 {
I2caRegs.I2CMDR.bit.STT = 1; //Send the start bit, transmission will follow
: \3 z! f+ O2 k+ o$ ]. u+ c# a while(I2caRegs.I2CSTR.bit.XRDY == 0){}; //Do nothing till data is shifted out5 m$ c J. ]" d& ?+ F" L
I2caRegs.I2CDXR = I2C_EEPROM_LOW_ADDR; //Send eeprom low address, ~6 E! J; `7 y3 j6 H
`/ @+ E5 _4 b for(i = 0; i < I2C_NUMBYTES; i++){
2 h( N( _% R$ i: I/ X- M) t while(I2caRegs.I2CSTR.bit.XRDY == 0){}; //Do nothing till data is shifted out( l! A4 ~/ @3 f1 r
I2caRegs.I2CDXR = TxdData; //Send out the message6 k2 e4 D3 V! A
}, r- g: Z) t4 a' W" L
}
4 C+ @3 r* U( V k//I2C模块从I2C器件接收数据。
' m; A1 D8 W6 _) J' ~void I2CA_ReceiveData(void)
4 R. S9 v/ A9 ~3 w {2 s) E% {{
0 m6 V' u2 h+ d0 S$ I; P- G Uint16 i;+ G ]8 Z. t; K; q" a
I2caRegs.I2CSAR = I2C_SLAVE_ADDR; //Set slave address9 p: J$ d. [6 o/ u( A! I t& ]% R
I2caRegs.I2CCNT = 2; //Set count to 2 address bytes
, ^: C }- T9 i! k8 T I2caRegs.I2CDXR = I2C_EEPROM_HIGH_ADDR; //Send eeprom high address
: k$ @& Y" X; {8 O I2caRegs.I2CMDR.bit.TRX = 1; //Set to Transmit mode
* F/ h K4 m5 j6 b& X( ]& H I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode0 d' p- i. M: ~, ?
I2caRegs.I2CMDR.bit.FREE = 1; //Run in FREE mode, B: G4 f ~: N2 _
I2caRegs.I2CMDR.bit.STP = 0; //Dont release the bus after Tx
2 t% p5 p& q0 j& h I2caRegs.I2CMDR.bit.STT = 1; //Send the start bit, transmission will follow( l: s1 ~9 b; R
& z7 Y0 Y3 c# `2 x while(I2caRegs.I2CSTR.bit.XRDY == 0){}; //Do nothing till data is shifted out( k) I% V5 K5 W. b ?4 M, F8 T
I2caRegs.I2CDXR = I2C_EEPROM_LOW_ADDR; //Send eeprom low address& |' }6 ]0 \7 q2 L. J- Y/ c
I2caRegs.I2CCNT = I2C_NUMBYTES; //read 5 bytes from eeprom% }2 {0 i( m% d' O' j" m
I2caRegs.I2CMDR.bit.TRX = 0; //Set to Recieve mode& N, C! t7 E& g4 b1 |( [% ^
I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode
2 T% E4 H( H5 k I2caRegs.I2CMDR.bit.FREE = 1; //Run in FREE mode' }5 T, H# _$ B" E
I2caRegs.I2CMDR.bit.STP = 1; //Stop when internal counter becomes 0& n) v; c8 K+ K+ ?$ W+ V
I2caRegs.I2CMDR.bit.STT = 1; //Repeated start, Reception will follow
/ `' E# ?6 m; o$ B6 f/ a$ } for(i = 0; i < I2C_NUMBYTES; i++){
% w% F1 e8 t/ ]- B/ f v- i while(I2caRegs.I2CSTR.bit.RRDY == 0){}; //I2CDRR not ready to read?
2 X# j" M6 W; ~, p$ w5 K3 D RxdData = I2caRegs.I2CDRR;% s: {8 c& f8 R- v
}) |6 \4 c# _) n! k
} |
|