|
EDA365欢迎您!
您需要 登录 才可以下载或查看,没有帐号?注册
x
F282xx/F283xx自身带有I2C模块,但受限于TI的官方例程中使用了fifo,其深度为4,在写EEPROM时,读写地址16位,占了2个字节,最多只留下2个字节存储数据,使用很不方便、实用性也极差。有不少网友在这一块碰壁,甚至逼的没办法使用IO口模拟I2C,放弃使用I2C模块。最近一直在测试28027的I2C模块有所获,可突破发送/接收长度限制(非fifo模式,当然这个长度也要和I2C器件匹)。本查介绍查询方式下的I2C模块使。
" Q$ S( y6 F/ Z( I2 @9 g4 e1、宏定义I2C模块操作参数
! _5 J! U% I, O#define I2C_SLAVE_ADDR 0x50 //器件地址不含读写位。以24Cxx系列为例,器件地址应为:(0xA0>>1),即0x507 o+ W+ X8 ~/ j
#define I2C_NUMBYTES 10 //发送/接收数据长度
: k# Z- G6 W9 Q, L* T. b# X) u% Q#define I2C_EEPROM_HIGH_ADDR 0x00
4 j7 `! H( Y/ Y8 {" D3 ^+ u#define I2C_EEPROM_LOW_ADDR 0x005 j# _) ^/ r9 V$ a2 q5 Q/ d! a
4 g+ Y* E. y8 B! S2、设置相应GPIO引脚用作I2C引脚。 修改F2802x_I2C.c文件中的void InitI2CGpio()函数。! k! ^8 k3 S+ v/ |! t
3、初始化I2C模块。9 p- @7 B' E3 A0 l
void I2CA_Init(void)
+ ]! G( n3 s$ c{
- d, B- M6 A& _# E) ` // Initialize I2C
5 [7 @% F* `" m0 @& B I2caRegs.I2CSAR = 0x0050; // Slave address - EEPROM control code) Y8 u, D1 V7 V1 _5 V) _# @/ h
4 ?1 {9 X9 a8 E7 f6 i1 y6 j // I2CCLK = SYSCLK/(I2CPSC+1)( _# e8 N# ?# j3 w1 `
#if (CPU_FRQ_40MHZ||CPU_FRQ_50MHZ)% D5 O: d1 v- f s$ T
I2caRegs.I2CPSC.all = 4; // Prescaler - need 7-12 Mhz on module clk
- j; j% |3 h0 F- s& x4 S #endif
+ u; a% n4 S A& i: F9 {7 M8 f; G) T" R+ D5 Q* n% g0 _
#if (CPU_FRQ_60MHZ)
. q$ [8 F, Z* L I2caRegs.I2CPSC.all = 6; // Prescaler - need 7-12 Mhz on module clk4 _. ]& O$ a* H% K- g, y" u
#endif
/ O S0 o2 d0 H& o/ W6 V i I2caRegs.I2CCLKL = 10; // NOTE: must be non zero
}6 s1 J% E( l0 B! Z! O6 ? I2caRegs.I2CCLKH = 5; // NOTE: must be non zero- h7 U1 ^. L- n1 P8 P
I2caRegs.I2CIER.all = 0x00; // Enable SCD & ARDY interrupts
/ G" p+ B+ o1 P1 c" F
4 Z( L( c/ s3 }7 }2 v I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset
8 e6 S" A6 G4 F D/ g3 p" B // Stop I2C when suspended& Y& g) X6 W+ k* p/ g: E
7 X/ K5 N7 M4 f7 N1 K) o% y2 L- h I2caRegs.I2CFFTX.all = 0x0000; // Enable FIFO mode and TXFIFO+ m0 ]/ y) B- I' M2 R
I2caRegs.I2CFFRX.all = 0x0000; // Enable RXFIFO, clear RXFFINT,
6 t$ Y S9 o5 X7 z/ D8 C4 y+ a
- O* m6 f0 c- r return;6 o5 A! y) z2 q: l
}( P& d( D+ a" G8 R- l
4、执行I2C模块接收或者发送。
8 V6 P0 f: P% g//I2C模块发送数据到I2C器件。
, ]2 b- |9 Z& a& V% X! j2 nvoid I2CA_SendData(void)
- ~* n, {- V: O" I; z1 T( R{
& @! \, I+ c2 g. m Uint16 i;
! Z- Z% K, \) k- u( ?# u5 K' } I2caRegs.I2CSAR = I2C_SLAVE_ADDR; //Set slave address$ C Y, a( E6 z# }
I2caRegs.I2CCNT = I2C_NUMBYTES + 2; //Set count to 5 characters plus 2 address bytes5 P0 t! `/ d- t/ [$ y4 y1 L3 M$ u
I2caRegs.I2CDXR = I2C_EEPROM_HIGH_ADDR; //Send eeprom high address7 L, d x% A+ P' e0 C4 ~
I2caRegs.I2CMDR.bit.TRX = 1; //Set to Transmit mode9 X6 K2 i& e) i" o
I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode
3 j# D/ W* ^5 C: H% K# ?+ X* W6 d I2caRegs.I2CMDR.bit.FREE = 1; //Run in FREE mode5 c% J. j, q* X5 @; k! V* [" o& G+ V
I2caRegs.I2CMDR.bit.STP = 1; //Stop when internal counter becomes 0' E5 u- ?5 ^8 c/ W3 t# }
I2caRegs.I2CMDR.bit.STT = 1; //Send the start bit, transmission will follow4 c" k" c$ e3 Z6 @! q, _
while(I2caRegs.I2CSTR.bit.XRDY == 0){}; //Do nothing till data is shifted out: c" C" h" O+ K- |2 _8 u
I2caRegs.I2CDXR = I2C_EEPROM_LOW_ADDR; //Send eeprom low address' U- ]! ^/ ]' o9 Q3 V
L _6 i( `+ i2 s: d4 B for(i = 0; i < I2C_NUMBYTES; i++){
7 g7 B" F7 ?9 V) A& ?5 O while(I2caRegs.I2CSTR.bit.XRDY == 0){}; //Do nothing till data is shifted out1 b: b" K/ }3 T. \. D+ _
I2caRegs.I2CDXR = TxdData; //Send out the message
; C$ \' r% D' u3 ` a4 n }# `- L5 Y% ]- \4 B. x
}
5 }& [$ o8 f5 f0 v3 F) e//I2C模块从I2C器件接收数据。
`+ v, V, @- ], l/ Avoid I2CA_ReceiveData(void)9 t0 I# B/ L, u: G5 w+ N; Z
{
. X8 ^' D' [& w" C3 G* h Uint16 i;
8 ^* B2 M. T( |# o6 y I2caRegs.I2CSAR = I2C_SLAVE_ADDR; //Set slave address* b+ W. ]1 a" G' x' @# Z6 e
I2caRegs.I2CCNT = 2; //Set count to 2 address bytes
) M. T: o3 y$ M# l$ R0 C' N$ e2 o I2caRegs.I2CDXR = I2C_EEPROM_HIGH_ADDR; //Send eeprom high address
3 \+ W; v) p( o+ ] I2caRegs.I2CMDR.bit.TRX = 1; //Set to Transmit mode$ }$ O; R$ ^( O% c
I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode' P6 w" Y" ^' e; w I
I2caRegs.I2CMDR.bit.FREE = 1; //Run in FREE mode, l7 y& t1 z6 a
I2caRegs.I2CMDR.bit.STP = 0; //Dont release the bus after Tx
) ~ E/ p( r: k. [# A I2caRegs.I2CMDR.bit.STT = 1; //Send the start bit, transmission will follow
; Z% `6 N) y, }
# e0 g/ W9 Y1 r while(I2caRegs.I2CSTR.bit.XRDY == 0){}; //Do nothing till data is shifted out
: ?# G' s9 c: \9 _. Z% A2 j9 O I2caRegs.I2CDXR = I2C_EEPROM_LOW_ADDR; //Send eeprom low address9 \3 x$ G3 x9 ]
I2caRegs.I2CCNT = I2C_NUMBYTES; //read 5 bytes from eeprom
& p0 d, M8 m% [& a0 v I2caRegs.I2CMDR.bit.TRX = 0; //Set to Recieve mode
; I. b+ G/ ^4 I, A/ Q3 p I2caRegs.I2CMDR.bit.MST = 1; //Set to Master mode
/ k1 b, c4 G4 c: y* Z/ n! f# \) k I2caRegs.I2CMDR.bit.FREE = 1; //Run in FREE mode9 f% F0 d0 A2 b
I2caRegs.I2CMDR.bit.STP = 1; //Stop when internal counter becomes 0
, q- s; f v( D2 r0 X" {' a5 E I2caRegs.I2CMDR.bit.STT = 1; //Repeated start, Reception will follow/ h+ y+ C: ~* F* B# ?! e' H
for(i = 0; i < I2C_NUMBYTES; i++){
( p! X1 q8 d$ t1 e5 O* |" h while(I2caRegs.I2CSTR.bit.RRDY == 0){}; //I2CDRR not ready to read?
) v- s( ]# }+ A# b, l RxdData = I2caRegs.I2CDRR;2 {) E+ ^5 E2 B/ O4 f- B3 p
}# c0 J0 R& l; B, w) U
} |
|