Tal como lo recomendaron mis compañeros apiladores en mi publicación anterior, probé la función "Write_to_slave" en Proteus también en tiempo real, enviando bytes al RTC y el esclavo responde adecuadamente con un bit de confirmación para cada byte que recibe Por lo tanto, la operación de escritura funciona bien. Sin embargo, ahora tengo problemas con mi función "Read_from_slave". El problema es que, durante la secuencia de lectura, hasta el envío de la "Dirección del esclavo + Lectura", es decir, 0xD1, funciona bien y también recibe un acuse de recibo del esclavo, pero el problema surge después de la ejecución de la función I2C_restart. Los datos leídos del SSPBUF o los datos recibidos del esclavo son FF, mientras que los segundos deben contar de 0 a 60 (y se muestra 63 en la pantalla LCD), seguido de un NACK. Y después de enviar el NACK, I2C_stop () debería finalizar la transacción mientras eso no esté sucediendo, como se puede ver en la instantánea de Proteus. A continuación se muestra el código, solo realicé una operación de lectura para leer el registro de segundos para verificar si mi método está funcionando, pero desafortunadamente no:
void Wait_MSSP()
{
while(SSPIF==0);
SSPIF = 0;
}
void check_ACK_Master_Transmit()
{
if(SSPCON2bits.ACKDT == 0) //If ACKDT is 0, ACK has been recieved
arraydisp("ACK success");
else if (SSPCON2bits.ACKDT == 1) //If ACKDT is 1, ACK has not been recieved
arraydisp("ACK fail");
}
unsigned char Read_from_slave(unsigned char addr)
{
unsigned char x;
I2C_start();
SSPBUF = RTC_ADDRW;
Wait_MSSP(); //Slave address+Write
SSPBUF = addr;
Wait_MSSP(); ////RTC register to be read
I2C_restart();
SSPBUF = RTC_ADDRR;
Wait_MSSP();
SSPCON2bits.RCEN = 1; //Enable Master to receive data from slave
x = SSPBUF; //Read the SSPBUF
SSPCON2bits.ACKDT = 1; //send NACK after receiving the data
SSPCON2bits.ACKEN = 1; //Enable Acknowledge sequence on SDA and SCL
I2C_stop(); //Wait until stop operation is completed
return(x);
}
void Write_to_slave(unsigned char addr, unsigned char data)
{
I2C_start();
SSPBUF = RTC_ADDRW; //Slave address + Write
Wait_MSSP();
check_ACK_Master_Transmit(); //Checks the
SSPBUF = addr; // RTC Registor location address to be written
Wait_MSSP();
check_ACK_Master_Transmit();
SSPBUF = data; //data to be writen to the address location
Wait_MSSP();
check_ACK_Master_Transmit();
I2C_stop();
Wait_MSSP();
}
void I2C_write(unsigned char addr)
{
PIR1bits.SSPIF = 0;
SSPBUF = addr;
while(PIR1bits.SSPIF == 0);
return;
}
void Reset_time()
{
I2C_start();
I2C_write(RTC_ADDRW);
I2C_write(0x00);
I2C_write(0x00);
I2C_write(0x00);
I2C_write(0x01);
I2C_write(0x01);
I2C_write(0x01);
I2C_write(0x01);
I2C_write(0x00);
I2C_stop();
return;
}
void Set_time()
{
Write_to_slave(0x00,0x00); //Write data 0x00 to address 00H (Seconds) of RTC (CH = 0)
Write_to_slave(0x01,0x30); //Write data 0x00 to address 01H(Minutes) of the RTC
Write_to_slave(0x02,0x10); //Write data 0x00 to address 02H(HOUR) of the RTC
Write_to_slave(0x03,0x06); //Write data 0x01 to address 03H (DAY) of the RTC
Write_to_slave(0x04,0x01); //Write data 0x01 to address 04H (Date) of the RTC
Write_to_slave(0x05,0x01); //Write data 0x01 to address 05H (Month) of the RTC
Write_to_slave(0x06,0x16); //Write data 0x00 to address 06H (Year) of the RTC
}
void main()
{
TRISCbits.TRISC0 = 0;
TRISCbits.TRISC1 = 0;
TRISCbits.TRISC2 = 0;
TRISD = 0;
char16x2LCDInit();
I2C_Init();
Reset_time();
Set_time();
while(1)
{
sec = Read_from_slave(0x00);
__delay_ms(10);
Write_Command(0xC0);
LCDWriteInt(BCD2Lowerch(sec),1);
LCDWriteInt(BCD2Upperch(sec),1);
}
}
Solo para obtener una imagen clara de las transacciones que ocurren en el bus I2C, adjunto una instantánea de la ventana del Depurador I2C que muestra las operaciones I2C durante la simulación en Proteus. La primera secuencia es la siguiente: S = inicio, D0 = dirección de esclavo + escritura, A = Acuse de recibo del esclavo, 05 = Registrar dirección en el RTC, A = Acuse de recibo del esclavo, 01 = datos escritos a 05H, A = Acuse de recibo del esclavo, P = Detener. De manera similar, para otros ciclos de escritura y lectura, mientras que en lectura hay "Sr", es decir, I2C_restart seguido de "N" NACK y, como podemos ver, no hay "P", es decir, se detiene después de NACK. También he adjuntado la imagen del hardware. Vuelvo a leer el esclavo como modo transmisor en la hoja de datos DS1307, pero no encuentro ningún problema con la secuencia "Read_from _slave".
Lo siento por el tedioso mensaje, ya que cualquier otro consejo o dirección con respecto a mi enfoque para realizar la operación de lectura o la identificación de cualquier problema con los métodos sería de gran ayuda. Gracias de nuevo!
Saludos ~ VD