easy 1MHz clock for shield?

hey up

i need to generate a 1MHz clock for a device I'm putting on a shield.

for some reason, part of my brain suspects that there's way some of configuring the atmel chip to generate this on one of its pins without having to waste cycles doing it in software.

this would also have the benefit of putting the clock on one of the shield connectors.

possible?

i realise i could build a divider circuit for the 16MHz system clock but don't really want to go soldering direct to the pcb unless i really have to.

thanks

ok it, looks like the FrequencyTimer2 library will do 1MHz (max)...

http://www.arduino.cc/playground/Code/FrequencyTimer2

but if it can only toggle pin 11 on overflow then i'll get 500kHz and I need a 1MHz clock.

is there a way of routing the timer's LSB to a pin?

ok it, looks like the FrequencyTimer2 library will do 1MHz (max)...

http://www.arduino.cc/playground/Code/FrequencyTimer2

but if it can only toggle pin 11 on overflow then i'll get 500kHz and I need a 1MHz clock.

is there a way of routing the timer's LSB to a pin?

I considered that library earlier to see if it would help you. Due to that "bug" I mentioned in the other thread, it will actually give you the 1MHz you want if you set it to 1uS.

The problem is it won't work, the MCU isn't fast enough to set it for 1MHz and you'll lock up the MCU because the interrupts occur faster than the interrupt handler finishes processing them.

Using this method, you can't really get faster than 50kHz.

The problem is it won't work, the MCU isn't fast enough to set it for 1MHz and you'll lock up the MCU because the interrupts occur faster than the interrupt handler finishes processing them.

Using this method, you can't really get faster than 50kHz.

Thanks Oracle, but I don't actually need any interrupts. I just want a 1MHz square wave to use as a clock signal for another device.

So if the timer is running at 1MHz I just need to route it to a pin that comes out on the shield connectors, such as 11.

Thanks Oracle, but I don't actually need any interrupts. I just want a 1MHz square wave to use as a clock signal for another device.

So if the timer is running at 1MHz I just need to route it to a pin that comes out on the shield connectors, such as 11.

The FrequencyTimer2 library uses interrupts, so if you go that route, you're using interrupts.

It should be possible to get a 16 MHz pulse because that's the clock speed, and run that through a frequency divider to get 1 MHz. I'm not sure if you can just tap off the crystal but it seems to work for the dual core arduino.

OK, backtracking a bit...

I've read in a few places that an output waveform of up to 8MHz is possible using "Fast PWM" mode and a duty cycle of 50%.

It looks like this should be possible just by assigning values to TCCR2A and TCCR2B to set the counter values, and the waveform will come out on pin 11.

The timer will be free-running, there will be no interrupt service routine involved and it's all happening in hardware.

Am I on the right track here? I don't have a scope so I'm a bit limited to what I can do just with trial and error.

thx!

OK, I've got a waveform coming out of pin 11 but I don't think it's the right frequency (I'm looking for 1MHz).

I found some of this in some old code Mellis posted at http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1141598539
and added a few As to the register names according to what's declared in header files in the hardware/cores/arduino directory.

I've copied over comments as well but they don't necessarily make sense any more.... :wink:

Could someone with a scope handy tell me what frequency this is putting out on pin 11, or maybe what the values for OCR2A and OCR2B should be?

btw I'm using Arduino 0010 and testing this on a freeduino with a '168.

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif

unsigned long clock, period;

void setup() {

Serial.begin(9600);
Serial.println("Alive");

clock = clockCyclesPerMicrosecond() * 1000000;
Serial.print("clock = ");
Serial.println(clock, DEC);

period = clock / (2 * 1000000L);
Serial.print("period = ");
Serial.print(period, DEC);

cli(); // turn interrupts off

// configure timer 2 for phase correct pwm
// this is better for motors as it ensures an even waveform
// note, however, that fast pwm mode can achieve a frequency of up
// 8 MHz (with a 16 MHz clock) at 50% duty cycle
cbi(TCCR2A, WGM21);
sbi(TCCR2A, WGM20);

TIMSK2 = 0 ; // no interrupts

pinMode(11, OUTPUT);

// configure timer 2 for normal (non-inverting) pwm operation
// this attaches the timer to the pwm pin
sbi(TCCR2A, COM2A1);
cbi(TCCR2A, COM2A0);

OCR2A = period;
OCR2B = 0;
}

void loop() {

// tra la la....

}