4
\$\begingroup\$

I am programming a PIC18F4520 and I've set it to use a 32Mhz internal clock.

I need a counter to tick every second so I'm using TMR0 for this purpose.

To use TMR0, I have set the following:

  • Prescaler 1:256
  • 16 Bit mode
  • High level interrupt on TMR0 overflow.

To set the timer to count every 1 second, I've calculated it as follows:

TMR0 = (Required time)/(4 * Timer clock * prescale value)
     = 1 / (4  * (1/32000000) * 256)
     = 31250

So, TMR0 = 0xFFFF - 31250.

Is this correct? If not, what am I missing? The code is as follows:

#pragma code
void main(void)
{
    //Set clock frequency
    OSCCON |= 0x70;             //8 Mhz clock, primary clock
    OSCTUNEbits.PLLEN = 1;          //4x Multiplier, thus we have 32 Mhz clock
    while (!OSCCONbits.IOFS);       //Wait until INTOSC is stable.

    //Enable TRISA as analog input (For ADC)
    TRISA = 0x2F;

    //PIN Outputs
    TRISB = 0;              //Make PORTD as output
    //Reset PORTB
    PORTB = 0;

    //Set ADC
    OpenADC(ADC_FOSC_32 &           //Fosc/32
         ADC_RIGHT_JUST &
         ADC_4_TAD,             //4xTAD
         ADC_CH0 &
         ADC_REF_VDD_VSS &
         ADC_INT_OFF, ADC_5ANA);        //ADC CH0-CH4 Initialized

    //Set Timer0
    OpenTimer0( TIMER_INT_ON &
                T0_16BIT &
                T0_SOURCE_INT &
                T0_PS_1_256);

    //Write Timer
    WriteTimer0(CLOCK_TICK);

    INTCON2bits.TMR0IP = 1;         //TMR0 has high overflow interrupt priority
    RCONbits.IPEN = 1;                  //enable priority levels
    INTCONbits.GIEH = 1;            //enable high interrupts

    //Begin
    while (TRUE)
    {

    }

    CloseADC();             //Closing ADC
    CloseTimer0();
}

On my high level interrupt vector, I've done this:

#pragma code 
#pragma interrupt high_priority_interrupt 
void high_priority_interrupt()
{
    if (INTCONbits.TMR0IF)                  //TIMER0 overflowed
    {
        //Stuff
        second += 1;
        if (second == 60)
        {
            minute += 1;
            second = 0;
        }

        if (minute == 60)
        {
            measure_and_switch();
            WriteTimer0(CLOCK_TICK);
            minute = 0;
        }

        INTCONbits.TMR0IF = 0;              //Clear TIMER0 overflow bit.
    }
}

So, basically, every 2 minutes, I want the method measure_and_switch() to be executed. Should I follow it with WriteTimer0()?

Btw: CLOCK_TICK is TMR0 (calculation from above).

Thanks

\$\endgroup\$
4
  • \$\begingroup\$ Can you tell us what is happening now? I can't see that from the question itself. \$\endgroup\$
    – AndrejaKo
    May 28, 2012 at 0:05
  • \$\begingroup\$ My timer was off-course (clock ticks wasn't "synced"). I resolved it. Thanks. :-) \$\endgroup\$ May 28, 2012 at 0:24
  • \$\begingroup\$ Don't forget to post the solution as an answer and accept it after two days! \$\endgroup\$
    – AndrejaKo
    May 28, 2012 at 0:25
  • \$\begingroup\$ Sweet, will do. \$\endgroup\$ May 28, 2012 at 0:34

1 Answer 1

4
\$\begingroup\$

The answer is simple. When the overflow bit occurs and the interrupt is raised, we need to first write the counter to TMR0 and reset the TMR0IF flag.

This solution works:

#pragma code 
#pragma interrupt high_priority_interrupt 
void high_priority_interrupt()
{
    if (INTCONbits.TMR0IF)              //TIMER0 overflowed
    {
        //Stuff
        second += 1;
        if (second == 60)
        {
            minute += 1;
            second = 0;
        }

        if (minute == 60)
        {
            measure_and_switch();
            minute = 0;
        }

        WriteTimer0(CLOCK_TICK);        //Write the count to TMR0.
        INTCONbits.TMR0IF = 0;          //Clear TIMER0 overflow bit.
    }
}

I hope this helps anyone. :-)

\$\endgroup\$
1
  • \$\begingroup\$ You should also check for TMR0IE before entering the function since it may be set even if you cleared the TMR0IE bit. \$\endgroup\$
    – fhlb
    Mar 11, 2016 at 12:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.