CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

time.h Library or equivalent

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
bwhiten



Joined: 26 Nov 2003
Posts: 151
Location: Grayson, GA

View user's profile Send private message

time.h Library or equivalent
PostPosted: Wed Nov 26, 2003 2:08 pm     Reply with quote

I'm trying to include some existing C code in my project which uses the time.h include file, the tm struct and specifically the following functions:

time()
localtime()

The CCS compiler doesn't provide the time library, that I can locate. Anyone seen PIC code for these functions or know the calculations they provide so I can write my own? If so I would apreciate a push in the right direction.

Thanks.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Nov 26, 2003 2:35 pm     Reply with quote

PIC microcontrollers have no inherent Real Time Clock in them,
unlike PC's. If want a RTC or elapsed time function, you'll have to
add a RTC chip, such as the DS1307.

If you just want to get the elapsed time since the PIC was powered up,
you could use a clock derived from the PIC's crystal frequency to
run one of the PIC's timers, and count elapsed seconds (or minutes, etc.).
Accuracy might not be perfect over a long period of time, because
microprocessor crystals have larger tolerances than RTC crystals.
(Though you could pay more, to get higher accuracy).

What are your actual requirements ?
bwhiten



Joined: 26 Nov 2003
Posts: 151
Location: Grayson, GA

View user's profile Send private message

PostPosted: Wed Nov 26, 2003 3:02 pm     Reply with quote

Thanks for the reply. Sorry, should have stated that I have a battery backed RTC, the 1307 as you stated. I am working a problem of sun location based on latitude, longitude and date. I saw some related but limited information on a previous post from Mark but didn't see a resolution to the problem.
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Wed Nov 26, 2003 3:31 pm     Reply with quote

Here are bits and pieces of the code that I used. It should give you a start. I used the C18 compiler for this project so you will probably have to make a few mods. If you come across a couple of functions that I didn't include, just post back. BTW, this does take up quite a bit of code space. I was using the 18F6720 so I didn't really care. However, I am running a bit short now and will probably at some point try and crunch a few things or possibly do a look up table with some offsets.

My sun.c file

Code:

#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

/* *************************************************************************
  A macro to compute the number of days elapsed since 2000 Jan 0.0 £
  (which is equal to 1999 Dec 31, 0h UT)
 *************************************************************************** */
#define days_since_2000_Jan_0(y, m, d) \
    (367L * (y) - ((7 * ((y) + (((m) + 9) / 12))) / 4) + ((275 * (m)) / 9) + (d) - 730530L)
#define INV360  (1.0 / 360.0)

static UINT16 sunrise = 0;
static UINT16 sunset = 0;

UINT16        Get_Sunrise(void);
UINT16        Get_Sunset(void);

static int    sun_rise_set
              (
                unsigned int  year,
                unsigned char month,
                unsigned char day,
                double        lon,
                double        lat,
                double        *trise,
                double        *tset
              );

/* static INT16 sun_rise_set(UINT16 year, UINT8 month, £
 * UINT8 day, double lon, double lat, £
 * double *rise, double *set); */
static void   sunpos(double d, double *lon, double *r);
static void   sun_RA_dec(double d, double *RA, double *dec, double *r);
static double revolution(double x);
static double rev180(double x);
static double GMST0(double d);

/* *************************************************************************
  NAME: sun_rise_set

  DESCRIPTION:  This function computes the length of the day PARAMETERS:
                year (IN) calendar date, 1801-2099 only month (IN) calendar
                date, 1801-2099 only day (IN) calendar date, 1801-2099 only
                lon (IN) Eastern longitude positive, Western longitude
                negative lat (IN) Northern latitude positive, Southern
                latitude negative altit (IN) the altitude which the Sun
                should cross upper_limb (IN) non-zero -> upper limb, zero
                -> center rise (OUT) where to store the sunrise time set
                (OUT) where to store the sunset time GLOBALS: none

  RETURN: 0 = sun rises/sets this day, times stored at trise and *tset. +1
          = sun above the specified "horizon" 24 hours. trise set to time
          when the sun is at south, minus 12 hours while *tset is set to
          the south time plus 12 hours. "Day" length = 24 hours -1 = sun is
          below the specified "horizon" 24 hours "Day" length 0 hours,
          trise and *tset are both set to the time when the sun is at
          south.

  ALGORITHM:  none

  NOTES:  The longitude value is not critical. Set it to the correct
          longitude if you're picky, otherwise set to to, say, 0.0 The
          latitude however IS critical - be sure to get it correct Set the
          altitude to: -35/60 degrees for rise/set, -6 degrees for civil,
          -12 degrees for nautical and -18 degrees for astronomical
          twilight. Set the upper limb to non-zero (e.g. 1) when computing
          day length and to zero when computing day+twilight length.
 *************************************************************************** */
