/* TMR1_INT.C: Set up Timer1 for a 5 Millisecond interrupt. The main program
 * simply counts seconds and displays the current elapsed time.
 * IMPORTANT: Specify "IV (0x4000)" in the compiler invocation line.
 * Link with STARTUP.OBJ for standalone operation.
 * Copyright (c) Blue Earth Research, 1995
 * Author: Tom Bachmann
 * Date: July 13, 1995
 */

#pragma DEBUG CODE
#include <stdio.h>              /* prototypes for standard I/O functions    */
#include <reg51F.h>             /* SFR declarations for the 8xC51FX         */

#define RELOAD      5000        /* Reload value for 5 milliseconds          */
#define RELOAD_LO   ((-RELOAD)&(0xFF))      /* Calculate low and high bytes */
#define RELOAD_HI   (((-RELOAD)&(0xFF00))/(256))

void    timer_interrupt(void);  /* 5 millisecond interrupt routine          */

unsigned char subseconds = 0;
unsigned char flag = 1;
unsigned int seconds = 0;

/****************/
/* main program */
/****************/
void main (void)
{
/* Set up and enable Timer1 for a 5 millisecond timer   */

  TL1 = RELOAD_LO;              /* Load the timer high and low bytes        */
  TH1 = RELOAD_HI;
  TMOD = 0x11;                  /* Timer1 & Timer0 as 16-bit timers         */
  TR1 = 1;                      /* Start the timer              */
  ET1 = 1;                      /* Enable the timer interrupt   */
  EA = 1;                       /* Enable the global interrupt  */

  TI    = 1;                    /* TI:   set TI to send first char of UART  */
  printf("\nCounting\n");       /* Print a sign-on message      */

  while (1) {
    while (flag) {
      ;                         /* Wait here until the clock ticks          */
    }
    printf("%5d\n", seconds);   /* Print the elapsed time       */
    flag = 1;                   /* Clear the clock flag         */
  }
}           /******** END OF THE MAIN BODY ********/

void    timer_interrupt(void) interrupt 3   /* 5 millisecond interrupt      */
{
  TL1 = TL1 + RELOAD_LO + 2 ;   /* Load the timer high and low bytes        */
  TH1 = RELOAD_HI;
  subseconds = subseconds + 1;  /* Increment the 5 millisecond counter      */
  if (subseconds == 200) {      /* and check for one-second rollover        */
    subseconds = 0;
    flag = 0;                   /* Set the flag that ticks with each second */
    seconds = seconds + 1;
  }
}           /******** END OF THE INTERRUPT ROUTINE ********/
