Using timers to create a digital clock

A digital clock application provides a good platform to illustrate the components that we discussed in this chapter. We'll use PuTTY to allow the user to set the time and then call HAL_GetTick () to provide a time-base for our digital clock that is displayed on the GLCD. We'll call this recipe ticToc_c3v0.

How to do it…

Follow the following steps to create a digital clock:

  1. Create a new folder for the ticToc_c3v0 recipe and, within it, a new project (ticToc) and use the RTE manager to select board support for Graphic LCD.
  2. Copy the retarget.c, serial.c and serial.h files to the project folder and add them to the project.
  3. Define a new type (time_t) in the ticToc.h header file. Please note that we could declare each variable (hours, minutes, seconds, and so on) as separate unsigned integers, but it is better practice to group them together as a structured type named time_t:
    #ifndef __TICTOC_H
    #define __TICTOC_H
    
    typedef struct {      /* structure of the clock record */
      unsigned char    hour;         /* hour */
      unsigned char     min;                     /* minute */
      unsigned char     sec;                     /* second */
    } time_t;
    
    #endif /* __TICTOC_H  */
  4. Create a new file named ticToc.c , add the necessary boilerplate and #include statements, and enter the following main () function:
    /*
     * main
     *******/
    int main (void) {
      
      time_t time;
      int32_t input;
      char buffer[128];
      
      uint32_t tic, toc = 0; 
      uint32_t elapsed_t;
      
      HAL_Init ();   /* Init Hardware Abstraction Layer */
      SystemClock_Config ();           /* Config Clocks */ 
        
      SER_Init();
    
      GLCD_Initialize();
      GLCD_SetBackgroundColor (GLCD_COLOR_WHITE);
      GLCD_ClearScreen ();            /* clear the GLCD */
      GLCD_SetBackgroundColor (GLCD_COLOR_BLUE);
      GLCD_SetForegroundColor (GLCD_COLOR_WHITE);
      GLCD_SetFont (&GLCD_Font_16x24);
      GLCD_DrawString (0, 0*24, " CORTEX-M4 COOKBOOK ");
      GLCD_DrawString (0, 1*24, "  PACKT Publishing  ");
      GLCD_SetBackgroundColor (GLCD_COLOR_WHITE);   
      GLCD_SetForegroundColor (GLCD_COLOR_BLACK);
    
      for (;;) {                        /* Loop forever */
    
      }
    }
  5. Add ticToc.c to the project. Build, download, and test this. Please note that the compiler may issue some warnings as we have declared some unused variables.
  6. Add the following code fragment immediately before the for statement:
      /* Set the current time using PuTTY */
      printf ("Clock Example
    ");
      printf ("Set Hours: ");
      scanf("%d", &input); time.hour = input;
      printf ("Set Minutes: ");
      scanf("%d", &input); time.min = input;
      printf ("Set Seconds: ");
      scanf("%d", &input); time.sec = input;
      
      /* elapsed_t is elapsed (10 * msec) since midnight */
      elapsed_t = 
            time.sec*100+time.min*60*100+time.hour*60*60*100;
  7. Build, download, and test this.
  8. Add the following code fragment within the for loop:
        for (;;) {                        /* Loop forever */ 
          tic = HAL_GetTick()/10;     
          if (tic != toc) {                 /* 10 ms update */
            toc = tic;
            time.sec = (elapsed_t/100)%60;   /* update time */
           time.min = (elapsed_t/6000)%60;
           time.hour = (elapsed_t/360000)%24;
    
            /* Update Display */
            sprintf(buffer, "%d : %d : %d", time.hour, 
                                    time.min, time.sec);
            GLCD_DrawString (4*16, 3*24, "             ");
           GLCD_DrawString (4*16, 3*24, buffer);    
          
            elapsed_t = (elapsed_t+1)%DAY;
          }
        }
  9. Remember to define the constant DAY as follows:
    #define DAY 8640000;        /* 10 ms ticks in a day */
  10. Compile, download, and run the program. The following below shows the GLCD screen:
    How to do it…

How it works…

Once we have declared a variable of type time_t, the fields (hours, min, sec) of the struct can be accessed using the dot operator (.) or the arrow operator (->). The dot operator accesses the structure field via the structure variable name, and the arrow operator accesses it via a pointer to the structure. We already used the arrow operator to access fields of structs that were used to represent peripheral registers. In this case, the arrow operator was used because the variable that was used to represent the struct (GPIOC, RCC, UART4 etc.) defines a pointer. As our main() function declares a variable (time) as time_t time;, we access the fields as time.hours, and so on.

The function named HAL_GetTick ( ) returns a value that is incremented every millisecond. We use this timebase to increment a counter variable named elapsed_t, which is initialized by the user's console (PuTTY). The tic and toc variables are updated to ensure that the display only needs to be updated every 100 ms. We call the function sprint() (declared in stdio.h) to format a string (stored in buffer [128]) representing the current time and write this to the Graphic LCD in a similar way to what was illustrated in this recipe, debugADC_c2v0.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.21.246.218