home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 September / pcwk_09_96.iso / demo / wgelectr / pk51demo / files.2 / EXAMPLES / TRAFFIC / TRAFFIC.C < prev    next >
C/C++ Source or Header  |  1993-10-07  |  15KB  |  300 lines

  1. /******************************************************************************/
  2. /*                                                                            */
  3. /*   TRAFFIC.C:  Traffic Light Controller using the C-51 COMPILER             */
  4. /*                                                                            */
  5. /******************************************************************************/
  6.  
  7. code char menu[] = 
  8.    "\n"
  9.    "+***** TRAFFIC LIGHT CONTROLLER using C51 and RTX-51 tiny *****+\n"
  10.    "| This program is a simple Traffic Light Controller.  Between  |\n"
  11.    "| start time and end time the system controls a traffic light  |\n"
  12.    "| with pedestrian self-service.  Outside of this time range    |\n"
  13.    "| the yellow caution lamp is blinking.                         |\n"
  14.    "+ command -+ syntax -----+ function ---------------------------+\n"
  15.    "| Display  | D           | display times                       |\n"
  16.    "| Time     | T hh:mm:ss  | set clock time                      |\n"
  17.    "| Start    | S hh:mm:ss  | set start time                      |\n"
  18.    "| End      | E hh:mm:ss  | set end time                        |\n"
  19.    "+----------+-------------+-------------------------------------+\n";
  20.  
  21.  
  22. #include <reg52.h>                    /* special function registers 8052      */
  23. #include <rtx51tny.h>                 /* RTX-51 tiny functions & defines      */
  24. #include <stdio.h>                    /* standard I/O .h-file                 */
  25. #include <ctype.h>                    /* character functions                  */
  26. #include <string.h>                   /* string and memory functions          */
  27.  
  28.  
  29. extern getline (char idata *, char);  /* external function:  input line       */
  30. extern serial_init ();                /* external function:  init serial UART */
  31.  
  32. #define INIT      0                   /* task number of task:  init           */
  33. #define COMMAND   1                   /* task number of task:  command        */
  34. #define CLOCK     2                   /* task number of task:  clock          */
  35. #define BLINKING  3                   /* task number of task:  blinking       */
  36. #define LIGHTS    4                   /* task number of task:  signal         */
  37. #define KEYREAD   5                   /* task number of task:  keyread        */
  38. #define GET_ESC   6                   /* task number of task:  get_escape     */
  39.  
  40. struct time  {                        /* structure of the time record         */
  41.   unsigned char hour;                 /* hour                                 */
  42.   unsigned char min;                  /* minute                               */
  43.   unsigned char sec;                  /* second                               */
  44. };
  45.  
  46. struct time ctime = { 12,  0,  0 };   /* storage for clock time values        */
  47. struct time start = {  7, 30,  0 };   /* storage for start time values        */
  48. struct time end   = { 18, 30,  0 };   /* storage for end   time values        */
  49.  
  50. sbit  red    = P1^2;                  /* I/O Pin:  red    lamp output         */
  51. sbit  yellow = P1^1;                  /* I/O Pin:  yellow lamp output         */
  52. sbit  green  = P1^0;                  /* I/O Pin:  green  lamp output         */
  53. sbit  stop   = P1^3;                  /* I/O Pin:  stop   lamp output         */
  54. sbit  walk   = P1^4;                  /* I/O Pin:  walk   lamp output         */
  55. sbit  key    = P1^5;                  /* I/O Pin:  self-service key input     */
  56.  
  57. idata    char inline[16];             /* storage for command input line       */
  58.  
  59.  
  60. /******************************************************************************/
  61. /*        Task 0 'init': Initialize                                           */
  62. /******************************************************************************/
  63. init () _task_ INIT  {                /* program execution starts here        */
  64.   serial_init ();                     /* initialize the serial interface      */
  65.   os_create_task (CLOCK);             /* start clock task                     */
  66.   os_create_task (COMMAND);           /* start command task                   */
  67.   os_create_task (LIGHTS);            /* start lights task                    */
  68.   os_create_task (KEYREAD);           /* start keyread task                   */
  69.   os_delete_task (INIT);              /* stop init task (no longer needed)    */
  70. }
  71.  
  72.  
  73. bit display_time = 0;                 /* flag:  signal cmd state display_time */
  74.  
  75. /******************************************************************************/
  76. /*        Task 2 'clock'                                                      */
  77. /******************************************************************************/
  78. clock ()  _task_ CLOCK  {
  79.   while (1)  {                        /* clock is an endless loop             */
  80.     if (++ctime.sec == 60)  {         /* calculate the second                 */
  81.       ctime.sec = 0;
  82.       if (++ctime.min == 60)  {       /* calculate the minute                 */
  83.         ctime.min = 0;
  84.         if (++ctime.hour == 24)  {    /* calculate the hour                   */
  85.           ctime.hour = 0;
  86.         }
  87.       }
  88.     }
  89.     if (display_time)  {              /* if command_status == display_time    */
  90.       os_send_signal (COMMAND);       /* signal to task command: time changed */
  91.     }
  92.     os_wait (K_IVL, 100, 0);          /* wait interval:  1 second             */
  93.   }
  94. }
  95.  
  96.  
  97. struct time rtime;                    /* temporary storage for entry time     */
  98.  
  99. /******************************************************************************/
  100. /*        readtime: convert line input to time values & store in rtime        */
  101. /******************************************************************************/
  102. bit readtime (char idata *buffer)  {
  103.   unsigned char args;                          /* number of arguments         */
  104.  
  105.   rtime.sec = 0;                               /* preset second               */
  106.   args = sscanf (buffer, "%bd:%bd:%bd",        /* scan input line for         */
  107.                  &rtime.hour,                  /* hour, minute and second     */
  108.                  &rtime.min,
  109.                  &rtime.sec);
  110.   
  111.   if (rtime.hour > 23  ||  rtime.min > 59  ||  /* check for valid inputs      */
  112.       rtime.sec > 59   ||  args < 2        ||  args == EOF)  {
  113.     printf ("\n*** ERROR: INVALID TIME FORMAT\n");
  114.     return (0);
  115.   }
  116.   return (1);
  117. }
  118.  
  119.  
  120.  
  121. #define ESC  0x1B                     /* ESCAPE character code                */
  122.  
  123. bit   escape;                         /* flag: mark ESCAPE character entered  */
  124.  
  125. /******************************************************************************/
  126. /*        Task 6 'get_escape': check if ESC (escape character) was entered    */
  127. /******************************************************************************/
  128. get_escape () _task_ GET_ESC  {
  129.   while (1)  {                                 /* endless loop                */
  130.     if (_getkey () == ESC)  escape = 1;        /* set flag if ESC entered     */
  131.     if (escape)  {                             /* if escape flag send signal  */
  132.       os_send_signal (COMMAND);                /* to task 'command'           */
  133.     }
  134.   }
  135. }
  136.  
  137.  
  138. /******************************************************************************/
  139. /*        Task 1 'command': command processor */
  140. /******************************************************************************/
  141. command () _task_ COMMAND  {
  142.   unsigned char i;
  143.  
  144.   printf (menu);                               /* display command menu        */
  145.   while (1)  {                                 /* endless loop                */
  146.     printf ("\nCommand: ");                    /* display prompt              */
  147.     getline (&inline, sizeof (inline));        /* get command line input      */
  148.  
  149.     for (i = 0; inline[i] != 0; i++)  {        /* convert to uppercase        */
  150.       inline[i] = toupper(inline[i]);
  151.     }
  152.  
  153.     for (i = 0; inline[i] == ' '; i++);        /* skip blanks                 */
  154.  
  155.     switch (inline[i])  {                      /* proceed to command function */
  156.       case 'D':                                /* Display Time Command        */
  157.         printf ("Start Time: %02bd:%02bd:%02bd    "
  158.                 "End Time: %02bd:%02bd:%02bd\n",
  159.                  start.hour, start.min, start.sec,
  160.                  end.hour,   end.min,   end.sec);
  161.         printf ("                        type ESC to abort\r");
  162.  
  163.         os_create_task (GET_ESC);              /* ESC check in display loop   */
  164.         escape = 0;                            /* clear escape flag           */
  165.         display_time = 1;                      /* set display time flag       */
  166.         os_clear_signal (COMMAND);             /* clear pending signals       */
  167.  
  168.         while (!escape)  {                     /* while no ESC entered        */
  169.           printf ("Clock Time: %02bd:%02bd:%02bd\r",      /* display time     */
  170.                    ctime.hour, ctime.min, ctime.sec);
  171.           os_wait (K_SIG, 0, 0);               /* wait for time change or ESC */
  172.         }
  173.  
  174.         os_delete_task (GET_ESC);              /* ESC check not longer needed */
  175.         display_time = 0;                      /* clear display time flag     */
  176.         printf ("\n\n");
  177.         break;
  178.  
  179.       case 'T':                                /* Set Time Command            */
  180.         if (readtime (&inline[i+1]))  {        /* read time input and         */
  181.           ctime.hour = rtime.hour;             /* store in 'ctime'            */
  182.           ctime.min  = rtime.min;
  183.           ctime.sec  = rtime.sec;
  184.         }
  185.         break;
  186.  
  187.       case 'E':                                /* Set End Time Command        */
  188.         if (readtime (&inline[i+1]))  {        /* read time input and         */
  189.           end.hour = rtime.hour;               /* store in 'end'              */
  190.           end.min  = rtime.min;
  191.           end.sec  = rtime.sec;
  192.         }
  193.         break;
  194.  
  195.       case 'S':                                /* Set Start Time Command */
  196.         if (readtime (&inline[i+1]))  {        /* read time input and         */
  197.           start.hour = rtime.hour;             /* store in 'start'            */
  198.           start.min  = rtime.min;
  199.           start.sec  = rtime.sec;
  200.         }
  201.         break;
  202.  
  203.       default:                                 /* Error Handling              */
  204.         printf (menu);                         /* display command menu        */
  205.         break;
  206.     }   
  207.   }
  208. }
  209.  
  210.  
  211. /******************************************************************************/
  212. /*        signalon: check if clock time is between start and end              */
  213. /******************************************************************************/
  214. bit signalon ()   {
  215.   if (memcmp (&start, &end, sizeof (struct time)) < 0)  {
  216.     if (memcmp (&start, &ctime, sizeof (struct time)) < 0  &&
  217.         memcmp (&ctime, &end,   sizeof (struct time)) < 0)  return (1);
  218.   }
  219.                                                 
  220.   else  { 
  221.     if (memcmp (&end,   &ctime, sizeof (start)) > 0  &&
  222.         memcmp (&ctime, &start, sizeof (start)) > 0)  return (1);
  223.   }
  224.   return (0);                                  /* signal off, blinking on     */
  225. }
  226.  
  227.  
  228. /******************************************************************************/
  229. /*        Task 3 'blinking': runs if current time is outside start & end time */
  230. /******************************************************************************/
  231. blinking () _task_ BLINKING  {                 /* blink yellow light          */
  232.   red    = 0;                                  /* all lights off              */
  233.   yellow = 0;
  234.   green  = 0;
  235.   stop   = 0;
  236.   walk   = 0;
  237.  
  238.   while (1)  {                                 /* endless loop                */
  239.     yellow = 1;                                /* yellow light on             */
  240.     os_wait (K_TMO, 30, 0);                    /* wait for timeout: 30 ticks  */
  241.     yellow = 0;                                /* yellow light off            */
  242.     os_wait (K_TMO, 30, 0);                    /* wait for timeout: 30 ticks  */
  243.     if (signalon ())  {                        /* if blinking time over       */
  244.       os_create_task (LIGHTS);                 /* start lights                */
  245.       os_delete_task (BLINKING);               /* and stop blinking           */
  246.     }
  247.   }
  248. }
  249.  
  250.  
  251. /******************************************************************************/
  252. /*      Task 4 'lights': executes if current time is between start & end time */
  253. /******************************************************************************/
  254. lights () _task_ LIGHTS  {                     /* traffic light operation     */
  255.   red    = 1;                                  /* red & stop lights on        */
  256.   yellow = 0;
  257.   green  = 0;
  258.   stop   = 1;
  259.   walk   = 0;
  260.   while (1)  {                                 /* endless loop                */
  261.     os_wait (K_TMO, 30, 0);                    /* wait for timeout: 30 ticks  */
  262.     if (!signalon ())  {                       /* if traffic signal time over */
  263.       os_create_task (BLINKING);               /* start blinking              */
  264.       os_delete_task (LIGHTS);                 /* stop lights                 */
  265.     }
  266.     yellow = 1;
  267.     os_wait (K_TMO, 30, 0);                    /* wait for timeout: 30 ticks  */
  268.     red    = 0;                                /* green light for cars        */
  269.     yellow = 0; 
  270.     green  = 1;
  271.     os_clear_signal (LIGHTS);
  272.     os_wait (K_TMO, 30, 0);                    /* wait for timeout: 30 ticks  */
  273.     os_wait (K_TMO + K_SIG, 250, 0);           /* wait for timeout & signal   */
  274.     yellow = 1;
  275.     green  = 0;
  276.     os_wait (K_TMO, 30, 0);                    /* wait for timeout: 30 ticks  */
  277.     red    = 1;                                /* red light for cars          */
  278.     yellow = 0;
  279.     os_wait (K_TMO, 30, 0);                    /* wait for timeout: 30 ticks  */
  280.     stop   = 0;                                /* green light for walkers     */    
  281.     walk   = 1;
  282.     os_wait (K_TMO, 100, 0);                   /* wait for timeout: 100 ticks */
  283.     stop   = 1;                                /* red light for walkers       */        
  284.     walk   = 0;
  285.   }
  286. }
  287.  
  288.  
  289. /******************************************************************************/
  290. /*        Task 5 'keyread': process key stroke from pedestrian push button    */
  291. /******************************************************************************/
  292. keyread () _task_ KEYREAD  {
  293.   while (1)  {                                 /* endless loop                */
  294.     if (key)  {                                /* if key pressed              */
  295.       os_send_signal (LIGHTS);                 /* send signal to task lights  */
  296.     }
  297.     os_wait (K_TMO, 2, 0);                     /* wait for timeout: 2 ticks   */
  298.   }
  299. }
  300.