Solved

convert unix time stamp for 8 bit C compiler

Posted on 2011-03-07
11
1,351 Views
Last Modified: 2012-05-11
Hi -
Anyone know how  (using a Keil C51 compiler on C8051F410 8 bit MPU) to convert a 47 bit RTC time (using unix time) to a display time yy:mm:dd:hh:mm:ss and convert back again.

Theres no <time.h> files available so most of the solutions i've googled are useless.

If possible I would appreciate source code in C or pseudo lang.
Thanks
Chris
0
Comment
Question by:chrislock
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 3
11 Comments
 
LVL 27

Expert Comment

by:d-glitch
ID: 35058178
Here are some notes that include data format for an RTC-47

     http://cache.freescale.com/files/dsp/doc/app_note/AN3874.pdf

The 32 MSB is just a seconds counter.  2^32 seconds gives you 136 year span.
I haven't been able to find out what t=0 refers to.

If you don't care about fractional seconds, you don't have to worry about the
15 LSB
0
 

Author Comment

by:chrislock
ID: 35058503
Thanks - but I cant see any C algorithms for converting the time counter in that link.
I would imagine that you would have to divide by some figure to calculate no of seconds since a start date, then take account of leap years etc etc. I was hoping for some code which would save me the trouble of re-inventing the wheel!
0
 
LVL 34

Expert Comment

by:sarabande
ID: 35059314
i don't know how you would read the 47-bit register but if you got it into a variable like a 6-byte char array (or a 64-bit integer or a double) you could use a 64-bit unsigned integer to extract the seconds:

   int64 i64 = 0;
   memcpy(&i64, &rtcvar, 6);   // copy 6 lower bytes 
   time_t seconds = (time_t)(i64>>15);

Open in new window


note, the typename int64 is not standard. depending on the compiler it can be 'unsigned long long' or other names.

the problem now is that i can't read from the specs what is the starting time. in a chat one tells the starting time is user definable, what would mean you can set the initial seconds yourself. if so it would be senseful that one uses seconds since 01/01/1970 and which can be retrieved by

   
time_t tt = time(NULL);

Open in new window


if now the seconds you got from rtc would map you easily could convert the time_t to struct tm what gives year, month, day, hours, minutes, seconds and more by

   
struct tm * stm = localtime(seconds);

Open in new window


if not, you firstly would need to synchronize the times.

Sara
 
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:chrislock
ID: 35059836
On the C51 compiler for 8 bit machines, the biggest integer is an unsigned long (4 bytes). However, I can map the counter into 6 bytes OK.

'if now the seconds you got from rtc would map you easily could convert the time_t to struct tm what gives year, month, day, hours, minutes, seconds and more by'

Assuming there is a standard start time of 01/01/1970,(all bytes zero) then I need to convert todays date to that format
making allowances for leap years etc.(and also convert back)  I thought perhaps there was some kind of standard algorithm to do that, but I havent found anything sensible yet! There must be a lot of standard code out there somewhere!
0
 
LVL 34

Accepted Solution

by:
sarabande earned 500 total points
ID: 35067215
if you only have 32-bit integers you could convert from 6 bytes like

  unsigned char rtc[6]; // contains RTC
  ...
  unsigned long tmp[2] = { 0 };
  memcpy(tmp, rtc, 6);
  tmp[0] = (tmp[0]>>15) | (tmp[1]<<17);

the seconds are now in tmp[0];

the time(NULL) would give seconds (as type time_t) from 01/01/1970 til now.

the localtime would convert a given time_t to struct tm which has all those members (year, month, ...) and correct leap and day-light-savings you need.

the mktime does the reverse. it converts a struct tm to time_t.

Sara
the localtime would create
0
 

Author Comment

by:chrislock
ID: 35068175
Thanks Sara, but this is an 8 bit microcontroller with no O/S to speak of.
There is no time.h or any of the structs that make it so easy in Windows or Unix.
The only thing I have is the 47 bit RTC counter, which I can set to any value, so I could have it incrementing each second for example.
What I'm asking for is the algorithm to emulate time.h in a true O/S. I could spend some time doing this from scratch, but there must be some code out there somewhere!
0
 

Assisted Solution

by:chrislock
chrislock earned 0 total points
ID: 35068281
Thanks all.
I've just downloaded open source compiler SDCC for 8051 micro and all the time.c etc source is in there.
0
 

Author Comment

by:chrislock
ID: 35068289
No I havent !! Thanks anyway.
0
 
LVL 34

Expert Comment

by:sarabande
ID: 35069314
you also could use the code below which i made out of older (working) code.

Sara
void calcDateTime(long seconds, long hours_to_gm, long * date, long * time)
{
   long daysmonth[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
   long secs_per_year  = 365 * 24 * 3600;
   long secs_per_month = 31 * 24 * 3600;
   long year           = 1970;
   long month          = 1;
   long day            = 1;
   long hours          = 0;
   long minutes        = 0;
   long leap           = 0 ;

   // adjust seconds to localtime
   seconds -= hours_to_gm * 3600;
   // year
   for ( ; seconds > secs_per_year; ++year, seconds -= secs_per_year)
   {
       leap = ((year)%4 == 0 && ((year%100 != 0) || (year%400 == 0)))? 1 : 0;
       secs_per_year = (365 + leap) * 24 * 3600;
   }   
   // month 
   leap = ((year)%4 == 0 && ((year%100 != 0) || (year%400 == 0)))? 1 : 0;
   daysmonth[2] = (leap)? 29 : 28;
   for ( ; seconds >= secs_per_month; ++month, seconds -= secs_per_month)
   {
       secs_per_month = daysmonth[month]*24*3600;
   }    
   // day
   day = (seconds / (24 * 3600) ) + 1;
   seconds = seconds % (24 * 3600) ;

   hours   = seconds / 3600;
   seconds = seconds % 3600;

   minutes = seconds / 60;
   seconds = seconds % 60;

   *date   = year * 10000 + month * 100 + day;
   *time   = hours * 10000 + minutes * 100 + seconds;
                                                                        
}

void calcSeconds(long date, long time, long hours_to_gm, long * seconds)
{
   long daysmonth[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
   long year           = date/10000;
   long month          = (date%10000)/100;
   long day            = date%100;
   long hours          = time/10000;
   long minutes        = (time%10000)/100;
   long leap           = ((year)%4 == 0 && ((year%100 != 0) || (year%400 == 0)))? 1 : 0;;

   *seconds            = time%100 + minutes * 60 + (hours + hours_to_gm) * 3600 + (day - 1) * 24 * 3600;

   // month 
   daysmonth[2] = (leap)? 29 : 28;
   for ( month = month-1; month > 0; --month)
   {
       *seconds += daysmonth[month] * 24 * 3600;
   }    

   // year
   for (year = year-1; year >= 1970; --year)
   {
       leap = ((year)%4 == 0 && ((year%100 != 0) || (year%400 == 0)))? 1 : 0;
       *seconds += (365 + leap) * 24 * 3600;
   }   
                                                                   
}

Open in new window

0
 

Author Comment

by:chrislock
ID: 35069354
Sara - You have been working hard!!
Thanks again
0
 

Author Closing Comment

by:chrislock
ID: 35120560
I've split points. Thanks
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Whether you’re a college noob or a soon-to-be pro, these tips are sure to help you in your journey to becoming a programming ninja and stand out from the crowd.
Although it can be difficult to imagine, someday your child will have a career of his or her own. He or she will likely start a family, buy a home and start having their own children. So, while being a kid is still extremely important, it’s also …
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.

737 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question