I am using a DS1307 for timekeeping. The device i am constructing is supposed to count the number of hours to a specific date. I have succeded with the communication between the RTC and my PIC16F88.
But i have a problem. The time is stored with HEX representation. The time 13:54 would be 0x13 and 0x54 in the memory of the RTC.
The thing is that i want to figure out the difference in hours. I have two byte variables Hour and xHour. The first is the current hour and xHour is the setup hour to which i am counting down.
BTW i am programming in PicBasic Plus, but i suppose it's just the theory of how to do this that matters.
Example to show my problem:
Hour = 14
xHour = 23
Diff = xHour - Hour
And the result i want is 9. But the result i get is 15 (35 - 20).
I would need to convert the Hour and xHour to decimal representation and then subtract. But how do i do this? Or is there another way of doing this without converting to decimal?
If you do a search on BCD arithmetic you should find some useful explanations. **broken link removed**
PICs have got a useful flag for BCD maths - the half carry (or digit carry) bit (DC). When subtracting, the DC bit acts as a borrow and so if it's clear you need to subtract 6 from the result. For your example you would do the following,
Code:
movlw 23h
movwf Acc
movlw 14h
movwf AccHi
movfw AccHi
subwf Acc,W
btfss STATUS,DC
addlw 100h-6; add -6 is same as subtracting 6
; W will now = 9 (23-14 = 9 not 4 as in your example)
Note that if your result was higher than 10 then it will still be in hex(BCD) format.
Are you sure you're decoding the data properly, because according to this datasheet, it is not hexadecimal or decimal, but a mix of the two. For Minutes bits 0-3 are standard binary (encodes a value from 0 to 16), while bits 4-6 are tens of minutes (bit 7 is always 0). So if I interpret it correctly, the following C code would convert that to a byte you could do standard math on:
The same routine could be used to decode seconds, minutes, months and years.
The hour is encoded even stranger, and has to be interpreted differently whether the 24 hour time bit is set or not.
Code:
unsigned char ConvertHour(unsigned char cSource) {
unsigned char cOut;
//Test bit 6
if (cSource & 0x40) {
//12 hour time
cOut=ConvertTime(cSource & 0x1f);
//Test bit 5 (PM)
if (cSource & 0x20)
cOut+=12;
else {
//Special case for 12 AM
if (cSource == 12)
cSource = 0;
}
return cOut;
} else {
//24 hour time
return ConvertTime(cSource & 0x3f);
}
}
That should return the hour in 24 hour time, so you can do standard math against it.
I've never actually worked with one of those chips before, so this is all just based on my interpretation of the datasheet, having just read it for the first time.