[McHUG] Arduino Timer help
n3sb at qis.net
n3sb at qis.net
Tue Sep 21 20:13:56 EDT 2010
Hi John;
Here's an Arduino program that uses the 16 bit timer to generate an
interrupt at 26400 Hz. You should be able to adapt it to your needs.
It uses one of the Output Compare registers to generate an interrupt
when the 16 bit timer, running at 16 MHz, matches the output compare
value. In the interrupt routine the program adds the right delay value
to the current output compare register value, and sets up for the next
interrupt.
Using this technique you can create all kinds of useful, very accurate
time delays. The interrupt routine itself will NOT cause a cumulative
time error because the timer itself keeps running.
NOTE: Be careful if you modify variables in the interrupt routine that
are used elsewhere in the program. You'll need to declare those
variables as volatile so that the compiler always fetches a new copy
of the variable from memory for your calculations.
73; Steve, N3SB
// Program interrupt1 written November 15, 2008 N3SB
//
// This program sets up a 26400 Hz interrupt on an Arduino (ATMega168 based)
// From that interrupt, timing for other packet functions can be
developed (1200 Hz tone, 2200 Hz tone, and 1200 baud bit rate).
// Macro and other defines
// Variable defines
unsigned int intcount = 0;
unsigned char ledon = 0;
unsigned char count1200 = 0;
unsigned char count2200 = 0;
unsigned char on1200 = 0;
unsigned char on2200 = 0;
// Pin Defines
int ledpin = 13; // Arduino pin used by the LED
int pin2200 = 12; // pin where the 2200 Hz signal will appear
int pin1200 = 11; // pin where the 1200 Hz signal will appear
// Arduino runs at 16 MHz; to get to 26400 Hz we count 606 clocks
// 16000000 / 606 = 26402.64 Hz (within 0.01%)
//
// We will use the 16 bit timer 1 hardware, and the COMPA interrupt.
ISR(TIMER1_COMPA_vect)
{
count1200++; // Counter for 1200 Hz tone. Toggles
every 11 interrupts at 26400 Hz, or 2400 times per second.
if (count1200 == 11)
{
count1200 = 0;
if (on1200 == 0)
{
digitalWrite(pin1200, HIGH);
on1200 = 1;
}
else
{
digitalWrite(pin1200, LOW);
on1200 = 0;
}
}
count2200++; // Counter for 2200 Hz tone. Toggles
every 6 interrupts at 26400 Hz, or 4400 times per second.
if (count2200 == 6)
{
count2200 = 0;
if (on2200 == 0)
{
digitalWrite(pin2200, HIGH);
on2200 = 1;
}
else
{
digitalWrite(pin2200, LOW);
on2200 = 0;
}
}
intcount++; // Counter for 1 Hz LED Blink
if (intcount == 26400)
{
intcount = 0;
if (ledon == 0)
{
digitalWrite(ledpin, HIGH);
ledon = 1;
}
else
{
digitalWrite(ledpin, LOW);
ledon = 0;
}
}
OCR1A = OCR1A + 606; // Set Output Compare register for
the next interrupt in 606 cycles
} // end of timer interrupt routine
void setup() {
pinMode(ledpin, OUTPUT); // configure LED pin for output
pinMode(pin1200, OUTPUT);
pinMode(pin2200, OUTPUT);
digitalWrite(ledpin, LOW); // turn off LED
// Serial.begin(9600);
// Serial.println(" ");
// Serial.println("Program Interrupt1 - 15 November 2008 - N3SB");
// Serial.println(" ");
//Timer1 Settings: Normal Mode, Timer Prescaler / 1
TCCR1A = 0;
TCCR1B = 1;
//Timer1 Overflow Interrupt Enable
TIFR1 |= (1<<OCF1A); // Clear any pending output compare A interrupts
TIMSK1 |= (1<<OCIE1A); // Timer1 Output Compare A Interrupt Enable
OCR1A = TCNT1 + 606;
TIMSK0 = 0; // Disable Timer0 interrupts (enabled
in Arduino setup code)
sei();
} // end of Arduino setup structure
void loop()
{
delay(1000); // give the main loop something to do.
} // end of Arduino loop structure
Quoting John Yost <k3yjp at yahoo.com>:
> Hi Pete,
>
> Nothing yet. If I let the timers just run to the max and overflow
> they work ok,
> but I want to set the TOP to a lower value than MAX to get the
> interrupt at the
> interval I want.
>
> Thanks for a reply
> John
> K3YJP
>
>
>
> ----- Original Message ----
> From: Peter Morton <mortonph at comcast.net>
> To: MicroController Ham User Group - Physical Computing for Ham Radio
> <mchug at mailman.qth.net>
> Sent: Tue, September 21, 2010 7:21:07 PM
> Subject: Re: [McHUG] Arduino Timer help
>
> John-
>
> I was just wondering if you got any responses. Didn't see any on McHug.
>
> I haven't played with the Arduino or ATMEGA for several years and my timer
> expertise was limited then. Hope you find some help.
>
> -Pete, W3GVX.
>
>
> ----- Original Message -----
> From: "John Yost" <k3yjp at yahoo.com>
> To: "MicroController Ham User Group - Physical Computing for Ham Radio"
> <mchug at mailman.qth.net>
> Sent: Monday, September 20, 2010 8:22 PM
> Subject: [McHUG] Arduino Timer help
>
>
>> I am trying to adjust a 16 bit timer to count to a value less than the max
>> xFFFF.
>>
>> I see examples in sketches for sound generation but can't get them to work
>> properly.
>>
>> In one case I want to load TCNT5 (timer5 on a Mega) with 12500, with a
>> prescale
>> of 64 to get a 50ms overflow interrupt.(hummm, probably can't cause an
>> overflow
>> but should cause something else to happen)
>>
>> One method I tried used one of the compare modes but it screwed up a bunch
>> of
>> pins.
>>
>> Also tried this on the BBB with no luck there as well.
>>
>> Any thoughts
>>
>> thanks
>>
>> John
>> K3YJP
>>
>>
>>
>>
>> ______________________________________________________________
>> McHUG mailing list
>> Home: http://mailman.qth.net/mailman/listinfo/mchug
>> Help: http://mailman.qth.net/mmfaq.htm
>> Post: mailto:McHUG at mailman.qth.net
>>
>> This list hosted by: http://www.qsl.net
>> Please help support this email list: http://www.qsl.net/donate.html
>
> ______________________________________________________________
> McHUG mailing list
> Home: http://mailman.qth.net/mailman/listinfo/mchug
> Help: http://mailman.qth.net/mmfaq.htm
> Post: mailto:McHUG at mailman.qth.net
>
> This list hosted by: http://www.qsl.net
> Please help support this email list: http://www.qsl.net/donate.html
>
>
>
>
> ______________________________________________________________
> McHUG mailing list
> Home: http://mailman.qth.net/mailman/listinfo/mchug
> Help: http://mailman.qth.net/mmfaq.htm
> Post: mailto:McHUG at mailman.qth.net
>
> This list hosted by: http://www.qsl.net
> Please help support this email list: http://www.qsl.net/donate.html
>
More information about the McHUG
mailing list