O período do PWM é determinado pela taxa de transbordamento do seu timer. Existem muitas configurações na seção Modos de Operação para pensar. Se tudo o que você quer fazer é gerar uma onda quadrada de período constante, com ciclo de trabalho variável, acho que você desejará usar o modo CTC (Clear Timer on Compare Match). A idéia básica é definir OCR0A para o número de marcações do timer até que você queira que o pino alterne a seguir e use a interrupção Compare Match para alterar esse valor pela próxima vez. Portanto, no avr-gcc, seria algo como:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>
// global variables defining number of ticks on and off
uint8_t on_time_ticks, off_time_ticks, csxx_bits=0;
void setup_timer(double p_ms, double duty){
TCCR0A = _BV(COM0A0) // toggle OC0A on Compare Match
TCCR0B = _BV(WGM02); // set CTC mode WGM0[2,1,0] = 0b100
// ... do some stuff based on your CPU frequency
// to define the csxx_bits of TCCR0B when the timer is running
// and consequently, to set on_time_ticks and off_time_ticks
OCR0A = on_time_ticks;
TCCR0B |= your_settings_here;
}
void start_timer(){
//start the timer running at the desired rate
TCCR0B |= csxx_bits;
}
int main(int argc, char **argv){
double period_ms, duty_cycle;
setup_timer(period_ms, duty cycle);
start_timer();
for(;;){
//spin or sleep or whatever
}
}
ISR(TIM0_COMPA_vect){
if(OCR0A == on_time_ticks){
OCR0A = off_time_ticks;
}
else{
OCR0A = on_time_ticks;
}
}
Aviso, este é um código não testado, mas acho que a idéia está correta. De maneira alguma é também a única maneira de fazê-lo.
Há uma coisa que você deve saber sobre o ATTiny13, a propósito. O oscilador RC interno é garantido apenas com precisão de 10% do chão de fábrica. Há um processo de calibração do usuário pelo qual você pode passar (descrito por um appmelote da atmel ) que fornecerá uma precisão de 2% para o ATTiny13. Se você quer fazer melhor do que isso, provavelmente precisará usar um chip que acomoda um cristal externo ...