int sun_rise_set(
  unsigned int  year,   /* FIX ME: add comment */
  unsigned char month,  /* FIX ME: add comment */
  unsigned char day,    /* FIX ME: add comment */
  double        lon,    /* FIX ME: add comment */
  double        lat,    /* FIX ME: add comment */
  double        *trise, /* FIX ME: add comment */
  double        *tset)  /* FIX ME: add comment */
{
  double  altit = -0.583333333; /* the altitude which the Sun should cross */
  double  d = 0.0,              /* Days since 2000 Jan 0.0 (negative before) */
  sr = 0.0,                     /* Solar distance, astronomical units */
  sRA = 0.0,                    /* Sun's Right Ascension */
  sdec = 0.0,                   /* Sun's declination */
  sradius = 0.0,                /* Sun's apparent radius */
  t = 0.0,                      /* Diurnal arc */
  tsouth = 0.0,                 /* Time when Sun is at south */
  sidtime = 0.0,                /* Local sidereal time */
  cost = 0.0;                   /* the diurnal arc */
  int     rc = 0;               /* Return code from function - usually 0 */

  /* Compute d of 12h local mean solar time */
  d = (long)days_since_2000_Jan_0((long)year, (long)month, (long)day) + 0.5 - lon / 360.0;

  /* Compute local sidereal time of this moment */
  sidtime = revolution(GMST0(d) + 180.0 + lon);

  /* Compute Sun's RA + Decl at this moment */
  sun_RA_dec(d, &sRA, &sdec, &sr);

  /* Compute time when Sun is at south - in hours UT */
  tsouth = 12.0 - rev180(sidtime - sRA) / 15.0;

  /* Compute the Sun's apparent radius, degrees */
  sradius = 0.2666 / sr;

  /* Adjust the altitude */
  altit -= sradius;

  /* Compute the diurnal arc that the Sun traverses to reach £
   * the specified altitude altit: */
  cost = (sind(altit) - sind(lat) * sind(sdec)) / (cosd(lat) * cosd(sdec));
  if (cost >= 1.0)
  {
    rc = -1;
    t = 0.0;                    /* Sun always below altit */
  }
  else if (cost <= -1.0)
  {
    rc = +1;
    t = 12.0;                   /* Sun always above altit */
  }
  else
    t = acosd(cost) / 15.0;     /* The diurnal arc, hours */

  /* Store rise and set times - in hours UT */
  *trise = tsouth - t;
  *tset = tsouth + t;

  return (rc);
}

#if 0

/* *************************************************************************
  FIX ME: add comment
 *************************************************************************** */
INT16 sun_rise_set(
  UINT16  year,   /* FIX ME: add comment */
  UINT8   month,  /* FIX ME: add comment */
  UINT8   day,    /* FIX ME: add comment */
  double  lon,    /* FIX ME: add comment */
  double  lat,    /* FIX ME: add comment */
  double  *trise, /* FIX ME: add comment */
  double  *tset)  /* FIX ME: add comment */
{
  double  altit = -0.583333333; /* the altitude which the Sun should cross */
  double  d = 0.0,              /* Days since 2000 Jan 0.0 (negative before) */
  sr = 0.0,                     /* Solar distance, astronomical units */
  sRA = 0.0,                    /* Sun's Right Ascension */
  sdec = 0.0,                   /* Sun's declination */
  sradius = 0.0,                /* Sun's apparent radius */
  t = 0.0,                      /* Diurnal arc */
  tsouth = 0.0,                 /* Time when Sun is at south */
  sidtime = 0.0,                /* Local sidereal time */
  cost = 0.0;                   /* the diurnal arc */
  INT16   rc = 0;               /* Return code from function - usually 0 */

  /* Compute d of 12h local mean solar time */
  d = (long)days_since_2000_Jan_0((long)year, (long)month, (long)day) + 0.5 - lon / 360.0;

  /* Compute local sidereal time of this moment */
  sidtime = revolution(GMST0(d) + 180.0 + lon);

  /* Compute Sun's RA + Decl at this moment */
  sun_RA_dec(d, &sRA, &sdec, &sr);

  /* Compute time when Sun is at south - in hours UT */
  tsouth = 12.0 - rev180(sidtime - sRA) / 15.0;

  /* Compute the Sun's apparent radius, degrees */
  sradius = 0.2666 / sr;

  /* Adjust the altitude */
  altit -= sradius;

  /* Compute the diurnal arc that the Sun traverses to reach £
   * the specified altitude altit: */
  cost = (sind(altit) - sind(lat) * sind(sdec)) / (cosd(lat) * cosd(sdec));
  if (cost >= 1.0)
  {
    rc = -1;
    t = 0.0;                    /* Sun always below altit */
  }
  else if (cost <= -1.0)
  {
    rc = +1;
    t = 12.0;                   /* Sun always above altit */
  }
  else
    t = acosd(cost) / 15.0;     /* The diurnal arc, hours */

  /* Store rise and set times - in hours UT */
  *trise = tsouth - t;
  *tset = tsouth + t;

  return (rc);
}
#endif

