Проблема чтения / записи I2C с RTCC, вызванная различиями PIC24HJ256GP610 / 610A?

У меня проблемы с модулем I2C на PIC24HJ256GP610A. Мой код (см. Фрагмент ниже) отлично работает на PIC24HJ256GP610 [примечание: не 610A]. Я использую шину I2C для связи с DS1374 RTCC. Но на 610A он застревает при опросе бита ACKSTAT при попытке записать значение в RTCC с помощью I2C. Кроме того, большую часть времени значение RTCC не увеличивается при чтении значения через I2C (иногда оно увеличивается должным образом). Любые идеи? Есть ли разница в битах / режимах / настройках конфигурации между 610 и 610A, которые работают с модулем I2C? Я пробовал отключить чип RTCC и переключить процессоры. Итак, единственная разница здесь в том, что связь I2C работает на 610, а не на 610A.

В чем разница между 610 и 610A? Является ли 610 устаревшей деталью, которая больше не производится, или она будет производиться и дальше?

Несколько вещей, которые я заметил, экспериментируя, исследуя сигналы и работая с отладчиком:

1). Тактовые импульсы I2C бесконечно переходят в высокий уровень на 20-м передаваемом бите, и именно здесь они застревают при опросе бита ACKSTAT, если я приостанавливаю отладчик. Первый бит кажется стартовым, затем еще 9 бит, затем еще один стартовый / стоповый бит, затем еще 9 бит, затем линия синхронизации переходит в высокий уровень.

2). Когда линия часов застревает и используется окно часов, значение в регистре I2C1STATbits равно 0x8008, что переводится как получение NACK от ведомого устройства, и что бит запуска (или повторного запуска) был обнаружен последним.

3). Я всегда могу читать с ведомого устройства (RTCC) как с 610, так и с 610A. Однако иногда с 610A его значение не увеличивается и остается на некотором целочисленном значении. Я считаю, что когда я отключаю питание и все перепрограммирую, значение RTCC меняется. Иногда он остается постоянным при чтении значения, и, возможно, в 25% случаев он фактически изменяется, как и должен, при чтении его значения.

4). Я не могу ничего писать в RTCC через I2C, используя 610A. Процессор застревает при опросе бита ACKSTAT (я предполагаю, потому что он получил NACK от RTCC). 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

person The_Ders    schedule 08.09.2012    source источник


Ответы (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!
...
...
...
person The_Ders    schedule 10.09.2012