Sunteți pe pagina 1din 7

Diseño con DSPIC30F4013 en lenguajes MikroBasicPro y MikroCPro for dsPIC Docente: Ing.

Roger Guachalla Narváez


xoroger@yahoo.es

PRACTICA 08: Transformada Discreta de Fourier DFT


1. Objetivos:
Implementar el algoritmo de la Transformada Discreta de Fourier en el controlador digital de señales
dsPIC30F4013
2. Aplicaciones de la Transformada Discreta de Fourier
La transformada discreta de Fourier (DFT) es una de las herramientas más importantes en el
Procesamiento Digital de Señales. Nombraremos tres maneras usuales en las cuales se utiliza la DFT:
 Primero, la DFT puede calcular el espectro de frecuencias de una señal. Esta es una examinación
directa de la información codificada en la frecuencia, fase y amplitud de las componentes
sinusoidales que conforman la señal. Por ejemplo, el habla y el oído humano usan señales con este
tipo de codificación.
 Segundo, la DFT puede encontrar la respuesta en frecuencia desde la respuesta al impulso del
sistema y viceversa. Esto permite que los sistemas sean analizados en el dominio de la frecuencia,
tal y como la convolución permite a los sistemas ser analizados en el dominio del tiempo.
 Tercero, la DFT puede ser usada como un paso intermedio a las técnicas más elaboradas de
procesamiento de señales. El ejemplo clásico es la Transformada Rápida de Fourier (FFT), un
algoritmo que es cientos de veces más rápido que el de los métodos convencionales.

3. Código fuente en MikroC for dsPIC para el algoritmo DFT

1: //Algoritmo de Transformada Discreta de Fourier DFT


