我在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
1 回答
我发现了这个问题 . 我重新启用了I2C模块,并在“... ACKSTAT); //问题这里”代码行之上的几行上断了一个不必要的启动条件 . 重新启用模块似乎没有什么区别,这是问题的开始条件位的重新断言 .
我不确定为什么它适用于610而不是610A . 无论如何,问题解决了!