trialex wrote:Dude this is awesome. Do you have any more details on getting an Arduino working with a watch crystal?
i used two boarduinos, and a usbtinyisp.
built one boarduino with the 16Mhz oscillator and one with a 32.768KHz watch crystal. the watch crystal should be soldered to the two outer pads of the three that the oscillator would have been in. install mega168 in board with 16MHz oscillator. attach usbtinyisp and run avrdude with
- Code: Select all
avrdude -p m168 -cusbtiny -U lfuse:w:0xf2:m
this makes the chip run on its internal 8MHz oscillator. now, with the isp still connected, run the arduino software. from the tools menu select burn bootloader. select lilypad arduino.
now remove the the chip from the board with the oscillator and install it on the board with the watch crystal. you pretty much need a chip puller to remove the chip from the board. it also helps to remove the power select jumper.
you now have a boarduino that runs at 8MHz, instead of the standard 16MHz. everything seems to work. i have my board set up with a 2x16 character lcd and make heavy use of the delay routines. i also use pwm on digital 10 to control the back light on the lcd.
i originally used digital 11 for the backlight, but it turns out that the pwm on digital 11 is generated by timer 2, which we'll have to hijack to use the watch crystal.
out of curiosity i displayed the contents of the timer2 control registers on my lcd and found that the timer was already running when my setup routine was called, so the first thing to do is stop the timer. then we need to change its source from the chip's i/o clock, to the watch crystal and set up an appropriate prescaler. all of this is explained with much obfuscation in the mega168 datasheet.
to set up the timer, use the following code in the setup routine
- Code: Select all
TCCR2A = 0;
TCCR2B = 0; // this stops the timer
TCNT2 = 0; // reset the timer2 counter
ASSR = (1 << AS2); // select watch crystal as clock source
// set prescaler to 128, this starts timer
TCCR2B = (1 << CS22) | (1 << CS20);
TIMSK2 = (1 << TOIE2); // enable timer2 interrupt
and now that you've enabled an interrupt, you'll need an interrupt handler. here's one that turns the led at digital 13 on for 1 second, then off for 1 second.
- Code: Select all
ISR (TIMER2_OVF_vect) {
PORTB ^= (1 << PB5); // digital 13 is portb pin 5
}
i'll post some pics if i can figure out how to set up a flicker account and i'll post my demo code that shows seconds ticking by on an lcd after i clean up the code a little. i just figured out setting up the timer this afternoon.