No IRQs generated for Mega128 Timer0 if XDIV is used

1 post / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This topic came up on the CodeVision Yahoo forum about a Mega64. There is a TIMER0_COMP interrupt and a TIMER1_OVF interrupt and the system clock is divided by 4 using the XDIV register.

The Studio Simulator shows both IRQs firing as expected, but when you run in real life with JTAG, the Timer0 IRQs do not occur. The TCNT0 gets clocked quite happily via the prescaled system clock but TIFR never gets the IRQ bits set.

If you reset the XDIVEN bit to stop the main clock division, the Timer0 IRQs re-occur.

There is a Note in the M128 data sheet:

Quote:
Note: When the system clock is divided, Timer/Counter0 can be used with Asynchronous clock
only. The frequency of the asynchronous clock must be lower than 1/4th of the frequency
of the scaled down Source clock. Otherwise, interrupts may be lost, and accessing the
Timer/Counter0 registers may fail.

If you set the AS0 bit in ASSR then Timer0 is clocked from the asynchronous 32kHz TOSC1. And the IRQs function in the usual way.

There is no great surprise that Simulator#1 does not match real-life. However my interpretation of the Atmel Note is that with AS==0, Timer0 is not clocked at all. It says nothing about IRQs being destroyed.

#include 

// Timer 0 output compare interrupt service routine
interrupt [TIM0_COMP] void timer0_comp_isr(void)
{
// Place your code here
    PORTE = PORTE ^ 0x80;       // TP3
}

// Timer1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Reinitialize Timer1 value
    TCNT1H = 0xFFF0 >> 8;
    TCNT1L = 0xFFF0 & 0xff;
    PORTE = PORTE ^ 0x40;       // TP2
}

void main(void)
{
// Crystal Oscillator division factor: 4
#if 1
    XDIV = 0xFD;	//0xFD;
#asm("nop")
#asm("nop")
#asm("nop")
#asm("nop")
#asm("nop")
#asm("nop")
#asm("nop")
#asm("nop")
#endif
// Port E initialization
// Func7=Out Func6=Out Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=1 State6=1 State5=T State4=T State3=T State2=T State1=T State0=T
    PORTE = 0xC0;
    DDRE = 0xC0;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 125.000 kHz
// Mode: CTC top=OCR0
// OC0 output: Disconnected
    ASSR = 0x00;
    TCCR0 = 0x0B;
    TCNT0 = 0x00;
    OCR0 = 0x10;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 250.000 kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// OC1C output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
// Compare C Match Interrupt: Off
    TCCR1A = 0x00;
    TCCR1B = 0x03;
    TCNT1H = 0xFF;
    TCNT1L = 0xF0;
    ICR1H = 0x00;
    ICR1L = 0x00;
    OCR1AH = 0x00;
    OCR1AL = 0x00;
    OCR1BH = 0x00;
    OCR1BL = 0x00;
    OCR1CH = 0x00;
    OCR1CL = 0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
    TIMSK = 0x06;        // Timer0 compare & Timer1 overflow 
    ETIMSK = 0x00;

// Global enable interrupts
#asm("sei")
    while (1) {
    };
}