Sei sulla pagina 1di 12

UNIVERSIDAD DE LOS LLANOS GRUPO DE INVESTIGACION MACRYPT GUIA: IMPLIMENTACION DE FILTROS DIGITALES EN MICROCONTROLADOR PIC Hecho por: Carlos

Arturo Gmez Jimnez Carlos19900907@gmail.com OBJETIVOS Aplicar los conocimientos adquiridos en el curso anlisis de seales. Implementar un filtro digital.

CONOCIMIENTOS PREVIOS: Tasa o frecuencia de muestreo: Es el nmero de muestras por unidad de tiempo que se toman de una seal continua para producir una seal discreta, durante el proceso necesario para convertirla de analgica en digital.

Teorema de Nyquist: Para poder replicar con exactitud la forma de una onda es necesario que la frecuencia de muestreo sea superior al doble de la mxima frecuencia a muestrear. El criterio se debe cumplir para evitar el efecto aliasing.

Aliasing: Este fenmeno ocurre cuando una seal continua es muestreada a una tasa menor que la que establece el teorema de Nyquist. En seales peridicas har aparecer una seal fantasma con una frecuencia menor que la de la seal real.

Para evitar este fenmeno se utiliza un filtro anlogo pasa bajos con frecuencia menor que la mxima frecuencia a muestrear.

Cuantificacin se define como el nmero de smbolos que se utilizan para guardar una medida de una seal. Para guardar o procesar la medida la se codifica con un conjunto de bits. A mayor nmero de bits empleados para guardar la medida mayor exactitud. Habitualmente se emplean valores de 8 y 16 bits.

Conversor analgico a digital de un micro-controlador Un conversor ADC es un circuito que toma valores analgicos de tensin y los convierte en cdigos binarios. Los valores que definen los lmites de las tensiones a medir se denominan voltajes de referencia y se representan por Vref- (el mnimo) y Vref+ (el mximo).

La resolucin del conversor queda determinada por la cantidad de bits que representan el resultado de la conversin. As, se pueden encontrar conversores de 8 bits, de 12 bits, etc. Un ADC de n bits puede representar hasta 2^n valores digitales, de modo que a la entrada analgica igual a Vref- le asignar el 0 digital y la entrada igual a Vref+ le asignar el 2^n -1 digital. A los otros valores analgicos se les asignar los otros 2^2 -2valores digitales distribuidos equidistantemente. Entre Vref- y Vref+ se pueden concebir infinitos valores analgicos, pero con n bits solo se pueden formar 2^2 valores discretos diferentes. Por lo tanto habr valores analgicos que no podrn ser representados con exactitud. La diferencia entre dos valores analgicos correspondientes a dos valores digitales consecutivos se define como resolucin de voltaje de ADC.

Por ejemplo, en un ADC 10 bits con Vref- = 0 V y Vref+ = 5V, la resolucin alcanzada ser de (5-0)/1023 = 4.88 mV. Significa que el mximo error posible ser de 4.88/2 = 2.44 mV. Es poco usual encontrar aplicaciones donde Vref- sea diferente de GND = 0V y donde Vref+ sea diferente de VCC = 5V. En estas condiciones se puede aplicar una regla de tres para deducir que una entrada analgica Vin cualquiera (entre 0 y Vref+) ser convertida en un valor numrico que se puede calcular con la siguiente frmula:

Las interrupciones y los temporizadores: Las interrupciones permiten que un suceso interrumpa la ejecucin de un programa en cualquier momento. En el momento en que se produce una interrupcin en un microcontrolador, este ejecuta un salto a la rutina de atencin de la interrupcin, definida previamente por el programador, donde se atender a la demanda de la interrupcin. Cuando se termina de ejecutar dicha rutina, el microcontrolador retorna a la ejecucin del programa principal en la misma posicin de la memoria de programa donde se produjo la interrupcin. Los TIMER o temporizadores son mdulos integrados en el microcontrolador que permiten realizar cuentas tanto de eventos internos como externos. Cuando la

cuenta es interna se habla de temporizacin y cuando la cuenta es externa se habla de contador. Los timers estn ntimamente ligados al uso de interrupciones, pero no por ello se utilizan siempre forma conjunta. Esta unin timer-interrupcion sern las que permitan realizar de forma precisa el muestreo de nuestras seales en el microcontrolador. Mas adelante se ver. Procedimiento: Lo mas importante ser tener claro cual es la ecuacin en diferencias que representa el comportamiento del filtro digital. Luego se deben identificar los coeficientes de la ecuacin en diferencias, y tener claro que estos son dependientes del periodo de muestreo (normalmente identificado con la letra N o la letra T). El periodo es igual al uno sobre la frecuencia de muestreo. Sea el filtro ( )

Siendo ( ) ( ) de salida, entonces

( ), donde

( ) es la seal de entrada y ( ) es la seal

( )

( )

( )

( )

( )

( )

( )

Por lo tanto

( )

( )

