
/************************************************************************/
/*                                                                      */
/*			High Precise Time Base				*/
/*                                                                      */
/*              Author: Peter Dannegger                                 */
/*                      danni@specs.de                                  */
/*                                                                      */
/************************************************************************/
#pragma cd pl(30000)


#define uchar	unsigned char
#define uint	unsigned int

#include <reg51.h>

/************************************************************************/
/*									*/
/*	Insert your crystal frequency and you get exact 1 second	*/
/*	without need understanding why :				*/
/*									*/
/**/	#define XTAL		12345701L			      /**/
/*									*/
/************************************************************************/

#define T0_RELOAD	((uint) (XTAL / 12.0 / 256.0 + 0.5))

#define T0_RELOAD_1S	((uint) (XTAL / 12.0 - 255.0 * T0_RELOAD + 0.5))

#define T0_STOP_CYCLES	16			// calculated with list file

bit F_1second = 0;

union bw{
  int w;
  struct{
    char h;
    char l;
  }b;
};


void t0_int( void ) interrupt 1
{
  static uchar prescaler = 0;
  union bw i;
  if( --prescaler == 0 ){
    EA = 0;
    TR0 = 0;
    i.b.l = TL0;
    i.b.h = TH0;
    i.w += -T0_RELOAD_1S + T0_STOP_CYCLES;	//   1 * every second
    TL0 = i.b.l;
    TH0 = i.b.h;
    EA = 1;
    TR0 = 1;
    F_1second = 1;
  }else{
    EA = 0;
    TR0 = 0;
    i.b.l = TL0;
    i.b.h = TH0;
    i.w += -T0_RELOAD + T0_STOP_CYCLES;		// 255 * every second
    TL0 = i.b.l;
    TH0 = i.b.h;
    EA = 1;
    TR0 = 1;
  }
}

