universidad de panamÁ - ieesa.com · 1dsp = digital signal processing ... 4iir = infinite impulse...

48
UNIVERSIDAD DE PANAM Á ESCUELA DE ELECTRÓNICA TRATAMIENTO DIGITAL DE LA INFORMACIÓN PROGRAMAS PARA EL DISEÑO E IMPLEMENTACIÓN DE FILTROS DIGITALES EN EL SHARC EZ-KIT (IMPLEMENTACIÓN EN LENGUAJE-C) RICARDO LAMBRAÑO 23/07/98

Upload: dangcong

Post on 26-Aug-2018

227 views

Category:

Documents


0 download

TRANSCRIPT

UNIVERSIDAD DE PANAMÁ

ESCUELA DE ELECTRÓNICA

TRATAMIENTO DIGITAL DE LA INFORMACIÓN

PROGRAMAS PARA EL DISEÑOE IMPLEMENTACIÓN DE FILTROS DIGITALES

EN EL SHARC EZ-KIT(IMPLEMENTACIÓN EN LENGUAJE-C)

RICARDO LAMBRAÑO

23/07/98

CONTENIDO

1 INTRODUCCIÓN..........................................................................................................................................32 PROCESAMIENTO DIGITAL DE SEÑALES .............................................................................................33 FILTROS DE RESPUESTA FINITA (FIR)...................................................................................................5

3.1 TEORÍA .......................................................................................................................................... 53.1.1 FILTRO PASA BAJOS............................................................................................................ 53.1.2 FILTRO PASA ALTOS............................................................................................................ 63.1.3 FILTRO PASA BANDA........................................................................................................... 63.1.4 FILTRO RECHAZA BANDA.................................................................................................... 63.1.5 DIFERENCIADOR................................................................................................................... 63.1.6 TRANSFORMADA HILBERT.................................................................................................. 73.1.7 VENTANAS............................................................................................................................. 7

3.2 PROGRAMA DE DISEÑO .............................................................................................................. 83.3 PROGRAMA DE IMPLEMENTACIÓN ........................................................................................... 9

4 FILTROS DE RESPUESTA INFINITA (IIR) ..............................................................................................114.1 TEORÍA ........................................................................................................................................ 12

4.1.1 FILTRO PASA BAJOS.......................................................................................................... 124.1.3 FILTRO PASA BANDA......................................................................................................... 134.1.4 FILTRO RECHAZA BANDA.................................................................................................. 144.1.5 FILTRO NOTCH .................................................................................................................... 15

4.2 PROGRAMA DE DISEÑO ............................................................................................................ 154.3 PROGRAMA DE IMPLEMENTACIÓN ......................................................................................... 16

5 LISTADO DE PROGRAMAS DE DISEÑO ...............................................................................................185.1 FILTROS DE RESPUESTA FINITA (FIR)..................................................................................... 185.2 FILTROS DE RESPUESTA INFINITA (IIR) .................................................................................. 26

6 LISTADO DE PROGRAMAS DE IMPLEMENTACIÓN............................................................................386.1 FILTROS DE RESPUESTA FINITA (FIR)..................................................................................... 386.2 FILTROS DE RESPUESTA INFINITA (IIR) .................................................................................. 42

7 RECOMENDACIONES Y MEJORAS .......................................................................................................488 BIBLIOGRAFÍA..........................................................................................................................................48

3

1 INTRODUCCIÓN

El objetivo de este trabajo es el de servir como explicación a la forma en que fueron escritos losprogramas de diseño y utilización de los filtros digitales de coeficientes constantes invariantes en el tiempo.

Como indica el titulo de este trabajo "PROGRAMAS PARA EL DISEÑO E IMPLEMENTACIÓN DEFILTROS DIGITALES...", en el mismo no solo nos dedicaremos al diseño de los filtros, sino a suimplementación en un sistema de DSP1.

El sistema que hemos seleccionado para la implementación de los filtros esta basado en elmicroprocesador de DSP de la compañía Analog Devices el ADSP-21061. El ADSP-21061 es unmicroprocesador de 32bits punto flotante optimizado2 para DSP. El mismo es el núcleo de un sistema deevaluación llamado el ADSP21061 SHARC EZ-KIT, este sistema fue utilizado por ser el sistema dedesarrollo con que cuenta la Universidad Tecnológica de Panamá, para este curso. En la tabla 1,mostramos un resumen de las características del sistema.

Tabla 1. Características del ADSP21061 SHARC EZ-KIT.

Parámetro ADSP-21061 SHARC EZ-KIT

MFLOPS 40(normal)/120(máximo)

Memoria de Datos 512Kbit (16K x 32bits)

Memoria de Programa 512Kbit (11K x 48bits)

Registros 16 Punto Flotante

Frec. Muestreo Hasta 48KHz

Canales A/D 2 x 16bits

Canales D/A 2 x 16bits

Simulador Sí

Documentación Extensa

Ensamblador Sí

Compilador C Sí

Por último, este documento asume un conocimiento previo de: Teorema de Nyquist; losdispositivos necesarios para la conversión análoga a digital y digital a análoga; concepto defrecuencia digital; conocimiento de la Transformada-Z; y diseño de filtros digitales.

2 PROCESAMIENTO DIGITAL DE SEÑALES

1DSP = Digital Signal Processing

2Los microprocesadores optimizados para DSP, cuentan conunidades físicas de multiplicación y acumulación, las cualespermiten realizar una multiplicación y acumulación (Sumatoria) enun ciclo de reloj.

4

El Procesamiento Digital de Señales, DSP por sus siglas en Inglés, es un área interdiciplinaria de laelectrónica, matemáticas e informática que permite realizar cualquier función de dispositivoselectrónicos analógicos y hasta funciones que no pueden ser realizadas con dispositivosanalógicos, en un sistema digital, normalmente basado en microprocesadores.

Con la utilización de DSP se puede realizar cualquier labor de una manera más precisa, ya quelos componentes no requieren ajustes y no cambian sus características con el tiempo.

Tabla 2. Áreas de utilización de DSPs

Audio Ecualizadores Gráficos; Analizadores de Espectro; compresión deaudio (MiniDisc); Discos Compactos; Efectos Digitales; Sistemas deTeatro Casero (THX); reducción de ruido (Dolby); etc.

Automóviles Frenos antibloqueo; Bolsas de Aire; Supresión de ruido activo;Control de mezcla de combustible; etc.

Computadoras MODEMs; tarjetas de sonido; tarjetas de video; sintetización yreconocimiento de voz; etc.

Comunicaciones Compresión de voz; eliminación de eco; ecualización adaptativa;multiplexión de canales; modulaciones digitales; etc.

Medicina Eliminación de ruido en ECG, EEG, VCG, EMG; análisis fisiológico;mejoramiento de imágenes CT, MR, X-RAY; etc.

Militar Guía de misiles; GPS; Detección de agentes químicos; RADAR;SONAR; Visión Nocturna; etc.

De hecho, consideramos que en un período de aproximadamente diez años, todos los sistemaselectrónicos serán basados en el procesamiento digital de señales, dejando campo para la electrónicaanalógica son en las tareas de amplificación de potencia, amplificación de bajas señales y mezcla defrecuencia para transmisión y recepción, o sea la preparación de la señal para ser procesada o despuésde ser procesada.

Aunque para las aplicaciones antes mencionadas se utilizan algoritmos o herramientas tales comola Transformada Rápida de Fourier (FFT), Filtros adaptivos, Filtros Pareados (Matched Filters), FiltrosPareados Adaptivos, Correlación, Convolución, Transformadas Discretas de Coseno, Transformadas deHilbert, Diferenciadores, Integradores, mezcladores, Algoritmos de Vitervi, Codificadores cíclicos,Codificadores Convolucionales, Decodificadores Trellis, etc. También se utilizan filtros de coeficientesconstantes.

Existen dos tipos de filtros de coeficientes constantes, implementables en el dominio del tiempo,estos son los Filtros de Respuesta Finita (FIR3) y los Filtros de Respuesta Infinita (IIR4).

3FIR = Finite Impulse Response

4IIR = Infinite Impulse Response

5

3 FILTROS DE RESPUESTA FINITA (FIR)

Los filtros FIR, también conocidos como Filtros Transversales (Transversal Filters) o como Sistemasde Average Móvil (Moving Average Systems MA), son los filtros más sencillos de diseñar e implementar.

Son llamados de respuesta finita, porque el proceso de filtrado se realiza por medio de laconvolución de la señal de entrada, con la respuesta al impulso del filtro. Como la respuesta al impulso esun número finito de coeficientes, el filtro es llamado "Filtro de Respuesta Finita".

La función de transferencia de los filtros FIR esta dada por (1), como se puede observar este filtrosolo cuenta con ceros y ningún polo, lo que nos garantiza la estabilidad del mismo.

Es importante destacar que los filtros FIR nos brindan las siguientes ventajas sobre los filtros IIR:estabilidad garantizada; fase lineal; poca sensibilidad a los efectos del tamaño finito de la palabra(número de bits); fácil de diseñar; y fácil de implementar.

La única desventaja de los filtros FIR en comparación a los filtros IIR, es el gran número decoeficientes que se necesitan para obtener las mismas características de ancho de banda de transición yatenuación en la banda de rechazo.

3.1 TEORÍA

El procedimiento de diseño de los filtros FIR utilizado, fue el método de ventanas. En este métodose obtienen los coeficientes del filtro ideal y se multiplica o ponderan por el valor de una función quellamaremos función de ventana.

En la ecuación (2), se muestra el calculo de los coeficientes del filtro.

Donde h(n) son los coeficientes del filtro; hd(n) son los coeficientes del filtro ideal; y w(n) son loscoeficientes de las ventanas.

3.1.1 FILTRO PASA BAJOS

zb=H(z) n-n

1-N

=0n∑ (Ec. 1)

N/2nN/2- para (n)w(n)h=h(n) d ≤≤ (Ec. 2)

0=n para =(0)h

0n para n

)(n=(n)h

cd

cd

πω

πω ≠

sin

(Ec. 3)

6

3.1.2 FILTRO PASA ALTOS

3.1.3 FILTRO PASA BANDA

3.1.4 FILTRO RECHAZA BANDA

3.1.5 DIFERENCIADOR

0=n para -1=(0)h

0n para n

)(n-=(n)h

cd

cd

πω

πω ≠

sin

(Ec. 4)

0=n para -

=(0)h

0n para n

)(n-)(n=(n)h

c1c2d

c1c2d

πωω

πωω ≠

sinsin

(Ec. 5)

0=n para -

-1=(0)h

0n para n

)(n-)(n-=(n)h

c1c2d

c1c2d

πωω

πωω ≠

sinsin

(Ec. 6)

0=n para 0=(0)h

0n para k

)(n-

n)(n

=(n)h

d

2d ≠π

ππ sincos

(Ec. 7)

7

3.1.6 TRANSFORMADA HILBERT

El diferenciador tiene una respuesta de frecuencia H(w) = jw, definida en todo el intervalo deNyquist. El transformador de Hilbert tiene una respuesta de frecuencia H(w) = -j sign(w). Ambos tienen altaimportancia en algoritmos de comunicaciones.

3.1.7 VENTANAS

Las ventanas, desde el punto de vista de los ingenieros electrónicos, nos sirven para suavisar elpaso entre los primeros coeficientes del filtro (ambos extremos) y cero, como sabemos cualquier pasoabrupto crea distorsiones armónicas.

Desde el punto de vista de los matemáticos (correcto), nos sirven para convolucionar el espectro delfiltro con el espectro de una señal mejor que la del sin(x)/(x) (espectro de ventana rectangular).

Ventana Rectangular

Ventana Hanning

Ventana Hamming

Ventana Blackman

En la tabla 3, se muestran las características de las ventanas antes mencionadas.

0=n para 0=(0)h

0n para n

)(n-1=(n)h

d

d ≠π

πcos

(Ec. 8)

1=w(n) (Ec. 9)

)N

