我在使用 PIC24HJ256GP610A 上的 I2C 模块时遇到问题。我的代码(见下面的片段)在 PIC24HJ256GP610 [注意:不是 610A] 上运行得非常好。我正在使用 I2C 总线与 DS1374 RTCC 进行通信。但是在 610A 上,当尝试使用 I2C 向 RTCC 写入值时轮询 ACKSTAT 位时,它会卡住。此外,大多数情况下,通过 I2C 读取值时 RTCC 值不会增加(有时它确实会增加)。有任何想法吗?处理 I2C 模块的 610 和 610A 之间是否存在配置位/模式/设置差异?我试过换掉 RTCC 芯片,换掉处理器。所以,这里唯一的区别是 I2C 通信在 610 上工作,而不是在 610A 上。
610和610A有什么区别?610 是不再生产的过时部件,还是会继续生产?
在试验、探测信号和使用调试器单步执行时,我注意到了一些事情:
1)。I2C 时钟在即将发送的第 20 个位上无限期变高,如果我暂停调试器,它会在轮询 ACKSTAT 位时卡住。第一位似乎是起始位,然后是 9 个更多位,然后是另一个开始/停止位,然后是 9 个更多位,然后时钟线变为高电平。
2)。当时钟线卡住并使用监视窗口时,I2C1STATbits 寄存器中的值为 0x8008,这意味着从从设备接收到 NACK,并且最后检测到启动(或重复启动)位。
3)。我总是能够从 610 和 610A 的从设备 (RTCC) 中读取数据。然而,有时对于 610A,它的值不会增加,而是保持在某个整数值。我相信当我切断一切电源并重新编程一切时,RTCC 值会发生变化。有时它在读取值时保持不变,并且可能有 25% 的时间在读取值时实际发生变化。
4)。我无法使用 610A 通过 I2C 向 RTCC 写入任何内容。处理器在轮询 ACKSTAT 位时卡住了(我假设是因为它收到了来自 RTCC 的 NACK。)610 工作完美。
工具:MPLAB v8.86、C30 v3.31、ICD3
谢谢你,布拉德
//Write RTCC Register: This functions writes a Byte to the DS1374 RTCC
void Write_RTCC_Register(int Register, unsigned char Byte
{
unsigned int config2, config1;
/* Baud rate is set for 100 Khz */
config2 = 0x97;
/* Configure I2C for 7 bit address mode */
config1 = (I2C1_ON & I2C1_IDLE_CON & I2C1_CLK_HLD &
I2C1_IPMI_DIS & I2C1_7BIT_ADD &
I2C1_SLW_DIS & I2C1_SM_DIS &
I2C1_GCALL_DIS & I2C1_STR_DIS &
I2C1_NACK & I2C1_ACK_DIS & I2C1_RCV_DIS &
I2C1_STOP_DIS & I2C1_RESTART_DIS &
I2C1_START_DIS);
OpenI2C1(config1,config2);
IdleI2C1();
StartI2C1();
//Configure RTCC
//Wait till Start sequence is completed
while(I2C1CONbits.SEN);
//Clear interrupt flag
IFS1bits.MI2C1IF = 0;
//Write Slave address and set master for transmission
MasterWriteI2C1(0xD0);
//Wait till address is transmitted
while(I2C1STATbits.TBF); // 8 clock cycles
while(!IFS1bits.MI2C1IF); // Wait for 9th clock cycle
IFS1bits.MI2C1IF = 0; // Clear interrupt flag
while(I2C1STATbits.ACKSTAT);
OpenI2C1(config1,config2);
IdleI2C1();
StartI2C1();
//Wait till Start sequence is completed
while(I2C1CONbits.SEN);
//Clear interrupt flag
IFS1bits.MI2C1IF = 0;
//Write Slave address and set master for transmission
MasterWriteI2C1(Register);
//Wait till address is transmitted
while(I2C1STATbits.TBF); // 8 clock cycles
while(!IFS1bits.MI2C1IF); // Wait for 9th clock cycle
IFS1bits.MI2C1IF = 0; // Clear interrupt flag
***while(I2C1STATbits.ACKSTAT); //problem here***
//Clear interrupt flag
IFS1bits.MI2C1IF = 0;
//Write Slave address and set master for transmission
MasterWriteI2C1(Byte);
//Wait till address is transmitted
while(I2C1STATbits.TBF); // 8 clock cycles
while(!IFS1bits.MI2C1IF); // Wait for 9th clock cycle
IFS1bits.MI2C1IF = 0; // Clear interrupt flag
while(I2C1STATbits.ACKSTAT);
StopI2C1();
//Wait till stop sequence is completed
while(I2C1CONbits.PEN);
CloseI2C1();
}; //Write RTCC Register