Вы находитесь на странице: 1из 8

SECRETARIA DE EDUCACIN PBLICA

INSTITUTO TECN DE MORE

INSTITUTO TECNOLGICO DE MORELIA

Reporte de prctica 3

Obtencin De la Transformada Rpida De Fourier De Una Seal Discreta A Travs De Un uC

David Raymundo Pin vila No Adrin Acua Prado


Prof: Dra. Adriana del Carmen Tllez Anguiano

Morelia, Michoacn

25 de Abril del 2013

Algoritmo de programacin en C empleando el micro controlador ATMEGA48 para calcular la DFT


#include #include #include #include <mega48.h> <alcd.h> <delay.h> <stdlib.h> //libreria del microcontrolador atmega48 //Librerya de funciones de la LCD // Libreria de funciones de los retardos // Libreria de funciones estandar de C.

struct complex // Creacin de una estructura compleja que consta de dos { int re; //tipos de variables uno real y uno imaginario. int im; }; struct complex complex_set(int real, int imag) // Fucion para crear un numero complejo, recibe dos valorer. { struct complex c; c.re=real; c.im=imag; return c; }; struct complex suma (struct complex a, struct complex b) // Funcion para sumar un numero complejo { struct complex resultado; resultado.re=a.re+b.re; resultado.im=a.im+b.im; return resultado; }; struct complex multiplicacion (struct complex a, struct complex b) //Multiplicacion de un nmero complejo { // (a+jb)(c+jd)=a*c + jad + jbc-bd struct complex resultado; resultado.re=a.re*b.re-a.im*b.im; resultado.im=a.re*b.im+a.im*b.re; return resultado; }; void main(void) { // Declaracion de variables locales empleadas en el programa char buffer [8]; int x[8]={12,-8,-5,-8,0,0,9,9}; int x21[2],x22[2],x23[2],x24[2],columna=0,enteros,decimales; struct complex x11_0,x11_1,x11_2,x11_3,tmp; struct complex x12_0,x12_1,x12_2,x12_3; struct complex XDFT; struct complex e; // Ajuste de la frecuencia de reloj a 1 MHz reloj #pragma optsizeCLKPR=(1<<CLKPCE); CLKPR=(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0); #ifdef _OPTIMIZE_SIZE_ #pragma optsize+

#endif // Declaracin de el Puerto B como salida. Es empleado para la comunicacin de la pantalla LCD DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0); PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0); DDRD = 0X00; PORTD = 0X03; lcd_init(16); //El numero 16 dentro de la funcion lcd_init el el tamao de la LCD a utilizar

while (1) //Ciclo infinito { //----------------------------------// Calculos necesarios para obtener la DFT x21[0] = x[0]+x[4]; x21[1] = x[0]-x[4]; x22[0] = x[2]+x[6]; x22[1] = x[2]-x[6]; x23[0] = x[1]+x[5]; x23[1] = x[1]-x[5]; x24[0] = x[3]+x[7]; x24[1] = x[3]-x[7]; //---------------------------------// Es multiplicado por mi los valores para poder trabajar // los numeros como enteros y obtener una mejor exactitud en los valore finales x11_0.re = (x21[0]+x22[0])*1000; x11_1 x11_1.re x11_1.im x11_2.re x11_3 x11_3.re x11_3.im x12_0.re x12_1 x12_2.re x12_3 = complex_set(x21[1],-x22[1]); // Crea un numero complejo = x11_1.re*1000; = x11_1.im*1000; = (x21[0] - x22[0])*1000; = complex_set(x21[1],x22[1]); = x11_3.re*1000; = x11_3.im*1000; = = = = x23[0]+x24[0]; complex_set(x23[1],-x24[1]); x23[0] - x24[0]; complex_set(x23[1],x24[1]); // Crea un numero complejo

// Crea un numero complejo // Crea un numero complejo

// Seleccin del la columna a mostrar del vector de la DFT (anterior o siguiete) if(PIND.0 ==0 && columna <7) { // Si se presiona el botn del pin 0 Puerto D delay_ms(20); // mostrar el siguiente valor y si se encuentra en el ultimo valor columna++; // este se sigue mostrando. } if(PIND.1 ==0 && columna > 0) // Si se preciona el vboton del pin 1 del Puerto D {// muestra el valor anterior y si se encuentra en el primer valor

delay_ms(20); columna--; }

// permanece en este.

// El codigo dentro del swith escoje que opcion es la que se quiere // que se muestre y se guanda en XDFT como la transformada es para un vector de 8 son 8 casos // e se multiplica por 1000 ya que todo se esta multiplicando por mil. tmp = complex_set(0,0); guarde valores anteriores switch(columna & 7) { // borra los valores de tmp para que no

