1
votes

I am trying to understand this piece of code, What I am not able to understand is how the interrupt routine works as the OCR1A is getting updated. I am using AVR series of controller to run this code.

 void TimerInit(void)
    {
        DISABLE_TIMER_INT;  // Disable timer interrupt

        m_nGlobalTime = 0;  // Reset system time

        OCR1A  += TICKS_PER_MSECOND;    // Set first clock period

        TCCR1A  = 0;// Set TimerMode to Normal
        TCCR1B |= (1 << CS10);// ClckIo, no pre-scaler; set TimerMode

        ENABLE_INTERRUPTS;
        ENABLE_TIMER_INT;// Enable send timer interrupt (1 ms)
    }



    ISR( TIMER1_COMPA_vect) {
        uint16_t nTemp; 

        nTemp = TCNT1;  // Get current time
        nTemp -= OCR1A; // Subtract interrupt time

        if (nTemp < (TICKS_PER_MSECOND / 2))// If more than half period left    
        {
            OCR1A += (TICKS_PER_MSECOND);// Add Offset to OCR1A relative
        } 
        else
        {
            OCR1A = TCNT1 + (TICKS_PER_MSECOND);// Set OCR1A to 1 ms absolute
        }

        m_nGlobalTime++;                                                            
    }
1

1 Answers

1
votes

The usual way to get an output compare interrupt to fire at a regular interval is to add a constant amount to the OCR1A. This is happening at

OCR1A += (TICKS_PER_MSECOND);

For some reason, the writer added some extra logic to handle bad luck. Perhaps, the period is too short, or maybe the OC interrupt may be delayed due to some other interrupt running.

If these cases were to occur, then the next OC interrupt would not occur TICKS_PER_MSECOND later than the last, but rather TICKS_PER_MSECOND plus an entire cycle of the counter. That is, the correct time would be missed, as the OC register would be set to a number after the number has been passed.

This code is an attempt to correct for this situation. That being said, I'm not sure it works correctly. The potential problem is that nTemp is unsigned, so the < comparison might not do what the writer expects.