This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
/*** PROJETO DE MICROCONTROLADORES LÍVIA LISANDRO JUDICE GODOY UFRJ - 2014.1 O CÓDIGO A SEGUIR: - Analisa o espectro de frequencia atraves da Transformada Rapida de Fourier - FFT - Indica a frequencia com maior espectro e seu modulo - Envia o espectro de frequencia para o PSIM atraves da UART - Dados da FFT: Pontos: 128; 128 amostragens no tempo transformarao em 128 pontos de frequencia fs: 7,68 kHz; taxa de amostragem fo: 60 Hz; passo entre as frequencias */ //------------------ Inclui funções auxiliares ------------------------- #include "dsp.h" #include "p33Fxxxx.h" #include "fft.h" #include <timer.h> #include <outcompare.h> #include <uart.h> #include <stdio.h> #include "def.h" //---------------------- Define constantes ------------------------------- #define display PORTB //----------------- Declaração de variaveis globais----------------------------------- fractional sinal_Entrada [128]= { //vetor que ira armazenar os dados de entrada, declarados para simulacao. tb testa o programa. 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x7FFF, 0x8001, 0x8001, 0x8001, 0x8001, 0x8001,
OpenUART2(U2MODEvalue, U2STAvalue, baud); //inicia UART2 } //********************** Envia dados para o computador pela serial UART *************** void transmite_dados () { unsigned int dadotx; int a, modulo_int; float modulo_dec; //-------------------------------------------------------------------- dadotx = 252; // inicio do bloco de dados while(BusyUART2()); //aguarda fim da ultima transmissao WriteUART2(dadotx); //envia delayms(1); //-------------------------------------------------------------------- //envia parte inteira dos 64 sinais for ( a = 0; a < PONTOS_FFT/2; a++ ) //envia modulo das 64 frequencias pela serial { // Encontra o modulo de cada frequencia temp3_pnt = &sinalComplexo[0].real ; //inicializa ponteiro temp3_pnt = temp3_pnt + a; tempFrac = *temp3_pnt; tempFloat = tempFrac; tempFloat = tempFloat / 32767; // Converte fracionario para float modulo = sqrt (tempFloat); // Extrai a raiz quadrada da soma dos quadrados da parte real/imaginaria dadotx = (modulo * 100); // Escalona o sinal para enviar pela serial while(BusyUART2()); //aguarda fim da ultima transmissao WriteUART2(dadotx); //envia delayms(1); } //------------------------------------------------------------------------ dadotx = picoFrequenciaBin + 65;//envia indice de maior frequencia while(BusyUART2()); //aguarda fim da ultima transmissao WriteUART2(dadotx); //envia delayms(1); //------------------------------------------------------------------ dadotx = 253; //checa envio do bloco de dados while(BusyUART2()); //aguarda fim da ultima transmissao WriteUART2(dadotx); //envia delayms(1); //------------------------------------------------------------------ //envia parte decimal dos 64 sinais for ( a = 0; a < PONTOS_FFT/2; a++ ) //envia modulo das 64 frequencias pela serial { // Encontra o modulo de cada frequencia temp3_pnt = &sinalComplexo[0].real ; //inicializa ponteiro temp3_pnt = temp3_pnt + a; tempFrac = *temp3_pnt; tempFloat = tempFrac;
tempFloat = tempFloat / 32767; // Converte fracionario para float modulo = sqrt (tempFloat); // Extrai a raiz quadrada da soma dos quadrados da parte real/imaginaria modulo_int = (modulo * 100); //encontra a partem inteira do sinal modulo_dec = (modulo * 100) - modulo_int; //encontra a parte decimal do sinal dadotx = (modulo_dec * 100); //escalona para enviar pela serial if ( dadotx > 164 ) dadotx = 164; //limita parte decimal de 0 a 99 while(BusyUART2()); //aguarda fim da ultima transmissao WriteUART2(dadotx); //envia delayms(1); } //------------------------------------------------------------------ dadotx = 254; // fim do bloco de dados while(BusyUART2()); //aguarda fim da ultima transmissao WriteUART2(dadotx); //envia delayms(1); } //*********************************** MAIN int main (void) //inicio do programa { int i = 0; fractional *p_real = &sinalComplexo[0].real ; fractcomplex *p_complexo = &sinalComplexo[0] ; //-------------- Inicia pinos de I/O do dsPIC ---------------------------------- TRISB = 0xff0f; TRISFbits.TRISF0 = 0; TRISDbits.TRISD0 = 0; TRISDbits.TRISD1 = 0; //------------------ Inicia variaveis ------ n = 0; buffer = 0; buffercheio = 0; tempFloat = 0; //-----Inicia perifericos do dsPIC ----- uart_init (); //inicializa comunicacao UART
init_timer1 (); //inicia timer1 para interromper a 7,68 k samples //---- Envio de mensagem ao PSIM while (1) //loop infinito { if (buffercheio) //confere se chegou fim das amostragens { p_real = &sinalComplexo[0].real ; //inicializa ponteiro p_complexo = &sinalComplexo[0]; //inicializa ponteiro for ( i = 0; i < PONTOS_FFT; i++ ) //move buffer do sinal de entrada (real)para vetor da FFT { *p_real = sinal_Entrada [i] ; *p_real++; //incrementa o ponteiro } p_real = &sinalComplexo[0].real ; //inicializa ponteiro for ( i = 0; i < PONTOS_FFT; i++ ) //Escalona o vetor para o range [-0.5, +0.5] { *p_real = *p_real >>1 ; //desloca 1 bit para a direita *p_real++; } p_real = &sinalComplexo[(PONTOS_FFT/2)-1].real ; //inicializa o ponteiro para parte real do vetor p_complexo = &sinalComplexo[PONTOS_FFT-1] ; for ( i = PONTOS_FFT; i > 0; i-- ) //Converte vetor real para vetor complexo { (*p_complexo).real = (*p_real--); (*p_complexo--).imag = 0x0000; //Não possui parte imaginaria, escreve valor zero } // Cálculo da FFT - Transformada Rapida de Fourier FFTComplexIP (LOG2_ESTAGIOS_BUTTERFLY, &sinalComplexo[0], (fractcomplex *) __builtin_psvoffset(&twiddleFactors[0]), (int) __builtin_psvpage(&twiddleFactors[0]));
// Organiza dados da saída da FFT - Bit-reverso BitReverseComplex (LOG2_ESTAGIOS_BUTTERFLY, &sinalComplexo[0]); // Calcula a soma do quadrado das partes real e imaginária transformando vetor complexo em um vetor real. Sinal = real^2 + imaginario^2 SquareMagnitudeCplx(PONTOS_FFT, &sinalComplexo[0], &sinalComplexo[0].real); // Encontra a frequency Bin ( indice da frequencia) que possui a maior energia VectorMax(PONTOS_FFT/2, &sinalComplexo[0].real, &picoFrequenciaBin); // Calcula a frequencia em Hz com maior espectro picoFrequencia = picoFrequenciaBin*(TAXA_AMOSTRAGEM/PONTOS_FFT); // Encontra o modulo da frequencia de pico temp3_pnt = &sinalComplexo[0].real ; //inicializa ponteiro temp3_pnt = temp3_pnt + picoFrequenciaBin; tempFrac = *temp3_pnt; tempFloat = tempFrac; tempFloat = tempFloat / 32767; // Converte fracionario para float modulo = sqrt (tempFloat); // Extrai a raiz quadrada da soma dos quadrados da parte real/imaginaria //tempFloat = Fract2Float (tempFrac); //converte fracional para float, usando funcao da biblioteca DSP //modulo = sqrt (tempFloat); // Extrai a raiz quadrada da soma dos quadrados da parte real/imaginaria linha2 (11); //posiciona cursor do LCD buffer16 = modulo*100000; //ajusta valor para indicar no LCD lcdval16(); //envia modulo da frequencia para lcd linha1 (4); //posiciona cursor do LCD buffer16 = picoFrequencia; lcdval16(); //envia frequencia de pico para lcd transmite_dados (); //transmite dados pela serial UART (RS232) buffercheio = 0; EnableIntT1 ; //habilita interrupcao do timer para reiniciar amostragens } } } /* Fim */