n2(0.5+0.5=w(n)

πcos (Ec. 10)

)N

n2(0.46+0.54=w(n)

πcos (Ec. 11)

)N

n4(0.08+)

Nn2

(0.5+0.42=w(n)ππ

coscos (Ec. 12)

8

Ventana Transición(Hz)

Rizo(db)

Relación(db)

Atenuación(db)

Rectangular 0.9/N 0.7416 13 21

Hanning 3.1/N 0.0546 31 44

Hamming 3.3/N 0.0194 41 53

Blackman 5.5/N 0.0017 57 74

Tabla 3. Características de distintas ventanas

3.2 PROGRAMA DE DISEÑO

El programa de diseño de filtros FIR, fue escrito en Lenguaje C, compilado con el Compilador de Cde Microsoft Versión 6.00.

Para ejecutar el mismo, el usuario debe escribir el nombre del programa FIRF.EXE desde la líneade comando de MS-DOS y presionar [Enter].

El programa pregunta que tipo de filtro o función desea calcular, el número de puntos, tipo deventana, frecuencia de muestreo y frecuencias de corte en caso de ser un filtro lo seleccionado, figura 1.

Programa Para el Diseño de Filtros FIR

Versión 2.00 de 23/07/98 R. Lambraño

1-Pasa Bajos 2-Pasa Altos 3-Pasa Banda 4-Rechaza Banda 5-Differenciador 6-Transformada de Hilbert

Seleccione Tipo de Filtro? 1 Numero de Puntos? 255Frecuencia de Muestreo (KHz)? 48 Frecuencia de Corte (Hz)? 1000

Ventana Transicion Rizo (db) Relacion Aten.1-Rectangular 0.9/N 0.7416 13db 21db2-Hanning 3.1/N 0.0546 31db 44db3-Hamming 3.3/N 0.0194 41db 53db4-Blackman 5.5/N 0.0017 57db 74db

Seleccione Tipo de Ventana? 1

Figura 1. Pantalla de Ejecución de Programa FIRF.EXE

9

El diseño brindado por el programa no contempla el calculo del número de coeficientes y tipo deventana, según sean las necesidades del filtro.

Esto tiene dos razones importantes de ser. Primero el objetivo del programa es principalmente parauso didáctico, de tal forma que el estudiante pueda evaluar las distintas respuestas con diferentes númerosde coeficientes y tipos de ventana.

Segundo, en la utilización real de filtros digitales uno cuenta con una cantidad definida decoeficientes que puede utilizar (por restricciones de tiempo), de tal forma que se deja al diseñador la libertadde controlar todos los parámetros del filtro y es responsabilidad del diseñador crear el mejor diseño con laslimitantes presentes en el proyecto.

La salida del programa es un archivo llamado FIR.DAT, este archivo tiene los coeficientes enformato de punto flotante y como comentarios, separados por "//", las especificaciones del filtro así como losvalores de los coeficientes, en la figura 2 se muestra un extracto del archivo FIR.DAT.

3.3 PROGRAMA DE IMPLEMENTACIÓN

Como habíamos anunciado anteriormente, la implementación de los filtros será realizada en elmicroprocesador de Analog Devices, el ADSP-21061.

El ADSP-21061 tiene un compilador de Lenguaje C, por lo que la implementación del filtro es muysencilla. No es necesario mostrar el listado completo del programa en esta sección (ver punto 10), así quenos concentraremos, solo en las secciones importantes del filtro.

#define TAPS 255 // Numero de Coeficientes (Orden del Filtro)float pm H[TAPS] = // Coeficientes del Filtros leidos del // Archivo ASCII <FIR.DAT>#include "fir.dat";float dm X[TAPS+1]; // Buffer del Filtro

// Filtro: LP//Ventana: Rectangular// Taps: 255// Fs: 48.000KHz// Fc: 1000.000Hz-0.0019884426097825, // h(-127) = -1.9884426E-003-0.0017863418970508, // h(-126) = -1.7863419E-003-0.0015501982493486, // h(-125) = -1.5501982E-003-0.0012835076054713, // h(-124) = -1.2835076E-003...-0.0035751597654873, // h(-086) = -3.5751598E-003-0.0037127847174568, // h(-085) = -3.7127847E-003-0.0037894034069617, // h(-084) = -3.7894034E-003-0.0038022494094094, // h(-083) = -3.8022494E-003-0.0037495578027593, // h(-082) = -3.7495578E-003

Figura 2. Extracto de archivo FIR.DAT creado por FIR.EXE

10

Lo primero que siempre se declara en cualquier programa, son las variables y constantes. Para elprograma FIR.C, se declara la constante global TAPS 255, esta constante tiene el número de coeficientes oderivaciones del filtro.

Con el valor de esta constante, se "dimensionan" los buffers o arreglos donde se almacenaran loscoeficientes del filtro (H[TAPS]), y los estados anteriores de x(n) (X[TAPS]).

La sentencia float dm X[TAPS+1], define a la etiqueta o arreglo X[], como una variable, en memoriade datos.

La sentencia float pm H[TAPS], define a la etiqueta o arreglo H[], como una variable (aunque seráutilizada como constantes), en memoria de programa.

Existen una razón importantísima para haber declarado ambos arreglos en distintas áreas dememoria (DATA y PROGRAMA), y es porque este microprocesador puede leer a la vez ambasdirecciones de memoria.

La sentencia #include "FIR.DAT" es lo que le indica al compilador que lea el archivo creado por elprograma FIRF.EXE y lo almacene o inicialize el buffer H[], a estos valores.

/***************************************************************************** Rutina de Interrupción del CODEC (Recepción)* Aquí se realiza el Filtrado!****************************************************************************/void SPORT0_RX( int sig_num )float ACUM;int k,FILT;

ACUM = rx_buf[1]; // Señal de Entra del CODEC (L)

if (ON_OFF) // Bandera de FuncionamientoX[TAPS] = ACUM; // X[n] = Ultimo elemento del bufferACUM = 0.0; // Blanquear Acumuladorfor(k=0;k<TAPS;k++)// Ciclo de K = 0 a TAPS

ACUM = ACUM + H[k]*X[k]; // "Convolución"X[k] = X[k+1]; // Corrimiento de Datos

tx_buf[1] = ACUM; // Señal de Salida del CODEC (L)tx_buf[2] = ACUM; // Señal de Salida del CODEC (R)

La rutina SPORT0_RX, es una rutina de interrupción. Esta rutina es llamada cada vez que losconvertidores realizan un muestreo. De hecho, en el Procesamiento Digital de Señales en tiempo real, todoel tratamiento de la información tiene que realizarse entre muestra y muestra.

Por ejemplo en este microprocesador muestreando a 48KHz, podemos ejecutar una rutina deinterrupción con un máximo de 833 instrucciones o ciclos de máquina (40MHz/48KHz=833.3).

11

La primera línea ACUM = rx_buf[1] lee el ADC izquierdo y escribe este valor en la variable ACUM.La línea if (ON_OFF), prueba el estado de una variable para verificar si el usuario desea el filtro encendido oapagado.

X[TAPS] = ACUM;ACUM = 0.0;for(k=0;k<TAPS;k++)

ACUM = ACUM + H[k]*X[k];X[k] = X[k+1];

Si el usuario desea el filtro encendido, entonces se entrega el valor leido en ACUM al elementoTAPS del buffer X[], se blanquea la variable ACUM y se realiza la sumatoria de convolución, entre loscoeficientes del filtro H[] y las entradas anteriores X[].

tx_buf[1] = ACUM; // Señal de Salida del CODEC (L)tx_buf[2] = ACUM; // Señal de Salida del CODEC (R)

Por último se escriben ambos canales del DAC con el valor de la variable ACUM, si el filtro estabaapagado, este será el valor leido del ADC. Si el filtro estaba encendido, esta variable contiene el valorfiltrado.

4 FILTROS DE RESPUESTA INFINITA (IIR)

Los filtros IIR, también conocidos como Sistemas Auto-regresivos (Auto-Regresive AR), sonllamados de respuesta infinita, porque el proceso de filtrado se realiza por medio de la evaluación de laecuación de diferencias que regulan el sistema. Como la ecuación de diferencias depende de las salidasanteriores del filtro, existe una dependencia de los infinitos estados anteriores de la variable desalida a la variable de salida actual, por tal razón son llamados de Respuesta al Impulso Infinita.

La función de transferencia de los filtros IIR esta dada por (13), como se puede observar este filtrocuenta con ceros y polos, por lo que la estabilidad del mismo, no esta garantizada.

Es importante destacar que los filtros IIR nos brindan una gran ventaja sobre los filtros FIR, esta esla pequeña cantidad de coeficientes que se requieren para obtener una gran atenuación y estrechabanda de transición.

Las desventajas de los filtros IIR en comparación a los filtros FIR son: Problemas deestabilidad; complejidad en el diseño; sensibilidad a tamaño finito de palabras; y fase no lineal.

za+1

zb=H(z)

k-k

1-M

=0k

k-k

1-N

=0k

∑(Ec. 13)

12

4.1 TEORÍA

El procedimiento de diseño de los filtros IIR utilizado, fue el método de transformada bilineal. Eneste método se obtienen los coeficientes del filtro analógico y se aplica una transformación de variables paraobtener los coeficientes del filtro digital.

Esta transformación de variables es conocida como la Transformación Bilineal, ecuación (14).

Además de la transformación de la variable (s->z), es importante también ajustar las frecuencias delplano de Laplace al plano Z, este ajuste (no lineal), es conocido en Inglés como Frequency Prewarping,ecuación (15).

Con esta información y nuestros conocimientos previos de diseño de filtros analógicos, podemosmodificar las formulas de diseño de Filtros Butterworth5 para diseñar directamente filtros digitales.

Debemos aclarar antes de continuar, que para mejorar la sensibilidad de los filtros IIR a losefectos de la palabra finita dentro del microprocesador, la implementación de los mismos es mejorrealizada como la cascada de varias secciones bi-cuadraticas, ecuación (16).

El ángulo de los polos de la función de transferencia de los filtros Butterworth viene dado por laecuación (17), donde N es el orden del filtro.

1,2,...N=i para 2i)+1-(N2N

=iπ

Φ (Ec. 17)

4.1.1 FILTRO PASA BAJOS

)2

(= 00

ωtanΩ (Ec. 18)

za+za+1)z+(1G=(z)H 2-i2

1-i1

2-1i

i (Ec. 19)

ΩΦΩΩ

20i0

20

i+2-1

=Gcos

(Ec. 20)

ΩΦΩΩ

20i0

20

i1+2-1

1)-2(=a

cos(Ec. 21)

5Valido también para otros tipos de filtro.

z+1z-1

=s1-

-1

(Ec. 14)

/2)(= ωtanΩ (Ec. 15)

zA+zA+1zB+zB+B=H(z)

2-2

1-1

-22

-110 (Ec. 16)

13

ΩΦΩΩΦΩ

20i0

20i0

i2+2-1+2+1

=acoscos

(Ec. 22)

4.1.2 FILTRO PASA ALTOS

)2