2: //Ing. Roger Guachalla Narvaez - xoroger@yahoo.es - May 2013
3: const double PI = 3.14159;
4: const int Np=8; //Np is el numero de puntos en XX[]
5:
6: sbit LCD_RS at LATF5_bit; //Conexiones LCD
7: sbit LCD_EN at LATF4_bit;
8: sbit LCD_D4 at LATF3_bit;
9: sbit LCD_D5 at LATF2_bit;
10: sbit LCD_D6 at LATF1_bit;
11: sbit LCD_D7 at LATF0_bit;
12:
13: sbit LCD_RS_Direction at TRISF5_bit;
14: sbit LCD_EN_Direction at TRISF4_bit;
15: sbit LCD_D4_Direction at TRISF3_bit;
16: sbit LCD_D5_Direction at TRISF2_bit;
17: sbit LCD_D6_Direction at TRISF1_bit;
18: sbit LCD_D7_Direction at TRISF0_bit;
19:
20: unsigned keypadPort at PORTB; //Conexiones teclado
21: unsigned keypadPort_Direction at TRISB;
22:
23: unsigned short k,i; //Subindices de barrido
24: unsigned short kp; //Tecla presionada
25: char ValStr[15]; //Valor flotante en cadena de caracteres
26:
27: float XX[Np]; //XX[ ] señal en el dominio del tiempo
28: float REX[(Np/2)+1]; //REX[ ] parte real del dominio de la frecuencia
29: float IMX[(Np/2)+1]; //IMX[ ] parte imaginaria del dominio de la frecuencia
30:
31: unsigned short LeeTecla(void)
32: {
33: do
34: {
35: kp = 0;
36: do //Esperar a que se presione una tecla
37: kp = Keypad_Key_Click();
38: while (!kp);
39: switch (kp)
40: {
41: case 1: kp = 10; break;
42: case 2: kp = 8; break;
43: case 3: kp = 4; break;
44: case 4: kp = 0; break;
45: case 5: kp = 10; break;
46: case 6: kp = 9; break;
47: case 7: kp = 5; break;
48: case 8: kp = 1; break;
49: case 9: kp = 10; break;
50: case 10: kp = 10; break;
51: case 11: kp = 6; break;
52: case 12: kp = 2; break;
53: case 13: kp = 10; break;
54: case 14: kp = 10; break;
55: case 15: kp = 7; break;
56: case 16: kp = 3; break;
57: }
58: }while (kp==10);
59: return kp;
60: }
61: void main()
62: {
63: ADPCFG = 0xFFFF; //Configurar pins como E/S digital
64: Keypad_Init(); //Inicializar teclado
65: Lcd_Init(); //Inicializar LCD
66: Lcd_Cmd(_LCD_CLEAR);
67: Lcd_Cmd(_LCD_CURSOR_OFF);
68: //Calculo de DFT Directa
69: Lcd_Out(1,1,"DFT Directa");
70: Lcd_Out(2,1,"Ingrese x[n] =>");
71: kp=LeeTecla();
72: Lcd_Cmd(_LCD_CLEAR);
73: Lcd_Out(1,1,"x[ ] = ");
74: Lcd_Cmd(_LCD_BLINK_CURSOR_ON);
75: for (k=0;k<=Np-1;k++) //Leer datos para XX[] desde teclado
76: {
77: Lcd_Chr(1,3,k+0x30);
78: Lcd_Chr(1,7,' ');
79: XX[k]=LeeTecla();
80: Lcd_Chr(1,8,kp+0x30);
81: Delay_ms(250);
82: }
83: Lcd_Cmd(_LCD_CURSOR_OFF);
84: Lcd_Cmd(_LCD_CLEAR);
85: for (k=0;k<=Np/2;k++) //Limpiar REX[] y IMX[]
86: {
87: REX[k]=0.0;
88: IMX[k]=0.0;
89: }
90: for (k=0;k<=Np/2;k++) //k barre cada muestra en REX[] e IMX[]
91: {
92: for (i=0;i<=Np-1;i++) //i barre cada muestra en XX[]
93: {
94: REX[k]=REX[k]+XX[i]*cos(2*PI*k*i/Np);
95: IMX[k]=IMX[k]-XX[i]*sin(2*PI*k*i/Np);
96: }
97: }
98: Lcd_Out(1,1,"ReX[ ]= =>");
99: for (k=0;k<=Np/2;k++) //Mostrar datos para REX[ ]
100: {
101: Lcd_Chr(1,5,k+0x30);
102: FloatToStr(REX[k],ValStr);
103: Lcd_Out(2,1,ValStr);
104: kp=LeeTecla();
105: }
106: Lcd_Out(1,1,"ImX[ ]= =>");
107: for (k=0;k<=Np/2;k++) //Mostrar datos para IMX[ ]
108: {
109: Lcd_Chr(1,5,k+0x30);
110: FloatToStr(IMX[k],ValStr);
111: Lcd_Out(2,1,ValStr);
112: kp=LeeTecla();
113: }
114: //Calculo DFT Inversa
115: Lcd_Cmd(_LCD_CLEAR);
116: Lcd_Out(1,1,"DFT Inversa");
117: Lcd_Out(2,1," =>");
118: kp=LeeTecla();
119: Lcd_Cmd(_LCD_CLEAR);
120: for (k=0;k<=Np/2;k++) //Normalizacion
121: {
122: REX[k]=REX[k]/(Np/2);
123: IMX[k]=-IMX[k]/(Np/2);
124: }
125: REX[0]=REX[0]/2; //Excepciones
126: REX[Np/2]=REX[Np/2]/2;
127: for(i=0;i<=Np-1;i++) //Limpiar XX[ ] para usarla como acumulador
128: {
129: XX[i]=0.0;
130: }
131: for (k=0;k<=Np/2;k++) //k barre cada muestra en REX[] e IMX[]
132: {
133: for (i=0;i<=Np-1;i++) //i barre cada muestra en XX[]
134: {
135: XX[i]=XX[i]+REX[k]*COS(2*PI*k*i/Np);
136: XX[i] = XX[i]+IMX[k]*SIN(2*PI*k*i/Np);
137: }
138: } //1234567890123456
139: Lcd_Out(1,1,"x[ ]= =>");
140: for (k=0;k<=Np-1;k++) //Mostrar datos para XX[ ]
141: {
142: Lcd_Chr(1,3,k+0x30);
143: FloatToStr(XX[k],ValStr);
144: Lcd_Out(2,1,ValStr);
145: kp=LeeTecla();
146: }
147: Lcd_Cmd(_LCD_CLEAR);
148: Lcd_Out(1,1,"Calculo");
149: Lcd_Out(2,1,"Terminado =>");
150: kp=LeeTecla();
151: Lcd_Cmd(_LCD_CLEAR);
152: asm{
153: PWRSAV #0 //Colocar el procesador en modo Sleep
154: }
155: }
4. Explicación de los algoritmos para las Transformadas DFT Directa y DFT Inversa