Vale la pena aclarar que un mismo conjunto de coeficientes (con el mismo valor) pueden expresar infinitos filtros con diferencia frecuencias de corte si el periodo de muestreo vara. Por ejemplo: si diseamos un filtro con frecuencia de corte 60hz y una frecuencia de muestreo de 500sps obtendremos un conjunto de coeficientes ( ) . Este mismo conjunto de coeficientes expresaran

un filtro con frecuencia de corte en 120hz si se usa una frecuencia de muestreo de 1000sps. Aunque forma exacta, llamaremos a los coeficientes constantes y a las funciones x(t-n) , y(t-n) variables. Esto porque una vez diseado el filtro unos se comportaran como constantes y otros como variables. Para hacerlo claro un ejemplo con el siguiente filtro no es la

( )

Si se obtiene la ecuacin en diferencias y se despeja y(t) se obtendra la siguiente ecuacin.

( )

( )

Entonces se define por ejemplo

La ecuacin quedara de la siguiente forma

( )

( )

Ahora se pueden suponer todas las condiciones iniciales de las variables igual a cero, es decir

)= (

)=0

Ahora se supone que se est tomando la muestra de una seal analgica x(t) y que en el instante t o en la primera muestra x(t) = 30, el valor de salida para el filtro seria como se describe a continuacin.

( )

( ) ( )

( )

( )

Al transcurrir un periodo de tiempo T se adquiere otra muestra x(t)=20, por lo que x(t-1) seria igual a la muestra anterior que era 30 es decir x(t-1)=30, de la misma forma se va a calcular y(t) para este instante de tiempo, pero como en el instante de tiempo anterior fue 60 podemos decir que y(t-1)=30.

( )

( )

( )

Y el resultado de la salida del filtro para el instante actual de tiempo seria 100. Si se repite el mismo procedimiento para las siguiente muestra x(t) = -10 se tendra lo siguiente

x(t-1)= 20, y(t-1)=100,y(t-2)=60

Si se observa con cuidado y(t-2) toma el valor de la salida del filtro cundo se tom la primer muestra es decir toma el valor de la salida t menos 2 periodos. Para calcular la salida actual del filtro

( )

