Time and Date

From Nutwiki
Revision as of 15:30, 12 October 2012 by Harald (Talk | contribs) (See also)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Test Environments

Hardware Comments Nut/OS
4.6.3
Nut/OS
4.6.4
Nut/OS
4.7.4
Nut/OS
4.8.0
Nut/OS
4.8.7
Ethernut 1.3 H No RTC hardware.
Date and time settings are lost after reset.
OK OK
Binaries
OK
Binaries
OK
Binaries
OK
Binaries
Compiler: AVR-GCC 4.3.2
Ethernut 2.1 B No RTC hardware.
Date and time settings are lost after reset.
OK OK
Binaries
OK
Binaries
OK
Binaries
OK
Binaries
Compiler: AVR-GCC 4.3.2
Ethernut 3.0 E OK OK
Binaries
OK
Binaries
OK
Binaries
OK
Binaries
Compiler: ARM-GCC 4.3.3
EIR 1.0 Set jumper JP1 to UART mode. OK

Add
<source lang="c"> outr(PIOA_PDR, _BV(PA5_RXD0_A) | _BV(PA6_TXD0_A)); </source> immediately after NutRegisterDevice().

OK
Binaries
OK
Binaries
OK
Binaries
Compiler: ARM-GCC 4.2.2 ; AVR-GCC 4.3.0

Description

This is an example on how to build a simple clock with Nut/OS.

Source Code

<source lang="c">

  1. include <dev/board.h>
  2. include <dev/debug.h>
  3. include <sys/timer.h>
  1. include <stdlib.h>
  2. include <stdio.h>
  3. include <io.h>
  4. include <string.h>
  5. include <time.h>

static char *weekday_name[7] = {

   "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

static char *month_name[12] = {

   "January", "February", "March", "April", "May", "June", "July", "August",
   "September", "October", "November", "December"};

static void PrintDateTime(CONST struct _tm *stm) {

   printf("%s, %02d. %s %04d, %02d:%02d:%02d", weekday_name[stm->tm_wday],
       stm->tm_mday, month_name[stm->tm_mon], stm->tm_year + 1900,
       stm->tm_hour, stm->tm_min, stm->tm_sec);

}

static void DisplayLocalTime(void) {

   time_t tt;
   struct _tm *ltm;
   while (!kbhit()) {
       tt = time(NULL);
       ltm = localtime(&tt);
       PrintDateTime(ltm);
       printf("\r");
       NutSleep(100);
   }
   putchar('\n');

}

int main(void) {

   u_long baud = 115200;
   NutRegisterDevice(&DEV_UART, 0, 0);
   freopen(DEV_UART_NAME, "w", stdout);
   freopen(DEV_UART_NAME, "r", stdin);
   _ioctl(_fileno(stdout), UART_SETSPEED, &baud);
  1. ifdef RTC_CHIP
   NutRegisterRtc(&RTC_CHIP);
  1. endif
   DisplayLocalTime();
   return 0;

}


</source>

Output

Wednesday, 31. December 1969, 19:00:00

Details

The first 9 lines include the required libraries for this program, as usual.

<source lang="C">static char *weekday_name[7] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};</source> declares an array of 7 pointers (of type char) and calls the array weekday_name. Each of those pointers point to an adress in memory where the specified strings are stored (e.g. "Sunday").

<source lang="C">static char *month_name[12] = {

   "January", "February", "March", "April", "May", "June", "July", "August",
   "September", "October", "November", "December"};

</source>behaves analog.

<source lang="C">static void PrintDateTime(CONST struct _tm *stm)</source>

defines a void function called PrintDateTime with a pointer (stm) to the _tm structure as parameter.

<source lang="C">printf("%s, %02d. %s %04d, %02d:%02d:%02d", weekday_name[stm->tm_wday],

       stm->tm_mday, month_name[stm->tm_mon], stm->tm_year + 1900,
       stm->tm_hour, stm->tm_min, stm->tm_sec);

</source> Prints out the time and date, stored in the _tm structure. In the case of weekday_name and month_name it replaces the content of the _tm structure, by the corresponding strings.

<source lang="C">static void DisplayLocalTime(void) {

   time_t tt;
   struct _tm *ltm;

   while (!kbhit()) {
       tt = time(NULL);
       ltm = localtime(&tt);
       PrintDateTime(ltm);
       printf("\r");
       NutSleep(100);
   }
   putchar('\n');

} </source> Defines a variable "tt" of the type type_t, which holds the calendar time (seconds since the start of the Unix epoche), and a pointer to the _tm structure.

