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!