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...
/***************************************************
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.3 KB)