Pages: [1]   Go Down
Author Topic: TIMER0_OVF_vect compile error  (Read 785 times)
0 Members and 1 Guest are viewing this topic.
Olympia, WA
Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

To learn more about timer/counters I started a test program to exercise various interrupts.
I ran in to the following compile error...suggestions?

core.a(wiring.c.o): In function `__vector_16':
C:\Users\Deborah\Desktop\arduino-1.0.1\hardware\arduino\cores\arduino/wiring.c:49: multiple definition of `__vector_16'
QuadTimer0Tests.cpp.o:C:\Users\Deborah\AppData\Local\Temp\build4138623748755652255.tmp/QuadTimer0Tests.cpp:116: first defined here

Here is the code...
Code:
/***************************************************
  QuadTimerInterruptTests
    Uses Arduino Uno Timer/Counters to explore timing relationships.
    1/4/2013  Lloyd Goodwin
  */
  //
  #include <avr/io.h>
  #include <avr/interrupt.h>
  //
  volatile uint16_t loopCounter = 0;   // count each cycle thru the main loop
  //
    //////////// Vector #15 #16 #17 //////////////////////////////////
    //  Timer/Counter0 Register descriptions
    //
    //  Timer/Counter0 Control Register A
    //  TCCR0A  COM0A1  Compare Output Mode Channel A    pin OC0A  pin PD6
    //          COM0A0 
    //          COM0B1  Compare Output Mode Channel B    pin OC0B  pin PD5
    //          COM0B0
    //          WGM01   Waveform Generation Mode
    //          WGM00
    //
    //------- Compare Output Mode, non-PWM Mode --------------
    #define COM0A_TOGGLE                (1<<COM0A0)      // 01
    #define COM0A_CLEAR     (1<<COM0A1)                  // 10
    #define COM0A_SET      ((1<<COM0A1)|(1<<COM0A0))     // 11
    //
    //------ Waveform Generation Mode Bit Description --------
    //  Mode WGM02 WGM01 WGM00 Mode of   TOP    Update   TOV Flag
    //                         Operation         OCRx     Set on
    //                                            at
    //   0     0     0     0   Normal    0xFF  Immediate   MAX
    //   1     0     0     1   PWM-pc*   0xFF     TOP     BOTTOM
    //   2     0     1     0   CTC       OCRA  Immediate   MAX
    //   3     0     1     1   Fast PWM  0xFF   BOTTOM     MAX
    //   4     1     0     0   Reserved
    //   5     1     0     1   PWM-pc*   OCRA     TOP     BOTTOM
    //   6     1     1     0   Reserved
    //   7     1     1     1   Fast PWM  OCRA   BOTTOM     TOP
    //  *pc means Phase Correct
    //  MAX   =0xFF
    //  BOTTOM=0x00
    #define TIMER0_WGM_MODE1  (1<<WGM00)
    // -----------------------------------------------------------
    //  Timer/Counter0 Control Register B
    //  TCCR0B  FOC0A   Force Output Compare A
    //          FOC0B   Force Output Compare B
    //
    //          WGM02   Waveform Generation Mode used with WGM01 & WGM00
    //
    //          CS02:0  Clock Select Bits       000  No clock source (Timer/Counter stopped)
    //                                          001  clk i/o / 1 (No prescaling)
    //                                          010          / 8
    //                                          011          / 64
    //                                          100          / 256
    //                                          101          / 1024
    //                                          110  External clock source on T0 - falling edge
    //                                          111                              - rising edge
    //
    #define TIMER0_CLOCK_1      (1<<CS00)
    #define TIMER0_CLOCK_8      (1<<CS01)
    #define TIMER0_CLOCK_64    ((1<<CS01)|(1<<CS00))
    #define TIMER0_CLOCK_256    (1<<CS02)
    #define TIMER0_CLOCK_1024  ((1<<CS02)|(1<<CS00))
    //----------------------------------------------------------
    //  Timer/Counter0 Interrupt Mask Register
    //  TIMSK0  OCIE0B  Output Compare B Match Interrupt Enable    0 = not enabled
    //             OCIE0A  Output Compare A Match Interrupt Enable    0 = not enabled
    //             TOIE0   Overflow Interrupt Enable                           0 = not enabled
    //
    //  the corresponding interrupt is executed if a compare match occurs, i.e.,
    //  the corresponding bit in TIFR0 is set
    #define TIMER0_OVERFLOW_DISABLE   (1<<TOIE0)
    //----------------------------------------------------------
    //  Timer/Counter0 Interrupt Flag Register
    //  TIFR0  OCF0B  Output Compare B Match Flag
    //         OCF0A  Output Compare A Match Flag
    //         TOV0   Overflow Flag
    //
    //  If SREG I-bit and OCIE0n bit are set, then a match will will trigger
    //  execution of the interrupt
    //
    ///////////// setup_timer0_overflow /////////////////////////////////////
    // 
    void setup_timer0_overflow(char scaler)
    {
      cli();
      //  test results: apparently OCR0B, OCR0A, and TCCR0A don't need to be reset
      //OCR0B   =  0;                         // reset register
      //OCR0A   =  0;                         // reset register
      //TCCR0A  =  0;                         // reset register
      //-------------
      TCCR0A  =  0;                         // reset register
      TCCR0B  =  0;                         // reset register
      TCCR0B |= scaler;                     // set the prescaler
      TIMSK0 |= ~TIMER0_OVERFLOW_DISABLE;   // set the overflow mask (~ was the key to make it work)
      sei();
      //  a cpu reset is being issued somewhere because setup() is re-entered on
      //    on overflow interrupt.  Why?
    }
  //////////// Vector #15 //////////////////////////////////
  ISR(TIMER0_COMPA_vect)
  {
    Serial.print("+15 ");
  }
  //////////// Vector #16 //////////////////////////////////
  ISR(TIMER0_COMPB_vect)
  {
    Serial.print("+16 ");
  }
  //////////// Vector #17 //////////////////////////////////
  ISR(TIMER0_OVF_vect)
  {
    cli();
    Serial.print("+17 ");
    loopCounter = 17;
    sei();
  }