case 0: e = complex_set(1000,0); tmp = multiplicacion(x12_0,e); XDFT = suma(x11_0, tmp); X12[0]e^(0) break; case 1: e = complex_set(707,-707); j0.707 tmp=multiplicacion(x12_1,e); XDFT = suma(x11_1, tmp); X12[1]*e^(-j*2*PI/8) break; case 2: e = complex_set(0,-1000); tmp=multiplicacion(x12_2,e); XDFT = suma(x11_2, tmp); X12[2]*e^(-j*2*PI*2/8) break; case 3: e = complex_set(-707,-707); 0.707 + j0.707 tmp=multiplicacion(x12_3,e); XDFT = suma(x11_3, tmp); X12[3]*e^(-j*2*PI*3/8) break; case 4: e = complex_set(-1000,0); tmp=multiplicacion(x12_0,e); XDFT = suma(x11_0, tmp); X12[4]*e^(-j*2*PI*4/8) break; case 5: e = complex_set(-707,707); 0.707 + j0.707 tmp=multiplicacion(x12_1,e); XDFT = suma(x11_1, tmp); X12[5]*e^(-j*2*PI*5/8) break; case 6: e = complex_set(0,1000); tmp=multiplicacion(x12_2,e); XDFT = suma(x11_2, tmp); X12[6]*e^(-j*2*PI*6/8)

// e^(0) = 1 aqui es 1000 // X12[0]*e^(0) // H1[0] = X11[0] +

//

e^(-j*2*PI/8) = 0.707 -

// X12[1]*e^(-j*2*PI/8) // H1[1] = X11[1] +

// e^(-j*2*PI*2/8) = -j // X12[2]*e^(-j*2*PI*2/8) // H1[2] = X11[2] +

//

e^(-j*2*PI*3/8) = -

// X12[3]*e^(-j*2*PI*3/8) // H1[3] = X11[3] +

// e^(-j*2*PI*4/8) = -1 // X12[4]*e^(-j*2*PI*4/8) // H1[4] = X11[4] +

//

e^(-j*2*PI*5/8) = -

// X12[5]*e^(-j*2*PI*5/8) // H1[5] = X11[5] +

// e^(-j*2*PI*6/8) = j // X12[6]*e^(-j*2*PI*6/8) // H1[6] = X11[6] +

break; case 7: e = complex_set(707,707); j0.707 tmp=multiplicacion(x12_3,e); XDFT = suma(x11_3, tmp); break; default: break; }

// e^(-j*2*PI*7/8) = 0.707 + // X12[7]*e^(-j*2*PI*7/8)

//========================================================================= // Mostrar en la LCD el valor real del numero complejo

// Se obtienen los enteros dividiendo entre 1000 la variable XDFT donde su // valor depende de la selecion del caso a mostrar en el switch enteros = XDFT.re/1000; // obtencion de enteros decimales = XDFT.re%1000; // Obtencion de decimales // Si los decimales son menores que cero todo se multiplica por -1 para quitar el signo // ya que este al momento de mostrarse en pantalla es asignado por en el funcion lcd_puts() if(decimales<0) { decimales*=-1; enteros*=-1; itoa(enteros, buffer); // Conversin de la variable string en Integer y se guada en buffer lcd_gotoxy(0,0); // Pocicona el cursor en la posicion (0,0) de la pantalla LCD lcd_puts("real= -"); // Escribe en pantalla el string lcd_puts(buffer); // Escribe en la lcd el valor de buffer lcd_puts("."); itoa(decimales, buffer); // Conversin de la variable string en Integer y se guada en buffer lcd_puts(buffer); // Escribe en la lcd el valor de buffer } else { itoa(enteros, buffer); // Escribe en la lcd el valor de buffer lcd_puts("real= "); // Escribe en pantalla el string lcd_puts(buffer); // Escribe en la lcd el valor de buffer lcd_puts("."); itoa(decimales, buffer); // Conversin de la variable string en Integer y se guada en buffer lcd_puts(buffer); // Escribe en la lcd el valor de buffer }

//=========================================================================

// complejo

Mostrar en la LCD el valor imaginario del numero

