Use of TMR2 for One Second Timing

copyright, Peter H Anderson, Baltimore, MD, July, '09


// tmr2_1.c  SourceBoost C, PIC16F886, ICD2 using MPLAB
//
// Illustrates the use of TMR2 for one second timing.
//
// Interrupts discusssed beginning on Microchip Manual page 216.
//
// Toggles LED on PORTB.4 every one second.  Also, independently flashes LED
// on PORTB.5 in bursts. nominally every five seconds.
//
// copyright, Peter H Anderson, July 19, '09

#include <system.h>
#include <icd2.h>

#pragma DATA 0x2007, 0x28e4
#pragma DATA 0x2008, 0x3eff
#pragma CLOCK_FREQ 4000000

#define byte unsigned char

#define FALSE 0
#define TRUE !0

void flash_burst(byte num, byte ms);

byte t2_timeouts;    // note that this is global

void main()
{
    byte n;
    osccon = 0x61;	// 4.0 MHz interrnal clock
    anselh = 0x00;

    portb.4 = 0;
    trisb.4 = 0;

    portb.5 = 0;
    trisb.5 = 0;

    t2con = 0x4d; // prescale of 4, post scale of 10
    pr2 = 249;	  // 250
                  // Thus, TMR2 interrupt every 1 us * 4 * 250 * 10 or every 10 ms

    pie1.TMR2IE = 1;  intcon.PEIE = 1;  pir1.TMR2IF = 0;

    t2_timeouts = 0;

    tmr2 = 0x00;
    intcon.GIE = 1;

    while(1)
    {
		flash_burst(25, 50);
        delay_s(5);

    }
}

void flash_burst(byte num, byte ms)
{
	while(num--)
	{
		portb.5 = 1;
		delay_ms(ms);
		portb.5 = 0;
		delay_ms(ms);
	}
}


void interrupt(void) // interrupt service routine
{
    if (pir1.TMR2IF)
    {
        pir1.TMR2IF = 0;
        ++t2_timeouts;

        if (t2_timeouts == 100) // 100 * 10 ms = 1 sec
        {
             t2_timeouts = 0;
             portb.4 = (portb.4) ? 0 : 1;
        }

    }
}