The following while (!kbhit()) loop cycles as long as no keyboard hit occured, gets the system time (if already stored, passes it to the _tm structure and passes the content of the _tm structure to the PrintTimeDate function.

printf("\r") causes a carriage return, followed by a NutSleep(100).
By that the output line gets refreshed every 100ms.

<source lang="C">int main(void)</source> declares the main function, the first function that will be executed.

<source lang="C">u_long baud = 115200;</source> Defines a variable of the type u_long (32bit long), calls it "baud" and assigns the value 115200 to it.

The following four lines register the UART device, open it, assign stdout and stdin to it and set the baudrate.

<source lang="C">

  1. ifdef RTC_CHIP
   NutRegisterRtc(&RTC_CHIP);
  1. endif

</source> registers the boards RTC(Real Time Clock) chip (if available), that holds the calender time. Thus it is powerded by a Goldcap capacitor it even stores the time, when the main power supply is disconnected, for some time.(Ethernut 3 only)

Description

With this example it is not only possible to display but also to set the time.

Source Code

<source lang="c">

  1. include <dev/board.h>
  2. include <dev/debug.h>
  1. include <sys/version.h>
  2. include <sys/timer.h>
  1. include <stdlib.h>
  2. include <stdio.h>
  3. include <io.h>
  4. include <string.h>
  5. include <time.h>

static char *weekday_name[7] = {

   "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

static char *month_name[12] = {

   "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};

static void PrintDateTime(CONST struct _tm *stm) {

   printf("%s, %02d. %s %04d, %02d:%02d:%02d",
       weekday_name[stm->tm_wday],
       stm->tm_mday, month_name[stm->tm_mon], stm->tm_year + 1900,
       stm->tm_hour, stm->tm_min, stm->tm_sec);

}

static int EnterDate(struct _tm *stm) {

   int year;
   int mon;
   int mday;
   printf("Enter date\n");
   printf("Year(YYYY): ");
   scanf("%d", &year);
   stm->tm_year = year - 1900;
   printf("%04d", stm->tm_year + 1900);
   printf("\nMonth(MM): ");
   scanf("%d", &mon);
   stm->tm_mon = mon - 1;
   printf("%02d", stm->tm_mon + 1);
   printf("\nDay(DD): ");
   scanf("%d", &mday);
   stm->tm_mday = mday;
   printf("%02d  (%s)", stm->tm_mday, weekday_name[stm->tm_wday]);
   putchar('\n');
   return 0;

}

static int EnterTime(struct _tm *stm) {

   int hour;
   int minute;
   int second;
   printf("Enter time, use 24h format\n");
   printf("Hours: ");
   scanf("%d", &hour);
   stm->tm_hour = hour;
   printf("%02d", stm->tm_hour);
   printf("\nMinutes: ");
   scanf("%d", &minute);
   stm->tm_min = minute;
   printf("%02d", stm->tm_min);
   printf("\nSeconds: ");
   scanf("%d", &second);
   stm->tm_sec = second;
   printf("%02d\n\n", stm->tm_sec);
   putchar('\n');
   return 0;

}

static void SetLocalTime(void) {

   struct _tm ltm;
   time_t now;
   time(&now);
   memcpy(&ltm, localtime(&now), sizeof(ltm));
   if (EnterDate(&ltm) == 0 && EnterTime(&ltm) == 0) {
       now = mktime(&ltm);
       stime(&now);
   }

}

static void DisplayLocalTime(void) {

   time_t tt;
   struct _tm *ltm;
   while (!kbhit()) {
       tt = time(NULL);
       ltm = localtime(&tt);
       PrintDateTime(ltm);
       printf("\r");
       NutSleep(100);
   }
   putchar('\n');

}

int main(void) {

   u_long baud = 115200;
   NutRegisterDevice(&DEV_UART, 0, 0);
   freopen(DEV_UART_NAME, "w", stdout);
   freopen(DEV_UART_NAME, "r", stdin);
   _ioctl(_fileno(stdout), UART_SETSPEED, &baud);
   #ifdef RTC_CHIP
       (NutRegisterRtc(&RTC_CHIP));
   #endif
   SetLocalTime();
   DisplayLocalTime();
   return 0;

}


</source>

Details

This example contains 3 additional functions: EnterDate, EnterTime and SetLocalTime

<source lang="C"> static int EnterDate(struct _tm *stm) </source> defines a function with a pointer to the _tm structure as parameter. <source lang="C"> printf("Hours: "); scanf("%d", &hour); stm->tm_hour = hour; printf("%02d", stm->tm_hour);

printf("\nMinutes: "); scanf("%d", &minute); stm->tm_min = minute; printf("%02d", stm->tm_min);

printf("\nSeconds: "); scanf("%d", &second); stm->tm_sec = second; printf("%02d\n\n", stm->tm_sec); </source> The scanf statements store the user input in a local variable. Then the value gets stored in the _tm structure through the stm pointer.

<source lang="C"> static int EnterTime(struct _tm *stm) </source> behaves analog.

<source lang="C"> static void SetLocalTime(void) {

   struct _tm ltm;
   time_t now;

   time(&now);
   memcpy(&ltm, localtime(&now), sizeof(ltm));

   if (EnterDate(&ltm) == 0 && EnterTime(&ltm) == 0) {
       now = mktime(&ltm);
       stime(&now);
   }

} </source> defines a variable "ltm" of the structure type _tm and a variable "now" of type time_t.

time(&now) stores the current calender time in now.

memcopy now copies the return of localtime(&now)(which converts calender time to a broken-down local time) via ltm to the _tm structure.

Then, within the if statement, the functions EnterDate(&ltm) and EnterTime(&ltm) are called. After that mktime converts the content of the _tm structure in calender time, which is then stored by time(&now) in the RTC.

See also

External Links

X1226/X1286 Realtime Clock And Calendar About the RTC chip on Ethernut 3.0.Template:Languages