Essentially, you provide a value for the OCR0A and it will count up to that value and send a high to PB2 when it does. Then it will get back to counting again. By setting the prescale first and then changing the OCR0A you can produce different frequencies.
Elliot Williams’ Make: AVR Programming was helpful for this code!
/*
* Attiny84 timers.c
*
* Created: 2/1/2019 5:14:43 PM
* Author : FablabDigiscope
* Variable frequency with timer
*/
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
TCCR0A |= (1<<COM0A0); // toggle pin on match
TCCR0A |= (1<<WGM01); // CTC mode (once hits OCRA)
TCCR0B |= (1<<CS00) | (1<<CS01); // Prescale: CPU clock div. by 64
DDRB = 0b00000100; // PB2 is OC0A (HOOK UP BUZZER HERE)
while (1)
{
OCR0A = 0b00111111;
_delay_ms(1000);
OCR0A = 0b11111111;
_delay_ms(1000);
OCR0A = 0b00000111;
_delay_ms(1000);
OCR0A = 0b00000011;
_delay_ms(1000);
}
}
The problem I had with this project was reading the high and low bytes of the ADC.