2012-09-08 4 views
1

PIC24HJ256GP610A의 I2C 모듈에 문제가 있습니다. 내 코드 (아래 스 니펫 참조)는 PIC24HJ256GP610 [참고 : not 610A]에서 완벽하게 실행됩니다. 저는 DS1374 RTCC와 통신하기 위해 I2C 버스를 사용하고 있습니다. 그러나 610A에서는 I2C를 사용하여 RTCC에 값을 쓰려고 할 때 ACKSTAT 비트를 폴링 할 때 막히게됩니다. 또한 I2C를 통해 값을 읽을 때 RTCC 값이 증가하지 않는 경우가 대부분입니다 (때로는 증가합니다). 어떤 아이디어? I2C 모듈을 다루는 610과 610A 사이의 설정 비트/모드/설정 차이가 있습니까? RTCC 칩을 전환하고 프로세서를 전환 해 보았습니다. 그래서, 여기서 유일한 차이점은 I2C 통신이 610A가 아닌 610에서 작동한다는 것입니다.I2C PIC24HJ256GP610/610A의 차이로 인해 RTCC에서 읽기/쓰기 문제가 발생합니까?

610과 610A의 차이점은 무엇입니까? 610은 더 이상 제조되지 않거나 계속 제조되는 구식 부품입니까?

, 실험 신호를 프로빙하고 디버거를 통해 스테핑 때 내가 발견 한 몇 가지 :

1). I2C 클록은 디버거를 일시 중지하면 ACKSTAT 비트를 폴링하는 데 걸리는 20 번째 전송 비트가 무한대로 올라갑니다. 첫 번째 비트는 시작 비트, 9 비트, 그 다음에 다른 시작/정지 비트, 9 비트가 더해진 다음 클록 라인이 높게 나타납니다.

2). 클록 라인이 멈추고 watch 윈도우를 사용할 때, I2C1STATbits 레지스터의 값은 슬레이브 디바이스로부터 NACK를 수신 한 것으로 해석하고 마지막으로 Start (또는 Repeated Start) 비트가 감지 된 0x8008입니다.

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); // 여기에서 문제가되는"행의 여러 행 위에 불필요한 시작 조건을 지정했습니다. 모듈을 다시 사용하면 차이가 발생하지 않는 것으로 보입니다. 문제였던 시작 조건 비트가 다시 주장되었습니다.

610A가 아닌 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! 
... 
... 
...