//////////////////////////////////////////////////////////////////////////////////
  void setup()
  {
    Serial.begin(57600);
    Serial.print(" TIMER0.");
    Serial.print(micros());
    Serial.print(".");
    Serial.print(MCUCR,HEX);
    Serial.print(".");
    //------- test Timer/Counter0 --------
    setup_timer0_overflow(TIMER0_CLOCK_1024);   // loopCounter gets to 22, then system restarts with setup()
    Serial.print(TCCR0A,HEX);
    Serial.print(".");
    Serial.print(TCCR0B,HEX);
    Serial.print(".");
    Serial.println(TIMSK0,HEX);
    //
    //
  }
  //////////////////////////////////////////////////////////////////////////////////
  void loop()
  {
    if (loopCounter>300) { return; }
    loopCounter++;
    Serial.println(loopCounter);
  }
  //////////////////////////////////////////////////////////////////////////////////


* QuadTimer0Tests.ino (11.31 KB - downloaded 3 times.)
Logged

Offline Offline
Sr. Member
****
Karma: 9
Posts: 254
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I believe the problem is that TIMER0 is used by the Arduino library for the delay, micros and millis functions, if you know you are not going to be using these you may be able to change this by playing around with wiring.c, but this may have unexpected results, particularly if you are planning on using any other libraries.
It is generally better to use one of the other timer/counter modules, they all do slightly different things but from a very quick look at your code I think you've got the right idea. Have a look at the ATMEL ATmega328 datasheet as this goes in to loads of detail on what each timer does.
Logged

Olympia, WA
Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In the interests of full disclosure...

Originally the ISR was coded as "ISR(Timer0_OVF_vect)" and then I noticed that I had used lowercase letters.  That version does compile and the overflow condition forces a restart (not sure why).

The modified code has "Timer0_OVF_vect" written with uppercase letters, i.e. "TIMER0_OVF_vect" and it is this version that generates a compile time error.  Surly, someone has working code that uses the TIMER0 overflow interrupt.
Logged

Offline Offline
Edison Member
*
Karma: 116
Posts: 2205
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
ISR(TIMER0_COMPA_vect)
Code:
  ISR(TIMER0_COMPB_vect)
Code:
  ISR(TIMER0_OVF_vect)

Once you have read the device header file, you will know why.

Code:
    cli();
    Serial.print("+17 ");
    loopCounter = 17;
    sei();

That's not going to work.
Logged

Olympia, WA
Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, which header file are you referencing?
Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 197
Posts: 12741
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I believe the problem is that TIMER0 is used by the Arduino library for the delay, micros and millis functions,...

Correct...
https://github.com/arduino/Arduino/blob/master/hardware/arduino/cores/arduino/wiring.c#L43

Quote
...if you know you are not going to be using these you may be able to change this by playing around with wiring.c, ...

Why bother.  Timer 2 is almost identical and almost unused.

Quote
Surly, someone has working code that uses the TIMER0 overflow interrupt.

See the link above.

Quote
To learn more about timer/counters I started a test program to exercise various interrupts.

I suggest using timer 2 (or timer 1).  It is only used for PWM, there is no associated interrupt handler, and timer 0 and timer 2 are almost identical.
Logged

Olympia, WA
Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you all for your guidance.
Logged

Pages: [1]   Go Up
Jump to: