Olá Amadeu, sou novo em AVR, mas pelo que entendí é só ajustar adequadamente o prescaler. A variação do conteúdo do registrador OCRx te dá a largura do pulso, mas a frequência depende essencialmente da sua fonte de clock.
Por exemplo:
Se no seu main, chamar uma inicialização do tipo a seguir (eu usei Xtal de 11,0592MHz)
- Código: Selecionar todos
void T1_Init_PWM(void)
{
// Configura o Registrador de Controle do Timer 1
TCCR1A = _BV(WGM10) | _BV(WGM11) | _BV(COM1A1); // 10 bits, clear OC1
// TCCR1B |= _BV(CS12) | _BV(CS10); // Prescaler de 1024 (~ 5.26 Hz)
// TCCR1B |= _BV(CS12); // Prescaler de 256 (~ 21.26 Hz)
TCCR1B |= _BV(CS11) | _BV(CS10); // Prescaler de 64 (~ 84.0 Hz)
// TCCR1B |= _BV(CS11); // Prescaler de 8 (~ 677.0 Hz)
// TCCR1B |= _BV(CS10); // Full clock (~ 5.40 kHz)
//
// Ajusta valor de comparação para geração de interrupção
OCR1A = 0;
// Gerar interrupção quando TCNT1 for igual a 0
DDRD |= _BV(PD5); // Define OC1 como saída do sinal PWM (PortD.5)
// Prepara Timer/Counter Interrupt Mask Register para o Timer 1
TIMSK |= _BV(TOIE1); // Ajusta para interrupção por Overflow do Timer 1
}
... e tratar a interrupção fazendo algo do tipo:
- Código: Selecionar todos
ISR (TIMER1_COMPA_vect)
{
static uint16_t PWMCount; // Valor corrente do PWM de 10 bits
static uint8_t direction; // Direção da contagem
//
// Determina o novo valor do PWM
switch (direction) // Verifica a direção
{
case UP: // Se UP..
if (++PWMCount == T1_TOP) // Incrementa e verifica se chegou ao máx.
{
direction = DOWN; // Se chegou ao máximo, muda a direção
}
break;
case DOWN: // Se DOWN..
if (--PWMCount == 0) // Decrementa e verifica se chegou a zero
{
direction = UP; // Se chegou ao mínimo, muda a direção
}
break;
}
//
// Aqui é onde o novo valor computado é carregado no registrador de PWM
// Este registrador deve ser acessado somente aqui dentro da interrupção.
// Se o registrador vier a ser acessado fora da interrupção, assegurar-se que
// as interrupções estejam desabilitadas para evitar corrupção dos valores.
//
OCR1A = PWMCount; // Novo valor de 10 bits
}
Sempre que OCR1A mudar, mudará a largura de pulso do PD5. A frequência é resultado dos ajustes feitos na inicialização.
Espero ter ajudado.