Hi All,
Any one help me in doing this. I need to continously print the current date and time in DD/MM/YY and HH:MM:SS format. Iam using ARM LPC2378. I am not sure whether my RTC code is correct. Please confirm or suggest if there is something else I need to do. My code which is creating the problem goes as follows:
void RTCInit(void) { PCONP |= 0x0200; /* RTC Power Enabled */ RTC_CCR = 0x11; /* RTC Osci.Clock Enabled */ RTC_ILR |= 0x01; /* RTC Interrupt Enabled */ RTC_AMR |= 0xFF; /* Alarm Mask Register Disabled */ RTC_CIIR = 0x01; /* Every Second Interrupt Enabled */ RTC_CISS = 0x87; /* Sub Second Interrupt Disabled */ return; } void RTCSetDateTime(RTCDateTime DateTime) { RTC_SEC = DateTime.RTCSec; RTC_MIN = DateTime.RTCMin; RTC_HOUR = DateTime.RTCHour; RTC_DOM = DateTime.RTCMday; RTC_MONTH = DateTime.RTCMon; RTC_YEAR = DateTime.RTCYear; return; } RTCDateTime RTCGetDateTime(void) { RTCDateTime LocalDateTime; /* Store RTC date and time in st_LocalDateTime structure */ LocalDateTime.RTCSec = RTC_SEC; LocalDateTime.RTCMin = RTC_MIN; LocalDateTime.RTCHour = RTC_HOUR; LocalDateTime.RTCMday = RTC_DOM; LocalDateTime.RTCMon = RTC_MONTH; LocalDateTime.RTCYear = RTC_YEAR; return (LocalDateTime); }
In some other part of the code I am updating the structure variables to set the time initially. And when I do this I call RTCSetDateTime(initiallocaltime); as follows
{ ... ... /* Reset the counter which is resposible for Sec Timer increment in RTC */ RTC_CCR |= 0x03; /* CTC Reset in CCR */ RTC_ILR |= 0x05; /* RTC Sec Timer Counter Reset*/ /* Updation of RTC with Date & Time initially*/ RTCSetDateTime(initiallocaltime); RTC_CCR = RTC_OSC_SELECT; ... ... }
and finally Iam printing the time. Date and time is printed correctly for some time and later the it jumps above or below (some times in seconds/minutes and mostly in hours) and starts running from there.
Please let me know how can I avoid this problems with RTC and print the correct date and time continously eoth out any disturbances.
Thanks and Regards, Sravan Kumar M.
Why are you enabling interrupts for the RTC? You don't need that in order to use the RTC like you are showing. Do you actually have an interrupt function?
And also, in your RTCGetDateTime function you could avoid some compiler copying if you passed a pointer to the RTCDateTime struct instead of having the function return a struct. Like this:
void RTCGetDateTime(RTCDateTime *LocalDateTime) { /* Store RTC date and time in LocalDateTime structure */ LocalDateTime->RTCSec = RTC_SEC; LocalDateTime->RTCMin = RTC_MIN; LocalDateTime->RTCHour = RTC_HOUR; LocalDateTime->RTCMday = RTC_DOM; LocalDateTime->RTCMon = RTC_MONTH; LocalDateTime->RTCYear = RTC_YEAR; }
The same also holds true for the RTCSetDateTime. That has nothing to do with your initial problem, however.
It seems you've got what is a frighteningly common problem with the accessing of the RTC registers; i.e., ignoring the fact that the time might change while doing the reading.
Your code is:
RTCDateTime RTCGetDateTime(void) { RTCDateTime LocalDateTime; /* Store RTC date and time in st_LocalDateTime structure */ LocalDateTime.RTCSec = RTC_SEC; LocalDateTime.RTCMin = RTC_MIN; LocalDateTime.RTCHour = RTC_HOUR; // What happens if the RTC minute changes around about here? LocalDateTime.RTCMday = RTC_DOM; LocalDateTime.RTCMon = RTC_MONTH; LocalDateTime.RTCYear = RTC_YEAR; return (LocalDateTime); }
Imagine, for example, that the time is about to change from 12:59:59 to 13:00:00 and that it just happens to change just after you have read MIN but before you have read HOUR.
The result would then be: 13:59:59
If the whole date/time can't be read as an atomic action, then I tend to do is something like:
{ RTCDateTime LocalDateTime; int OldSec; do { OldSec = RTC_SEC; /* Store RTC date and time in st_LocalDateTime structure */ LocalDateTime.RTCSec = RTC_SEC; LocalDateTime.RTCMin = RTC_MIN; LocalDateTime.RTCHour = RTC_HOUR; LocalDateTime.RTCMday = RTC_DOM; LocalDateTime.RTCMon = RTC_MONTH; LocalDateTime.RTCYear = RTC_YEAR; } while (LocalDateTime.RTCSec != OldSec); return (LocalDateTime); }
So now the date/time would be re-read if the seconds change during the read of all of the data.
Thanks for your valuable suggestions.. I'll try to incorporate this change and get back to you..
Thanks and regards, Sravan Kumar M.
sir, I have one more doubt. what if RTC_SEC the register itself is giving a wrong value due to some reason. how can I correct RTC_SEC value?
Thanks and Regards, Sravan
"I have one more doubt. what if RTC_SEC the register itself is giving a wrong value due to some reason. how can I correct RTC_SEC value?"
What reason?
Is the RTC_SEC any more likely to return a wrong value than any other register?
Sometimes you have to trust what your given - Otherwise you'll have to check every register on every access?!
But ... On a restart, you might want to check all date/time registers for validity and reset them if the value is obviously wrong; e.g., the RTC might be battery backed and the battery might be flat.
View all questions in Keil forum