|
ARM裸机IIC例程中的疑惑(各位看官进来看看)
[复制链接]
关于ARM裸机IIC例程中的疑惑:
write数据函数中,为什么会有POLLACK模式?(此时所有数据已经发送完了,再来判断ACK)
望大神解惑!谢谢!!!
- /****************************************************************
- * ARMSYS S3C44B0X IIc At24Cxx TEST *
- ****************************************************************
-
- 1.2005.5.13:ZXJ: IIc AT24Cxx TEST
-
- ***************************************************************/
-
- #include <string.h>
- #include "..\Target\44b.h"
- #include "..\Target\44blib.h"
- #include "..\Target\def.h"
- #include "..\iictest\IIC.h"
- #define WRDATA (1)
- #define POLLACK (2)
- #define RDDATA (3)
- #define SETRDADDR (4)
- #define IICBUFSIZE 0x20
- U8 _iicData[IICBUFSIZE];
- volatile int _iicDataCount;
- volatile int _iicStatus;
- volatile int _iicMode; //I2C总线读写操作模式
- int _iicPt;
- void __irq IicInt(void);
- void Test_Iic(void)
- {
- unsigned int i,j,save_F,save_PF;
- static U8 data[256];
- Uart_Printf("[IIC Test using AT24Cxx]\n");
- rINTCON=0x5;
- rINTMOD=0x0;
- rINTMSK= BIT_GLOBAL;
- //rINTMSK=~(BIT_EINT0 | BIT_GLOBAL);
-
- save_F=rPCONF;
- save_PF=rPUPF;
- rPCONF |=0xa; //PF0:IICSCL, PF1:IICSDA
- rPUPF |=0x3; //pull-up disable
- pISR_IIC=(unsigned)IicInt;
- rINTMSK=~(BIT_GLOBAL|BIT_IIC);
-
- rIICCON=(1<<7)|(0<<6)|(1<<5)|(0xf);
- //Enable interrupt, IICCLK=MCLK/16, Enable ACK
- //40Mhz/16/(15+1) = 257Khz
- rIICADD=0x10; // S3C44B0X slave address
- rIICSTAT=0x10;
- Uart_Printf("Write test data into AT24LCxx\n");
- for(i=0;i<256;i++)
- Wr24LCxx(0xa0,(U8)i,i);
- for(i=0;i<256;i++)
- data[i]=0;
- Uart_Printf("Read test data from AT24LCxx\n");
- for(i=0;i<256;i++)
- Rd24LCxx(0xa0,(U8)i,&(data[i]));
- for(i=0;i<16;i++)
- {
- for(j=0;j<16;j++)
- Uart_Printf("%2x ",data[i*16+j]);
- Uart_Printf("\n");
- }
-
- rPCONF=save_F;
- rPUPF=save_PF;
- }
- void Wr24LCxx(U32 slvAddr,U32 addr,U8 data)
- {
- _iicMode=WRDATA;
- _iicPt=0;
- _iicData[0]=(U8)addr;
- _iicData[1]=data;
- _iicDataCount=2;
-
- rIICDS=slvAddr;//0xa0
- rIICSTAT=0xf0; //MasTx,Start
- //Clearing the pending bit isn't needed because the pending bit has been cleared.
- while(_iicDataCount!=-1); //等待数据发送完毕
- _iicMode=POLLACK;
- while(1)
- {
- rIICDS=slvAddr;
- _iicStatus=0x100;
- rIICSTAT=0xf0; //MasTx,Start
- rIICCON=0xaf; //resumes IIC operation.
- while(_iicStatus==0x100);
- if(!(_iicStatus&0x1)) //
- break; // when ACK is received
- }
- rIICSTAT=0xd0; //stop MasTx condition
- rIICCON=0xaf; //resumes IIC operation.
- Delay(1); //wait until stop condtion is in effect.
- //write is completed.
- }
-
- void Rd24LCxx(U32 slvAddr,U32 addr,U8 *data)
- {
- _iicMode=SETRDADDR;
- _iicPt=0;
- _iicData[0]=(U8)addr;
- _iicDataCount=1;
- rIICDS=slvAddr;
- rIICSTAT=0xf0; //MasTx,Start
- //Clearing the pending bit isn't needed because the pending bit has been cleared.
- while(_iicDataCount!=-1);
- _iicMode=RDDATA;
- _iicPt=0;
- _iicDataCount=1;
-
- rIICDS=slvAddr;
- rIICSTAT=0xb0; //MasRx,Start
- rIICCON=0xaf; //resumes IIC operation.
- while(_iicDataCount!=-1);
- *data=_iicData[1];
- }
- void __irq IicInt(void)
- {
- U32 iicSt,i;
- rI_ISPC=BIT_IIC;
- iicSt=rIICSTAT;
- if(iicSt&0x8){} // when bus arbitration is failed.
- if(iicSt&0x4){} // when a slave address is matched with IICADD
- if(iicSt&0x2){} // when a slave address is 0000000b
- if(iicSt&0x1){} // when ACK isn't received
- switch(_iicMode)
- {
- case POLLACK:
- _iicStatus=iicSt;
- break;
- case RDDATA:
- if((_iicDataCount--)==0)
- {
- _iicData[_iicPt++]=rIICDS;
-
- rIICSTAT=0x90; //stop MasRx condition
- rIICCON=0xaf; //resumes IIC operation.
- Delay(1); //wait until stop condtion is in effect.
- //too long time...
- //The pending bit will not be set after issuing stop condition.
- break;
- }
- _iicData[_iicPt++]=rIICDS;
- //The last data has to be read with no ack.
- if((_iicDataCount)==0)
- rIICCON=0x2f; //resumes IIC operation with NOACK.
- else
- rIICCON=0xaf; //resumes IIC operation with ACK
- break;
- case WRDATA:
- if((_iicDataCount--)==0)
- {
- rIICSTAT=0xd0; //stop MasTx condition
- rIICCON=0xaf; //resumes IIC operation.
- Delay(1); //wait until stop condtion is in effect.
- //The pending bit will not be set after issuing stop condition.
- break;
- }
- rIICDS=_iicData[_iicPt++]; //_iicData[0] has dummy.
- for(i=0;i<10;i++); //for setup time until rising edge of IICSCL
- rIICCON=0xaf; //resumes IIC operation.
- break;
- case SETRDADDR:
- //Uart_Printf("[S%d]",_iicDataCount);
- if((_iicDataCount--)==0)
- {
- break; //IIC operation is stopped because of IICCON[4]
- }
- rIICDS=_iicData[_iicPt++];
- for(i=0;i<10;i++); //for setup time until rising edge of IICSCL
- rIICCON=0xaf; //resumes IIC operation.
- break;
- default:
- break;
- }
- }
复制代码
|
|