// Se obtienen los enteros dividiendo entre 1000 la variable XDFT donde su // valor depende de la selecion del caso a mostrar en el switch enteros = XDFT.im/1000; // obtencion de enteros decimales = XDFT.im%1000; // obtencion de decimales // Si los decimales son menores que cero todo se multiplica por -1 para quitar el signo // ya que este al momento de mostrarse en pantalla es asignado por en el funcion lcd_puts() if(decimales<0) { decimales*=-1; enteros*=-1; itoa(enteros, buffer); // Conversin de la variable enteros Integer en string y se guada en buffer lcd_gotoxy(0,1); // Pocicona el cursor en la posicion (0,1) de la pantalla LCD lcd_puts("imag= - "); // Escribe en pantalla el string lcd_puts(buffer); // Escribe en la lcd el valor de buffer lcd_puts("."); itoa(decimales, buffer); // Conversin de la variable decimales (Integer) en stringy se guada en buffer lcd_puts(buffer); // Escribe en la lcd el valor de buffer lcd_clear(); // Limpia pantalla del lcd } else //En caso de que sean positivos los valores { itoa(enteros, buffer); // Conversin de la variable enteros Integer en string y se guada en buffer lcd_gotoxy(0,1); // Pocicona el cursor en la posicion (0,1) de la pantalla LCD lcd_puts("imag= "); // Escribe en pantalla el string lcd_puts(buffer); // Escribe en la lcd el valor de buffer lcd_puts("."); itoa(decimales, buffer); // Conversin de la variable decimales (Integer) en stringy se guada en buffer lcd_puts(buffer); // Escribe en la lcd el valor de buffer lcd_clear(); // Limpia pantalla del lcd } } }

Conclusiones:
David Raymundo Pin vila La transformada discreta de Fourier (DFT por sus siglas en ingles) es una operacin que es similar a la transformada de Fourier de funciones analgicas, la diferencia radica en que una funcin analgica se integra en el dominio del tiempo, es decir la funcin debe de ser integrable, para la transformada discreta de Fourier la funcin descrita no existe ya que se trata de valores dados por un muestreo, as

que no es posible integrar una serie de puntos. Es entonces donde se emplea otro mtodo similar pero haciendo uso de sumatorias de nmeros complejos. Si se desea realizar algn tipo de procesamiento de alguna funcin discreta, es decir, muestreada por algn dispositivo digital es muy complicado, ya que para obtener la transformada discreta de Fourier es necesario hacer bastantes operaciones de suma y multiplicacin. Este procedimiento consume mucho recurso del dispositivo. Existe un mtodo alternativo para obtener la transformada discreta de Fourier denominada transformada rpida de Fourier (FFT por sus siglas en ingles). Este mtodo obtiene la transformada discreta de Fourier con muchas menos operaciones, lo cual ahora en gran medida el procesamiento de la funcin muestreada. Con la realizacin de la prctica se pudo comprobar que existen dos mtodos para encontrar la transformada discreta de Fourier, uno de ellos es muy simple de realizar para nosotros, DFT, ya que estamos familiarizados con hacer operaciones directas, a diferencia de la transformada rpida de Fourier, FFT, que es necesario obtener bastantes seales auxiliares y el nmero de stas aumentan a medida que aumenta el nmero de muestras. Sin embargo `para el uC le resulta ms simple y ms rpido hacer uso de la FFT ya que las lneas de comando se volvieron muy simples y el uC responda rpidamente ante el clculo de la FFT.

No Adrian Acua Prado


Mediante la DFT se obtiene una representacin en el dominio de la frecuencia, siendo la funcin original una funcin en el dominio del tiempo. Pero la DFT requiere que la funcin de entrada sea una secuencia discreta y de duracin finita, tal como se muestra al momento de ingresar los valores de la seal, estos son valores dicretos con duracin finita. En este caso la seal no fue muestreada, simplemente se ingresaron los valores de una seal. Al estar trabajando con microncontroladores en ocaciones nos vemos limitados al trabajar con ciertas ecuaciones matemticas ya que no tienen soporte lo uC para todo tipo de ecuaciones, por lo que es conveniente trabajar con algebra bsica. Tal como se muestra en el cdigo del programa las operaciones para obtener la transformada fueron simplemente algebra. Al parecer, para una persona realizar este proceso llevara tiempo, sin embargo, para un uC que realiza instrucciones en el orden de los useg es muy poco tiempo. Se tuvieron inconvenientes de desbordamiento de datos y no se puede execer el lmite de memoria del uC. Por lo que el programa solo sirve para valores

pequeos. Una mejor que se pudiera tener es quitar la librera stdlib.h ya que este tipo de librera es muy pesada y se carga por completo al Microcontrolador, tambin se tendra que quitar la funcin que convierte los enteros en string y tendramos ms espacio para cambiar de valores enteros a unos con mayor capacidad.

Вам также может понравиться