Wednesday, January 18, 2012

PIC24F DS1307 RTC Communication



/***********************************************************************
/* Description: Use the following code as it is to communicate with external RTC(DS1307).
/* include the file i2c.h(C30 installed) that declares all the I2C module related functions.
/* Code compiled with Microchip C30 compiler.
***********************************************************************/




void initRTCC(void) {
unsigned int config1 = 0;
unsigned int config2 = 0;

CloseI2C2();
Delay10ms(10);// some delay
ConfigIntI2C2(MI2C_INT_OFF); //Disable I2C interrupt
Delay10ms(10);// some delay

config1 = (I2C_ON | I2C_7BIT_ADD);
config2 = 157; //baud rate 100KHz
OpenI2C2(config1, config2);//configure I2C2
Delay10ms(10);// some delay
}

void SetRTCDate(unsigned char dd, unsigned char mm, unsigned char yy) {
// START
IdleI2C2();
StartI2C2();
while (I2C2CONbits.SEN); //Wait till Start sequence is completed
MI2C2_Clear_Intr_Status_Bit; //Clear interrupt flag

// Control Byte
MasterWriteI2C2(0xD0); //Write Slave address and set master for transmission
while (I2C2STATbits.TBF); //Wait till address is transmitted
while (!IFS3bits.MI2C2IF); //Wait for ninth clock cycle
MI2C2_Clear_Intr_Status_Bit; //Clear interrupt flag
while (I2C2STATbits.ACKSTAT);
MasterWriteI2C2(0x04); // Write address pointer for read
while (I2C2STATbits.TBF); //Wait till address is transmitted
while (!IFS3bits.MI2C2IF); //Wait for ninth clock cycle
MI2C2_Clear_Intr_Status_Bit; //Clear interrupt flag
while (I2C2STATbits.ACKSTAT);
MasterWriteI2C2(dd); // Write slave address for write
while (I2C2STATbits.TBF); //Wait till address is transmitted
while (!IFS3bits.MI2C2IF); //Wait for ninth clock cycle
MI2C2_Clear_Intr_Status_Bit; //Clear interrupt flag
while (I2C2STATbits.ACKSTAT);
MasterWriteI2C2(mm); // Write slave address for write
while (I2C2STATbits.TBF); //Wait till address is transmitted
while (!IFS3bits.MI2C2IF); //Wait for ninth clock cycle
MI2C2_Clear_Intr_Status_Bit; //Clear interrupt flag
while (I2C2STATbits.ACKSTAT);
MasterWriteI2C2(yy); // Write slave address for write
while (I2C2STATbits.TBF); //Wait till address is transmitted
while (!IFS3bits.MI2C2IF); //Wait for ninth clock cycle
MI2C2_Clear_Intr_Status_Bit; //Clear interrupt flag
while (I2C2STATbits.ACKSTAT);
StopI2C2(); // Create Stop Sequence
while (I2C2CONbits.PEN); // Wait till stop sequence is completed
}

void SetRTCTime(unsigned char ss, unsigned char mn, unsigned char hh) {
// START
IdleI2C2();
StartI2C2();
while (I2C2CONbits.SEN); //Wait till Start sequence is completed
MI2C2_Clear_Intr_Status_Bit; //Clear interrupt flag

// Control Byte
MasterWriteI2C2(0xD0); //Write Slave address and set master for transmission
while (I2C2STATbits.TBF); //Wait till address is transmitted
while (!IFS3bits.MI2C2IF); //Wait for ninth clock cycle
MI2C2_Clear_Intr_Status_Bit; //Clear interrupt flag
while (I2C2STATbits.ACKSTAT);
MasterWriteI2C2(0x00); // Write address pointer for read
while (I2C2STATbits.TBF); //Wait till address is transmitted
while (!IFS3bits.MI2C2IF); //Wait for ninth clock cycle
MI2C2_Clear_Intr_Status_Bit; //Clear interrupt flag
while (I2C2STATbits.ACKSTAT);
MasterWriteI2C2(ss); // Write slave address for write
while (I2C2STATbits.TBF); //Wait till address is transmitted
while (!IFS3bits.MI2C2IF); //Wait for ninth clock cycle
MI2C2_Clear_Intr_Status_Bit; //Clear interrupt flag
while (I2C2STATbits.ACKSTAT);
MasterWriteI2C2(mn); // Write slave address for write
while (I2C2STATbits.TBF); //Wait till address is transmitted
while (!IFS3bits.MI2C2IF); //Wait for ninth clock cycle
MI2C2_Clear_Intr_Status_Bit; //Clear interrupt flag
while (I2C2STATbits.ACKSTAT);
MasterWriteI2C2(hh); // Write slave address for write
while (I2C2STATbits.TBF); //Wait till address is transmitted
while (!IFS3bits.MI2C2IF); //Wait for ninth clock cycle
MI2C2_Clear_Intr_Status_Bit; //Clear interrupt flag
while (I2C2STATbits.ACKSTAT);
StopI2C2(); // Create Stop Sequence
while (I2C2CONbits.PEN); // Wait till stop sequence is completed
}


/* use this function to read day,hour etc. to read individually by passing
/* the corresponding address value. Refer DS1307 datasheet for address mapping */

unsigned char ReadRTC(unsigned char addr) {
unsigned char data;

// START
IdleI2C2();
StartI2C2();
while (I2C2CONbits.SEN); //Wait till Start sequence is completed
MI2C2_Clear_Intr_Status_Bit; //Clear interrupt flag
// Control Byte
MasterWriteI2C2(0xD0); //Write Slave address and set master for transmission
while (I2C2STATbits.TBF); //Wait till address is transmitted
while (!IFS3bits.MI2C2IF); //Wait for ninth clock cycle
MI2C2_Clear_Intr_Status_Bit; //Clear interrupt flag
while (I2C2STATbits.ACKSTAT);
MasterWriteI2C2(addr); // Write address pointer for read
while (I2C2STATbits.TBF); //Wait till address is transmitted
while (!IFS3bits.MI2C2IF); //Wait for ninth clock cycle
MI2C2_Clear_Intr_Status_Bit; //Clear interrupt flag
while (I2C2STATbits.ACKSTAT);
RestartI2C2(); // Write Restart sequence
while (I2C2CONbits.RSEN); // Wait for ACK
MI2C2_Clear_Intr_Status_Bit; //Clear interrupt flag

// Control Byte
MasterWriteI2C2(0xD1); //Write Slave address and set master for transmission
while (I2C2STATbits.TBF); //Wait till address is transmitted
while (!IFS3bits.MI2C2IF); //Wait for ninth clock cycle
MI2C2_Clear_Intr_Status_Bit; //Clear interrupt flag
while (I2C2STATbits.ACKSTAT);
data = MasterReadI2C2(); // Read from I2C the desired byte
NotAckI2C2(); // Make NACK for the read byte
while (I2C2CONbits.ACKEN == 1); // Wait till ACK/NACK sequence is over
StopI2C2(); // Create Stop Sequence
while (I2C2CONbits.PEN); // Wait till stop sequence is completed

return (data); // Return read data
}