/* *************************************************************************
  NAME: sunpos

  DESCRIPTION:  This function computes the Sun's position at any instant
                PARAMETERS: d (IN) days since 2000 Jan 0 lon (OUT) ecliptic
                longitude r (OUT) distance, astronomical units GLOBALS:
                none

  RETURN: none

  ALGORITHM:  none

  NOTES:  Computes the Sun's ecliptic longitude and distance at an instant
          given in d, number of days since 2000 Jan 0.0. The Sun's ecliptic
          latitude is not computed, since it's always very near 0.
 *************************************************************************** */
static void sunpos(
  double  d,    /* FIX ME: add comment */
  double  *lon, /* FIX ME: add comment */
  double  *r)   /* FIX ME: add comment */
{
  double  M = 0.0,          /* Mean anomaly of the Sun */
  w = 0.0,                  /* Mean longitude of perihelion */

  /* Note: Sun's mean longitude = M + w */
  e = 0.0,                  /* Eccentricity of Earth's orbit */
  E = 0.0,                  /* Eccentric anomaly */
  x = 0.0, y = 0.0,         /* x, y coordinates in orbit */
  v = 0.0;                  /* True anomaly */

  /* Compute mean elements */
  M = revolution(356.0470 + 0.9856002585 * d);
  w = 282.9404 + 4.70935E-5 * d;
  e = 0.016709 - 1.151E-9 * d;

  /* Compute true longitude and radius vector */
  E = M + e * RADEG * sind(M) * (1.0 + e * cosd(M));
  x = cosd(E) - e;
  y = sqrt(1.0 - e * e) * sind(E);
  *r = sqrt(x * x + y * y); /* Solar distance */
  v = atan2d(y, x);         /* True anomaly */
  *lon = v + w;             /* True solar longitude */
  if (*lon >= 360.0)
    *lon -= 360.0;          /* Make it 0..360 degrees */

  return;
}

/* *************************************************************************
  NAME: sun_RA_dec

  DESCRIPTION:  Returns the Sun's Right Ascension and the Sun's declination
                for this moment. PARAMETERS: d (IN) days since 2000 Jan 0
                RA (OUT) Right Ascension dec (OUT) declination r (OUT)
                distance, astronomical units GLOBALS: none

  RETURN: none

  ALGORITHM:  none

  NOTES:  none
 *************************************************************************** */
static void sun_RA_dec(
  double  d,    /* FIX ME: add comment */
  double  *RA,  /* FIX ME: add comment */
  double  *dec, /* FIX ME: add comment */
  double  *r)   /* FIX ME: add comment */
{
  double  lon = 0.0;      /* Sun's ecliptic longitude */
  double  obl_ecl = 0.0;  /* obliquity of ecliptic */
  double  x = 0.0;        /* rectangular coordinate */
  double  y = 0.0;        /* rectangular coordinate */
  double  z = 0.0;        /* rectangular coordinate */

  /* Compute Sun's ecliptical coordinates */
  sunpos(d, &lon, r);

  /* Compute ecliptic rectangular coordinates (z=0) */
  x = *r * cosd(lon);
  y = *r * sind(lon);

  /* Compute obliquity of ecliptic (inclination of Earth's axis) */
  obl_ecl = 23.4393 - 3.563E-7 * d;

  /* Convert to equatorial rectangular coordinates - x is unchanged */
  z = y * sind(obl_ecl);
  y = y * cosd(obl_ecl);

  /* Convert to spherical coordinates */
  *RA = atan2d(y, x);
  *dec = atan2d(z, sqrt(x * x + y * y));

  return;
}