( ( )

As sucesivamente se podr obtener el valor arrojado por el filtro para cada muestra de la seal de entrada. Las siguiente tabla contiene los valores arrojados por el filtro y(t) para la seal de entrada x(t).

x(t) 30 20 -10 5 10 30 -5 25

x(t-1) y(t-1) y(t-2) y(t) 0 0 0 60 30 60 0 100 20 100 60 -70 -10 -70 100 -85 5 -85 -70 147,5 10 148 -85 101,25 30 101 148 -118,1 -5 -118 101 -7,188

Implementacin en Pic 18f4550 o 18f2550 Para hacerlo ms fcil para quienes an no han tenido contacto con programacin de microcontroladores en c, se propone iniciar a desarrollar el programa a partir de la siguiente estructura en ccs picc.

#include <18f4550.h> #fuses HS,MCLR,NOWDT,NOPROTECT #device ADC=8 //se configura el ADC para que sea de 8 bits #use delay(clock=20M)// se usara una frecuencia de reloj de 20MHz //----------------------------------------------------------------// Esta directiva indica que la funcin de abajo debe ser llamada cuando se produzca la //interrupcin por timer0 #int_timer0 void obtener_muestra() { //implementacin filtro digital }

//----------------------------------------------------------------void main() { set_tris_b(0);//configuracin del Puerto B como Puerto de salida bit_set(TRISA,0);//configuracin de pin0 de Puerto A como entrada setup_adc_ports(AN0|VSS_VDD);//configura el pin A0 como entra ADC set_adc_channel(0);// // Las siguientes instrucciones configurar el ADC para que pueda leer datos a alta velocidad #asm movlw 0b10111110; iorwf 0xFC0,1; #endasm setup_adc(ADC_CLOCK_DIV_32); // se habilita la interrupcin por desbordamiento de timer 0 setup_timer_0(RTCC_INTERNAL | RTCC_DIV_1); /*Configuracin del timer0*/ enable_interrupts(INT_TIMER0); /*Habilitacin general de las interrupciones*/ enable_interrupts(GLOBAL); while(TRUE) { //ciclo infinito } }

En el cdigo anterior al inicio se definen las libreras a usar y las configuraciones bsicas para que funciones el micro controlador. Con la directiva #int_timer0 se le indica al programa que cuando se ejecute una interrupcin por el timer 0 se llame la funcin que se encuentra abajo en este caso obtener_muestra(). Se necesitara configurar el timer para que se active la interrupcin cada vez que este se desborde o en otras palabras cada vez que cuente 65535 y pase a 0. Como el objetivo de este documento no es explicar sobre micro controladores se le dejara de tarea al lector que profundice en el funcionamiento delos timer para el PIC. Luego en la funcion principal main() se inicializa el puerto b como salida puesto que ser usado para entregar el valor que arroje el filtro a un conversor digital anlogo, luego se indica al micro que el pin A0 sera usado como entrada, que ser un pin analgico y se le indica al ADC que se conecte a este pin.

Ser necesario configurar el ADC para que tome muestrar a alta velocidad esto se logra con las siguiente instrucciones que pueden ser estudiadas mas a fondo por el lector:
#asm movlw 0b10111110; iorwf 0xFC0,1; #endasm setup_adc(ADC_CLOCK_DIV_32);

Otra parte importante ser configurar las seales de reloj que alimenta el timer y activar las interrupciones por desbordamiento de timer.
/*Configuracin del timer0, oscilador interno | prescaler = 1*/ setup_timer_0(RTCC_INTERNAL | RTCC_DIV_1); enable_interrupts(INT_TIMER0); /*Habilitacin general de las interrupciones*/ enable_interrupts(GLOBAL);

Por ultimo para que el micro pueda seguir funcionando se crea un ciclo infinito, en el que no har nada, el micro solo ejecutara las instrucciones que en la funcin de interrupcin. Ya configuradas la interrupciones, se debe calcular el valor que se debe cargar al timer para que este ocasione un desbordamiento cada cierto periodo de tiempo. La siguiente formula es til:

( .

Como ejemplo se usara un cristal de 20Mhz, el prescaler seleccionado igual a 1 y una frecuencia de muestro = 500sps, que equivale a un periodo de muestro de dos milisegundos (0.002 seg). Con lo que se obtiene un valor a cargar en el timer de igual a 55535.

Se crea una variable global con dicho valor, este valor ser cargado en el timer cada vez que se ejecuta la interrupcin asi se reiniciara el conteo. La funcin que carga un valor en el timer es la siguiente: set_timer( );

Tambin se agregara en la funcin main inmediata mente antes del while(true). La funcin que es llamada en la interrupcin quedara de la siguiente manera:
int16 ValorTimer = //----------------------------------------------------------------// Esta directiva indica que la funcin de abajo debe ser llamada cuando se produzca la //interrupcin por timer0 #int_timer0 void obtener_muestra() { set_timer(ValorTimer); //implementacin filtro digital }

El siguiente paso ser adquirir la seal con el ADC y escribir esta misma en la salida de uno de los puertos del micro para este ejemplo se usara el puerto b del pic, as se comprobara que todo hasta ac est funcionando como debe ser. Se recomienda usa el conversor digital-anlogo DAC0808, es un conversor que recibe datos en paralelo de 8 bits.
int16 ValorTimer = float x_0=0; float y_0=0; //----------------------------------------------------------------// Esta directiva indica que la funcin de abajo debe ser llamada cuando se produzca la //interrupcin por timer0 #int_timer0 void obtener_muestra() { set_timer(ValorTimer); x_0 = read_adc(); //implementacin filtro digital y_0 = x_0; output_b( (int8) y_0 );// se escribe la variable y_0 en el puerto b pero antes se convierte en dato de 8 bits }

Se crearon las variables y_0 y x_0 para almacenar el valor de salida y la muestra de entrada respectivamente. Si se quisiera implementar el siguiente filtro FIR (La salida depende nicamente de la seal de entrada) un filtro de media con el que se obtendr en la salida el promedio de las ltimas 3 muestras de la seal, es decir:

( )

( )

Que se obtiene de la funcin de transferencia:

( ) En donde

La implementacin seria como se ve a continuacin:


int16 ValorTimer = float x_0=0, x_1=0, x_2=0; float y_0=0; //----------------------------------------------------------------// Esta directiva indica que la funcin de abajo debe ser llamada cuando se produzca la //interrupcin por timer0 #int_timer0 void obtener_muestra() { set_timer(ValorTimer); x_2 = x_1; x_1 = x_0; x_0 = read_adc(); y_0 = ( x_0+ x_1+ x_2 ) / 2.0f ; //implementacin filtro digital output_b( (int8) y_0 );// se escribe la variable y_0 en el puerto b pero antes se convierte en dato de 8 bits }

Es importante resaltar que se debe hacer el corrimiento de las muestras esto es; x(t-2) tomara el valor de x(t-1), x(t-1) tomara el valor de x(t) y el valor de x(t) ser la nueva muestra. Este corrimiento se hace con las siguientes instrucciones:
x_2 = x_1; x_1 = x_0;

Ahora como ltimo ejemplo se implementara el filtro IIR (La salida depende de la seal de entrada y de la seal de salida) que se mostr como primer ejemplo:

( )

( ) Y los valores ficticios

( )

El cdigo seria el siguiente:


int16 ValorTimer = float x_0=0, x_1=0; float y_0=0, y_1=0, y_2=0; //----------------------------------------------------------------// Esta directiva indica que la funcin de abajo debe ser llamada cuando se produzca la //interrupcin por timer0 #int_timer0 void obtener_muestra() { set_timer(ValorTimer); x_1 = x_0; y_2 = y_1; y_1 = y_0; x_0 = read_adc(); y_0 = (2.0f* x_0+3.0f* x_1+ 0.5f*y_1+10.0f*y_2) / 1.2f ; //implementacin filtro digital output_b( (int8) y_0 );// se escribe la variable y_0 en el puerto b pero antes se convierte en dato de 8 bits }

Potrebbero piacerti anche