首页 文章

由PIC24HJ256GP610 / 610A引起的I2C读/写I2C问题的区别?

提问于
浏览
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

1 回答

  • 1

    我发现了这个问题 . 我重新启用了I2C模块,并在“... ACKSTAT); //问题这里”代码行之上的几行上断了一个不必要的启动条件 . 重新启用模块似乎没有什么区别,这是问题的开始条件位的重新断言 .

    我不确定为什么它适用于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!
    ...
    ...
    ...
    

相关问题