/* Play music with your robot! Buzzer example for the Orangutan/ATmega168. This example uses Timer2 in "Clear Timer/Counter on Compare Match" mode to generate the buzzer frequency. The counter is incremented at 125 kHz, and resets when count = OCR2A. Upon reset, buzzer port pin is toggled. The longest period before overflow (when OCR2A=255) corresponds to 488 Hz or buzzer frequency=244 Hz. Higher frequencies are set by reducing the value of OCR2A. In this example, notes are defined according to the equal interval twelve tone scale. CPU clock frequency assumed to be 8 MHz. If different, TCCR2 divider should be changed appropriately. Produces about 1312 bytes of loaded code with -O3 sjames_remington at yahoo dot com */ #define F_CPU 8000000UL #include #include #include // TIMER 2 Interrupt service vector // This routine is called with TIMER2 count (TCNT2) = OCR2A, which is set on the fly // Operation is to simply toggle the buzzer line // ISR(TIMER2_COMPA_vect) { PORTB ^= 1; //toggle buzzer output line } /* Set up buzzer to play tones. Timer/Counter 2 is used in CTC mode, clear timer on compare/match Clocked at 125 kHz, = 8MHz/64 OCR2A overflow buzzer value freq freq 255 488 244 ("concert A" = 440 Hz) 128 976 488 64 1953 976 32 3906 1953 For other clock ratios, multiply or divide accordingly Individual notes are = base frequency*2^(1/12), on twelve tone scale (1.05946 multiplicative factor) Here, we define notes by the value of OCR2A: A0 255 A2 63 A3 31 A# 241 67 33 B 227 71 35 C 214 75 37 C# 202 80 40 D 191 85 42 D# 180 90 44 E 170 95 47 F 161 101 50 F# 152 107 53 G 143 113 56 G# 135 120 59 A1 127 127 A2 63 */ /* define three octaves of notes for coding convenience. x=sharp */ #define p 0 //pause, no sound #define a0 255 #define ax0 241 #define b0 227 #define c0 214 #define cx0 202 #define d0 191 #define dx0 180 #define e0 170 #define f0 161 #define fx0 152 #define g0 143 #define gx0 135 #define a1 127 #define ax1 120 #define b1 113 #define c1 107 #define cx1 101 #define d1 95 #define dx1 90 #define e1 85 #define f1 80 #define fx1 75 #define g1 71 #define gx1 67 #define a2 63 #define ax2 59 #define b2 56 #define c2 53 #define cx2 50 #define d2 47 #define dx2 44 #define e2 42 #define f2 40 #define fx2 37 #define g2 35 #define gx2 33 #define a3 31 void init_buzzer(void) { DDRB |= 1; //set data direction reg bit 0 to output PORTB &=~(1); //set buzzer output low TCCR2A= (1< counter increments at 8 MHz/64 = 125 kHz, // ... Counter overflows at 125kHz/256 = 488 Hz => lowest buzzer freq = 244 Hz TCNT2=0; //clear counter OCR2A=255; //set both compare match registers to MAX OCR2B=255; //set both compare match registers to MAX TIMSK2=(1<0); return 0; }