To generate “beep” AVR must generate signal with frequency that human can hear. The human ear can detect sounds with frequencies between 20 and 20,000 Hz. Popular piezo buzzers can generate sound only in specific range, typically it is up to 4 kHz.
For this purpose any PWM mode can be used but in this example Phase correct mode is used.
The waveform frequency is defined by the following equation:
Assuming we use timer1 with 8 bit resolution (the system clock is 8 MHz), by selecting prescaler only we can simply generate sound with the following frequencies:
All the above values except the first one are in the range typical buzzer can play (4kHz max). Prescalers from 8 to 1024 can be used to generate beep.
Greater duty cycle gives louder sound. Reasonable values for duty cycle are in range from 1 to 127 (although these values may vary for different buzzers).
Configure OC1B pin as output
DDRD |= _BV(DDD4);
Configure timer1 in Phase Correct PWM mode
TCCR1A = _BV(WGM10) // PWM, Phase Correct, 8-bit | _BV(COM1A1) // set OC1A on compare match, clear them at top | _BV(COM1B1); // set OC1B on compare match, clear them at top
Prescaler 1 (no prescaler)
TCCR1B |= ~(_BV(CS12) | _BV(CS11) | _BV(CS10));
TCCR1B |= _BV(CS11);
TCCR1B |= _BV(CS11) | _BV(CS10);
TCCR1B |= _BV(CS12);
TCCR1B |= _BV(CS12) | _BV(CS10);
|Compiler||AVR Studio + GCC|
|External hardware||Piezo buzzer/speaker without internal generator|
In the example OC1B pin is used to generate PWM wave. First timer1 is configured to work in 8 bit Phase Correct mode. Then prescaler divider 8 is set, that gives nice beep sound. Writing 100 to OCR1B generate sound. The beep is generated every 1s. Beep sound lasts for 0.5s.
The code contains commented lines for different prescaler configurations. You can uncomment some lines to hear sound of different frequency.