/* *************************************************************************
  NAME: GMST0

  DESCRIPTION:  This function computes GMST0, the Greenwich Mean Sidereal
                Time at 0h UT (i.e. the sidereal time at the Greenwhich
                meridian at 0h UT). PARAMETERS: d (IN) angle GLOBALS: none

  RETURN: angle to within +180..+180 degrees

  ALGORITHM:  Sidtime at 0h UT = L (Sun's mean longitude) + 180.0 degr L M
              + w, as defined in sunpos(). Since I'm too lazy to add these
              numbers, I'll let the C compiler do it for me. Any decent C
              compiler will add the constants at compile time, imposing no
              runtime or code overhead.

  NOTES:  GMST is then the sidereal time at Greenwich at any time of the
          day. I've generalized GMST0 as well, and define it as: GMST0 GMST
          - UT -- this allows GMST0 to be computed at other times than 0h
          UT as well. While this sounds somewhat contradictory, it is very
          practical: instead of computing GMST like: GMST (GMST0) UT
          (366.2422/365.2422) where (GMST0) is the GMST last time UT was 0
          hours, one simply computes: GMST = GMST0 + UT where GMST0 is the
          GMST "at 0h UT" but at the current moment! Defined in this way,
          GMST0 will increase with about 4 min a day. It also happens that
          GMST0 (in degrees, 1 hr = 15 degr) is equal to the Sun's mean
          longitude plus/minus 180 degrees! (if we neglect aberration,
          which amounts to 20 seconds of arc or 1.33 seconds of time)
 *************************************************************************** */
static double GMST0(
  double  d)  /* FIX ME: add comment */
{
  return (revolution((180.0 + 356.0470 + 282.9404) + (0.9856002585 + 4.70935E-5) * d));
}

/* *************************************************************************
  NAME: revolution

  DESCRIPTION:  This function reduces any angle to within the first
                revolution by subtracting or adding even multiples of 360.0
                until the result is >= 0.0 and < 180.0 PARAMETERS: x (IN)
                angle

  RETURN: angle to within +180..+180 degrees

  ALGORITHM:  none

  NOTES:  none
 *************************************************************************** */
static double rev180(
  double  x)  /* FIX ME: add comment */
{
  return (x - 360.0 * floor(x * INV360 + 0.5));
}

/* *************************************************************************
  NAME: revolution

  DESCRIPTION:  This function reduces any angle to within the first
                revolution by subtracting or adding even multiples of 360.0
                until the result is >= 0.0 and < 360.0 PARAMETERS: x (IN)
                angle

  RETURN: angle to within 0..360 degrees

  ALGORITHM:  none

  NOTES:  none
 *************************************************************************** */
static double revolution(
  double  x)  /* FIX ME: add comment */
{
  return (x - 360.0 * floor(x * INV360));
}

/* *************************************************************************
  NAME: Calculate_Dusk_Dawn

  DESCRIPTION:  Returns the time for dawn and dusk in minutes after
                midnight PARAMETERS: latitude (IN) latitude (in deg min)
                longitude (IN) longitude (in deg min) tz (IN) time zone (in
                minutes) year (IN) years after Christ for which to compute
                month (IN) months (1=January...12=December) day (IN) day of
                the month GLOBALS: none

  RETURN: none

  ALGORITHM:  none

  NOTES:  TimeZone is to be specified according to U.S Naval Observatory
          Astronimical Applications Department World Time Zone Map, with
          cities located west of 0 degrees longitude (Zulu time, UTC) using
          a negative value for time zone. year,month,date = calendar date,
          1801-2099 only. Eastern longitude positive, Western longitude
          negative Northern latitude positive, Southern latitude negative
          The longitude value is not critical. Set it to the correct
          longitude if you're picky, otherwise set to to, say, 0.0 The
          latitude however IS critical - be sure to get it correct
 *************************************************************************** */
