1

我在使用 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
4

1 回答 1

1

我发现了这个问题。我重新启用了 I2C 模块,并在“...ACKSTAT); //problem here”代码行上方几行断言了一个不必要的启动条件。重新启用模块似乎没有什么不同,问题在于重新断言启动条件位。

我不确定为什么它适用于 610 而不是 610A。不管怎样,问题解决了!

...
...
...
//**DELETED** OpenI2C1(config1,config2);
//**DELETED** IdleI2C1();
//**DELETED** StartI2C1();
////**DELETED** Wait till Start sequence is completed
//**DELETED** 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 no more!
...
...
...
于 2012-09-10T22:34:20.540 回答