pwm no avr

Software e Hardware para ATMEL

Moderadores: 51, guest2003, brasilma

pwm no avr

Mensagempor amadeu » 29 Ago 2007 18:44

boa tarde,

já sei usar o pwm no avr, porém somente com o tempo de estouro do timer. Neste caso, caso seja 1 us e o pwm seja de 8 bits, de 256 em 256 está definido o período do pwm. Porém estou precisando utilizar frequencias de pwm diferentes, e não estou sabendo ajustar esta temporização. Por acaso algum dos colegas do fórum sabem me dizer o que devo fazer para alterar o período do pwm?

abs,
amd
amadeu
Nibble
 
Mensagens: 65
Registrado em: 26 Nov 2006 14:49

Mensagempor Fandango » 30 Ago 2007 10:29

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.
Fandango
Byte
 
Mensagens: 187
Registrado em: 11 Jun 2007 22:13
Localização: SC - Brasil


Voltar para AVR

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x