void Calculate_Dusk_Dawn(
  INT16   latitude,   /* FIX ME: add comment */
  INT16   longitude,  /* FIX ME: add comment */
  INT16   tz,         /* FIX ME: add comment */
  UINT16  date)       /* FIX ME: add comment */
{
  double  rise = 0.0; /* decimal hours */
  double  set = 0.0;  /* decimal hours */
  double  lat = 0.0;  /* decimal degrees */
  double  lon = 0.0;  /* decimal degrees */
  UINT8   dst = 0;
  UINT8   month, day, y;
  UINT16  year;

  Time_DateFrom2000(&month, &day, &y, date);
  year = y + 2000;

  /* We need to disable ints before we do the floating point math. £
   * I had problems if I didn't. */
  Global_Int(INT_DISABLED);

  /* Adjust for daylight savings */
  if (Time_IsDaylightSavings(month, day, y))
    dst = 60;

  /* convert minutes to decimal degrees */
  lat = (double)latitude / 60.0;
  lon = (double)longitude / 60.0;

  if (!sun_rise_set(year, month, day, lon, lat, &rise, &set))
  {
    /* convert decimal hours into minutes and adjust for locality */
    sunrise = (INT16) ((rise * 60.0) + dst + tz);
    sunset = (INT16) ((set * 60.0) + dst + tz);

    /* Validate the time */
    if (sunrise >= (24 * 60L))
      sunrise = 0;
    if (sunset >= (24 * 60L))
      sunset = 0;
  }
  else
  {
    sunrise = 0;
    sunset = 0;
  }

  Global_Int(INT_RESTORE);
  return;
}

/* *************************************************************************
  NAME: Get_Sunrise

  DESCRIPTION:  This function allows access to our module level variable
                containing the sunrise value. PARAMETERS: none

  RETURN: The time when the sun will rise in minutes

  ALGORITHM:  none

  NOTES:  none
 *************************************************************************** */
UINT16 Get_Sunrise(void)
{
  return (sunrise);
}

/* *************************************************************************
  NAME: Get_Sunset

  DESCRIPTION:  This function allows access to our module level variable
                containing the sunset value. PARAMETERS: none

  RETURN: The time when the sun will set in minutes

  ALGORITHM:  none

  NOTES:  none
 *************************************************************************** */
UINT16 Get_Sunset(void)
{
  return (sunset);
}

#ifdef __cplusplus
}
#endif /* __cplusplus */



Other functions called from sun.c
Code:


typedef enum { MON, TUE, WED, THU, FRI, SAT, SUN, HOL } DAYSOFWEEK;

