Pages: [1]   Go Down
Author Topic: Strange behavior of Timer2 interrupt  (Read 425 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi everybody,

I am new to this forum so I take the occasion to say my greetings to all of you.
I am spending some time to play with Arduino and I have my first issue to understand a strange way of working of my code.
Here is the code

Code:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <WProgram.h>

volatile unsigned char tic_counter = 0;
volatile unsigned char led_toggle = 1;

// interrupt service routine that wraps a user defined function supplied by attachInterrupt
ISR(TIMER2_OVF_vect)         
{
    if (tic_counter++ == 61)
    {
        tic_counter = 0;
        PORTB = led_toggle ? 0xFF : 0x00;
        led_toggle = !led_toggle;
        Serial.println("tic!");
    }

}

// Cofiguration for Timer2
// 16 MHz / 1024 = 15625 Hz (prescaler 1024)
// 15625 Hz / 256 = 61.035 Hz (timer2 resolution)
void tic_setup(void)
{
    // Disable interrupts while setting registers
    cli();

    // Use internal clock - external clock not used in Arduino
    ASSR &= ~(1<<AS2);

    // 17.11.1 TCCR2A – Timer/Counter Control Register A
    //   Bit    7      6      5      4      3      2      1      0
    // (0xB0) COM2A1 COM2A0 COM2B1 COM2B0   –      –    WGM21 WGM20
    //          0      0      0      0      0      0      0      0
    // Compare output mode (OC2A): normal port operation
    // Compare output mode (OC2B): normal port operation
    // Waveform generation mode: normal
    TCCR2A = 0x00;
   
    // TCCR2B – Timer/Counter Control Register B
    //   Bit    7     6     5     4     3     2     1    0
    // (0xB1) FOC2A FOC2B   –     –   WGM22  CS22  CS21 CS20
    //          0     0     0     0     0     1     1    1
    // Output compare A & B: 0
    // Prescaler: clkT2S/1024 (From prescaler)
    TCCR2B = 0x07;
   
    // TCNT2 – Timer/Counter Register
    // When normal mode is selected int TCCR2A and TCCR2B, Timer2 counts
    // upwards
    TCNT2 = 0x00;
   
   
    // TIMSK2 – Timer/Counter2 Interrupt Mask Register
    // Bit      7     6     5     4     3     2     1     0
    // (0x70)   –     –     –     –     –  OCIE2B OCIE2A TOIE2
    //          0     0     0     0     0     0     0     1
    // Output Compare A & B Interr. Enable: 0
    // Overflow Interrupt Enable: 1
    TIMSK2 = 0x01;
   
    // Enable global interrupts
    sei();
}
   
int main()
{
    DDRB = 0xFF; // set PORTB for output
    PORTB = 0xFF;

    Serial.begin(115200);
    Serial.println("Initializing Timer Interrupt");
   
    tic_setup();
   
    while(1) ;   // <=== HERE IS THE PROBLEM!
}

Basically I configure Timer2 to trigger an interrupt with the frequency of ~61Hz.

The strange thing is on the infinite loop at the end of the file: if it is present, everything works fine, if not, then the interrupts are not triggered.
I would have expected that the ints were triggered even without the infinite loop.

I am using Linux and I am building using the command line.

Thanks in advance for any possible feedback.

Best,

Y.
Logged

UK, Southwest
Offline Offline
Full Member
***
Karma: 5
Posts: 138
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The code starts main, and it runs through main.  Then it returns from main to ????

You don't want it to exit main, its got to stay under execution control there.  There is no operating system, the processor is executing what instructions you gave it.

Edit:  I've loaded your sketch in the ide, then run avr-objdump -d on the .elf file.
main gets called, and at the end of main it transfers control to exit, where it disables interrupts then goes into a continuous loop. However, I cannot see how it gets out of main - it looks like it should stay the end of main forever.
« Last Edit: February 20, 2011, 06:54:33 pm by shelleycat » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you very much!!!
You are completely right, if you do not put an infinite loop at the end of main() the execution terminates. I should not code by night...
BTW, I wonder about the power consumption when the infinite loop is executing, it should be a kind of 'busy form of waiting'.
Is there any instruction in this case to, let's say, put the execution to 'sleep', without consuming any cpu resources, hence running the code only when the interrupts are triggered?

Thanks again.

Y.
Logged

UK, Southwest
Offline Offline
Full Member
***
Karma: 5
Posts: 138
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes, but you are way out of arduino sketches then.  See the Atmegs spec and sleep mode, and various ways to wake up.  It might be simpler to run at a slower clock rate/lower voltage if you are worried about  power.
Logged

Pages: [1]   Go Up
Jump to: