I am trying to create a time delay interrupt with Arduino. I would like to use the interrupts() function, because it is an internal interrupt.
Example: Let's say, I would like to make a light blink on and off, with only the timing of the interrupt.
There is sample code, but it uses external interrupts (attachInterrupt()). I would like to remain using the internal interrupts.
Answer
Noah Stahl's blog has an example of blinking a LED with Timer2. With that and the data sheet, you should be able to adapt it to whichever interrupt you want to use -- i.e., the interrupt whose normal function you can most afford to give up or are willing to modify. Timer2 is usually used for some PWM functions.
His example cites the ATmega2560; I can confirm that it works with an ATmega328p as well. Look around his site for more useful Arduino interrupt examples.
Edit:
Here's my slightly edited -- mostly in the comments -- version of Noah's code. Call Timer2init() from the Arduino setup() function after you initialize any related data-structures or hardware, because timing - and interrupting - will begin once you do.
F/ex, I used it to multiplex a 3-digit 7-segment display so I before initializing the timer, I initialized the display I/O registers and blanked the display data in the place where the ISR will look for it.
There is a table in the comments of some useful timing data from the data-sheet and my own calculations for reference to set up another timing scheme.
The ISR() macro takes care of creating interrupt entry- and exit-code for an ISR instead a normal function's entry and exit, and of linking it with the proper interrupt vector. The rest of that function is 1) the code to be run at each interrupt, and 2) the code code to reset the timer for the next interrupt.
As written, this should drop in to a .pde or .ino sketch (or a .cpp file, if you use eclipse, f/ex). The sketch needs to #define LEDPIN, and setup() needs to call Timer2init(). The loop function may be empty or not; the LED should start flashing on download (well, literally, after Timer2init() is called).
/*
* From sample interrupt code published by Noah Stahl on his blog, at:
* http://arduinomega.blogspot.com/p/arduino-code.html
*
*/
/*** FUNC
Name: Timer2init
Function: Init timer 2 to interrupt periodically. Call this from
the Arduino setup() function.
Description: The pre-scaler and the timer count divide the timer-counter
clock frequency to give a timer overflow interrupt rate:
Interrupt rate = 16MHz / (prescaler * (255 - TCNT2))
TCCR2B[b2:0] Prescaler Freq [KHz], Period [usec] after prescale
0x0 (TC stopped) 0 0
0x1 1 16000. 0.0625
0x2 8 2000. 0.500
0x3 32 500. 2.000
0x4 64 250. 4.000
0x5 128 125. 8.000
0x6 256 62.5 16.000
0x7 1024 15.625 64.000
Parameters: void
Returns: void
FUNC ***/
void Timer2init() {
// Setup Timer2 overflow to fire every 8ms (125Hz)
// period [sec] = (1 / f_clock [sec]) * prescale * (255-count)
// (1/16000000) * 1024 * (255-130) = .008 sec
TCCR2B = 0x00; // Disable Timer2 while we set it up
TCNT2 = 130; // Reset Timer Count (255-130) = execute ev 125-th T/C clock
TIFR2 = 0x00; // Timer2 INT Flag Reg: Clear Timer Overflow Flag
TIMSK2 = 0x01; // Timer2 INT Reg: Timer2 Overflow Interrupt Enable
TCCR2A = 0x00; // Timer2 Control Reg A: Wave Gen Mode normal
TCCR2B = 0x07; // Timer2 Control Reg B: Timer Prescaler set to 1024
}
/*** FUNC
Name: Timer2 ISR
Function: Handles the Timer2-overflow interrupt
Description: Maintains the 7-segment display
Parameters: void
Returns: void
FUNC ***/
ISR(TIMER2_OVF_vect) {
static unsigned int led_state = 0; // LED state
led_state = !led_state; // toggles the LED state
digitalWrite(TOGGLE_PIN, led_state);
TCNT2 = 130; // reset timer ct to 130 out of 255
TIFR2 = 0x00; // timer2 int flag reg: clear timer overflow flag
};
No comments:
Post a Comment