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

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

      Example code for using timer1 on a 16C745

      In this code we can adjust interrupt period from 1mS up to more than 100ms.

      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 Timer1
   *  Set Xtal Frequency, chose a Period and a Prescale then 
   *  calculate Prelode. Check That Preload is not upper than 0xFFFF
   *  and not too low. Change prescale as possible.
   */
  #define XTAL        6000000     // crystal frequency - 6MHz
  #define PERIOD        10000     // interrupt period in uS
  //#define   PRESCALE          0     // prescale by 1
  //#define   PRESCALE          1     // prescale by 2
  //#define   PRESCALE          2     // prescale by 4
  #define PRESCALE          3     // prescale by 8

  #define PRELOAD ((PERIOD*(XTAL>>(2+PRESCALE)))/1000000)
  #define PRELOADH    (unsigned char)((PRELOAD>>8)&0xff)
  #define PRELOADL    (unsigned char)(PRELOAD&0xff)

  /* Globals vars */
  unsigned long   ticks=0;    // ticks count. May be in integer
  unsigned char   seconds=0;  // second count for demo


  /* service routine for Timer1 interrupt */
  void interrupt
  timer1_isr(void)
  {
      ticks++;
      seconds = ticks/(1000000/PERIOD);

  //  TMR1ON = 0;             // Timer1 Off
      TMR1H = -PRELOADH;      // reload Timer hight value
      TMR1L = -PRELOADL;      // reload Timer low value
  //  TMR1ON = 1;             // Timer1 ON
      TMR1IF = 0;             // clear Timer1 overflow interrupt flag
      TMR1IE = 1;             // enable Timer1 overflow interrupt
  }

  main()
  {
      // initialize Timer1;
      T1CON = (PRESCALE<<4);  // T1CKPS:00    prescaler by 1,2,4,8
                              // T1OSGEN:0    Oscillator is shut off
                              // T1SYNC:0     Don't care
                              // TMR1CS:0     Select internal clock
                              // TMR1ON:1     Enable Timer1 

      TMR1H = -PRELOADH;      // preload Timer hight value
      TMR1L = -PRELOADL;      // preload Timer low value

      TMR1CS = 0;         // Select internal clock
      TMR1IF = 0;         // clear Timer1 overflow interrupt flag
      TMR1ON = 1;         // enable Timer1
      TMR1IE = 1;         // enable Timer1 overflow interrupt
      PEIE = 1;           // enable all un-masqued peripheral interrupts
      GIE = 1;            // enable global interrupts


      // Display seconds on port B 
      RBPU = 0;               // PortB pull-ups enabled
      TRISB = 0;              // all bits output

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