segunda-feira, 25 de fevereiro de 2013

Usando o modo captura de eventos externos no avr.

     Neste exemplo vou demonstrar como capturar e medir o periodo de um sinal aplicado ao pino de captura de eventos externos(pino PB0) do ATmega328P,este exemplo é útil para o momento em que se deseja medir a frequência de um sinal,existe a ainda a possibilidade de habilitar a interrupção do de estouro do timer1 para medir sinal muito longos(deixei comentado mas é só adaptar para a sua necessidade).Quando um botão é pressionado o microcontrolador muda o estado logico do portD e lê o valor que está em ICR1(período), pressionando varias vezes o botão você pode notar que ele dará diferentes valores de período(veja figura abaixo).


     Para achar a frequência basta fazer F=1/T(período),sendo que T = (1/frequência do cristal) X valor lido .segue abaixo o exemplo de código.

Código fonte: 
        
//************************************************************************
//                             usando o modo captura de pulsos 
//  Version    : 1.0
//  microcontrolador : AVR ATMega328
//  Autor        : Aguivone
//  descrição  : captura de eventos externos
//  data : 25/02/2013.
//
//************************************************************************
#define F_CPU 16000000UL  //  deve vir antes das interrupçoes
#include <avr/io.h>
#include <avr/interrupt.h>

int long lido; //variavel que vai ler o valor do registrador

//////////////////////////interrupções do timer0 ///////////////////////////////////
/*
ISR(TIMER1_OVF_vect )
  {                    //interrupção overflow

         PORTD =~ PORTD; //nessa interrupção não é preciso ler ou zerar o TCNT0  aprox 15hz
         //veja que na simulação dará 30hz pois o valor maximo de cristal para simular é 8 mhz
  }
  */
ISR(TIMER1_CAPT_vect)
{              //interrupção de captura de eventos externos.
          int high = ICR1L;//primeiro deve ser lido os byte mais baixo e depois os mais altos
          lido = (ICR1H<<8) + high;
          PORTD =~ PORTD;
          TCNT1 = 0;//limpar o timer
}
/////////////////////////////////////////////////Funções usadas/////////////////////////////////////////////
void inicializa_modo_captura(void)
{
   TCCR1A = 0X00;//não tem uso para o modo captura de eventos externos
   TCCR1B = 0x41;//filtro desabilitado,captura na borda de subida do sinal,clock interno sem prescaler 
   TCCR1C = 0X00;//não tem uso para o modo captura de eventos externos
   TIMSK1 = 0x20; //habilita interrupção de captura
   //TIMSK1 = 0x21; //habilita interrupção de estouro de timer e de captura
   sei(); //habilita interrupções
}
/*
opcional vai depender da aplicação

void parar_timer(void)
{
TIMSK0 = 0x20; //desabilita interrupção do timer 0(estouro do contador)
}

void reiniciar_timer(void)
{
TIMSK0 = 0x21; //habilita interrupção do timer 0(estouro do contador)
}*/
//////////////////////////////////////////////função principal///////////////////////////////////////////
int main(void)
{

            DDRD = 0xFF;  //inicializa portd como saida
            PORTD = 0;//limpa as portas logicas.
            inicializa_modo_captura();
           for(;;)
            {
             //faz nada!
            }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
veja tambem o posto do frequencimetro com o AVR

Nenhum comentário :

Postar um comentário

olá,digite aqui seu comentário!