El algoritmo para el cálculo de la DFT es el siguiente:

 1ero: Usando el teclado, se cargan los valores de la señal en el dominio del tiempo (XX[ ]) (Líneas #75
a #82). Se requieren 8 datos, por ejemplo:

XX[7]=(1.0, 0.0, 1.0, 2.0, 2.0, 1.0, 1.0, 0.0)

 2do: Se limpian los vectores que almacenarán las Amplitudes de las ondas Coseno de la partes Real
(REX[4]) y las Amplitudes de las ondas Seno (IMX[4]) de la señal transformada en el dominio de la
frecuencia. (Líneas #895 a #97)

 3ro: Se procede al cálculo de la Transformada Directa DFT (Líneas #90 a #97). Para ello se
implementan en software las siguientes expresiones:

donde:
x[i] es la señal en el dominio del tiempo siendo analizada
ReX[k] e ImX[k] son las señales en el dominio de la frecuencia que son calculadas
El índice i barre desde 0 a N-1, mientras que k barre de 0 a N/2

Los resultados de dichos cálculos se almacenan en 5 valores para REX[] e IMX[] que tienen los
siguientes valores:

 4to: Para realizar el cálculo de la Transformada Inversa DFT (Líneas #120 a #126), se normalizan los
vectores REX[] e IMX[]

 5to: Se limpia el vector XX[] para usarlo como acumulador (Líneas #127 a #130)

 6to: Se procede a realizar el cálculo de la Transformada Inversa DFT (Líneas #131 a #138). Para ello se
implementa en software la siguiente expresión:
donde:
x[i] es la señal siendo sintetizada, con el índice i barrido desde 0 a N-1
k es barrido de 0 a N/2
 7mo: Si el proceso se ha ejecutado correctamente los valores obtenidos para el vector XX[] serán los mismos
que fueron almacenados originalmente en el primer paso. Se debe tomar en cuenta que los resultados serán
aproximaciones cercanas a los originales debidos a los errores de redondeo y truncamiento inherentes a
cualquier proceso DSP.

5. Representación Gráfica de la Transforma Discreta de Fourier

 1ro: Se introdujo la señal digitalizada XX[] por medio de 8 valores discretos La figura muestra una
representación gráfica de esta señal en el dominio del tiempo:

XX[n]
2.5
2
1.5
1
0.5
0
1 2 3 4 5 6 7 8

 2do: Esta señal fue transformada a dos grupos de señales REX[4] e IMX[4].
REX[] contiene las Amplitudes de los Cosenos de las 5 señales que la conforman.
IMX[] contiene las Amplitudes de los Senos de las 5 señales que la conforman.

Grafiquemos las señales correspondientes al grupo de Coseno, el grupo de Seno debe realizar de manera análoga.
Finalmente si sumamos punto a punto TODAS las señales Coseno y Seno, obtendremos la señal original.

Grupo Coseno:
Para k=0, REX[0]=8.0 : XX0 =

i XX0
0 8
1 8
2 8
3 8
4 8
5 8
6 8
7 8

Para k=1, REX[1]=-3.12132 : XX1 =


i XX1
0 -3.12132
1 -2.20710654
2 -1.912E-16
3 2.207106538
4 3.12132
5 2.207106538
6 5.73612E-16
7 -2.20710654

Para k=2, REX[2]=0.9999996 : XX2 =

i XX2
0 0.9999996
1 6.12574E-17
2 -0.9999996
3 -1.8377E-16
4 0.9999996
5 3.06287E-16
6 -0.9999996
7 -4.288E-16

Para k=3, REX[3]=1.12132 : XX3 =

i XX0
0 1.12132
1 -0.79289298
2 -2.0607E-16
3 0.792892976
4 -1.12132
5 0.792892976
6 6.18203E-16
7 -0.79289298

Para k=4, REX[4]=2.0 : XX4 =


i XX0
0 2
1 -2
2 2
3 -2
4 2
5 -2
6 2
7 -2

6. Diagrama Esquemático

7. Informe de Laboratorio
I. Realizar un RESUMEN (escrito a mano) de por lo menos 3 páginas del fundamento teórico matemático
de la Transformada Discreta de Fourier. (Incluir las fuentes de Direcciones WEB así como el Material
Impreso usado para el resumen)

II. (1ra Firma) Probar el funcionamiento del algoritmo DFT armando el circuito en protoboard. Para los
valores de entrada usar el Número de Carnet de uno de los integrantes del grupo (Si se requieren más
dígitos añadir el número de carnet de otro integrante). Escribir una tabla para todos los valores
ingresados y obtenidos. Comparar y comentar si existe alguna discrepancia entre los valores ingresados
inicialmente y los valores obtenidos al final.

III. (2da Firma) Implementar el algoritmo DFT (Transformada Directa e Inversa) en Matlab. Escribir una
tabla para todos los valores ingresados y obtenidos. Comparar y comentar si existe alguna discrepancia
entre los valores ingresados inicialmente y los valores obtenidos al final.

IV. Probar gráficamente que la suma de las señales obtenidas con los valores de REX[ ] e IM[ ],
efectivamente generan la señal XX[ ] original.

V. Conclusiones

S-ar putea să vă placă și