The FrequencyTimer2 library steals the hardware timer2 from the PWMs on pin 11 and 3(on a atmega168) and reprograms it to generate a frequency of your choosing. It can toggle pin11 if you wish or call a function you supply each cycle.
Version 2 adds support for newer boards, including Arduino Uno (and other '328-based boards), Arduino Mega, Teensy++ and Sanguino. It also updates the library for compatibility with Arduino 1.0.
all methods are static, call them with a FrequencyTimer2:: in front.
The library is about 600 bytes plus 4 bytes of SRAM.
You can retrieve this library from frequencytimer2.zip. Unpack it in your lib/targets/libraries/ directory and include it in your sketch.
FYI: You may have to remove the #if defined() statements from the CPP library for the FrequencyTimer2 to work with boards using the ATMEGA 328.
Following is my little test program. You can issue commands like
#include <FrequencyTimer2.h> void setup() { pinMode(11,OUTPUT); Serial.begin(19200); delay(2); Serial.print("Ready"); FrequencyTimer2::setPeriod(200); FrequencyTimer2::enable(); } long burpCount = 0; extern "C" void Burp(void) { burpCount++; } void loop() { static unsigned long v = 0; if ( Serial.available()) { char ch = Serial.read(); switch(ch) { case '0'...'9': v = v * 10 + ch - '0'; break; case 'p': FrequencyTimer2::setPeriod(v); Serial.print("set "); Serial.print((long)v, DEC); Serial.print(" = "); Serial.print((long)FrequencyTimer2::getPeriod(), DEC); Serial.println(); v = 0; break; case 'e': FrequencyTimer2::enable(); break; case 'd': FrequencyTimer2::disable(); break; case 'o': FrequencyTimer2::setOnOverflow( Burp); break; case 'n': FrequencyTimer2::setOnOverflow(0); break; case 'b': Serial.println(burpCount,DEC); break; case 'x': #if defined(__AVR_ATmega168__) Serial.print("TCCR2A:"); Serial.println(TCCR2A,HEX); Serial.print("TCCR2B:"); Serial.println(TCCR2B,HEX); Serial.print("OCR2A:"); Serial.println(OCR2A,HEX); #else Serial.print("TCCR2:"); Serial.println(TCCR2,HEX); Serial.print("OCR2:"); Serial.println(OCR2,HEX); #endif Serial.print("TCNT2:"); Serial.println(TCNT2,HEX); break; } } }