/****************************************************************************

      timer0.c
      v1.0 (22/02/2003)

      Example code for using timer0 on a 16C745

      In tis code we can adjust interrupt period from 1mS up to 21ms.

      Written by Philippe Corbes <philippe.corbes@laposte.net>
      This code is free for personal use. 
      You need my agreement for a commercial use. 

  ****************************************************************************/

  #include    <pic.h>

  __CONFIG( HS & UNPROTECT & BORDIS & WDTDIS & PWRTEN );

  /*
   *  Calculate PRELOAD value for timer 0
   */
  #define PERIOD      20          // interrupt period in mS
  #define XTAL        6000        // crystal frequency - 6MHz
  //#define   PRESCALE    1           // prescale by 2
  //#define   PRESCALE    2           // prescale by 4
  //#define   PRESCALE    3           // prescale by 8
  //#define   PRESCALE    4           // prescale by 16
  //#define   PRESCALE    5           // prescale by 32
  //#define   PRESCALE    6           // prescale by 64
  //#define   PRESCALE    7           // prescale by 128
  #define PRESCALE    8           // prescale by 256

  #define PRELOAD (((XTAL>>2)*PERIOD)>>PRESCALE)
  #if (PRELOAD > 255)
  #warning PERIOD too hight or PRESCALE too small or both
  #endif



  unsigned        ticks=0;    // ticks count
  unsigned char   seconds=0;  // second count


  /* service routine for timer 0 interrupt */

  void interrupt
  //timer0_isr(void) @ 0x10
  timer0_isr(void)
  {
      ticks++;
      seconds = ticks/(1000/PERIOD);

      TMR0 += -PRELOAD;   // re-load timer

      // no need to clear T0IF - the hardware did it
      T0IF = 0;           // clear T0IF
      T0IE = 1;           // enable timer interrupt
  }

  main()
  {

      // initialize timer 0;
      OPTION = PRESCALE-1;    // PS:111   prescaler by 256
                              // PSA:0    Select Timer0
                              // TOSE:0   Don't care
                              // T0CS:0   select internal clock
                              // INTEDG:0 Don't care
      TMR0 = -PRELOAD;    // preload timer
      T0IE = 1;           // enable timer interrupt
      GIE = 1;            // enable global interrupts

      // Initialize port B for dispay
      TRISB = 0;              // all bits output

      // Display seconds on port B 
      for(;;) {
          PORTB = seconds;    // output seconds
          continue;           // let interrupt do its job
      }
  }