24FJ64GA006的硬件I2C总是不对,是芯片BUG吗?芯片上面的印字为PIC24FJ64GA006 -I / PT 064932P,在MPLAB IDE中连接信息如下:
Target Device PIC24FJ64GA006 found, revision = Rev 0x3002
这个是PIC24FJ128GA010 Family Silicon Errata and Data Sheet Clarification
ERROR.jpg (41.12 KB)
2009-10-30 22:37
我用这款芯片的第一组I2C端口,外接了一片24FC512的EEPROM,我外接4M的晶体,I2CBRG设定为2,但是和EE的通信总是不对,使用MICROCHIP上面的例子程序也不行!这个芯片有点早,当时项目用24FJ64GA004了,申请了一直放着,所以是不是我这款有硬件BUG呢,不知道芯片版本如何看!请各位FAE帮助给看一下,谢谢啦。
我的程序如下:unsigned GetValue(void) //本函数的返回值:0,表示接收错误;1,表示接收正确
{
unsigned OK;
unsigned char j;
OK = false;
I2C1BRG = 0x02; //Fosc=4MHZ, Fcy=2MHZ, Fscl=100K
I2C1CON = 0xD200; //Enable I2C
I2Cdelay(30);
I2CIdle();
I2C1CONbits.PEN=1; //发送Stop位;
while(I2C1CONbits.PEN); //
I2Cdelay(30);
I2CIdle();
I2C1CONbits.SEN=1; //I2CStart
while(I2C1CONbits.SEN); //PIC24的特点就是:SEN人工置1=启动;自动清零=启动执行完毕
I2CIdle();
MasterWriteI2C1(0B10100001); //写器件地址(bit7~bit6:器件地址1010 000,bit0=0表示写,=1表示读)
I2CIdle();
if(I2C1STATbits.ACKSTAT)
goto STOPI2C; //如果cpu收到的是NACK,则直接发送I2CSTOP
I2CIdle();
MasterWriteI2C1(0x01); //选中内部地址 A15~A8
I2CIdle();
if(I2C1STATbits.ACKSTAT)
goto STOPI2C; //如果cpu收到的是NACK,则直接发送I2CSTOP
I2CIdle();
MasterWriteI2C1(0x01); //选中内部地址 A7~A0
I2CIdle();
if(I2C1STATbits.ACKSTAT)
goto STOPI2C; //如果cpu收到的是NACK,则直接发送I2CSTOP
for(j=0;j<15;j++)
{
I2C_RECV[j]=MasterReadI2C1();
if (j!=15)
{
I2C1CONbits.ACKDT = 0; //要发的应答信号是0(即ACK)
I2C1CONbits.ACKEN = 1; //要发的应答的使能信号
while(I2C1CONbits.ACKEN); //发送ACKDT数据位,主器件应答序列结束时由硬件清零
}
else
{
I2C1CONbits.ACKDT = 1; //要发的应答信号是0(即NO ACK)
I2C1CONbits.ACKEN = 1; //要发的应答的使能信号
while(I2C1CONbits.ACKEN); //发送ACKDT数据位,主器件应答序列结束时由硬件清零
OK = true;
STOPI2C:
I2Cdelay(30);
I2C1CONbits.PEN=1; //发送Stop位;
while(I2C1CONbits.PEN); //
}
}
I2C1CON = 0; //Disable I2C1
SETSDA = 1; //input status
SETSCL = 1;
return(OK);
}
//***********************************************
//daughter routines
//***********************************************
void I2CIdle(void)
{
while(I2C1CONbits.SEN||I2C1CONbits.PEN||I2C1CONbits.RSEN
||I2C1CONbits.RCEN||I2C1CONbits.ACKEN||I2C1STATbits.TRSTAT); //wait I2C idle
}
unsigned char MasterWriteI2C1(unsigned int Data_out)
{
I2C1TRN = Data_out; //所谓“OUT”,是说CPU输出(可不是说2304输出),TRN是transist的缩写
//I2C1TRN=发送缓冲器,存放数据
if(I2C1STATbits.IWCOL) /* If write collision occurs,return 0 */
return 0;
else
{
while(I2C1STATbits.TBF); //发送过程中,处于“忙”状态,发完后自动清零,不用我们操心
return 1;
}
}
unsigned int MasterReadI2C1(void) /*read data*/
{
I2Cdelay(3);
I2C1CONbits.RCEN = 1;
I2Cdelay(3);
while(!I2C1STATbits.RBF); //置1、清0均由硬件自动完成,1=已经接收完;0=没接收完,请等待
I2C1STAT&= 0xFFBF; //here , please use word operation to clr i2cov
//i2cov=1表示溢出(收到的旧数据尚未处理,新数据来了,)
return(I2C1RCV); //I2C1RCV=接收缓冲器,存放数据
}
void I2Cdelay(unsigned int Time)
{
unsigned int i,j;
for(i=0;i<=Time;i++)
{
asm("nop");
for(j=0;j<=570;j++) //1ms
{
asm("nop");
asm("nop");
}
}
} |