struct TTime {
char year, month, day, hours, minutes, seconds;
} TimeRead;
struct Wr_TTime {char year, month, day, hours, minutes, seconds;
} TimeToWrite;
char yearmod4, byteRead;
void Display_Time() {
unsigned const digit[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
char txt[4];
TRISB=0;
PORTB.RB1=0;
PORTB.RB2=0;
PORTB.RB3=0;
PORTB.RB0=1;
txt[0]=TimeRead.hours / 10;
PORTD=digit[txt[0]];
delay_us(5);
//end first digit
TRISB=0;
PORTB.RB0=0;
PORTB.RB2=0;
PORTB.RB3=0;
PORTB.RB1=1;
txt[1]=TimeRead.hours % 10;
PORTD=digit[txt[1]];
delay_us(5);
//end second digit
TRISB=0;
PORTB.RB1=0;
PORTB.RB2=1;
PORTB.RB3=0;
PORTB.RB0=0;
txt[2]=TimeRead.minutes / 10;
PORTD=digit[txt[2]];
delay_us(5);
//end third digit
TRISB=0;
PORTB.RB1=0;
PORTB.RB2=0;
PORTB.RB3=1;
PORTB.RB0=0;
txt[3]=TimeRead.minutes % 10;
PORTD=digit[txt[3]];
delay_us(5);
//end fourth digit
}
void ReadTime() {
char updateYear;
updateYear = 0;
I2C1_Start(); // issue start signal
I2C1_Wr(0xA0); // address PCF8583
I2C1_Wr(2); // first word address
I2C1_Repeated_Start(); // issue repeated start signal
I2C1_Wr(0xA1); // address PCF8583 for reading R/W=1
byteRead = I2C1_Rd(1u); // read minutes byte
TimeRead.minutes = (byteRead >> 4)*10 + (byteRead & 0x0F); // transform minutes
while (!I2C1_Is_Idle())
asm nop;
byteRead = I2C1_Rd(1u); // read hours byte
TimeRead.hours = (byteRead >> 4)*10 + (byteRead & 0x0F); // transform hours
while (!I2C1_Is_Idle())
asm nop;
byteRead = I2C1_Rd(0u); // read weekday/month byte
TimeRead.month = ((byteRead & 0b00010000) >> 4)*10 + (byteRead & 0x0F); // transform month
while (!I2C1_Is_Idle())
asm nop;
I2C1_Stop();
I2C1_Start(); // issue start signal
I2C1_Wr(0xA0); // address PCF8583
I2C1_Wr(0x10); // first word address
I2C1_Repeated_Start(); // issue repeated start signal
I2C1_Wr(0xA1); // address PCF8583 for reading R/W=1
byteRead = I2C1_Rd(0u); // read year
if (yearmod4 != byteRead % 4 ) { // check if year is incremented in RTC
byteRead++; // in this case the new value should be written to RTC RAM at address 16(0x10)
updateYear = 1;
}
TimeRead.year = byteRead;
while (!I2C1_Is_Idle())
asm nop;
I2C1_Stop();
if (updateYear > 0) {
I2C1_Start(); // issue start signal
I2C1_Wr(0xA0); // address PCF8530
I2C1_Wr(0x10); // start from word at address 16
I2C1_Wr(TimeRead.year); // write year to RAM
I2C1_Stop(); // issue stop signal
}
}
void MainInit() {
CMCON = 0x07;
I2C1_Init(100000); // initialize I2C
}
void write_time(void)
{
TimeToWrite.hours = 22;
TimeToWrite.minutes = 10;
I2C1_Start(); // issue start signal
I2C1_Wr(0xA0); // address PCF8583
I2C1_Wr(0); // start from word at address 0 (configuration word)
I2C1_Wr(0x80); // write 0x80 to config. (pause counter...)
I2C1_Wr(0); // write 0 to cents word
I2C1_Wr(((TimeToWrite.minutes/10)<<4) + (TimeToWrite.minutes%10)); // write minutes word
I2C1_Wr(((TimeToWrite.hours/10)<<4) + (TimeToWrite.hours%10)); // write hours word
I2C1_Stop(); // issue stop signal
I2C1_Start(); // issue start signal
I2C1_Wr(0xA0); // address PCF8530
I2C1_Wr(0x10); // start from word at address 16
I2C1_Wr(TimeToWrite.year); // write year to RAM
I2C1_Stop(); // issue stop signal
I2C1_Start(); // issue start signal
I2C1_Wr(0xA0); // address PCF8530
I2C1_Wr(0); // start from word at address 0
I2C1_Wr(0); // write 0 to config word (enable counting)
I2C1_Stop(); // issue stop signal
}
void main() {
MainInit();
write_time();
while (1) {
ReadTime();
Display_Time();
Delay_ms(1000);
}
}