O código fonte:
///************************************************************************/ // contador de pulsos - (frequencimetro) // Version : 1.0 // microcontrolador : AVR ATMega8 // Autor : Aguivone // descrição : captura de sinais // data : 09/12/2011. // //************************************************************************/ #define F_CPU 16000000UL // 16 MHz deve vir antes das interrupçoes #include <avr/io.h> #include <avr/interrupt.h> #include <stdio.h> #include <util/delay.h> #include <string.h> int amostra1, amostra2 ; int dig1='0'; int dig2='0'; int dig3='0'; int dig4='0'; int dig5='0'; int valor_lido=0; int frequencia; int tem_interrupcao=0; int estouro = 0; /////////////////////////////////////////////////Funções usadas///////////////////////////////////////////// void inicializa_timer1(void) { //TIMSK = 0x21; //Habilita interrupção de captura do timer1 , e habilita interrupção de estouro do contador1 TIMSK = 0x20; //Habilita interrupção de captura do timer1 , e habilita interrupção de estouro do contador1 TCCR1A=0X00;//desabilita geração de pulsos TCNT1=0x00;//zera contagem; OCR1A =0x00;//desabilita comparadores OCR1B =0x00;//desabilita comparadores TCCR1B=0x41;//filtro de ruido desabilitado(atrasa 4 ciclos),habilita interrupção na borda de subida,preescaler div por 1 /* pra outros valores basta mudar o ultimo digito para: 1-dividido por 1 2-dividido por 8 3-dividido por 64 4-dividido por 256 5-dividido por 1024 obs: o registrador ICR1 só pode ser zerado no modo de geração de pulso. ou seja é melhor zerar o TCNT1, pois quando o conteudo deste for copiado ele será zerado tambem. */ } ///////////////////////////////////////////////funçoes usadas pela usart//////////////////////////////////////////////// void serial_inicializa(unsigned int BAUD) { unsigned int valor = F_CPU/16/BAUD-1; //é recomendavel ver o data sheet para ter certeza se está formula irá funcionar na sua mcu /* baud rate */ UBRRH = (unsigned char)(valor>>8); UBRRL = (unsigned char)valor; UCSRA = 0X20; /* habilita receiver and transmitter buffers */ UCSRB = 0X98;//deve se habilitar somente a interrupção de recepção para não travar o microcontrolador /* 8 bits , 1 stop bit, assincrono , sem paridade */ UCSRC = 0X86; } void impri_serial(const char frase[80]) { unsigned int indice=0; unsigned int tamanho = strlen(frase); while(indice<=tamanho)///veja que o programa pode travar se aqui não tiver as duas aspas { while ( !( UCSRA & (1<<UDRE)) ); //espera transmitir para enviar um novo UDR =frase[indice]; indice++; } } void put_serial(int carac) { while ( !( UCSRA & (1<<UDRE)) ); //espera transmitir para enviar um novo UDR = carac; } void converte(int quant)//converte int para 3 caracter numerico { dig1='0'; dig2='0'; dig3='0'; dig4='0'; dig5='0'; if(quant > 0) { while(quant>=10000) { quant=quant-10000; dig1++; } while(quant>=1000) { quant=quant-1000; dig2++; } while(quant>=100) { quant=quant-100; dig3++; } while(quant>=10) { quant=quant-10; dig4++; } while(quant>=1) { quant=quant-1; dig5++; } } } //////////////////////////interrupções do timer1 /////////////////////////////////// ISR(TIMER1_CAPT_vect) {///quando a interrupção é ativada e o vetor de interrupção é zerado unsigned char sreg; cli();//disabilita as interrupçoes TCNT1 = 0;//zera contador sreg = SREG;//salva o valor dos flags de interrupçoes. valor_lido = ICR1; tem_interrupcao = 1; SREG = sreg;//restaura o valor das interrupçoes globais (consequentemente habilita as interrupçoes novamente) } //////////////////////////////////////////////função principal/////////////////////////////////////////// int main(void) { DDRC = 0xFF; //inicializa portd PORTC = 0; inicializa_timer1(); serial_inicializa(9600); sei(); for(;;) {//obs : no laço for não pode ficar sem nenhuma acão,deve ser coisa do compilador if(tem_interrupcao == 1) { frequencia=16000000/valor_lido;//veja que vai ser arredondado para dar o resultado em inteiros. converte(frequencia); put_serial(dig1); put_serial(dig2); put_serial(dig3); put_serial(dig4); put_serial(dig5); put_serial(*"\n"); //pula linha put_serial(*"\r"); //retorna ao inicio da linha estouro =0; } tem_interrupcao=0; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////
A simulação:
Consigo medir na PRATICA frequencias entre 500KHz e 2MHz ?
ResponderExcluir