(-= 00

ωcotΩ (Ec. 23)

za+za+1)z-(1G=(z)H 2-i2

1-i1

2-1i

i (Ec. 24)

ΩΦΩΩ

20i0

20

i+2-1

=Gcos

(Ec. 25)

ΩΦΩΩ

20i0

20

i1+2-1

1)-2(=a

cos(Ec. 26)

ΩΦΩΩΦΩ

20i0

20i0

i2+2-1+2+1

=acoscos

(Ec. 27)

4.1.3 FILTRO PASA BANDA

)(+)(

)+(=c

pbpa

pbpa

ωωωω

sinsin

sin(Ec. 28)

))(

)(-cabs(=

pb

pb0

ωω

sin

cosΩ (Ec. 29)

za+za+za+za+1)z-(1G=(z)H 4-

i43-

i32-

i21-

i1

2-2i

i (Ec. 30)

ΩΦΩΩ

20i0

20

i+2-1

=Gcos

(Ec. 31)

ΩΦΩΦΩ

20i0

i0i1

+2-11)-4c(

=acoscos

(Ec. 32)

14

ΩΦΩΩ

20i0

20

2

i2+2-1

)-1+c2(2=a

cos(Ec. 33)

ΩΦΩΦΩ

20i0

i0i3

+2-11)+4c(

-=acoscos

(Ec. 34)

ΩΦΩΩΦΩ

20i0

20i0

i4+2-1+2+1

=acoscos

(Ec. 35)

4.1.4 FILTRO RECHAZA BANDA

)(+)(

)+(=c

pbpa

pbpa

ωωωω

sinsin

sin(Ec. 36)

)c-

abs(=pb

pb0

ωω

cos

sinΩ (Ec. 37)

za+za+za+za+1)z+cz2-(1G=(z)H 4-

i43-

i32-

i21-

i1

2-2-1i

i (Ec. 38)

ΩΦΩΩ

20i0

20

i+2-1

=Gcos

(Ec. 39)

ΩΦΩΩΦΩ

20i0

0i0i1

+2-1)-(4c

=acos

cos(Ec. 40)

ΩΦΩΩΩ

20i0

20

20

2

i2+2-1

1)-+c2(2=a

cos(Ec. 41)

ΩΦΩΩΦΩ

20i0

0i0i3

+2-1)+(4c

-=acos

cos(Ec. 42)

ΩΦΩΩΦΩ

20i0

20i0

i4+2-1+2+1

=acoscos

(Ec. 43)

15

4.1.5 FILTRO NOTCH

)2

(+1

1=b

ω∆tan

(Ec. 44)

z1)-(2b+z2b-1z+z2-1

=H(z)2-1-

0

-2-10

ωω

coscos

(Ec. 45)

4.2 PROGRAMA DE DISEÑO

El programa de diseño de filtros IIR, fue escrito en Lenguaje C, compilado con el Compilador de Cde Microsoft Versión 6.00.

Para ejecutar el mismo, el usuario debe escribir el nombre del programa IIRF.EXE desde la línea decomando de MS-DOS y presionar [Enter].

El programa pregunta que tipo de filtro desea calcular, el número de secciones bi-cuadráticas,frecuencia de muestreo y frecuencias de corte, figura 3.

El diseño brindado por el programa no contempla el calculo del número de bi-cuadráticasnecesarias, según sean las necesidades del filtro.

Programa Para el Diseño de Filtros IIR

Versión 2.00 de 23/07/98 R. Lambraño

1-Pasa Bajos 2-Pasa Altos 3-Pasa Banda 4-Rechaza Banda

5-Notch 6-Selectivo

Seleccione Tipo de Filtro? 1 Numero de Bi-cuadraticas? 4Frecuencia de Muestreo (KHz)? 48 Frecuencia de Corte (Hz)? 1000

Figura 3. Pantalla de Ejecución de Programa IIRF.EXE

16

Esto tiene dos razones importantes de ser. Primero el objetivo del programa es principalmente parauso didáctico, de tal forma que el estudiante pueda evaluar las distintas respuestas con diferentes númerosde bi-cuadráticas.

Segundo, en la utilización real de filtros digitales uno cuenta con una cantidad definida decoeficientes que puede utilizar (por restricciones de tiempo), de tal forma que se deja al diseñador la libertadde controlar todos los parámetros del filtro y es responsabilidad del diseñador crear el mejor diseño con laslimitantes presentes en el proyecto.

La salida del programa es un archivo llamado IIR.DAT, este archivo tiene los coeficientes en formatode punto flotante y como comentarios, separado por "//", las especificaciones del filtro así como los valoresde los coeficientes, en la figura 4 se muestra un extracto del archivo IIR.DAT.

4.3 PROGRAMA DE IMPLEMENTACIÓN

Como habíamos anunciado anteriormente, la implementación de los filtros será realizada en elmicroprocesador de Analog Devices, el ADSP-21061.

El ADSP-21061 tiene un compilador de Lenguaje C, por lo que la implementación del filtro es muysencilla. No es necesario mostrar el listado completo del programa en esta sección (ver punto 10), así quenos concentraremos, solo en las secciones importantes del filtro.

#define BICUADS 4 // Número de Bicuadraticas (Orden del Filtro)float pm H[BICUADS*5] = // Coeficientes del Filtros leidos del // Archivo ASCII <IIR.DAT>

// Filtro: LP// Polos: 8// Fs: 48.000KHz// Fc: 1000.000Hz+0.0041713484408825, // B2 = +4.1713484E-003+0.0083426968817649, // B1 = +8.3426969E-003+0.0041713484408825, // B0 = +4.1713484E-003-0.9503358732908425, // A2 = -9.5033587E-001+1.9336504795273130, // A1 = +1.9336505E+000+0.0039883483793306, // B2 = +3.9883484E-003+0.0079766967586613, // B1 = +7.9766968E-003+0.0039883483793306, // B0 = +3.9883484E-003-0.8647732333154958, // A2 = -8.6477323E-001+1.8488198397981730, // A1 = +1.8488198E+000+0.0038587813232834, // B2 = +3.8587813E-003+0.0077175626465667, // B1 = +7.7175626E-003+0.0038587813232834, // B0 = +3.8587813E-003-0.8041934757174437, // A2 = -8.0419348E-001+1.7887583504243100, // A1 = +1.7887584E+000+0.0037921102995321, // B2 = +3.7921103E-003+0.0075842205990642, // B1 = +7.5842206E-003+0.0037921102995321, // B0 = +3.7921103E-003-0.7730210883769970, // A2 = -7.7302109E-001+1.7578526471788690, // A1 = +1.7578526E+000

Figura 4. Extracto de archivo IIR.DAT creado por IIRF.EXE

17

#include "iir.dat";float dm X[BICUADS*5]; // Buffer del Filtro X(n) y Y(n)

Lo primero que siempre se declara en cualquier programa, son las variables y constantes. Para elprograma IIR.C, se declara la constante global BICUADS 4, esta constante tiene el número de bicuadraticasque componen el filtro.

Con el valor de esta constante, se "dimensionan" los buffers o arreglos donde se almacenaran loscoeficientes del filtro (H[BICUADS*5]), y los estados anteriores de x(n) (X[BICUADS*5]).

La sentencia float dm X[], define a la etiqueta o arreglo X[], como una variable, en memoria dedatos.

La sentencia float pm H[], define a la etiqueta o arreglo H[], como una variable (aunque seráutilizada como constantes), en memoria de programa.

Existen una razón importantísima para haber declarado ambos arreglos en distintas áreas dememoria (DATA y PROGRAMA), y es porque este microprocesador puede leer a la vez ambasdirecciones de memoria.

La sentencia #include "IIR.DAT" es lo que le indica al compilador que lea el archivo creado por elprograma IIRF.EXE y lo almacene o inicialize el buffer H[], a estos valores.

void SPORT0_RX( int sig_num )float ACUM;int i,ii,FILT;

ACUM = rx_buf[1]; // Señal de Entra del CODEC (L)

if (ON_OFF) // Bandera de Funcionamientofor(ii = 0; ii < BICUADS; ii++) // Repetir por N bicuadraticas

i = ii*5; // Ajustar Indice de variablesX[i+2] = ACUM; // X[n] = Valor del ADC

// o ultimo filtro!ACUM = H[i+2]*X[i+2]; // Y[n] = B0*X[n]ACUM = ACUM + H[i+1]*X[i+1]; // Y[n] = Y[n] + B1*X[n-1]ACUM = ACUM + H[i+0]*X[i+0]; // Y[n] = Y[n] + B2*X[n-2]ACUM = ACUM + H[i+3]*X[i+3]; // Y[n] = Y[n] + A1*Y[n-1]ACUM = ACUM + H[i+4]*X[i+4]; // Y[n] = Y[n] + A2*Y[n-2]X[i+0] = X[i+ 1]; // X[n-2] = X[n-1]X[i+1] = X[i+ 2]; // X[n-1] = X[n]X[i+3] = X[i+ 4]; // Y[n-2] = Y[n-1]X[i+4] = ACUM; // Y[n-1] = Y[n]

tx_buf[1] = ACUM; // Señal de Salida del CODEC (L)tx_buf[2] = ACUM; // Señal de Salida del CODEC (R)

La rutina SPORT0_RX, es una rutina de interrupción. Esta rutina es llamada cada vez que losconvertidores realizan un muestreo. De hecho, en el Procesamiento Digital de Señales en tiempo real, todoel tratamiento de la información tiene que realizarse entre muestra y muestra.

18

Por ejemplo en este microprocesador muestreando a 48KHz, podemos ejecutar una rutina deinterrupción con un máximo de 833 instrucciones o ciclos de máquina (40MHz/48KHz=833.3).

La primera línea ACUM = rx_buf[1] lee el ADC izquierdo y escribe este valor en la variable ACUM.La línea if (ON_OFF), prueba el estado de una variable para verificar si el usuario desea el filtro encendido oapagado.

Si el usuario desea el filtro encendido, entonces se entrega el valor leido en ACUM al elemento i+2del buffer X[], se asigna a la variable ACUM la operación que da como resultado B0*X[n] y se realizan lasdemás operaciones para obtener finalmente en la variable ACUM = B0*X(n) + B1*X(n-1) + B2*X(n-2) +A1*Y(n-1) + A2*Y(n-2), que es la función de transferencia de una bicuadratica.

Luego se realiza el corrimiento de datos (X[n-2] = X[n-1], etc.) y se realiza nuevamente todo para lasiguiente bicuadratica, hasta llegar a la última. Luego de la última bicuadratica ACUM contiene el valorfiltrado y el mismo es escrito a los convertidores DAC del CODEC.

5 LISTADO DE PROGRAMAS DE DISEÑO

5.1 FILTROS DE RESPUESTA FINITA (FIR)

/************************************************************************

Programa: FIRF.EXE Objetivo: Calcular los coeficientes de la funcion de transfe- rencia de un filtro FIR invariante en el tiempo.

El resultado lo almacena en un archivo llamadoFIR.DAT, el mismo tiene un formato capaz de serleido por el compilador-C del microprocesador ADSP-21061.

Los coeficientes son calculado utilizando el metodode ventana. Para mayor informacion referente aeste metodo ver el Capitulo 10 de:Introduction to Signal ProcessingSophocles J. OrfanidisPrentice Hall, 1996ISBN: 0-13-209172-0

Archivo: FIRF.C

Escrito: RICARDO LAMBRANO Fecha: 06/06/97 Compilado: MicroSoft C, Ver 6.00

Version: 1.00 Escrito Fecha: 06/06/97 Version: 1.10 Documentado Fecha: 12/12/97 Version: 1.20 Coeficientes hasta 2048 Fecha: 03/06/98 Version: 2.00 Formato Punto Flotante Fecha: 23/07/98

************************************************************************/

#include <stdio.h>#include <math.h>#include <dos.h>#include <graph.h>#define PI 3.14159265358

19

/************************************************************************ Funcion: WINObjetivo: Calcular el Valor de la funcion de ventana en un punto Entrada: I,N,VEN I = Punto en Ventana

N = Largo de VentanaVEN = Tipo de Ventana

Salida: Valor de Ventana (VEN), en punto (I) de (N) puntos************************************************************************/double WIN(I,N,VEN)int I,N,VEN;double TEMP;

switch(VEN) /* Que Tipo de Ventana? */case 1: /* Ventana: Rectangular */

TEMP = 1.0; /* Calcular Valor */break;

case 2: /* Ventana: Hanning */TEMP = 0.50 + 0.50*cos(2*PI*I/N);break;

case 3: /* Ventana: Hamming */TEMP = 0.540 + 0.460*cos(2*PI*I/N);break;

case 4: /* Ventana: Blackman */TEMP = 0.42 + 0.50*cos(2*PI*I/N) + 0.08*cos(4*PI*I/N);break;

return TEMP; /* Retornar Resultado */

/************************************************************************ Funcion: LPObjetivo: Calcular coeficientes de Filtro Pasa Bajo Entrada: FC, FS, N, VEN FC = Frecuencia de Corte en Hz FS = Frecuencia de Muestreo en Hz N = Numero de Puntos

VEN = Tipo de Ventana Salida: COEF COEF = Arreglo con Coeficientes Calculados

************************************************************************/LP(FC,FS,COEF,N,VEN)double FC,FS,*COEF;int N,VEN;int I,J,K;double TEMP,WC;

FC = FC/FS; /* Normalizar F-corte */WC = 2*PI*FC; /* Calcular W-corte */

20

J = -1*N/2; /* Limite Inferior */K = N/2; /* Limite Superior */

for(I = J; I <= K; I++) /* Ciclo de Calculo */if (I != 0) /* Si I <> 0 */

TEMP = sin(I*WC); /* Calcular Nominador */TEMP = TEMP/(PI*I); /* Dividir por Denominador */COEF[I+K] = TEMP*WIN(I,N,VEN); /* Ponderar por Ventana */

else /* Cuando I = 0 */COEF[I+K] = WC*WIN(I,N,VEN)/PI; /* Calcular y Ponderar */

/************************************************************************ Funcion: HPObjetivo: Calcular coeficientes de Filtro Pasa Alto Entrada: FC, FS, N, VEN FC = Frecuencia de Corte en Hz FS = Frecuencia de Muestreo en Hz N = Numero de Puntos

VEN = Tipo de Ventana Salida: COEF COEF = Arreglo con Coeficientes Calculados

************************************************************************/HP(FC,FS,COEF,N,VEN)double FC,FS,*COEF;int N,VEN;int I,J,K;double TEMP,WC;

FC = FC/FS; /* Normalizar F-corte */WC = 2*PI*FC; /* Calcular W-corte */

J = -1*N/2; /* Limite Inferior */K = N/2; /* Limite Superior */

for(I = J; I <= K; I++) /* Ciclo de Calculo */if (I != 0) /* Si I <> 0 */

TEMP = -sin(I*WC); /* Calcular Nominador */TEMP = TEMP/(PI*I); /* Dividir por Denominador */COEF[I+K] = TEMP*WIN(I,N,VEN); /* Ponderar por Ventana */

else /* Cuando I = 0 *//* Calcular y Ponderar */

COEF[I+K] = 1 - WC*WIN(I,N,VEN)/PI;

/************************************************************************ Funcion: BP

21

Objetivo: Calcular coeficientes de Filtro Pasa Banda Entrada: FC1, FC2, FS, N, VEN FC1 = Frecuencia de Corte1 en Hz FC2 = Frecuencia de Corte2 en Hz FS = Frecuencia de Muestreo en Hz N = Numero de Puntos

VEN = Tipo de Ventana Salida: COEF COEF = Arreglo con Coeficientes Calculados

************************************************************************/BP(FC1,FC2,FS,COEF,N,VEN)double FC1,FC2,FS,*COEF;int N,VEN;int I,J,K;double TEMP,WC1,WC2;

FC1 = FC1/FS; /* Normalizar F-corte1 */FC2 = FC2/FS; /* Normalizar F-corte2 */WC1 = 2*PI*FC1; /* Calcular W-corte1 */WC2 = 2*PI*FC2; /* Calcular W-corte2 */

J = -1*N/2; /* Limite Inferior */K = N/2; /* Limite Superior */

for(I = J; I <= K; I++) /* Ciclo de Calculo */if (I != 0) /* Si I <> 0 */

TEMP = sin(I*WC2) - sin(I*WC1); /* Calcular Nominador */TEMP = TEMP/(PI*I);/* Dividir por Denominador */COEF[I+K] = TEMP*WIN(I,N,VEN); /* Ponderar por Ventana */

else /* Si I = 0 *//* Calcular y Ponderar */

COEF[I+K] = (WC2 - WC1)*WIN(I,N,VEN)/PI;

/************************************************************************ Funcion: BRObjetivo: Calcular coeficientes de Filtro Rechaza Banda Entrada: FC1, FC2, FS, N, VEN FC1 = Frecuencia de Corte1 en Hz FC2 = Frecuencia de Corte2 en Hz FS = Frecuencia de Muestreo en Hz N = Numero de Puntos

VEN = Tipo de Ventana Salida: COEF COEF = Arreglo con Coeficientes Calculados

************************************************************************/BR(FC1,FC2,FS,COEF,N,VEN)double FC1,FC2,FS,*COEF;int N,VEN;int I,J,K;double TEMP,WC1,WC2;

FC1 = FC1/FS; /* Normalizar F-corte1 */FC2 = FC2/FS; /* Normalizar F-corte2 */

22

WC1 = 2*PI*FC1; /* Calcular W-corte1 */WC2 = 2*PI*FC2; /* Calcular W-corte2 */

J = -1*N/2; /* Limite Inferior */K = N/2; /* Limite Superior */

for(I = J; I <= K; I++) /* Ciclo de Calculo */if (I != 0) /* Si I <> 0 */

/* Calcular Nominador */TEMP = -1.0*(sin(I*WC2) - sin(I*WC1));TEMP = TEMP/(PI*I);/* Dividir por Denominador */COEF[I+K] = TEMP*WIN(I,N,VEN); /* Ponderar por Ventana */

else /* Si I = 0 *//* Calcular y Ponderar */

COEF[I+K] = 1 - 1.0*(WC2 - WC1)*WIN(I,N,VEN)/PI;

/************************************************************************ Funcion: DFObjetivo: Calcular coeficientes de un Diferenciador Entrada: N, VEN N = Numero de Puntos

VEN = Tipo de Ventana Salida: COEF COEF = Arreglo con Coeficientes Calculados

************************************************************************/DF(COEF,N,VEN)double *COEF;int N,VEN;int I,J,K;double TEMP;

J = -1*N/2; /* Limite Inferior */K = N/2; /* Limite Superior */

for(I = J; I <= K; I++) /* Ciclo de Calculo */if (I != 0) /* Si I <> 0 */

/* Calcular Valor */TEMP = (cos(PI*I))/I - (sin(PI*K))/(PI*I*I);COEF[I+K] = TEMP*WIN(I,N,VEN); /* Ponderar por Ventana */

else /* Si I = 0 */COEF[I+K] = 0; /* Valor = 0 */

/************************************************************************ Funcion: HLObjetivo: Calcular coeficientes de transformador de Hilbert Entrada: N, VEN

N = Numero de PuntosVEN = Tipo de Ventana

Salida: COEF COEF = Arreglo con Coeficientes Calculados

************************************************************************/HL(COEF,N,VEN)double *COEF;

23

int N,VEN;int I,J,K;double TEMP;

J = -1*N/2; /* Limite Inferior */K = N/2; /* Limite Superior */

for(I = J; I <= K; I++) /* Ciclo de Calculo */if (I != 0) /* Si I <> 0 */

TEMP = (1 - cos(PI*I))/(PI*I); /* Calcular Valor */COEF[I+K] = TEMP*WIN(I,N,VEN); /* Ponderar por Ventana */

else /* Si I = 0 */COEF[I+K] = 0; /* Valor = 0 */

/************************************************************************ Funcion: MAINObjetivo: Cuerpo del Programa Entrada: Varias desde el Teclado Salida: Archivo de coeficientes COEF.DAT

************************************************************************/main()int TIPO,N,I,MID,VEN;double FS,FC1,FC2,FACTOR;static double COEF[2048];FILE *FILE_OUT;

/************************************************************************Borrar Pantalla y desplegar menu de tipos de filtro

************************************************************************/

_clearscreen( _GCLEARSCREEN );

printf("\n\n Programa Para el Diseño de Filtros FIR\n\n");printf(" Versión 2.00 de 23/07/98 R. Lambraño\n\n");printf(" 1-Pasa Bajos\n");printf(" 2-Pasa Altos\n");printf(" 3-Pasa Banda\n");printf(" 4-Rechaza Banda\n");printf(" 5-Differenciador\n");printf(" 6-Transformada de Hilbert\n\n");printf(" Seleccione Tipo de Filtro? ");scanf("%d",&TIPO); /* Aceptar tipo de Filtro */

printf(" Numero de Puntos? ");scanf("%d",&N); /* Aceptar Numero de Coefs */

if (TIPO < 5) /* Si es un filtro */ /* Pedir Frecuencia Muesteo */printf("Frecuencia de Muestreo (KHz)? ");scanf("%lf",&FS); /* Aceptar F. muestro KHz */FS = FS * 1000; /* Convertir a Hz */

24

if (TIPO < 3) /* Si es LP o HP */ /* Pedir Frec. corte */printf(" Frecuencia de Corte (Hz)? ");scanf("%lf",&FC1);

else /* Si es LP o HP */ /* Pedir Frec. corte 1 y 2 */printf(" Frecuencia de Corte1 (Hz)? ");scanf("%lf",&FC1);printf(" Frecuencia de Corte2 (Hz)? ");scanf("%lf",&FC2);

/************************************************************************Desplegar menu de tipos de Ventana

************************************************************************/printf("\nVentana Transicion Rizo (db) Relacion Aten.\n");printf("1-Rectangular 0.9/N 0.7416 13db 21db\n");printf("2-Hanning 3.1/N 0.0546 31db 44db\n");printf("3-Hamming 3.3/N 0.0194 41db 53db\n");printf("4-Blackman 5.5/N 0.0017 57db 74db\n\n");printf(" Seleccione Tipo de Ventana? ");scanf("%d",&VEN); /* Aceptar Seleccion */

/************************************************************************Calcular Coeficientes dependiendo de Tipo de Filtro

************************************************************************/switch(TIPO)

case 1: /* Pasa Bajo */

LP(FC1,FS,COEF,N,VEN);break;

case 2: /* Pasa Alto */HP(FC1,FS,COEF,N,VEN);break;

case 3: /* Pasa Banda */BP(FC1,FC2,FS,COEF,N,VEN);break;

case 4: /* Rechaza Banda */BR(FC1,FC2,FS,COEF,N,VEN);break;

case 5: /* Diferenciador */DF(COEF,N,VEN);break;

case 6: /* Hilbert */HL(COEF,N,VEN);break;

FILE_OUT = fopen("FIR.DAT","w"); /* Abrir Archivo Salida */

FS = FS / 1000.0; /* Convertir Fs a KHz */

/************************************************************************Escribir tipo de Filtro en Archivo de Salida

************************************************************************/switch(TIPO)

25

case 1:

fprintf(FILE_OUT,"// Filtro: LP \n" );break;

case 2:fprintf(FILE_OUT,"// Filtro: HP \n" );break;

case 3:fprintf(FILE_OUT,"// Filtro: BP \n" );break;

case 4:fprintf(FILE_OUT,"// Filtro: BS \n" );break;

case 5:fprintf(FILE_OUT,"// Filtro: Diferenciador \n" );break;

case 6:fprintf(FILE_OUT,"// Filtro: Hilbert \n" );break;

/************************************************************************Escribir tipo de Ventana en Archivo de Salida

************************************************************************/switch(VEN)

case 1:

fprintf(FILE_OUT,"//Ventana: Rectangular \n");break;

case 2:fprintf(FILE_OUT,"//Ventana: Hanning \n");break;

case 3:fprintf(FILE_OUT,"//Ventana: Hamming \n");break;

case 4:fprintf(FILE_OUT,"//Ventana: Blackman \n");break;

/************************************************************************Escribir Numero de Coeficientes en Archivo de Salida

************************************************************************/fprintf(FILE_OUT,"// Taps: %3d \n", N );

/************************************************************************Escribir Frec. Muestreo y Corte en Archivo de Salida

************************************************************************/if (TIPO < 5)

fprintf(FILE_OUT,"// Fs: %8.3lfKHz \n", FS );

if (TIPO < 3)fprintf(FILE_OUT,"// Fc: %8.3lfHz \n", FC1 );

elsefprintf(FILE_OUT,"// Fc1: %8.3lfHz \n", FC1 );fprintf(FILE_OUT,"// Fc2: %8.3lfHz \n", FC2 );

26

/************************************************************************Escribir Coeficientes en 1.15 y Flotante en Archivo de Salida

************************************************************************/for(I = 0; I < (N-1); I++)

fprintf(FILE_OUT,"%+19.16lf, ",COEF[I]);fprintf(FILE_OUT,"// h(%+04d) = %+14.7E \n",I-N/2,COEF[I]);

I = N-1;fprintf(FILE_OUT,"%+19.16lf ",COEF[I]);fprintf(FILE_OUT,"// h(%+04d) = %+14.7E \n",I-N/2,COEF[I]);

fclose(FILE_OUT); /* Cerrar Archivo de Salida */

/* Fin de Programa */

5.2 FILTROS DE RESPUESTA INFINITA (IIR)

/************************************************************************

Programa: IIRF.EXE Objetivo: Calcular los coeficientes de la funcion de transfe- rencia de un filtro IIR invariante en el tiempo.

El resultado lo almacena en un archivo llamadoIIR.DAT, el mismo tiene un formato capaz de serleido por el ensamblador del microprocesador ADSP-21061.

Los coeficientes son calculado utilizando el metodode transformada bilineal aplicada a filtros ButterworthPara mayor informacion referente a este metodo ver elCapitulo 11 de:

Introduction to Signal ProcessingSophocles J. OrfanidisPrentice Hall, 1996ISBN: 0-13-209172-0

Archivo: IIRF.C

Escrito: RICARDO LAMBRANO Fecha: 06/06/97 Compilado: MicroSoft C, Ver 6.00

Version: 1.00 Escrito Fecha: 06/06/97 Version: 1.10 Documentado Fecha: 12/12/97 Version: 1.20 Incluido Filtro Selectivo Fecha: 03/06/98 Version: 2.00 Formato Punto Flotante Fecha: 23/07/98

************************************************************************/

#include <stdlib.h>#include <stdio.h>#include <dos.h>#include <math.h>#include <graph.h>

27

#define PI 3.14159265358

typedef struct complex complex;

/************************************************************************ Funcion: LPHPObjetivo: Calcular coeficientes de Bicuadraticas de filtros

pasa bajo y pasa alto. Entrada: FC, FS, N, T FC = Frecuencia de Corte en Hz

FS = Frecuencia de Muestreo en HzN = Numero de BicuadraticasT = Tipo de Filtro (0=LP) (1=HP)

Salida: COEF COEF = Arreglo con coeficientes de bicuadraticas SE,B2,B1,B0,A2,A1,SE,B2,...

SE = Exponente de Normalizacion/Denormalizacion************************************************************************/LPHP(FC,FS,COEF,N,T)double FC,FS,*COEF;int N,T;int I,J,K;double WC,ANG,G,A1,A2,DEN;

if (T == 0) /* Si es LP */WC = tan(PI*FC/FS); /* Wc = tan(pi*Fc/Fs */

else /* Si es HP */WC = 1.0/tan(PI*FC/FS); /* Wc = cot(pi*Fc/Fs */

J = N/2; /* Correguir Num de Biquad */for(I = 1; I <= J; I++) /* Ciclo de Calculo */

K = (I - 1)*6; /* Indice en Arreglo */ANG = PI*(N - 1 + 2*I)/(2*N); /* Angulo de Polos */DEN = (1.0 - 2.0*WC*cos(ANG) + WC*WC); /* Calculo de Denominador */G = (WC*WC) / DEN; /* Calculo de G */A1 = 2.0*(WC*WC-1) / DEN; /* Calculo de A1 */A2 = (1.0 + 2.0*WC*cos(ANG)+WC*WC)/ DEN;/* Calculo de A2 */

COEF[K+0] = 0; /* SE */COEF[K+1] = G; /* B2 */if (T == 0) /* Si es Pasa Bajo */

COEF[K+2] = 2*G; /* B1 */else /* Si es Pasa Alto */

COEF[K+2] = -2*G; /* B1 */

COEF[K+3] = G; /* B0 */COEF[K+4] = -1*A2; /* A2 */if (T == 0) /* Si es Pasa Bajo */

COEF[K+5] = -1*A1; /* A1 */else /* Si es Pasa Alto */

COEF[K+5] = A1; /* A1 */

/************************************************************************

28

Funcion: BPObjetivo: Calcular coeficientes de Bicuadraticas de filtro

pasa banda. Entrada: FC1, FC2, FS, N FC1 = Frecuencia de Corte1 en Hz FC2 = Frecuencia de Corte2 en Hz

FS = Frecuencia de Muestreo en HzN = Numero de Bicuadraticas

Salida: COEF COEF = Arreglo con coeficientes de bicuadraticas SE,B2,B1,B0,A2,A1,SE,B2,...

SE = Exponente de Normalizacion/Denormalizacion************************************************************************/BP(FC1,FC2,FS,COEF,N)double FC1,FC2,FS,*COEF;int N;

int I,J,K;double WC,WC1,WC2,ANG,G,A1,A2,A3,A4,FC,CC,DEN;double A,B,C,D,Q,R,X;double M0,M1,M2,N0,N1,N2;double L,F1,F2;complex T,T1,T2,S1,S2;

WC1 = 2*PI*FC1/FS; /* Normalizacion de FC1 */WC2 = 2*PI*FC2/FS; /* Normalizacion de FC2 */

CC = sin(WC1 + WC2)/(sin(WC1) + sin(WC2)); /* Calculo de F central */

WC = fabs( (CC - cos(WC2))/sin(WC2)); /* Calculo de Wc */

J = N/2; /* Correguir Num de Biquad */for(I = 1; I <= J; I++) /* Ciclo de Calculo */

K = (I - 1)*12; /* Indice en Arreglo */ANG = PI*(N - 1 + 2*I)/(2*N); /* Angulo de Polos */DEN = (1.0 - 2.0*WC*cos(ANG) + WC*WC); /* Calculo de Denominador */G = (WC*WC) / DEN; /* Calculo de G */A1 = 4*CC*(WC*cos(ANG) - 1)/DEN; /* Calculo de A1*Z^-1 */A2 = 2*(2*CC*CC + 1 - WC*WC)/DEN; /* Calculo de A2*Z^-2 */A3 = -4*CC*(WC*cos(ANG) + 1)/DEN; /* Calculo de A3*Z^-3 */A4 = (1.0 + 2.0*WC*cos(ANG) + WC*WC)/DEN;/* Calculo de A4*Z^-4 */

/************************************************************************Los coeficientes antes calculados son de una Ecuacion Cuarticaaqui los convertiremos en dos cuadraticas.Ref. Pag 2-14 de Handbook of Engineering Fundamentals

Eshbach Second Edition Wiley Handbook Series 1952. ISBN: No existia en esos tiempos (Las Matematicas nunca cambian...)

a0*X^4 + a1*X^3 + a2*X^2 + a3*X + a4 = 0

dividimos entre a0 para obtenerX^4 + a*X^3 + b*X^2 + c*X + d = 0

29

buscamos cualquier raiz real y1 de8*Y^3 - 4*B*Y^2 + 2(A*C - 4*D)*Y - (C^2 + D*(A^2 - 4B)) = 0

entonces las dos cuadraticas sonx^2 + (a/2 - (a^2/4 + 2*y1 - b)^.5)*x + (y1 + (y1^2 - d)^.5) = 0x^2 + (a/2 + (a^2/4 + 2*y1 - b)^.5)*x + (y1 + (y1^2 - d)^.5) = 0

para encontrar una raiz real de una cubicaa*x^3 + b*x^2 + c*x + d = 0

hacemosq = a*c - b^2r = 0.5*(3*a*b*c - a^2*d) - b^3s1 = (r + (q^3 + r^2)^.5)^(1/3)s2 = (r - (q^3 + r^2)^.5)^(1/3)

Entonces las raices sonx1 = (s1 + s2 - b)/ax2 = (-.5(s1 + s2) + (-3)^(1/3)*(s1-s2)/2 -b)/ax3 = (-.5(s1 + s2) - (-3)^(1/3)*(s1-s2)/2 -b)/a

************************************************************************/

/************************************************************************Calculo de raiz real y1 de cubica

************************************************************************/A = 8.0; /* A = 8 */B = -4*A2/3; /* B = -4*a2/3 */C = 2*(A1*A3 - 4*A4)/3; /* C = 2*(a1*a3 - 4*a4)/3 */D = -1.0*(A3*A3+ A4*(A1*A1 - 4*A2)); /* D = ... */

Q = A*C - B*B; /* Calculo de Q */R = 0.5*(3*A*B*C - A*A*D) - B*B*B; /* Calculo de R */

L = Q*Q*Q + R*R; /* Argumento de Raiz Cuad Sx*/if (L > 0.0) /* Si es positiva */

T.x = sqrt(L); /* Resultado es Real */T.y = 0.0; /* Imaginario = 0 */

else /* Si es Negativa */T.x = 0.0; /* Real = 0 */T.y = sqrt(fabs(L)); /* Resultado Imaginario */

T1.x = R + T.x; /* Calculo del Resto de S1 */T1.y = T.y;T2.x = cabs(T1);T2.y = atan2(T1.y,T1.x);S1.x = pow(T2.x,1.0/3.0);S1.y = T2.y / 3.0;

T1.x = R - T.x; /* Calculo del Resto de S2 */T1.y = T.y;T2.x = cabs(T1);T2.y = atan2(T1.y,T1.x);S2.x = pow(T2.x,1.0/3.0);

30

S2.y = T2.y / 3.0;

/* Calculo de X1 (REAL */X = (S1.x*cos(S1.y) + S2.x*cos(S2.y) - B)/A;

/************************************************************************Calculo de Coeficientes de Cuadraticas

************************************************************************/F1 = A1*A1/4 + 2*X - A2;F1 = sqrt(F1);

F2 = X*X - A4;F2 = sqrt(F2);

N2 = 1;N1 = A1/2 - F1;N0 = X + F2;

M2 = 1;M1 = A1/2 + F1;M0 = X - F2;

/************************************************************************Asignacion de Coeficientes de Cuadraticas

************************************************************************/G = sqrt(G); /* Ponderacion de Ganancia */

/* En dos bicuadraticas *//* Este metodo no da buenos *//* resultados, ver informe */

COEF[K+0] = 0; /* SE */COEF[K+1] = G; /* B2 */COEF[K+2] = 0; /* B1 */COEF[K+3] = G; /* B0 */COEF[K+4] = -1.0*N0; /* A2 */COEF[K+5] = -1.0*N1; /* A1 */

COEF[K+6] = 0; /* SE */COEF[K+7] = G; /* B2 */COEF[K+8] = 0; /* B1 */COEF[K+9] = G; /* B0 */COEF[K+10] = -1.0*M0; /* A2 */COEF[K+11] = -1.0*M1; /* A1 */

/************************************************************************ Funcion: BRObjetivo: Calcular coeficientes de Bicuadraticas de filtro

Rechaza Banda. Entrada: FC1, FC2, FS, N FC1 = Frecuencia de Corte1 en Hz FC2 = Frecuencia de Corte2 en Hz

FS = Frecuencia de Muestreo en HzN = Numero de Bicuadraticas

Salida: COEF

31

COEF = Arreglo con coeficientes de bicuadraticas SE,B2,B1,B0,A2,A1,SE,B2,...

SE = Exponente de Normalizacion/Denormalizacion************************************************************************/BR(FC1,FC2,FS,COEF,N)double FC1,FC2,FS,*COEF;int N;

int I,J,K;double WC,WC1,WC2,ANG,G,A1,A2,A3,A4,FC,CC,DEN;double A,B,C,D,Q,R,X;double M0,M1,M2,N0,N1,N2;double L,F1,F2;complex T,T1,T2,S1,S2;

WC1 = 2*PI*FC1/FS; /* Normalizacion de FC1 */WC2 = 2*PI*FC2/FS; /* Normalizacion de FC2 */

CC = sin(WC1 + WC2)/(sin(WC1) + sin(WC2)); /* Calculo de F central */

WC = fabs( sin(WC2) / (cos(WC2) - CC)); /* Calculo de Wc */

J = N/2; /* Correguir Num de Biquad */for(I = 1; I <= J; I++) /* Ciclo de Calculo */

K = (I - 1)*12; /* Indice en Arreglo */ANG = PI*(N - 1 + 2*I)/(2*N); /* Angulo de Polos */DEN = (1.0 - 2.0*WC*cos(ANG) + WC*WC); /* Calculo de Denominador */G = (WC*WC) / DEN; /* Calculo de G */A1 = 4*CC*WC*(cos(ANG) - WC)/DEN; /* Calculo de A1*Z^-1 */A2 = 2*(2*CC*CC*WC*WC + WC*WC - 1)/DEN;/* Calculo de A2*Z^-2 */A3 = -4*CC*WC*(cos(ANG) + WC)/DEN; /* Calculo de A3*Z^-3 */A4 = (1.0 + 2.0*WC*cos(ANG) + WC*WC)/DEN;/* Calculo de A4*Z^-4 */

/************************************************************************Los coeficientes antes calculados son de una Ecuacion Cuarticaaqui los convertiremos en dos cuadraticas.Ref. Pag 2-14 de Handbook of Engineering Fundamentals

Eshbach Second Edition Wiley Handbook Series 1952. ISBN: No existia en esos tiempos (Las Matematicas nunca cambian...)

a0*X^4 + a1*X^3 + a2*X^2 + a3*X + a4 = 0

dividimos entre a0 para obtenerX^4 + a*X^3 + b*X^2 + c*X + d = 0

buscamos cualquier raiz real y1 de8*Y^3 - 4*B*Y^2 + 2(A*C - 4*D)*Y - (C^2 + D*(A^2 - 4B)) = 0

entonces las dos cuadraticas sonx^2 + (a/2 - (a^2/4 + 2*y1 - b)^.5)*x + (y1 + (y1^2 - d)^.5) = 0x^2 + (a/2 + (a^2/4 + 2*y1 - b)^.5)*x + (y1 + (y1^2 - d)^.5) = 0

para encontrar una raiz real de una cubica

32

a*x^3 + b*x^2 + c*x + d = 0

hacemosq = a*c - b^2r = 0.5*(3*a*b*c - a^2*d) - b^3s1 = (r + (q^3 + r^2)^.5)^(1/3)s2 = (r - (q^3 + r^2)^.5)^(1/3)

Entonces las raices sonx1 = (s1 + s2 - b)/ax2 = (-.5(s1 + s2) + (-3)^(1/3)*(s1-s2)/2 -b)/ax3 = (-.5(s1 + s2) - (-3)^(1/3)*(s1-s2)/2 -b)/a

************************************************************************/

/************************************************************************Calculo de raiz real y1 de cubica

************************************************************************/

A = 8.0; /* A = 8 */B = -4*A2/3; /* B = -4*a2/3 */C = 2*(A1*A3 - 4*A4)/3; /* C = 2*(a1*a3 - 4*a4)/3 */D = -1.0*(A3*A3+ A4*(A1*A1 - 4*A2)); /* D = ... */

Q = A*C - B*B; /* Calculo de Q */R = 0.5*(3*A*B*C - A*A*D) - B*B*B; /* Calculo de R */

L = Q*Q*Q + R*R; /* Argumento de Raiz Cuad Sx*/if (L > 0.0) /* Si es positiva */

T.x = sqrt(L); /* Resultado es Real */T.y = 0.0; /* Imaginario = 0 */

else /* Si es Negativa */T.x = 0.0; /* Real = 0 */T.y = sqrt(fabs(L)); /* Resultado Imaginario */

T1.x = R + T.x; /* Calculo del Resto de S1 */T1.y = T.y;T2.x = cabs(T1);T2.y = atan2(T1.y,T1.x);S1.x = pow(T2.x,1.0/3.0);S1.y = T2.y / 3.0;

T1.x = R - T.x; /* Calculo del Resto de S2 */T1.y = T.y;T2.x = cabs(T1);T2.y = atan2(T1.y,T1.x);S2.x = pow(T2.x,1.0/3.0);S2.y = T2.y / 3.0;

/* Calculo de X1 (REAL */X = (S1.x*cos(S1.y) + S2.x*cos(S2.y) - B)/A;

/************************************************************************Calculo de Coeficientes de Cuadraticas

************************************************************************/

33

F1 = A1*A1/4 + 2*X - A2;F1 = sqrt(F1);

F2 = X*X - A4;F2 = sqrt(F2);

N2 = 1;N1 = A1/2 - F1;N0 = X + F2;

M2 = 1;M1 = A1/2 + F1;M0 = X - F2;

/************************************************************************Asignacion de Coeficientes de Cuadraticas

************************************************************************/G = sqrt(G); /* Ponderacion de Ganancia */

/* En dos bicuadraticas *//* Este metodo no da buenos *//* resultados, ver informe */

COEF[K+0] = 0; /* SE */COEF[K+1] = G; /* B2 */COEF[K+2] = -2*G; /* B1 */COEF[K+3] = G; /* B0 */COEF[K+4] = -1*N0; /* A2 */COEF[K+5] = -1*N1; /* A1 */

COEF[K+6] = 0; /* SE */COEF[K+7] = G; /* B2 */COEF[K+8] = -2*G; /* B1 */COEF[K+9] = G; /* B0 */COEF[K+10] = -1*M0; /* A2 */COEF[K+11] = -1*M1; /* A1 */

/************************************************************************ Funcion: NOTCHObjetivo: Calcular coeficientes de Bicuadraticas de filtros

Notchs. Entrada: FN, AF, FS, N FN = Arreglo con Frecuencia Central en Hz AF = Arreglo con Ancho de Frecuencia en Hz

FS = Frecuencia de Muestreo en HzN = Numero de Bicuadraticas

Salida: COEF COEF = Arreglo con coeficientes de bicuadraticas SE,B2,B1,B0,A2,A1,SE,B2,...

SE = Exponente de Normalizacion/Denormalizacion************************************************************************/NOTCH(FN,AF,FS,COEF,N)double *FN,*AF,FS,*COEF;int N;

34

int I,J,K;double A1,A2,B,WC;

for(I = 0; I < N; I++) /* Ciclo de Calculo */K = I*6; /* Indice en Arreglo */B = 1.0 / (1.0 + tan(PI*AF[I]/FS)); /* Calculo de Ancho de Banda */WC = 2*PI*FN[I]/FS; /* Calculo de Freq. Central */A1 = -2.0*B*cos(WC); /* Calculo de A1 */A2 = (2*B-1.0); /* Calculo de A2 */

COEF[K+0] = 0; /* SE */COEF[K+1] = B; /* B2 */COEF[K+2] = -2*B*cos(WC); /* B1 */COEF[K+3] = B; /* B0 */COEF[K+4] = -1*A2; /* A2 */COEF[K+5] = -1*A1; /* A1 */

/************************************************************************ Funcion: NOTCHObjetivo: Calcular coeficientes de Bicuadraticas de filtros

Notchs. Entrada: FN, AF, FS, N FN = Arreglo con Frecuencia Central en Hz AF = Arreglo con Ancho de Frecuencia en Hz

FS = Frecuencia de Muestreo en HzN = Numero de Bicuadraticas

Salida: COEF COEF = Arreglo con coeficientes de bicuadraticas SE,B2,B1,B0,A2,A1,SE,B2,...

SE = Exponente de Normalizacion/Denormalizacion************************************************************************/SELEC(FN,AF,FS,COEF,N)double *FN,*AF,FS,*COEF;int N;int I,J,K;double A1,A2,B,WC;

for(I = 0; I < N; I++) /* Ciclo de Calculo */K = I*6; /* Indice en Arreglo */B = 1.0 / (1.0 + tan(PI*AF[I]/FS)); /* Calculo de Ancho de Banda */WC = 2*PI*FN[I]/FS; /* Calculo de Freq. Central */A1 = -2.0*B*cos(WC); /* Calculo de A1 */A2 = (2*B-1.0); /* Calculo de A2 */

COEF[K+0] = 0; /* SE */COEF[K+1] = (1-B); /* B2 */COEF[K+2] = 0; /* B1 */COEF[K+3] = (1-B); /* B0 */COEF[K+4] = -1*A2; /* A2 */COEF[K+5] = -1*A1; /* A1 */

35

/************************************************************************ Funcion: MAINObjetivo: Cuerpo del Programa Entrada: Varias desde el Teclado Salida: Archivo de coeficientes COEF.DAT

************************************************************************/main()int TIPO,N,I,J,MID,INDX;double FS,FC1,FC2,FACTOR,NORM;double COEF[512],FN[512],AF[512];FILE *FILE_OUT;div_t DIVRES;

/************************************************************************Borrar Pantalla y desplegar menu de tipos de filtro

************************************************************************/

_clearscreen( _GCLEARSCREEN );

printf("\n\n Programa Para el Diseño de Filtros IIR\n\n");printf(" Versión 2.00 de 23/07/98 R. Lambraño\n\n");printf(" 1-Pasa Bajos\n");printf(" 2-Pasa Altos\n");printf(" 3-Pasa Banda\n");printf(" 4-Rechaza Banda\n\n");printf(" 5-Notch\n");printf(" 6-Selectivo\n\n");printf(" Seleccione Tipo de Filtro? ");

scanf("%d",&TIPO); /* Aceptar tipo de Filtro */

if(TIPO < 5) /* Si no es Notch */printf(" Numero de Bi-cuadraticas? ");scanf("%d",&N); /* Aceptar Numero de Bicuads */if (TIPO < 3)

N = N*2;

else /* Si es Notch */printf(" Numero de Filtros? ");scanf("%d",&N); /* Numero de Notchs o Selec*/

printf("Frecuencia de Muestreo (KHz)? ");scanf("%lf",&FS); /* Aceptar Frec. Muestreo */FS = FS * 1000; /* Convertir a Hz */

if (TIPO < 3) /* Si es LP o HP */printf(" Frecuencia de Corte (Hz)? ");scanf("%lf",&FC1); /* Aceptar Frec. Corte */

if ((TIPO == 3) || (TIPO == 4) ) /* Si es BP o BR */printf(" Frecuencia de Corte1 (Hz)? ");

36

scanf("%lf",&FC1); /* Aceptar Frec. Corte1 */printf(" Frecuencia de Corte2 (Hz)? ");scanf("%lf",&FC2); /* Aceptar Frec. Corte2 */

if (TIPO == 5) /* Si es Notch */for(I = 0; I < N; I++)

printf("Frecuencia Central del NOTCH%2d (Hz)? ",I);scanf("%lf",&FN[I]); /* Aceptar F. Central */printf(" Ancho de Banda del NOTCH%2d (Hz)? ",I);scanf("%lf",&AF[I]); /* Aceptar Ancho de Banda */

if (TIPO == 6) /* Si es Selectivo */for(I = 0; I < N; I++)

printf("Frecuencia Central del Selectivo%2d (Hz)? ",I);scanf("%lf",&FN[I]); /* Aceptar F. Central */printf(" Ancho de Banda del Selectivo%2d (Hz)? ",I);scanf("%lf",&AF[I]); /* Aceptar Ancho de Banda */

/************************************************************************Calcular Coeficientes dependiendo de Tipo de Filtro

************************************************************************/switch(TIPO)

case 1:

LPHP(FC1,FS,COEF,N,0); /* Pasa Bajo */break;

case 2:LPHP(FC1,FS,COEF,N,1); /* Pasa Alto */break;

case 3:BP(FC1,FC2,FS,COEF,N); /* Pasa Banda */N = N * 2;break;

case 4:BR(FC1,FC2,FS,COEF,N); /* Rechaza Banda */N = N * 2;break;

case 5:NOTCH(FN,AF,FS,COEF,N); /* Notch */N = N * 2;break;

case 6:SELEC(FN,AF,FS,COEF,N); /* Selectivo */N = N * 2;break;

FILE_OUT = fopen("IIR.DAT","w"); /* Abrir archivo de salida */

FS = FS / 1000.0; /* Convertir Fs a KHz */

/************************************************************************Escribir tipo de Filtro en Archivo de Salida

37

************************************************************************/switch(TIPO)

case 1:

fprintf(FILE_OUT,"// Filtro: LP \n" );break;

case 2:fprintf(FILE_OUT,"// Filtro: HP \n" );break;

case 3:fprintf(FILE_OUT,"// Filtro: BP \n" );break;

case 4:fprintf(FILE_OUT,"// Filtro: BS \n" );break;

case 5:fprintf(FILE_OUT,"// Filtro: NOTCH \n" );break;

case 6:fprintf(FILE_OUT,"// Filtro: SELECTIVO \n" );break;

/************************************************************************Escribir Numero de Polos en Archivo de Salida

************************************************************************/fprintf(FILE_OUT,"// Polos: %3d \n", N );

/************************************************************************Escribir Frecuencia de Muestreo en Archivo de Salida

************************************************************************/fprintf(FILE_OUT,"// Fs: %8.3lfKHz \n", FS );

/************************************************************************Escribir Frecuencia de Corte en Archivo de Salida

************************************************************************/if (TIPO < 3)

fprintf(FILE_OUT,"// Fc: %8.3lfHz \n", FC1 );

if ((TIPO == 3) || (TIPO == 4) )fprintf(FILE_OUT,"// Fc1: %8.3lfHz \n", FC1 );fprintf(FILE_OUT,"// Fc2: %8.3lfHz \n", FC2 );

if ( (TIPO == 5) || (TIPO == 6) )for(I = 0; I < N/2; I++)

fprintf(FILE_OUT,"// Fc: %8.3lfHz \n", FN[I] );fprintf(FILE_OUT,"// AF: %8.3lfHz \n", AF[I] );

/************************************************************************Escribir Coeficientes en 1.15 y Flotante en Archivo de Salida

************************************************************************/for(I = 0; I < (N/2); I++)

J = I*6;

38

fprintf(FILE_OUT,"%+19.16lf, // B2 = %+14.7E\n",COEF[J+1],COEF[J+1]);fprintf(FILE_OUT,"%+19.16lf, // B1 = %+14.7E\n",COEF[J+2],COEF[J+2]);fprintf(FILE_OUT,"%+19.16lf, // B0 = %+14.7E\n",COEF[J+3],COEF[J+3]);fprintf(FILE_OUT,"%+19.16lf, // A2 = %+14.7E\n",COEF[J+4],COEF[J+4]);fprintf(FILE_OUT,"%+19.16lf, // A1 = %+14.7E\n",COEF[J+5],COEF[J+5]);

fclose(FILE_OUT); /* Cerrar Archivo de Salida */

/* Fin de Programa */

6 LISTADO DE PROGRAMAS DE IMPLEMENTACIÓN

6.1 FILTROS DE RESPUESTA FINITA (FIR)

/***************************************************************************** Universidad Tecnológica de Panamá* Facultad de Ingeniería Eléctrica* Departamento de Electrónica* Post-Grado en Electrónica Digital* Tratamiento Digital de la Informacion** Fecha: 01/07/98** Estudiante: Ricardo Lambraño** Sistema: SHARC EZ-KIT Lite* Proyecto: Filtro FIR* Archivos: FIR.C, FIR.DAT** Archivo: FIR.C* Objetivo: Archivo Principal* Escrito: 05/06/97 Ver.: 1.00 (Analog Devices)* Revision: 25/06/98 Ver.: 1.00A Modificado para appl.****************************************************************************/

#include <def21060.h>#include <21060.h>#include <signal.h>#include <sport.h>#include <macros.h>#include <math.h>

#define CP_PCI 0x20000 // Definicion de Punteros del DMA#define CP_MAF 0x1ffff // Direcciones de Memoria Validas

#define SetIOP(addr, val) (* (int *) addr) = (val)#define GetIOP(addr) (* (int *) addr)

/***************************************************************************** Definicion de Numero de Coeficientes, Arreglo de Coeficientes* y Arreglo de Variables*

39

***************************************************************************/

#define TAPS 255 // Numero de Coeficientes (Orden del Filtro)

float pm H[TAPS] = // Coeficientes del Filtros leidos del // Archivo ASCII <FIR.DAT>#include "fir.dat";

float dm X[TAPS+1];// Buffer del Filtro

/***************************************************************************** Registros de Inicializacion del CODEC AD1847****************************************************************************/

#define CNT_1847 16int REGS_1847[CNT_1847] =

0xc000, // Registro 0 - left input control0xc100, // Registro 1 - right input control0xc280, // Registro 2 - left aux 1 input control0xc380, // Registro 3 - right aux 1 input control0xc480, // Registro 4 - left aux 2 input control0xc580, // Registro 5 - right aux 2 input control0xc600, // Registro 6 - left dac control0xc700, // Registro 7 - right dac control0xc85c, // Registro 8 - data format0xc909, // Registro 9 - interface configuration0xca00, // Registro 10 - pin control0xcb00, // Registro 11 - no register0xcc40, // Registro 12 - miscellaneous information0xcd00, // Registro 13 - digital mix control0xce00, // Registro 14 - no register0x8f00; // Registro 15 - no register

int rx_buf[3]; // Buffer de Recepcionint tx_buf[3] = 0xcc40, 0, 0; // Buffer de Transmision

/***************************************************************************** Bloque de Control de Transferencia (TCB) del DMA****************************************************************************/

typedef struct unsigned lpath3;unsigned lpath2;unsigned lpath1;unsigned db;unsigned gp;unsigned** cp;unsigned c;int im;unsigned * ii;

_tcb;

_tcb rx_tcb = 0, 0, 0, 0, 0, 0, 3, 1, 0; // TCB del Receptor

40

_tcb tx_tcb = 0, 0, 0, 0, 0, 0, 3, 1, 0; // TCB del Transmisor

static int xmit_count; // Contador de Datos a transmitirstatic int * xmit_ptr; // Puntero a Datos a transmitir

static int ON_OFF; // Bandera de filtro encendido o apagado

/***************************************************************************** Rutina de Programacion del CODEC****************************************************************************/void SPORT0_TX( int sig_num )if( xmit_count ) // Hay Datos para transmitir

tx_buf[0] = *xmit_ptr++; // Si, Transmitir el actual e inc punteroxmit_count--; // Decrementar cuenta de datos a transmitir

/***************************************************************************** Rutina de Interrupcion del CODEC (Recepcion)* Aqui se realiza el Filtrado!****************************************************************************/void SPORT0_RX( int sig_num )float ACUM;int k,FILT;

ACUM = rx_buf[1]; // Señal de Entra del CODEC (L)

if (ON_OFF) // Bandera de FuncionamientoX[TAPS] = ACUM; // X[n] = Ultimo elemento del bufferACUM = 0.0; // Blanquear Acumuladorfor(k=0;k<TAPS;k++) // Ciclo de K = 0 a TAPS

ACUM = ACUM + H[k]*X[k];// "Convolucion"X[k] = X[k+1]; // Corrimiento de Datos

tx_buf[1] = ACUM; // Señal de Salida del CODEC (L)tx_buf[2] = ACUM; // Señal de Salida del CODEC (R)

/***************************************************************************** Rutina de Interrupcion del IRQ1 (Interruptor)****************************************************************************/void IRQ1( int sig_num )ON_OFF = ON_OFF ^ 0xFF;set_flag( SET_FLAG1, TGL_FLAG); // Cambiar de estado los LEDs

41

set_flag( SET_FLAG2, TGL_FLAG); // LEDs Encendidos indica Filtro Funcionandoset_flag( SET_FLAG3, TGL_FLAG); // LEDs Apagados indica Fil. no funcionando

/***************************************************************************** Rutina de inicializacion de los puertos seriales (SPORTS)* Los registros aqui inicializados, dependen de la construccion de la* tarjeta y no son sujetos a cambios.****************************************************************************/void INIT_SPORTS( void )sport0_iop.mtcs = 0x00070007; // Transmitir en canales 0,1,2,16,17,18sport0_iop.mrcs = 0x00070007; // Recibir en canales 0,1,2,16,17,18sport0_iop.mtccs = 0x00000000; // no companding on transmitsport0_iop.mrccs = 0x00000000; // no companding on receive

SetIOP(STCTL0, 0x001c00f2); // Inicializacin del Control de TransmisionSetIOP(SRCTL0, 0x1f8c20f2); // Inicializacin del Control de Recepcion

interrupt(SIG_SPR0I, SPORT0_RX); // Establece manejador de Interrupcion RXinterrupt(SIG_SPT0I, SPORT0_TX); // Establece manejador de Interrupcion TXinterrupt(SIG_IRQ1, IRQ1); // Establece manejador de Interrupcion IRQ1

tx_tcb.ii = tx_buf; // Establece buffer de Transmisiontx_tcb.cp = &tx_tcb.ii;SetIOP(CP2, (((int)&tx_tcb.ii) & CP_MAF) | CP_PCI);

rx_tcb.ii = rx_buf; // Establece buffer de Recepcionrx_tcb.cp = &rx_tcb.ii;SetIOP(CP0, (((int)&rx_tcb.ii) & CP_MAF) | CP_PCI);

/***************************************************************************** Rutina de Inicializacion del CODEC AD1847****************************************************************************/void INIT_1847( void )xmit_ptr = REGS_1847; // Datos de registros para inicializacionxmit_count = CNT_1847; // Cantidad de Datos

while( xmit_count ) // Esperar hasta tranmitir todos los datosidle();

while( !(rx_buf[0] & 0x0002) ) // Esperar inicio de Auto-Calibracionidle();

while( rx_buf[0] & 0x0002 ) // Esperar fin de Auto-Calibracionidle();

/****************************************************************************

42

* Rutina de Inicializacion del SHARC 21061****************************************************************************/void INIT_21K( void )timer_off(); // Des-habilitar el TIMER

xmit_count = 0; // Inicializar variables mientrasxmit_ptr = REGS_1847; // se llegan a utilizar

asm( "#include <def21060.h>" ); // Habilitar interrupciones anidadasasm( "bit set mode1 NESTM;" ); // con instrucciones en Assemblerasm( "bit set mode2 IRQ1E;"); // Hacer IRQ1 interrupcion por flanco

ON_OFF = 0; // Bandera ON_OFF apagadaset_flag( SET_FLAG1, SET_FLAG); // Apagar los LEDs (Indica Filtro Apagado)set_flag( SET_FLAG2, SET_FLAG); // Apagar los LEDs (Indica Filtro Apagado)set_flag( SET_FLAG3, SET_FLAG); // Apagar los LEDs (Indica Filtro Apagado)

/***************************************************************************** Cuerpo del Programa****************************************************************************/void main ( void )int i;int x;

for( i=0 ; i<TAPS+1 ; i++ ) // Inicializar varibles del FiltroX[i] = 0.0;

INIT_21K(); // Inicializar el ADSP-21061

set_flag( SET_FLAG0, CLR_FLAG ); // Re-Inicializar el CODEC (conectado aFLG0)for( x=0 ; x<0xffff ; x++ ) // Esperar el tiempo necesario para el RESET

;

set_flag( SET_FLAG0, SET_FLAG ); // Habilitar el CODEC

INIT_SPORTS(); // Inicializar los puertos seriales INIT_1847(); // Inicializar el CODEC

while( 3 < 4 ) // Ciclo inifinito, porque el procesamiento // se realiza en la rutina de interrupcionidle(); // del CODEC (RX);

6.2 FILTROS DE RESPUESTA INFINITA (IIR)

/****************************************************************************

43

* Universidad Tecnológica de Panamá* Facultad de Ingeniería Eléctrica* Departamento de Electrónica* Post-Grado en Electrónica Digital* Tratamiento Digital de la Informacion** Fecha: 01/07/98** Estudiante: Ricardo Lambraño** Sistema: SHARC EZ-KIT Lite* Proyecto: Filtro IIR* Archivos: IIR.C, IIR.DAT** Archivo: IIR.C* Objetivo: Archivo Principal* Escrito: 05/06/97 Ver.: 1.00 (Analog Devices)* Revision: 25/06/98 Ver.: 1.00A Modificado para appl.****************************************************************************/

#include <def21060.h>#include <21060.h>#include <signal.h>#include <sport.h>#include <macros.h>#include <math.h>

#define CP_PCI 0x20000 // Definicion de Punteros del DMA#define CP_MAF 0x1ffff // Direcciones de Memoria Validas

#define SetIOP(addr, val) (* (int *) addr) = (val)#define GetIOP(addr) (* (int *) addr)

/***************************************************************************** Definicion de Numero de Coeficientes, Arreglo de Coeficientes* y Arreglo de Variables****************************************************************************/

#define BICUADS 4 // Numero de Bicuadraticas (Orden delFiltro)

float pm H[BICUADS*5] = // Coeficientes del Filtros leidos del // Archivo ASCII <IIR.DAT>#include "iir.dat";

float dm X[BICUADS*5]; // Buffer del Filtro X(n) y Y(n)

/***************************************************************************** Registros de Inicializacion del CODEC AD1847****************************************************************************/

#define CNT_1847 16

44

int REGS_1847[CNT_1847] = 0xc000, // Registro 0 - left input control0xc100, // Registro 1 - right input control0xc280, // Registro 2 - left aux 1 input control0xc380, // Registro 3 - right aux 1 input control0xc480, // Registro 4 - left aux 2 input control0xc580, // Registro 5 - right aux 2 input control0xc600, // Registro 6 - left dac control0xc700, // Registro 7 - right dac control0xc85c, // Registro 8 - data format0xc909, // Registro 9 - interface configuration0xca00, // Registro 10 - pin control0xcb00, // Registro 11 - no register0xcc40, // Registro 12 - miscellaneous information0xcd00, // Registro 13 - digital mix control0xce00, // Registro 14 - no register0x8f00; // Registro 15 - no register

int rx_buf[3]; // Buffer de Recepcionint tx_buf[3] = 0xcc40, 0, 0; // Buffer de Transmision

/***************************************************************************** Bloque de Control de Transferencia (TCB) del DMA****************************************************************************/

typedef struct unsigned lpath3;unsigned lpath2;unsigned lpath1;unsigned db;unsigned gp;unsigned** cp;unsigned c;int im;unsigned * ii;

_tcb;

_tcb rx_tcb = 0, 0, 0, 0, 0, 0, 3, 1, 0; // TCB del Receptor_tcb tx_tcb = 0, 0, 0, 0, 0, 0, 3, 1, 0; // TCB del Transmisor

static int xmit_count; // Contador de Datos a transmitirstatic int * xmit_ptr; // Puntero a Datos a transmitir

static int ON_OFF; // Bandera de filtro encendido o apagado

/***************************************************************************** Rutina de Programacion del CODEC****************************************************************************/void SPORT0_TX( int sig_num )if( xmit_count ) // Hay Datos para transmitir

tx_buf[0] = *xmit_ptr++; // Si, Transmitir el actual e inc punteroxmit_count--; // Decrementar cuenta de datos a transmitir

45

/***************************************************************************** Rutina de Interrupcion del CODEC (Recepcion)* Aqui se realiza el Filtrado!** Y(n) = B0*X(n) + B1*X(n-1) + B2*X(n-2) + A1*Y(n-1) + A2*Y(n-2)****************************************************************************/void SPORT0_RX( int sig_num )float ACUM;int i,ii,FILT;

ACUM = rx_buf[1]; // Señal de Entra del CODEC (L)

if (ON_OFF) // Bandera de Funcionamientofor(ii = 0; ii < BICUADS; ii++)// Repetir por N bicuadraticas

i = ii*5; // Ajustar Indice de variablesX[i+2] = ACUM; // X[n] = Valor del ADC

// o ultimo filtro!ACUM = H[i+2]*X[i+2]; // Y[n] = B0*X[n]ACUM = ACUM + H[i+1]*X[i+1]; // Y[n] = Y[n] + B1*X[n-1]ACUM = ACUM + H[i+0]*X[i+0]; // Y[n] = Y[n] + B2*X[n-2]ACUM = ACUM + H[i+3]*X[i+3]; // Y[n] = Y[n] + A1*Y[n-1]ACUM = ACUM + H[i+4]*X[i+4]; // Y[n] = Y[n] + A2*Y[n-2]X[i+0] = X[i+ 1]; // X[n-2] = X[n-1]X[i+1] = X[i+ 2]; // X[n-1] = X[n]X[i+3] = X[i+ 4]; // Y[n-2] = Y[n-1]X[i+4] = ACUM; // Y[n-1] = Y[n]

tx_buf[1] = ACUM; // Señal de Salida del CODEC (L)tx_buf[2] = ACUM; // Señal de Salida del CODEC (R)

/***************************************************************************** Rutina de Interrupcion del IRQ1 (Interruptor)****************************************************************************/void IRQ1( int sig_num )ON_OFF = ON_OFF ^ 0xFF;set_flag( SET_FLAG1, TGL_FLAG); // Cambiar de estado los LEDsset_flag( SET_FLAG2, TGL_FLAG); // LEDs Encendidos indica Filtro Funcionandoset_flag( SET_FLAG3, TGL_FLAG); // LEDs Apagados indica Fil. no funcionando

/***************************************************************************** Rutina de inicializacion de los puertos seriales (SPORTS)* Los registros aqui inicializados, dependen de la construccion de la

46

* tarjeta y no son sujetos a cambios.****************************************************************************/void INIT_SPORTS( void )sport0_iop.mtcs = 0x00070007; // Transmitir en canales 0,1,2,16,17,18sport0_iop.mrcs = 0x00070007; // Recibir en canales 0,1,2,16,17,18sport0_iop.mtccs = 0x00000000; // no companding on transmitsport0_iop.mrccs = 0x00000000; // no companding on receive

SetIOP(STCTL0, 0x001c00f2); // Inicializacin del Control de TransmisionSetIOP(SRCTL0, 0x1f8c20f2); // Inicializacin del Control de Recepcion

interrupt(SIG_SPR0I, SPORT0_RX); // Establece manejador de Interrupcion RXinterrupt(SIG_SPT0I, SPORT0_TX); // Establece manejador de Interrupcion TXinterrupt(SIG_IRQ1, IRQ1); // Establece manejador de Interrupcion IRQ1

tx_tcb.ii = tx_buf; // Establece buffer de Transmisiontx_tcb.cp = &tx_tcb.ii;SetIOP(CP2, (((int)&tx_tcb.ii) & CP_MAF) | CP_PCI);

rx_tcb.ii = rx_buf; // Establece buffer de Recepcionrx_tcb.cp = &rx_tcb.ii;SetIOP(CP0, (((int)&rx_tcb.ii) & CP_MAF) | CP_PCI);

/***************************************************************************** Rutina de Inicializacion del CODEC AD1847****************************************************************************/void INIT_1847( void )xmit_ptr = REGS_1847; // Datos de registros para inicializacionxmit_count = CNT_1847; // Cantidad de Datos

while( xmit_count ) // Esperar hasta tranmitir todos los datosidle();

while( !(rx_buf[0] & 0x0002) ) // Esperar inicio de Auto-Calibracionidle();

while( rx_buf[0] & 0x0002 ) // Esperar fin de Auto-Calibracionidle();

/***************************************************************************** Rutina de Inicializacion del SHARC 21061****************************************************************************/void INIT_21K( void )timer_off(); // Des-habilitar el TIMER

xmit_count = 0; // Inicializar variables mientras

47

xmit_ptr = REGS_1847; // se llegan a utilizar

asm( "#include <def21060.h>" ); // Habilitar interrupciones anidadasasm( "bit set mode1 NESTM;" ); // con instrucciones en Assemblerasm( "bit set mode2 IRQ1E;"); // Hacer IRQ1 interrupcion por flanco

ON_OFF = 0; // Bandera ON_OFF apagadaset_flag( SET_FLAG1, SET_FLAG); // Apagar los LEDs (Indica Filtro Apagado)set_flag( SET_FLAG2, SET_FLAG); // Apagar los LEDs (Indica Filtro Apagado)set_flag( SET_FLAG3, SET_FLAG); // Apagar los LEDs (Indica Filtro Apagado)

/***************************************************************************** Cuerpo del Programa****************************************************************************/void main ( void )int i;int x;

for( i=0 ; i<BICUADS*5 ; i++ ) // Inicializar varibles del FiltroX[i] = 0.0;

INIT_21K(); // Inicializar el ADSP-21061

set_flag( SET_FLAG0, CLR_FLAG ); // Re-Inicializar el CODEC (conectado aFLG0)for( x=0 ; x<0xffff ; x++ ) // Esperar el tiempo necesario para el RESET

;

set_flag( SET_FLAG0, SET_FLAG ); // Habilitar el CODEC

INIT_SPORTS(); // Inicializar los puertos seriales

INIT_1847(); // Inicializar el CODEC

while( 3 < 4 ) // Ciclo inifinito, porque el procesamiento // se realiza en la rutina de interrupcionidle(); // del CODEC (RX);

48

7 RECOMENDACIONES Y MEJORAS

Ambos programas de diseño pueden tener un gran número de mejoras, por ejemplo, para elprograma de diseño de filtros FIR se pueden incluir más ventanas; graficar la respuesta del filtro adistintas entradas; etc.

Para el programa de diseño de filtros IIR se pueden incluir otros tipos de filtro tales comoChebyshev Tipo-I, Chebyshev Tipo-II, Elipticos, etc. También como en el caso del programa de IIR sepuede graficar la respuesta del filtro a distintas entradas; mostrar un diagrama de polos y ceros;calcular el tiempo de estabilización del filtro (setling time); etc.

Para el programa de diseño de filtros IIR se puede y debe mejorar la ponderación de lasganancias en los filtros Pasa Banda y Rechaza Banda, ya que con filtros de orden mayor a 4 estaponderación crea un gran problema, produciendose sobre flujos aun a nivel de audio relativamente bajos.

La ponderación actual de la ganancia es simplemente establecerle una ganancia igual a ambassecciones bicuadráticas, siendo la ganancia de cada una G1 = G2 = sqrt(G). Obviamente G1*G2 = G.

Sin embargo hemos encontrado que la mejor manera es hacer G1 = sqrt(G)*T y G2 = sqrt(G)/T.Sin embargo el valor de T adecuado no es fácil de encontrar.

8 BIBLIOGRAFÍA

[1] Introduction toSignal ProcessingSophocles J. OrfanidisPrentice Hall, 1996

[2] Digital Signal ProcessingA Practical ApproachAddison-Wesley, 1993

[3] Foundations ofDigital Signal Processingand Data AnalysisJames A. CadzowMacmillan, 1987

[4] ADSP-21000 FamilyApplication Handbook Volume 1Analog Devices, 1994

[5] Para listados de programas y más información:www.ieesa.com/universidades/adsp21061/index.html