rom const UINT8   MONTH_DAYS[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

/* *************************************************************************
  DESCRIPTION:  Converts days to month, day, and year

  RETURN: month, day, and year are returned through parameters

  ALGORITHM:  none

  NOTES:  none
 *************************************************************************** */
void Time_DateFrom2000(
  UINT8   *pMonth,  /* holds month */
  UINT8   *pDay,    /* holds day */
  UINT8   *pYear,   /* holds year */
  UINT16  days)     /* days that we are converting */
{
  static UINT16 date = 0;   /* storage to speed up if the last date was the same */
  static UINT8  month = 1;  /* storage to speed up if the last date was the same */
  static UINT8  day = 1;    /* storage to speed up if the last date was the same */
  static UINT8  year = 0;   /* storage to speed up if the last date was the same */

  /* See if we have already computed the month, day, and year for this
   * date */
  if (days != date)
  {
    /* Set date equal to days so that we can avoid this calculation later */
    date = days;
    year = 0;
    month = 1;
    day = 1;

    while (days >= 365)
    {
      if ((LeapYear(year)) && days == 365)
        break;
      days -= 365;
      if (LeapYear(year))
        --days;
      year++;
    }

    while (days >= MonthDays(month, year))
    {
      days -= MonthDays(month, year);
      month++;
    }

    day += days;
  }

  *pYear = year;
  *pMonth = month;
  *pDay = day;
}

/* *************************************************************************
  DESCRIPTION:  Returns true if the date is during DST.

  RETURN: TRUE if date falls in DST. FALSE if not.

  ALGORITHM:  none

  NOTES:  none
 *************************************************************************** */
UINT8 Time_IsDaylightSavings(
  UINT8 month,  /* holder for month */
  UINT8 day,    /* holder for day */
  UINT8 year)   /* holder for year */
{
  UINT8 i;  /* day of month counter */

  /* a month between April and October */
  if ((month > 4) && (month < 10))
  {
    return (TRUE);
  }

  /* get the start date for DST - First Sunday in April */
  if (month == 4)
  {
    for (i = 1; i <= MonthDays(month, year); i++)
    {
      if (DayOfWeek(Time_DaysSince2000(month, i, year)) == SUN)
      {
        if (day >= i)
          return (TRUE);
      }
    }
  }

  /* get the end date for DST - Last Sunday in October */
  else if (month == 10)
  {
    for (i = MonthDays(month, year); i > 0; i--)
    {
      if (DayOfWeek(Time_DaysSince2000(month, i, year)) == SUN)
      {
        if (day < i)
          return (TRUE);
      }
    }
  }

  return (FALSE);
}

/* *************************************************************************
  DESCRIPTION:  Converts date to days since 1/1/2000

  RETURN: number of days since Jan 1, 2000, or 0 if date is invalid

  ALGORITHM:

  NOTES:  none
 *************************************************************************** */
UINT16 Time_DaysSince2000(
  UINT8 month,  /* holds month */
  UINT8 day,    /* holds day */
  UINT8 year)   /* holds year */
{
  UINT8   i;
  UINT16  days = 0; /* return value */

  /* check for a vaild date */
  if (!Time_IsDateValid(month, day, year))
    return (0);

  for (i = 0; i < year; i++)
  {
    days += 365;

    if (LeapYear(i))
      ++days;
  }

  for (i = 1; i < month; i++)
  {
    days += MonthDays(i, year);
  }

  days += (day - 1);

  return (days);
}

/* *************************************************************************
  DESCRIPTION:  Returns the day of the week value

  RETURN: day of the week (0 = Monday...6=Sunday)

  ALGORITHM:  none

  NOTES:  none
 *************************************************************************** */
static DAYSOFWEEK DayOfWeek(
  UINT16  days) /* number of days since 1/1/2000 */
{
  return (DAYSOFWEEK) (((days + 5) % 7));
}

/* *************************************************************************
  DESCRIPTION:  This routine determines if a year is a leap year.

  RETURN: 1 if a leap year, 0 if not.

  ALGORITHM:  none

  NOTES:  Note that this is not the proper way of checking for leap year
          but is good enough for our life time.
 *************************************************************************** */
static UINT8 LeapYear(
  UINT8 year) /* year that we are checking */
{
  if (year & 0x03)
    return (FALSE);
  else
    return (TRUE);
}

/* *************************************************************************
  DESCRIPTION:  Returns the number of days in given month and year

  RETURN: number of days in month, or -1 if month is out of range

  ALGORITHM:  none

  NOTES:  none
 *************************************************************************** */
static UINT8 MonthDays(
  UINT8 month,  /* holds month */
  UINT8 year)   /* holds year */
{
  if ((month == 2) && LeapYear(year))
    return (29);
  else if (month < 13)
    return (MONTH_DAYS[month]);
  else
    return (0);
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Nov 26, 2003 3:53 pm     Reply with quote

I think Mark has pretty much covered it, but here's a Maxim appnote
that has Date-Time to binary seconds and vice versa functions.
http://pdfserv.maxim-ic.com/en/an/app517.pdf
bwhiten



Joined: 26 Nov 2003
Posts: 151
Location: Grayson, GA

View user's profile Send private message

PostPosted: Wed Nov 26, 2003 4:12 pm     Reply with quote

Mark! I'm not worthy! I'm sure I can pull the functions I need out of your listing. Have you had a chance to verify any sunrise/sunset results with the online calculators like the US Naval Observatory? Thanks again for the support. Hopefully I can return the favor some day.
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Wed Nov 26, 2003 6:27 pm     Reply with quote

Yes, I have never seen it more than a minute off.

Here are some BCD functions that I use for the DS1307

Code:

/* *************************************************************************
  DESCRIPTION:  This function converts an 8 bit binary value to an 8 bit
                BCD value. The input range must be from 0 to 99.

  RETURN: bcd representation of binary_value

  ALGORITHM:  none

  NOTES:  none
 *************************************************************************** */
UINT8 bin2bcd(
  UINT8 binary_value) /* value we are converting to binary */
{
  UINT8 temp;
  UINT8 retval;

  temp = binary_value;
  retval = 0;

  while (1)
  {
    /* Get the tens digit by doing multiple subtraction of 10 from the
     * binary value */
    if (temp >= 10)
    {
      temp -= 10;
      retval += 0x10;
    }
    else  /* Get the ones digit by adding the remainder. */
    {
      retval += temp;
      break;
    }
  }

  return (retval);
}

/* *************************************************************************
  DESCRIPTION:  This function converts an 8 bit BCD value to an 8 bit
                binary value. The input range must be from 0 to 99.

  RETURN: none

  ALGORITHM:  none

  NOTES:  none
 *************************************************************************** */
UINT8 bcd2bin(
  UINT8 bcd_value)  /* FIX ME: add comment */
{
  UINT8 tens;
  UINT8 ones;

  tens = (bcd_value >> 4) * 10;
  ones = bcd_value & 0x0f;

  return (tens + ones);
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group