EDA365电子工程师网

标题: I2C模块应用篇(查询法) [打印本页]

作者: wu68aq    时间: 2016-6-28 15:05
标题: I2C模块应用篇(查询法)
F282xx/F283xx自身带有I2C模块,但受限于TI的官方例程中使用了fifo,其深度为4,在写EEPROM时,读写地址16位,占了2个字节,最多只留下2个字节存储数据,使用很不方便、实用性也极差。有不少网友在这一块碰壁,甚至逼的没办法使用IO口模拟I2C,放弃使用I2C模块。最近一直在测试28027的I2C模块有所获,可突破发送/接收长度限制(非fifo模式,当然这个长度也要和I2C器件匹)。本查介绍查询方式下的I2C模块使。
, e9 @5 O! S  P6 u1、宏定义I2C模块操作参数
# ~4 b" `) \9 B/ O* Y" ^7 {% R#define I2C_SLAVE_ADDR        0x50    //器件地址不含读写位。以24Cxx系列为例,器件地址应为:(0xA0>>1),即0x50* V5 C2 n/ e# F2 K  A  d) h
#define I2C_NUMBYTES          10        //发送/接收数据长度
: `6 q9 Y- b  M& z0 T- h, B. Y#define I2C_EEPROM_HIGH_ADDR  0x00( ~/ D  N8 g, O0 b, [: n* {- E( E
#define I2C_EEPROM_LOW_ADDR   0x00$ T. K: l0 d) k2 }4 f2 L3 K
8 V; T' ~) C/ z* H8 r' O. s
2、设置相应GPIO引脚用作I2C引脚。 修改F2802x_I2C.c文件中的void InitI2CGpio()函数。, `0 n5 E6 n1 Q3 k, n9 m
3、初始化I2C模块。3 Y% M/ N9 {0 M( f' J
void I2CA_Init(void)
# R+ b" k( h7 l& |/ z+ R4 C4 z' x{
; ?5 g0 ^4 G' q   // Initialize I2C
7 ~9 Z% p/ o( _$ V0 }   I2caRegs.I2CSAR = 0x0050;        // Slave address - EEPROM control code
3 {$ J1 o$ n; c
' o* U4 Y4 x3 Y3 b2 e: V! q" ]: o   // I2CCLK = SYSCLK/(I2CPSC+1)% c1 P5 Z, G+ Y! c
   #if (CPU_FRQ_40MHZ||CPU_FRQ_50MHZ)0 K2 N4 }2 ?7 W& \: e- U
     I2caRegs.I2CPSC.all = 4;       // Prescaler - need 7-12 Mhz on module clk$ J6 u) z- @2 I" V% j4 R
   #endif
9 K$ |! K4 u2 v% ?
1 a3 v. u4 a4 d   #if (CPU_FRQ_60MHZ)3 a# g. N* s! P5 ^; ^6 R# |
     I2caRegs.I2CPSC.all = 6;       // Prescaler - need 7-12 Mhz on module clk
9 E* ]. E, }, p9 F   #endif4 \& y5 L% \! G4 m! ?
   I2caRegs.I2CCLKL = 10;           // NOTE: must be non zero
4 a  V; D$ B1 u! b+ M   I2caRegs.I2CCLKH = 5;            // NOTE: must be non zero
5 ~+ e$ g- ~3 ]0 \   I2caRegs.I2CIER.all = 0x00;      // Enable SCD & ARDY interrupts
2 ~6 {2 L! u1 I2 g7 r6 r
6 b3 `& q% C  K' J+ g  Q! j" W   I2caRegs.I2CMDR.all = 0x0020;    // Take I2C out of reset& D5 j4 I2 b, G
                                    // Stop I2C when suspended
. P- \$ S* {% B- D* h4 _0 l$ j& d" p9 d
   I2caRegs.I2CFFTX.all = 0x0000;   // Enable FIFO mode and TXFIFO; {' c0 |9 e0 B
   I2caRegs.I2CFFRX.all = 0x0000;   // Enable RXFIFO, clear RXFFINT,
9 T1 o- x( e9 F% `4 j2 H; G6 y7 p; Q8 L
   return;
, [5 H- R2 U5 C/ T3 u1 b}
7 |4 A$ n( d) Z' c4、执行I2C模块接收或者发送。
& L$ s$ e& x0 J//I2C模块发送数据到I2C器件。% B7 i. @9 ^3 p( W" c
void  I2CA_SendData(void)
- G& m. |7 S, I1 V% o' q{
2 Y' Q5 b2 {# T' Y6 }: [1 Q. Z* x# I           Uint16 i;
5 a# U3 k7 ]% E8 [6 t/ F4 ]& x4 u           I2caRegs.I2CSAR = I2C_SLAVE_ADDR;                         //Set slave address
# X( k6 z! m4 z/ W, z4 M           I2caRegs.I2CCNT = I2C_NUMBYTES + 2;                         //Set count to 5 characters plus 2 address bytes+ R; O) e! b& y( j
           I2caRegs.I2CDXR = I2C_EEPROM_HIGH_ADDR;                        //Send eeprom high address
# h) U" s: I: K4 h" h- O0 \0 u           I2caRegs.I2CMDR.bit.TRX = 1;                                 //Set to Transmit mode
( n9 a3 B0 V/ t* b7 ^           I2caRegs.I2CMDR.bit.MST = 1;                                 //Set to Master mode5 S# v2 Q7 k! V5 w( C  D4 D. \- c9 Q
           I2caRegs.I2CMDR.bit.FREE = 1;                                //Run in FREE mode3 V& U8 P0 W" D5 C: b5 S
           I2caRegs.I2CMDR.bit.STP = 1;                                 //Stop when internal counter becomes 0- s, |% R& O5 z8 t
           I2caRegs.I2CMDR.bit.STT = 1;                                 //Send the start bit, transmission will follow: F. ?+ F! o% N; u, a$ Y
           while(I2caRegs.I2CSTR.bit.XRDY == 0){};                 //Do nothing till data is shifted out
# T6 L' ?- i. W+ c! Z) ^  i1 U* R           I2caRegs.I2CDXR = I2C_EEPROM_LOW_ADDR;                          //Send eeprom low address8 }, u* U, P, w# P, J  h2 z

* i) J" N) ^! \3 x8 G9 T           for(i = 0; i < I2C_NUMBYTES; i++){
) r: E1 X8 h6 i( v                   while(I2caRegs.I2CSTR.bit.XRDY == 0){};         //Do nothing till data is shifted out. x) G- `, x3 u' Y
                   I2caRegs.I2CDXR = TxdData;                                         //Send out the message
! B' V8 l6 P, {, c           }+ ]3 r& ?8 j, c. x3 [5 M
}  e0 Z5 H+ A5 D# m- o. ?1 b0 `
//I2C模块从I2C器件接收数据。
; K; D7 e, Y1 Q' Cvoid  I2CA_ReceiveData(void)
% r1 Y: a/ @8 p8 |{! z6 p8 c/ a0 [" x7 i8 D
           Uint16 i;1 r% C4 P( G& J6 {* S( a
           I2caRegs.I2CSAR = I2C_SLAVE_ADDR;                         //Set slave address; g4 v" e& S- M2 Z
           I2caRegs.I2CCNT = 2;                                                 //Set count to 2 address bytes
0 A: I1 x' @- k; w           I2caRegs.I2CDXR = I2C_EEPROM_HIGH_ADDR;                        //Send eeprom high address; o& P  ?; j2 Q7 [0 A' G
           I2caRegs.I2CMDR.bit.TRX = 1;                                 //Set to Transmit mode
( b: t) O/ g* x6 d7 b2 T           I2caRegs.I2CMDR.bit.MST = 1;                                 //Set to Master mode! g1 _2 i, `3 w& h7 a1 r
           I2caRegs.I2CMDR.bit.FREE = 1;                                //Run in FREE mode. D5 p, m$ P* @  D4 L* H; s
           I2caRegs.I2CMDR.bit.STP = 0;                                 //Dont release the bus after Tx
3 a, t) P1 Z  U+ i           I2caRegs.I2CMDR.bit.STT = 1;                                 //Send the start bit, transmission will follow
1 N) h7 @2 J3 `9 y2 w% a2 s" j3 I1 ^, _: a& \; E
           while(I2caRegs.I2CSTR.bit.XRDY == 0){};                 //Do nothing till data is shifted out
2 r3 t# h3 b  y           I2caRegs.I2CDXR = I2C_EEPROM_LOW_ADDR;                         //Send eeprom low address
6 C5 n6 ]0 z. h           I2caRegs.I2CCNT = I2C_NUMBYTES;                                //read 5 bytes from eeprom; h' R  I1 f9 v) n+ M
           I2caRegs.I2CMDR.bit.TRX = 0;                                 //Set to Recieve mode
+ k3 P7 H5 C7 s! p5 |% F2 e6 b1 o  L           I2caRegs.I2CMDR.bit.MST = 1;                                 //Set to Master mode+ E  p; c, i2 a1 U. v' ~
           I2caRegs.I2CMDR.bit.FREE = 1;                                //Run in FREE mode
6 l& F; o; [8 H, H* }* c- U8 p8 A           I2caRegs.I2CMDR.bit.STP = 1;                                 //Stop when internal counter becomes 0
. G5 X7 I0 Q: q           I2caRegs.I2CMDR.bit.STT = 1; //Repeated start, Reception will follow
: f3 V2 {' a8 y! k2 _           for(i = 0; i < I2C_NUMBYTES; i++){
- B- w' x% u. J$ F. x  x6 F                   while(I2caRegs.I2CSTR.bit.RRDY == 0){};         //I2CDRR not ready to read?6 I# w! m2 ]$ Y2 c; X9 `" X2 X0 ?
                   RxdData = I2caRegs.I2CDRR;
1 v3 \% ~  P2 h$ B9 R. S           }
2 l3 E  E; F; ?6 `% C}
作者: Titianyeer    时间: 2016-6-29 10:11
学习中,谢谢分享5 H1 ^+ U6 z% j) u  ~





欢迎光临 EDA365电子工程师网 (https://bbs.elecnest.cn/) Powered by Discuz! X3.2