Libro Simulacion Mikroc
Libro Simulacion Mikroc
=
) )( (
Ecuacin 12-18
Dado que el valor de salida Vout se puede ingresar a una entrada AD, del microcontrolador se
puede asumir como Vadc, con la siguiente relacin y un voltaje de referencia positivo de 5
voltios:
004887585 , 0 ) (
1023
) 5 )( (
Radc
Radc
Vadc = = Ecuacin 12-19
Remplazando la ecuacin (13.19) en la ecuacin (13.18), y asumiendo que Vcc es de 5 voltios,
obtenemos la siguiente relacin:
) 004887585 , 0 )( ( 5
) )( 04887585 , 0 )( (
Radc
R Radc
LDR
= Ecuacin 12-20
Para el caso particular de la simulacin de este ejercicio la resistencia del divisor de voltaje ser
de 10k de est manera la ecuacin para calcular la resistencia de la LDR, es:
) 004887585 , 0 )( ( 5
) 87585 , 48 )( (
Radc
Radc
LDR
= Ecuacin 12-21
Para la compilacin y edicin del programa se puede observar y analizar el siguiente cdigo
fuente:
//Definicin de pines del LCD
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D4 at RB0_bit;
//Definicin de los TRIS del LCD
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D7_Direction at TRISB3_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB0_bit;
void main( void )
{
//Declaracin de variables.
unsigned long Radc, DisI;
char Text[16];
//Inicio del LCD.
140
Lcd_Init();
//Borrado del cursor.
Lcd_Cmd(_LCD_CURSOR_OFF);
//Impresin de texto.
Lcd_Out( 1, 1, "Resistencia:");
while(1) //Bucle infinito.
{
//Lectura del canal anlogo.
Radc=ADC_Read(0);
//Implementacin del clculo de la LDR, ecuacin (13.20).
DisI = (Radc*48.87585533)/(5.0-Radc*0.004887585);
//Se convierte el valor entero largo, en cadena de texto.
LongToStr( DisI, Text );
//Se imprime la lectura del sensor.
Lcd_Out( 2, 1, Text );
//Retardo de 100m segundos.
delay_ms(100);
}
}
Para realizar la simulacin en ISIS, se implementan los siguiente dispositivos: 16F877A, RES,
LM016L, TORCH_LDR, en el siguiente circuito electrnico:
Circuito 12-5
141
12.5 Sensores de humedad y temperatura
La humedad y la temperatura son dos variables fsicas de amplio uso en la industria y para su
medida se pueden usar dispositivos que integran las dos lecturas simultneamente, en un solo
encapsulado. La familia de sensores SHT7x permiten hacer la lectura de ambos parmetros, con
una calibracin de fbrica que garantiza la fidelidad de las lecturas. La apariencia fsica y la vista
de estos dispositivos en ISIS, as como su distribucin de pines, es la siguiente:
Figura 12-6
Pin Funcin
1 Reloj
2 Vdd, Poder
3 Gnd, Referencia
4 Datos
Tabla 12-4
Estos sensores entregan la informacin por medio de un puerto serial similar al protocolo IC, sin
embargo no es exactamente igual, y por est razn no es posible usarlo. Esto implica realizar por
medio del cdigo de programa, el protocolo de comunicacin especificado en la hoja tcnica del
dispositivo. El protocolo incluye una condicin de inicio, bloque de datos tanto de lectura como
de escritura, y un bit de conformacin o ACK. La comunicacin se basa en dos pines uno de reloj
que siempre debe ser de salida y un pin de datos bidireccional, el cual es de drenador abierto, lo
que hace necesario implementar una resistencia pull-up en est lnea a Vcc de 10k.
Para realizar la comunicacin con el sensor, el desarrollador debe implementar su propia librera
para el enlace de datos, a continuacin se mostrar paso a paso un ejemplo que permite cumplir
con este cometido:
//Declaracin de pines de comunicacin.
sbit SHT_Reloj at RC0_bit;
sbit SHT_Datos at RC1_bit;
//Declaracin de TRIS de los pines de comunicacin.
sbit SHT_Reloj_Dire at TRISC0_bit;
sbit SHT_Datos_Dire at TRISC1_bit;
//Declaracin de constantes.
const unsigned short RH_8bits_TEM_12bits = 1;
142
const unsigned short RH_12bits_TEM_14bits = 0;
const unsigned short Peso_bits[8] = {1,2,4,8,16,32,64,128};
//Bandera de resolucin.
unsigned short RH_TEM;
//Funcin para estblecer un estdo
//lgico en el pin de datos
void SHT_Bus( unsigned short e )
{
//Si el estdo es 1 se impone en alta
//impedancia el pin de datos.
if( e )
SHT_Datos_Dire = 1;
else
{
//Si el estdo es un 0 lgico
//se estblece la salida en 0.
SHT_Datos_Dire = 0;
SHT_Datos = 0;
}
}
//Funcin para estblecer el estdo del reloj.
void SHT_Reloj_Salida( unsigned short e )
{
//Se estblece el estdo lgico en el reloj.
if( e )
SHT_Reloj = 1;
else
SHT_Reloj = 0;
//Periodo del reloj, para frecuencia de 1MHz.
delay_us(1);
}
//Funcin para crear la condicin de inicio.
void SHT_Inicio( void )
{
//Secuencia de inicio.
SHT_Reloj_Salida(1);
SHT_Bus(0);
SHT_Reloj_Salida(0);
SHT_Reloj_Salida(1);
SHT_Bus(1);
SHT_Reloj_Salida(0);
delay_ms(1);
}
143
//Funcin para escribir un dato en el bus.
void SHT_Escribe_Bus( unsigned short d )
{
unsigned short n;
//Bucle para el envi serial.
for( n=7; n!=255; n-- )
{
//Se asigna el bit segn su peso.
if( (d>>n)&1 )
SHT_Bus( 1 );
else
SHT_Bus( 0 );
//Generacin de pulsos de reloj.
SHT_Reloj_Salida( 1 );
SHT_Reloj_Salida( 0 );
}
//Generacin de bit ACK.
SHT_Bus( 1 );
SHT_Reloj_Salida( 1 );
SHT_Reloj_Salida( 0 );
}
//Funcin para leer un dato en el bus.
unsigned short SHT_Leer_Bus( void )
{
unsigned short n, Dato_SHT=0;
//Se configura el bus de entrada.
SHT_Bus( 1 );
//Bucle para recibir los bits de forma serial.
for( n=7; n!=255; n-- )
{
//Pulso de reloj.
SHT_Reloj_Salida( 1 );
//Se reciben los bits segn su peso.
if( SHT_Datos )
Dato_SHT += Peso_bits[n];
SHT_Reloj_Salida( 0 );
}
//Se transmite la condicin de ACK.
SHT_Bus( 0 );
SHT_Reloj_Salida( 1 );
SHT_Reloj_Salida( 0 );
//Se deja el bus de entrada.
SHT_Bus( 1 );
//Se retorna el valor de la lectura.
return Dato_SHT;
}
//Funcin para grabar el registro Status.
144
void SHT_Status_Graba( unsigned short s )
{
//Se transmite el valor del status.
SHT_Inicio();
SHT_Escribe_Bus( 0b00000110 );
SHT_Escribe_Bus( s );
}
//Funcin para leer el valor del Status.
unsigned short SHT_Status_Leer( void )
{
unsigned short st;
SHT_Inicio();
SHT_Escribe_Bus( 0b00000111 );
st=SHT_Leer_Bus();
SHT_Leer_Bus();
return st;
}
//Funcin para leer la temperatura.
float SHT_Leer_Tem( void )
{
float tem;
unsigned int LEC=0;
unsigned short DH, DL;
//Se aplica el protocolo de lectura.
SHT_Inicio();
SHT_Escribe_Bus( 0b00000011 );
//Espera para hacer la lectura.
delay_ms(310);
DH=SHT_Leer_Bus();
DL=SHT_Leer_Bus();
SHT_Leer_Bus();
LEC = DL + DH*256;
//Se implementan las ecuaciones para
//la temperatura.
if( RH_TEM )
tem = -40.1 + 0.04*LEC;
else
tem = -40.1 + 0.01*LEC;
//Se retorna la temperatura.
return tem;
}
float SHT_Leer_Hum( void )
{
float hum;
unsigned int LEC=0;
unsigned short DH, DL;
145
//Se aplica el protocolo de lectura.
SHT_Inicio();
SHT_Escribe_Bus( 0b00000101 );
//Espera para hacer la lectura.
delay_ms(310);
DH=SHT_Leer_Bus();
DL=SHT_Leer_Bus();
SHT_Leer_Bus();
LEC = DL + DH*256;
//Se implemetan las ecuacion para
//la humedad.
if( RH_TEM )
hum = -4.3468 + 0.5872*LEC - 0.00040845*LEC*LEC;
else
hum = -4.3468 + 0.0367*LEC - 0.0000015955*LEC*LEC;
//Se retorna la humedad.
return hum;
}
//Funcin para inicializar el sensor.
void Inicio_SHT7x( unsigned short St )
{
unsigned short n;
//Configuracin de pines,
//y estdo inicial del bus de datos.
SHT_Reloj_Dire = 0;
//Se estble el pin de datos en 1.
SHT_Bus(1);
//Se inicia el reloj en 0.
SHT_Reloj_Salida(0);
delay_ms(100);
//Se generan 9 ciclos de reloj, para reiniciar el sensor.
for(n=0; n<9; n++)
{
SHT_Reloj_Salida(1);
SHT_Reloj_Salida(0);
}
//Se configura el registro Status.
SHT_Inicio();
SHT_Status_Graba( St );
delay_ms(1);
RH_TEM = St;
}
Para el caso puntual de este ejemplo se complementa el cdigo con la siguiente funcin main:
void main( void )
{
//Declaracin de variables.
146
float Sen;
char Text[16];
//Inicio del LCD.
Lcd_Init();
//Se inicializa el sensor SHT7x.
Inicio_SHT7x(RH_12bits_TEM_14bits);
//Borrado del cursor.
Lcd_Cmd(_LCD_CURSOR_OFF);
//Impresin de texto.
Lcd_Out( 1, 1, "Tem:");
Lcd_Out( 2, 1, "Hum:");
while(1) //Bucle infinito.
{
//Se lee la temperatura y se imprime en el LCD.
Sen = SHT_Leer_Tem();
FloatToStr( Sen, Text );
Lcd_Out( 1, 6, Text );
//Se lee la humedad y se imprime en el LCD.
Sen = SHT_Leer_hum();
FloatToStr( Sen, Text );
Lcd_Out( 2, 6, Text );
}
}
Finalizada la edicin y compilacin del cdigo fuente, se procede a realizar la simulacin en
ISIS, con los dispositivos: 16F877A, LM016L, RES, y SHT71, en el siguiente circuito
electrnico:
Circuito 12-6
147
13 Comunicacin con
dispositivos
La comunicacin con diversos dispositivos se hace indispensable para realizar tareas como la
lectura de sensores, el sistema de control, y lectura de mdulos como: relojes en tiempo real,
GPS, puntos inalmbricos, entre otros. En funcin de la necesidad y de las capacidades del
desarrollador, tambin es posible crear sus propios aplicativos de software para ordenadores
personales, ests aplicaciones se pueden desarrollar en paquetes, como Visual Basic, Java, C++,
etc. Para poder simular la conectividad con aplicativos propios e incluso con paquetes de
software como Hyper Terminal, se puede recurrir a aplicativos que crean en el ordenador puertos
seriales virtuales. De la misma forma el simulador ISIS permite implementar un puerto virtual
con conectividad a los puertos seriales fsicos del ordenador. Uno de los aplicativos que permite
crear los puertos virtuales es Virtual Serial Port Kit, del cual se puede descargar una versin
demostrativa en la pgina www.virtual-serial-port.com La apariencia visual de este paquete es la
siguiente:
Figura 13-1
Sin embargo este es tan solo uno de los diversos aplicativos que cumplen con la misma funcin.
13.1 Mdulos GPS
Los mdulos GPS son dispositivos de comunicacin inalmbrica que toman tramas de
informacin suministrada por los satlites artificiales geoestcionarios del planeta. Los mdulos
GPS deben contar con la lectura de un mnimo de tres satlites para realizar un clculo conocido
como triangulacin; este consiste en medir la diferencia en tiempo entre las lecturas para
determinar la posicin del GPS sobre la superficie de la tierra. La calidad de la lectura depender
del nmero de satlites simultneos conectados al GPS; la lectura ser de mayor precisin
cuantos ms satlites estn conectados; sin embargo los GPS comerciales que se consiguen tienen
un margen de error aproximado de 3 metros, lo que implica que con respecto al dimetro del
globo terrqueo, el margen de error es casi del 0%. Los mdulos GPS se pueden adquirir
148
comercialmente en varias presentaciones con encapsulado, o simplemente un circuito impreso
con el mdulo. La apariencia fsica de ellos se puede apreciar en las siguientes figuras:
Figura 13-2
Los mdulos GPS cuentan con puertos seriales que transmiten peridicamente la lectura de las
coordenadas geogrficas ledas por el GPS. El periodo por defecto de los GPS, es un segundo. La
lectura de un GPS, es el conjunto de coordenadas esfricas sobre el globo terrqueo, usando
como referencia de medida el meridiano de Greenwich, y el paralelo del Ecuador. Para
contextualizar este concepto se puede observar el siguiente grfico:
Figura 13-3
Longitud ngulo , Latitud ngulo .
Las coordenadas esfricas usan tres parmetros; el primero es la longitud, que es el ngulo ,
representado en la grfica y se mide a partir del meridiano de Greenwich, este ngulo puede ser
Este, u Oeste, y su magnitud puede variar de 0 a 90 grados. El segundo parmetro es la latitud,
que es el ngulo , representado en la grfica, su punto de referencia es el paralelo del Ecuador y
puede ser Norte, o Sur, de la misma forma su magnitud varia de 0 a 90 grados. El ltimo
parmetro es conocido como altitud, este determina la altura del punto coordenado con respecto
al nivel del mar, y su magnitud est definida en metros.
Los Mdulos GPS, suministran una variedad de datos a dems de las coordenadas esfricas,
como: Nmero de satlites detectados, especificaciones mnimas del GPS, y caractersticas de
curso y velocidad, entre otras. Sin embargo para realizar la lectura de las coordenadas solo se
149
requiere la trama de informacin con el encabezado: $GPGGA. El siguiente ejemplo muestra la
lectura de las coordenadas:
Latitud: 30 47 43,47 Sur.
Longitud: 39 57 33,36 Oeste.
Altura: 2600 metros.
$GPGGA,000000.000,3047.724500,S,03957.556000,W,1,8,0,2600,M,0,M,,*7B
Informacin de Latitud:
$GPGGA,000000.000,3047.724500,S,03957.556000,W,1,8,0,2600,M,0,M,,*7B
Donde 3047.724500,S representa: 30 47 43,47 Sur. Es decir 30 grados, 47.7245 minutos, que
es equivalente a 47 minutos y 43,47 segundos.
Informacin de Longitud:
$GPGGA,000000.000,3047.724500,S,03957.556000,W,1,8,0,2600,M,0,M,,*7B
Donde: 03957.556000,W representa: 39 57 33,36 Oeste. Es decir 39 grados, 57.556 minutos,
que es equivalente a 57 minutos y 33,36 segundos.
Informacin del nmero de satlites, conectados:
$GPGGA,000000.000,3047.724500,S,03957.556000,W,1,8,0,2600,M,0,M,,*7B
Donde este campo 8, representa el nmero de satlites conectados al GPS, en este caso 8.
Informacin de altitud:
$GPGGA,000000.000,3047.724500,S,03957.556000,W,1,8,0,2600,M,0,M,,*7B
Donde 2600,M representa la magnitud en metros y la altitud de 2600 metros.
Los campos de informacin siempre son fijos y ests separados por una coma (,) entre si.
El siguiente ejemplo muestra una trama completa de datos entregados por un GPS:
$GPZDA,000000.000,30,12,1899,00,00*5F
$GPGGA,000000.000,3354.673167,S,04125.539667,W,1,8,0,2600,M,0,M,,*78
$GPGLL,3354.673167,S,04125.539667,W,000000.000,A,A*5F
$GPVTG,9,T,0,M,4.86,N,9.00500277932185,K,A*2A
$GPRMC,000000.000,A,3354.673167,S,04125.539667,W,4.86,9,301299,0,E,A*30
$GPGSA,A,3,1,2,3,4,5,6,17,22,,,,,0,0,0*2D
$GPGSV,2,1,8,1,0,24,0,2,0,24,0,3,0,24,0,4,0,24,0*46
$GPGSV,2,2,8,5,0,24,0,6,0,24,0,17,0,24,0,22,0,24,0*44
$GPRTE,1,1,C,0,*0B
Las tramas de informacin entregadas por un GPS, son de forma texto, por medio de caracteres
ASCII, y finalizadas con los caracteres ASCII, enter: 13, y retroceso del carro 10.
Para fines de diseo es importante identificar la velocidad de transmisin del mdulo GPS y
ajustar la misma velocidad en el mdulo USART del PIC.
Para iniciar el proceso de diseo con el microcontrolador es importante crear una rutina que
identifique las tramas y los encabezados para poder filtrar los datos de inters, que para este caso
son las coordenadas esfricas o geogrficas. Es indispensable usar el mdulo USART del PIC, en
150
este caso, y se establecer una velocidad de transmisin de 4800 bits por segundo. Para evitar la
prdida de datos se implementar la lectura de los datos seriales por medio de las interrupciones.
En primera instancia se hace un programa para el PIC 18F452, que este en capacidad de recibir y
almacenar las tramas en un bfer de datos:
char Dato;
char Bufer[50];
unsigned short Pos=0, Bandera=0;
//Declaracin de la funcin de interrupciones.
void interrupt ( void )
{
//Se evala si la interrupcin disparada por
//recepcin serial.
if( PIR1.F5 )
{
//Se lee el dato de entrada.
Dato = UART1_Read();
switch( Dato )
{
case 13: Pos=0; //Se recibe el carcter Enter.
Bandera = 1;
break;
case 10:break; //Se recibe el retroceso del carro.
default:Bufer[Pos++]=Dato; //Se guardan los datos en el bfer.
Bufer[Pos]=0; //Se estblece el fin de cadena.
break;
}
}
}
void main( void )
{
//Se configuran los puertos.
//
//Se activa la interrupcin por
//recepcin serial.
PIE1 = 0b00100000;
//Se desactivan las dems fuentes de interrupcin.
PIE2 = 0;
//Se apagan las banderas de interrupcin.
PIR2 = 0;
PIR1 = 0;
//Configuracin del puerto serial a 4800 bps.
UART1_Init(4800);
//Se activan las interrupciones globales,
//y perifricas.
INTCON = 0b11000000;
151
while(1) //Bucle infinito.
{
//Se evala si una trama ha llegado.
if( Bandera )
{
//Aqu se debe analizar el contenido de la informacin del bfer.
Bandera=0; //Se apaga la bandera de llegada.
}
}
}
El procedimiento siguiente es implementar una funcin que identifique la trama de informacin y
los datos contenidos en ella, es importante recordar que los campos de informacin son fijos pero
no necesariamente el contenido de cada campo. Para estblecer la informacin de la lectura se
usa una variable o estructura diseada por el desarrollador:
typedef struct
{
short Grados_longitud;
float Minutos_longitud;
char Longitud;
short Grados_latitud;
float Minutos_latitud;
char Latitud;
float Altitud;
short Satelites;
}Coordenada;
A continuacin se mostrar una funcin capaz de validar una trama para la lectura de las
coordenadas:
//Funcin para detectar la trama de coordenadas.
short EsGPGGA( char *trama )
{
//Est funcin retorna 1 si la trama es vlida y 0 de lo contrario.
if( trama[0]=='$' && trama[1]=='G' && trama[2]=='P'
&& trama[3]=='G' && trama[4]=='G' && trama[5]=='A' )
return 1;
else
return 0;
}
A continuacin se muestra un ejemplo de una funcin diseada para leer los datos de las
coordenadas:
//Funcin para adquirir los datos del campo.
Coordenada LecturaGPS( char *trama )
{
//Declaracin de variables.
152
Coordenada C;
char Texto[50];
unsigned short j,k;
//Valor inicial de las variables.
C.Grados_longitud=0;
C.Minutos_longitud=0;
C.Longitud=0;
C.Grados_latitud=0;
C.Minutos_latitud=0;
C.Latitud=0;
C.Altitud=0;
C.Satelites=0;
//Se verifica que el encabezado contenga el texto $GPGGA.
if( !EsGPGGA( trama ) )return C;
//Se filtra el campo 9 que contiene la altitud.
BuscarCampo( Trama, Texto, 9 );
//Se convierte el texto en el valor numrico.
C.Altitud = atof(Texto);
//Se filtra el campo 7 que contiene el nmero de satlites detectados.
BuscarCampo( Trama, Texto, 7 );
//Se convierte el texto en el valor numrico.
C.Satelites = atoi(Texto);
//Se filtra el campo 2 que contiene los minutos de la latitud.
BuscarCampo( Trama, Texto, 2 );
//Se convierte el texto en el valor numrico.
C.Minutos_latitud = atof( Texto + 2 );
//Se truncan los minutos de la latitud.
Texto[2]=0;
//Se convierte el texto en el valor numrico de los grados de la latitud.
C.Grados_latitud = atoi(Texto);
//Se filtra el campo 3 que contiene la orientacin de la latitud.
BuscarCampo( Trama, Texto, 3 );
C.Latitud = Texto[0];
//Se filtra el campo 4 que contiene los minutos de la longitud.
BuscarCampo( Trama, Texto, 4 );
//Se convierte el texto en el valor numrico los minutos de la longitud.
C.Minutos_longitud = atof( Texto + 3 );
Texto[3]=0;
//Se convierte el texto en el valor numrico de los grados de la longitud.
C.Grados_longitud = atoi( Texto );
//Se filtra el campo 2 que contiene.
BuscarCampo( Trama, Texto, 5 );
C.Longitud = Texto[0];
return C;
}
La siguiente funcin permite buscar dentro de la trama enviada por el GPS, un campo de
informacin determinado:
153
//Funcin para buscar y filtrar un campo en la trama.
void BuscarCampo( char *Fuente, char *Destino, short campo )
{
unsigned short j=0,k=0;
//Bucle para buscar el campo.
while( j<campo )if( Fuente[k++]==',' )j++;
j=0;
//Bucle para copiar el campo.
while( !(Fuente[k]==',' || Fuente[k]=='*') )
{
Destino[j++]=Fuente[k++];
Destino[j]=0;
}
}
Est ltima funcin permite convertir la informacin de una lectura en una cadena de
coordenadas entendible en grados, minutos, segundos, y orientacin:
//Funcin para encadenar los valores de una coordenada.
void Convertir_coordenada( char *coor, int grados, float minutos, char ll )
{
//Declaracin de variables de la funcin.
char Text[20];
short j=0,k=0;
short g;
float s;
//Se pega en la cadena de texto, el valor de los grados.
IntToStr( grados, Text );
while( Text[j]!=0 )
{
if( Text[j]!=' ' )
coor[k++]=Text[j];
j++;
}
coor[k++]=':';
//Se separan los segundos de los minutos.
g = (short)minutos;
s = minutos - (float)g;
//Se pega en la cadena de texto, el valor de los minutos.
IntToStr( g, Text );
j=0;
while( Text[j]!=0 )
{
if( Text[j]!=' ' )
coor[k++]=Text[j];
j++;
}
154
coor[k++]=':';
//Se calculan los segundos, de la fraccin de minutos.
s *= 60.0;
//Se pega en la cadena de texto, el valor de los segundos.
FloatToStr( s, Text );
j=0;
while( Text[j]!=0 )
{
if( Text[j]!=' ' )
coor[k++]=Text[j];
j++;
}
//Se pega en la cadena de texto, la orientacin.
coor[k++]=' '; coor[k++]=ll; coor[k]=0;
}
Complementando las funciones antes citadas y la estructura final del programa con un display
LCD de caracteres y la comunicacin del puerto serial se tiene el siguiente cdigo fuente final:
// Definicin de las conexiones del LCD.
sbit LCD_RS at RD4_bit;
sbit LCD_EN at RD5_bit;
sbit LCD_D4 at RD0_bit;
sbit LCD_D5 at RD1_bit;
sbit LCD_D6 at RD2_bit;
sbit LCD_D7 at RD3_bit;
//Definicin de los registros TRIS del LCD.
sbit LCD_RS_Direction at TRISD4_bit;
sbit LCD_EN_Direction at TRISD5_bit;
sbit LCD_D4_Direction at TRISD0_bit;
sbit LCD_D5_Direction at TRISD1_bit;
sbit LCD_D6_Direction at TRISD2_bit;
sbit LCD_D7_Direction at TRISD3_bit;
//Estructura para la lectura de una coordenada esfrica.
typedef struct
{
short Grados_longitud;
float Minutos_longitud;
char Longitud;
short Grados_latitud;
float Minutos_latitud;
char Latitud;
float Altitud;
short Satelites;
}Coordenada;
//Declaracin de variables.
155
char Dato;
char Bufer[100];
unsigned short Pos=0;
unsigned short Bandera=0;
//Funcin para detectar la trama de coordenadas.
short EsGPGGA( char *trama )
{
//Est funcin retorna 1 si la trama es valida y 0 de lo contrario.
if( trama[0]=='$' && trama[1]=='G' && trama[2]=='P'
&& trama[3]=='G' && trama[4]=='G' && trama[5]=='A' )
return 1;
else
return 0;
}
//Funcin para buscar y filtrar un campo en la trama.
void BuscarCampo( char *Fuente, char *Destino, short campo )
{
unsigned short j=0,k=0;
//Bucle para buscar el campo.
while( j<campo )if( Fuente[k++]==',' )j++;
j=0;
//Bucle para copiar el campo.
while( !(Fuente[k]==',' || Fuente[k]=='*') )
{
Destino[j++]=Fuente[k++];
Destino[j]=0;
}
}
//Funcin para adquirir los datos del campo.
Coordenada LecturaGPS( char *trama )
{
//Declaracin de variables.
Coordenada C;
char Texto[50];
unsigned short j,k;
//Valor inicial de las variables.
C.Grados_longitud=0;
C.Minutos_longitud=0;
C.Longitud=0;
C.Grados_latitud=0;
C.Minutos_latitud=0;
C.Latitud=0;
C.Altitud=0;
C.Satelites=0;
//Se verifica que el encabezado contenga el texto $GPGGA.
if( !EsGPGGA( trama ) )return C;
156
//Se filtra el campo 9 que contiene la altitud.
BuscarCampo( trama, Texto, 9 );
//Se convierte el texto en el valor numrico.
C.Altitud = atof(Texto);
//Se filtra el campo 7 que contiene el nmero de satlites detectados.
BuscarCampo( trama, Texto, 7 );
//Se convierte el texto en el valor numrico.
C.Satelites = atoi(Texto);
//Se filtra el campo 2 que contiene los minutos de la latitud.
BuscarCampo( trama, Texto, 2 );
//Se convierte el texto en el valor numrico.
C.Minutos_latitud = atof( Texto + 2 );
//Se truncan los minutos de la latitud.
Texto[2]=0;
//Se convierte el texto en el valor numrico de los grados de la latitud.
C.Grados_latitud = atoi(Texto);
//Se filtra el campo 3 que contiene la orientacin de la latitud.
BuscarCampo( trama, Texto, 3 );
C.Latitud = Texto[0];
//Se filtra el campo 4 que contiene los minutos de la longitud.
BuscarCampo( trama, Texto, 4 );
//Se convierte el texto en el valor numrico los minutos de la longitud.
C.Minutos_longitud = atof( Texto + 3 );
Texto[3]=0;
//Se convierte el texto en el valor numrico de los grados de la longitud.
C.Grados_longitud = atoi( Texto );
//Se filtra el campo 2 que contiene.
BuscarCampo( trama, Texto, 5 );
C.Longitud = Texto[0];
return C;
}
//Funcin para encadenar los valores de una coordenada.
void Convertir_coordenada( char *coor, int grados, float minutos, char ll )
{
//Declaracin de variables de la funcin.
char Text[20];
short j=0,k=0;
short g;
float s;
//Se pega en la cadena de texto, el valor de los grados.
IntToStr( grados, Text );
while( Text[j]!=0 )
{
if( Text[j]!=' ' )
coor[k++]=Text[j];
j++;
}
157
coor[k++]=':';
//Se separan los segundos de los minutos.
g = (short)minutos;
s = minutos - (float)g;
//Se pega en la cadena de texto, el valor de los minutos.
IntToStr( g, Text );
j=0;
while( Text[j]!=0 )
{
if( Text[j]!=' ' )
coor[k++]=Text[j];
j++;
}
coor[k++]=':';
//Se calculan los segundos, de la fraccin de minutos.
s *= 60.0;
//Se pega en la cadena de texto, el valor de los segundos.
FloatToStr( s, Text );
j=0;
while( Text[j]!=0 )
{
if( Text[j]!=' ' )
coor[k++]=Text[j];
j++;
}
//Se pega en la cadena de texto, la orientacin.
coor[k++]=' '; coor[k++]=ll; coor[k]=0;
}
//Declaracin de la funcin de interrupciones.
void interrupt ( void )
{
//Se evala si la interrupcin disparada por
//recepcin serial.
if( PIR1.F5 )
{
//Se lee el dato de entrada.
Dato = UART1_Read();
switch( Dato )
{
case 13: Pos=0; //Se recibe el carcter Enter.
Bandera = 1;
break;
case 10:break; //Se recibe el retroceso del carro.
default:Bufer[Pos++]=Dato; //Se guardan los datos en el bfer.
Bufer[Pos]=0; //Se estblece el fin de cadena.
break;
}
}
158
}
void main( void )
{
Coordenada C;
char Texto[20];
//Se configuran los puertos.
TRISB = 0;
PORTB = 0;
//Se activa la interrupcin por
//recepcin serial.
PIE1 = 0b00100000;
//Se desactivan las dems fuentes de interrupcin.
PIE2 = 0;
//Se apagan las banderas de interrupcin.
PIR2 = 0;
PIR1 = 0;
//Configuracin del puerto serial a 4800 bps.
UART1_Init(4800);
//Se activan las interrupciones globales,
//y perifricas.
INTCON = 0b11000000;
//Inicializacin del display LCD.
Lcd_Init();
Lcd_Cmd(_LCD_CURSOR_OFF);
while(1) //Bucle infinito.
{
//Se evala si una trama ha llegado.
if( Bandera )
{
//Se verifica que la trama sea valida para las coordenadas.
if( EsGPGGA( Bufer ) )
{
//Se leen los datos de las coordenadas y se guardan en la variable C.
C=LecturaGPS( Bufer );
//Se transcriben los datos de la latitud.
Convertir_coordenada( Texto, C.Grados_latitud, C.Minutos_latitud, C.Latitud );
//Se imprimen los datos de la latitud en el display LCD.
Lcd_Out(1,1,"Lat ");
Lcd_Out(1,5,Texto);
//Se transcriben los datos de la longitud.
Convertir_coordenada(Texto,C.Grados_longitud,C.Minutos_longitud,C.Longitud);
//Se imprimen los datos de la longitud en el display LCD.
Lcd_Out(2,1,"Lon ");
Lcd_Out(2,5,Texto);
//Se transcriben el valor de la altitud.
FloatToStr(C.Altitud,Texto);
//Se imprimen el valor de la altitud en el display LCD.
Lcd_Out(3,1,"Altitud: ");
159
Lcd_Out(3,9,Texto);
//Se transcriben el valor del nmero de satlites conectados.
IntToStr(C.Satelites,Texto);
//Se imprimen el nmero de satlites en el display LCD.
Lcd_Out(4,1,"Satelites: ");
Lcd_Out(4,11,Texto);
}
Bandera=0; //Se apaga la bandera de llegada.
}
}
}
Despus de editar y compilar el programa con fuente de reloj de 20 Mhz, se procede a crear en
ISIS, un circuito con los siguientes dispositivos: PIC 18F452, LM044L, y el puerto virtual,
COMPIM. Este ltimo se debe configurar a 4800 bps, tanto en el puerto virtual como el puerto
real, la vista de configuracin del puerto virtual COMPIM debe ser la siguiente:
Figura 13-4
La configuracin del puerto fsico que en este caso est determinado como COM1, puede variar
en funcin de los puertos disponibles en el ordenador.
160
La construccin del circuito en ISIS debe ser como se aprecia en la siguiente grfica:
Circuito 13-1
La conexin del GPS, en este caso se puede hacer por medio de un simulador de GPS, o por
medio de un GPS real conectado al puerto fsico. Para la simulacin del GPS, se puede usar el
paquete de software: Virtual GPS, o cualquier otro que funcione de la misma forma, la vista del
simulador de GPS, es la siguiente:
Figura 13-5
161
En este caso se pueden comparar los datos emitidos por el simulador y su verificacin en el
circuito hecho en ISIS. De la misma forma se pueden cambiar los datos enviados por el simulador
de GPS. Se debe recordar hacer la creacin de dos puertos virtuales cruzados, si se desea hacer la
simulacin de todo el sistema con un simulador de GPS.
13.2 Mdulos inalmbricos unidireccionales
Las comunicaciones inalmbricas entre dos puntos hacen parte fundamental de muchas
aplicaciones en el mbito del control y el monitoreo de variables o estdos. La lectura de un
sensor, o el control de actuadores son posibles por medio de enlaces inalmbricos. La
comunicacin usada por estos dispositivos es unidireccional o simplex. Los mdulos
inalmbricos tiles para este fin funcionan con modulacin ASK, o FSK, y tienen velocidades de
transmisin hasta 9600 bits por segundo. Este tipo de dispositivos se pueden conseguir de
fabricantes como Laipac Tech, o Linx Technologies, entre otros. La apariencia fsica de estos
dispositivos es la siguiente:
Figura 13-6
Estos dispositivos solo son un medio de transmisin inalmbrico por lo cual no tienen ningn
sistema de correccin ni deteccin de errores de transmisin, por est razn es importante hacer
dentro de la programacin alguna rutina de deteccin de errores. Para fines de este ejemplo se
implementarn los radios Laipac. De igual manera las frecuencias portadoras de estos
dispositivos son variadas, y funcionan dentro del espectro de bandas libres para enlaces de
comunicacin. La distribucin de pines de estos dispositivos es la siguiente:
Figura 13-7
162
TLP434A
PIN Funcin
1 GND, Referencia
2 Entrada serial
3 Vcc, de 5 a 12 V
4 Antena
RLP434A
PIN Funcin
1 GND, Referencia
2 Salida Serial
3 Salida de prueba
4 Vcc
5 Vcc 5 V
6 GND, Referencia
7 GND, Referencia
8 Antena
Tabla 13-1
Para el envi de bits este ejemplo usa la modulacin por ancho de pulso o PWM. El programa
representa un 1 lgico con un pulso en alto de 2m segundos de duracin seguido por 1m segundo
en bajo, el 0 lgico se transmite con un pulso en alto de 1m segundo y 1m segundo en bajo, y
como estrategia de sincronismo se implementa un pulso en alto de 500u segundos, y 500u
segundos en bajo. Para este ejemplo se envan 16 pulsos de sincronismo, posteriormente se
envan 8 bits con el byte que se desea transmitir, y por ltimo se transmiten 4 bits con un nmero
de 0 a 8 que contiene el nmero de unos que contiene el byte que se est transmitiendo como
estrategia de verificacin. Este sistema no est en capacidad de corregir errores de transmisin,
pero si permite verificar el dato recibido, en otras palabras el sistema entrega un dato que es
recibido correctamente y si el dato se detecta con errores se descarta. Cuando un dato es recibido
correctamente se entrega un byte que puede valer de 0 a 255, y si el dato est daado se entrega
un valor igual a -1.
Para la demostracin de est comunicacin se implementar una librera que transmite bytes con
las reglas antes mencionadas, de igual manera los microcontroladores implementados en est
librera son los PIC 16F628A con frecuencia de reloj de 4M Hz, sin embargo puede ser usada en
cualquier otro microcontrolador, la librera bsica es la siguiente:
//Declaracin de pines de comunicacin.
sbit RXPIN at RB7_bit;
sbit RXPIN_TRIS at TRISB7_bit;
sbit TXPIN at RB6_bit;
sbit TXPIN_TRIS at TRISB6_bit;
//Declaracin de constantes de peso binario.
const unsigned int Peso[12] = {1,2,4,8,16,32,64,128,256,512,1024,2048};
//Funcin para iniciar los pines de comunicacin.
163
void Inicio_Radio_Tx( void )
{
TXPIN_TRIS=0;
TXPIN=0;
}
//Funcin para iniciar los pines de comunicacin.
void Inicio_Radio_Rx( void )
{
RXPIN_TRIS=1;
}
//Funcin para determinar que bit se est recibiendo.
char Entra_Bit( void )
{
unsigned short T=0;
while( !RXPIN ); //Se espera el estdo 1 lgico.
//Se mide el tiempo en alto de la modulacin.
while( RXPIN ){ delay_us(50); T++; }
//Se clasifica el bit recibido en funcin de su tiempo.
if( T > 38 && T < 42 )return '1'; //Aprox. 2m Seg.
if( T > 18 && T < 22 )return '0'; //Aprox. 1m Seg.
if( T > 8 && T < 12 )return 'S'; //Aprox. 500u Seg.
return 'E'; // Tiempo errado.
}
//Funcin para enviar un byte.
int Resibir_Dato( void )
{
unsigned short D, BIT, N_Bits;
int DATO;
DATO=0;
BIT=0;
//Se espera un bit de sincronismo.
while( Entra_Bit()!='S' );
//Se espera el ltimo BIT de sincronismo.
while( (D=Entra_Bit())=='S' );
//Bucle para archivar el byte de entrada.
while( 1 )
{
//Se evala el BIT que llego.
switch( D )
{
case '1': DATO += Peso[BIT++];
break;
case '0': BIT++;
break;
case 'E':
case 'S': return -1;
164
}
//Si el nmero bits recibidos es 12, se
//evalan los errores.
if( BIT==12 )
{
//Se cuentan los bits del dato de informacin.
N_Bits=0;
for( BIT=0; BIT<8; BIT++ )
if( (DATO>>BIT)&1 )N_Bits++;
//Se verifica que el nmero de unos sea igual.
//y se retorna el byte de entrada.
if( N_Bits == (DATO>>8)&0x0F )return DATO&0x00FF;
//Ocurre un error y se espera una nueva trama.
return -1;
}
//Se lee el siguiente bit.
D=Entra_Bit();
}
}
//Funcin para transmitir un byte.
void Enviar_Dato( unsigned short d )
{
unsigned short BITS, N_Bits=0;
//Se cuentan el nmero de bits a enviar.
for( BITS=0; BITS<8; BITS++ )
if( (d>>BITS)&1 )N_Bits++;
//Se envan 16 bits de sincronismo.
for( BITS=0; BITS<16; BITS++ )
{
TXPIN = 1; delay_us(500);
TXPIN = 0; delay_us(500);
}
//Se envan 8 bits de datos, el byte.
for( BITS=0; BITS<8; BITS++ )
{
TXPIN=1;
if( (d>>BITS)&1 )
delay_ms(2);
else
delay_ms(1);
TXPIN=0;
delay_ms(1);
}
//Se envan 4 bits de verificacin
//con el nmero de unos en el byte.
165
for( BITS=0; BITS<4; BITS++ )
{
TXPIN=1;
if( (N_Bits>>BITS)&1 )
delay_ms(2);
else
delay_ms(1);
TXPIN=0;
delay_ms(1);
}
//Retardo final.
delay_ms(3);
}
Para concretar el ejemplo se realizan dos programas, uno para la transmisin, y otro para la
recepcin, este sistema transmite el estdo de 4 pulsadores y se puede visualizar en el receptor
por medio de 4 LEDs. De igual manera la simulacin puede soportar los dos microcontroladores
al mismo tiempo, pero no puede simular los radios. Para fines de simulacin se implementa una
conexin directa, sin embargo el desarrollador puede posteriormente hacer una prueba real con
los radios.
Cada uno de los programas debe tener anexa la librera anteriormente citada, y anexar las
siguientes funciones main, en cada uno de los cdigos fuente:
Funcin main para el transmisor:
void main( void )
{
//Declaracin de variables.
unsigned char DATO;
//Configuracin de puertos.
TRISB = 0xFF;
//Activacin de las resistencias PULL-UP del puerto B.
OPTION_REG = 0;
//Inicio del puerto de transmisin.
Inicio_Radio_Tx();
while(1) //Bucle infinito.
{
//Adquisicin de estdos de los pulsadores.
DATO = (~PORTB)&0x0F;
//Transmisin del byte.
Enviar_Dato( DATO );
}
}
166
Funcin main para el receptor:
void main( void )
{
//Declaracin de variables.
int DATO;
//Configuracin de puertos.
TRISB = 0;
PORTB = 0;
//Inicio del puerto de recepcin.
Inicio_Radio_Rx();
while(1) //Bucle infinito.
{
//Lectura del byte de entrada.
DATO = Resibir_Dato();
//Verificacin de errores, y visualizacin del byte.
if( DATO!=-1 )
PORTB =DATO;
}
}
Para realizar la simulacin se deben usar los siguientes dispositivos: PIC 16F628A, RES, LED-
RED, y BUTTON, en el circuito que se puede ver a continuacin:
Circuito 13-2
167
Para fines prcticos con los radios Laipac, se bebe hacer un par de circuitos como los que se
pueden ver en la siguiente grfica:
Circuito 13-3
13.3 Mdulos inalmbricos bidireccionales
En algunos casos las comunicaciones deben ser imperativamente bidireccionales, como el caso de
los controles realimentados y los sistemas de comunicacin full duplex. Para cumplir con el
propsito de realizar la comunicacin full duplex se pueden implementar mdulos de radio
prediseados como los XBee, o XBee PRO, estos dispositivos son mdulos MODEM, que
trabajan sobre la banda de 2,4GHz, e implementan el estndar IEEE 801.15.4. Estos son
dispositivos que trabajan con tecnologa de 3 voltios de bajo consumo, y velocidades de
transmisin de 1200 a 115200 bits por segundo. El alcance de los radios depende de la antena y
de la referencia de los mismos. Los mdulos XBee tienen un alcance de 100 metros con una lnea
de vista directa y 1000 metros en los mdulos XBee PRO. Los mdulos XBee, son de fcil
instalacin y programacin por medio de un paquete de software, suministrado por el fabricante,
este se denomina: X-CTU, este aplicativo se puede descargar gratuitamente en la pgina:
www.digi.com, este programa estblece con el radio la comunicacin para su programacin por
medio de un puerto serial COM. La simulacin de estos radios no es posible con ISIS; pero dado
el ptimo desempeo de los mismos es equivalente en ISIS a realizar una conexin cruzada entre
Tx y Rx, de los microcontroladores. Los mdulos XBee incorporan dentro de su hardware y
software un procedimiento de deteccin y correccin de errores en la transmisin. De la misma
forma es posible estblecer una conexin inalmbrica entre un microcontrolador con un
ordenador personal por medio de un puerto serial COM. Para trabajar y programar los radios
XBee es necesario crear o implementar un acople de hardware para hacer la conexin con un
puerto serial COM, para este proposito se debe tener presente el siguiente circuito electrnico:
168
Mdulo de acople con un ordenador personal:
Circuito 13-4
El anterior circuito electrnico puede ser construido en una protoborad, sin embargo se puede
construir un circuito impreso como el que se puede apreciar en las siguientes grficas:
Figura 13-8
169
La vista de este circuito impreso finalizado y del mdulo XBee, es la siguiente:
Figura 13-9
Los mdulos XBee por defecto vienen programados para establecer una comunicacin a 9600
bits por segundo. Sin embargo se puede cambiar por medio del programa X-CTU. La
reprogramacin del radio XBee, permite cambiar los parmetros de velocidad, canal de
comunicacin entre 16 posibles, se puede asignar un identificador del radio y asignar direccin de
trabajo en una red Zigbee.
Para hacer una demostracin del funcionamiento con los mdulos XBee, se puede editar y
analizar el siguiente cdigo fuente:
//Declaracin de pines de control para LCD.
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
void main( void )
{
//Declaracin de variables.
char Texto[30];
char Dato;
unsigned short N=0;
//Inicio de los mdulos USART, y LCD.
Lcd_Init();
UART1_Init(9600);
170
//Se imprimen los textos de inicio.
Lcd_Out(1,1,"Datos de entrada:");
Lcd_Out(2,1,"");
while(1) //Bucle infinito.
{
//Se evala si un dato llega por el puerto serial.
if( UART1_Data_Ready() )
{
//Se lee el dato de entrada.
Dato = UART1_Read();
//Se evala que Dato llega por el puerto serial.
switch( Dato )
{
//Se evala la llegada de un enter.
case 13: N=0;
//Se limpian las lneas del LCD.
Lcd_Out(2,1," "); //Se imprimen 20 espacios vacos.
Lcd_Out(2,1," "); //Se imprimen 20 espacios vacos.
Lcd_Out(4,1," "); //Se imprimen 20 espacios vacos.
//Se posiciona el cursor en la segunda lnea.
Lcd_Out(2,1,"");
//Se transmite un enter y un retroceso del carro.
UART1_Write(13);
UART1_Write(10);
//Se transmite el texto: Texto Xbee.
UART1_Write_Text("Texto Xbee: ");
//Se retransmite la cadena recibida.
UART1_Write_Text(Texto);
//Se transmite un enter y un retroceso del carro.
UART1_Write(13);
UART1_Write(10);
break;
default: //Se guardan los datos entrantes en la cadena de caracteres Texto.
Texto[N++]=Dato;
Texto[N]=0;
//Se refresca la informacin en el LCD.
Lcd_Out(2,1,Texto);
//Se retransmite eco del dato de entrada.
UART1_Write(Dato);
break;
}
}
}
}
Para fines de simulacin se puede implementar un circuito con los dispositivos: 16F877A,
LM044L, y el puerto virtual VIRTUAL TERMINAL, como se puede apreciar en el siguiente
esquema:
171
Circuito 13-5
Para fines prcticos se puede usar el mdulo de acople con un ordenador personal, antes citado
con una sesin de Hyper terminal de Windows. Como parte complementaria se puede hacer un
circuito real como se puede ver en la siguiente grfica:
Circuito 13-6
172
13.4 Comunicacin RS 485
El protocolo RS 485, es un formato de comunicacin serial que usa como estrategia de
transmisin, la diferencia de potencial entre dos terminales denominadas A, y B. Cuando la
diferencia de potencial es positiva el protocolo representa un 1 lgico y cuando la diferencia es
negativa representa un 0 lgico. La comunicacin RS 485, implementa un par trenzado de cobre
para la transmisin de datos, como caractersticas notables de este protocolo se tiene que puede
estblecer la comunicacin en una topologa en forma de bus, con un alcance mximo de 1000
metros sin la necesidad de implementar dispositivos de repeticin. De igual forma es posible
conectar al bus de datos un mximo de 32 nodos, con una conectividad half duplex, esto quiere
decir que la comunicacin es bidireccional pero no al mismo tiempo. El protocolo RS 485
permite estblecer comunicaciones con una velocidad de hasta 2,5M bits por segundo. Para la
implementacin de este tipo de comunicacin se usan convertidores integrados que permiten
hacer un enlace de niveles TTL, a RS 485, el circuito integrado ms popular para ests
aplicaciones es el MAX485, que es un integrado de 8 pines. La distribucin de pines y la
apariencia fsica de este dispositivo es la siguiente:
Figura 13-10
Los pines A, y B, son el bus de datos bidireccional, los pines DE, y RE, son los habilitadores de
los bfer de transmisin y recepcin respectivamente. Los pines DI, y RO, son respectivamente
los terminales de transmisin y recepcin. Como medida adicional se deben implementar un par
de resistencias de 120 en paralelo a los pines A, y B, en el primer y en el ltimo terminal de la
red RS 485.
Para demostrar una comunicacin con este tipo de redes se realizar en este captulo una
comunicacin de half duplex entre dos microcontroladores, para este fin se usarn los mdulos
USART, y un control adicional con los pines de habilitacin. Para contextualizar el uso de la
comunicacin RS 485, se puede observar y analizar el siguiente cdigo de programa que permite
enviar el estdo de un potencimetro para controlar la intensidad de luz de una lmpara en el
terminal opuesto:
void main( void )
{
//Declaracin de variables.
unsigned short DATO;
//Configuracin de puertos.
TRISB = 0b11111110;
PORTB = 0; //Se Configura la MAX485 como receptor.
173
//Se activan las resistencias PULL-UP.
OPTION_REG = 0;
//Se configura el mdulo USART a 250000 bps.
UART1_Init(250000);
//Se configura el mdulo PWM con una frecuencia de 1K Hz.
PWM1_Init(1000);
//Se inicia el mdulo PWM con 0%.
PWM1_Start();
PWM1_Set_Duty(0);
while(1) //Bucle infinito.
{
//Se evala si un dato ha llegado.
if( UART1_Data_Ready() )
{
DATO = UART1_Read();
//Se evala si el dato de llegada vale 170.
if( DATO==170 )
{
//Se espera el siguiente dato.
while( !UART1_Data_Ready() );
DATO = UART1_Read();
//Se actualiza el ciclo til del PWM.
PWM1_Set_Duty(DATO);
}
}
//Se evala si se ha pulsado el botn.
if( Button(&PORTB, 1, 50, 0) )
{
PORTB = 1; //Se Configura la MAX485 como transmisor.
//Se lee el canal anlogo con el voltaje del
//potencimetro, y se guardan los 8 bits de mayor peso
//en el la variable DATO.
DATO = (ADC_Read(0)>>2)&0xFF;
//Se transmite la bandera 170, para sincronizar la comunicacin.
UART1_Write(170);
//Se hace una pausa de 1m segundos entre datos.
delay_ms(1);
//Se transmite el valor de la variable DATO.
UART1_Write(DATO);
//Se espera a que se suelte el botn.
while( Button(&PORTB, 1, 50, 0) );
PORTB = 0; //Se Configura la MAX485 como receptor.
}
}
}
El anterior programa es simtrico, es decir que los dos microcontroladores de la simulacin se
cargan con el mismo programa. El circuito electrnico recurre a una lmpara incandescente con
el fin de mostrar la intensidad de la luz, la diferencia de potencial se obtiene del mdulo PWM,
174
con la conversin digital anlogo. Para fines ideales de la simulacin las caractersticas por
defecto de la lmpara son reconfiguradas cambiando la impedancia de 24 a 100K y su voltaje
nominal de 12V a 5V. Para realizar la simulacin se deben implementar los siguientes
dispositivos: 16F877A, RES, MAX487, LAMP, BUTTON, CAP, y POT-HG. La teora vista en
este captulo cita el dispositivo MAX485, sin embargo para fines de simulacin se usa el
MAX487, que tiene caractersticas y funcionamiento similar. El circuito a implementar es el
siguiente:
Circuito 13-7
Cuando la simulacin est corriendo, cada uno de los mdulos MAX, estn configurados como
receptores, y en el momento que se pulsa un botn el microcontrolador hace la conversin
anloga digital, y transmite est informacin para configurar la intensidad de luz en el mdulo
opuesto.
13.5 Mdulos inalmbricos infrarrojos
La comunicacin infrarroja es una estrategia prctica para sistemas que no requieren una gran
velocidad de transmisin, y que admiten lnea de vista directa. El alcance de un enlace infrarrojo
depende de la potencia del emisor. Sin embargo este estndar es utilizado en la comunicacin de
control de los electrodomsticos convencionales como: televisores, equipos de sonido,
reproductores de video, aires acondicionados entre otros, tiene un alcance promedio de 10
metros.
La transmisin de datos se realiza por medio de diodos emisores de luz infrarroja, con una
modulacin digital por amplitud, ASK. Los estndares de comunicacin para los controles
infrarrojos implementan frecuencias portadoras de 36, 38, y 40 K Hz entre otras. La recepcin de
los datos se hace por medio de un demodulador ASK, que puede recibir datos hasta los 2,4K bits
por segundo. Los demoduladores ASK, infrarrojos son dispositivos de carcter integrado que se
pueden conseguir comercialmente. Estos poseen tres terminales que corresponden a dos de
polarizacin, Vcc o poder, y referencia, y una salida demodulada en amplitud, con colector
abierto, esto quiere decir que se requiere el uso de una resistencia PULL-UP, a Vcc, en este
ltimo terminal. Algunos fabricantes incorporan est resistencia en la integracin del dispositivo.
175
Para fines de diseo es importante tener presente que la salida del demodulador est invertida, es
decir que cuando el dispositivo detecta la seal portadora la salida del demodulador se activa en
bajo y se activa en alto cuando se detecta la ausencia de la misma. La apariencia fsica de estos
dispositivos es la siguiente:
Figura 13-11
La distribucin de pines puede variar de un fabricante a otro, sin embargo siempre sern las
mismas tres, Vcc, Referencia, y Salida, para fines prcticos se hace imperativo consultar la ficha
tcnica del dispositivo que se use.
Para la simulacin de este tipo de enlaces se puede usar en ISIS el mdulo virtual: IRLINK, el
cual tiene la siguiente apariencia en el simulador:
Figura 13-12
Este dispositivo virtual simula el enlace inalmbrico por medio del LED infrarrojo, y el
dispositivo demodulador, de igual manera permite editar la frecuencia de la seal portadora ASK.
Para contextualizar el desempeo de estos enlaces se debe observar y analizar el siguiente cdigo
fuente, que usa el mdulo PWM, como fuente portadora, y el mdulo USART, como seal
moduladora, la informacin transmitida son datos ASCII, con textos fijos que se pueden ver en
un hyper terminal virtual:
void main( void )
{
//Configuracin del mdulo USART a 2400 bps.
UART1_Init(2400);
//Configuracin de PWM para crear la frecuencia portadora a 38K Hz.
PWM1_Init(38000);
PWM1_Start();
176
//Se configura el ciclo til del PWM al 50%.
PWM1_Set_Duty(127);
while(1) //Bucle infinito.
{
//Se transmite informacin en un texto fijo.
UART1_Write_Text("Transmision de datos infrarrojos.");
//Se enva los caracteres enter y retroceso del carro.
UART1_Write(13);
UART1_Write(10);
//Se transmite informacin en un texto fijo.
UART1_Write_Text("Est emision est modulada a 38K Hz.");
UART1_Write(13);
UART1_Write(10);
//Se transmite informacin en un texto fijo.
UART1_Write_Text("Con una velocidad de transmision de 2400 bps.");
//Se enva los caracteres enter y retroceso del carro.
UART1_Write(13);
UART1_Write(10);
//Se enva los caracteres enter y retroceso del carro.
UART1_Write(13);
UART1_Write(10);
//Se realiza una pausa de 200m segundos.
delay_ms(200);
}
}
Para la simulacin de este ejemplo se implementan en ISIS los dispositivos: 16F628A, RES,
1N4148, IRLINK, 74LS04, y el VIRTUAL TERMINAL. El circuito electrnico debe ser
ensamblado de la siguiente manera:
Circuito 13-8
177
La modulacin se realiza por medio de la multiplicacin de la seal moduladora, con la seal
portadora, para esto se implementa una compuerta AND, diseada con diodos rectificadores de
switcheo rpido. En funcionamiento de la simulacin, el hiperterminal virtual debe mostrar los
datos de texto de la siguiente forma:
Figura 13-13
13.6 Comunicacin con memorias SD
Las memorias de almacenamiento masivo SD, pueden ser manipuladas por los
microcontroladores de alta gama como la familia 18F. Para leer o escribir sobre una memoria SD,
se requiere trabajar con segmentos de memoria de 512 bytes. Para este fin es necesario contar con
espacios de memoria RAM, de gran capacidad como los microcontroladores de la familia 18F. La
comunicacin de las memorias SD, requieren de un protocolo serial conocido como SPI, para
este fin los microcontroladores cuentan con un mdulo de comunicacin serial de este tipo. La
alimentacin de voltaje de las memorias SD es de 3 voltios, para esto se requiere hacer un acople
de voltajes con el microcontrolador por medio de un divisor de voltaje con resistencias. La
apariencia fsica y la distribucin de pines de este tipo de memorias son las siguientes:
Figura 13-14
La capacidad de las memorias SD actuales es del orden de los Giga bytes, sin embargo la mxima
capacidad que soporta la librera para ests memorias en MikroC PRO, es de 1G bytes. Para la
manipulacin de este tipo de memorias el compilador MikroC PRO, cuenta con una librera
178
denominada: Mmc. La cual posee tres funciones para estblecer de forma simple la comunicacin
y control de la memoria. La funcin: unsigned char Mmc_Init( void ); est funcin inicializa la
comunicacin con la memoria SD, y retorna 0 si la comunicacin se estbleci exitosamente, o
retorna 1 si algn error se presenta. La funcin: unsigned char Mmc_Read_Sector(unsigned long
sector, char *dbuff); est permite leer un sector de 512 bytes, guardando la lectura en el
apuntador dbuff, e iniciando en el sector definido por el parmetro sector. La funcin: unsigned
char Mmc_Write_Sector(unsigned long sector, char *dbuff); est funcin trabaja de forma
similar a la funcin de lectura, en las dos funciones se retorna el valor 0 si la operacin culmina
exitosamente o retornan 1 si un fallo se presenta. Para la comunicacin fsica se requieren 4
conexiones que son: una lnea de reloj, dos lneas de datos, entrada y salida, y un selector de
pastilla.
Para contextualizar el funcionamiento de estos dispositivos se puede observar y analizar el
siguiente cdigo fuente:
// Pines de conexin para el selector de pastilla
sbit Mmc_Chip_Select at RC2_bit;
sbit Mmc_Chip_Select_Direction at TRISC2_bit;
void main( void )
{
//Declaracin de variables.
char SD;
char Texto[50];
long SEC=0;
unsigned int Cont;
unsigned short Menu=0;
unsigned short NN;
char Dato;
unsigned short Bufer[512];
//Inicio del puerto serial a 9600 bps.
UART1_Init(9600);
//Inicio del puerto SPI, para la memoria SD.
SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV64, _SPI_DATA_SAMPLE_MIDDLE,
_SPI_CLK_IDLE_HIGH, _SPI_LOW_2_HIGH);
//Inicio de la memoria.
if( Mmc_Init()==0 )
{
//Confirmacin exitosa de conexin.
SD = 1;
UART1_Write_Text("// La memoria fue iniciada exitosamente. //");
UART1_Write(13);
UART1_Write(10);
UART1_Write(13);
UART1_Write(10);
179
}
else
{
//Confirmacin fallida de conexin.
SD = 0;
UART1_Write_Text("ERROR no se puede iniciar la memoria !!!");
UART1_Write(13);
UART1_Write(10);
UART1_Write(13);
UART1_Write(10);
}
while(1) //Bucle infinito.
{
if( SD ) //Se ejecuta el Men si la conexin fue exitosa.
{
//Se despliega el Men.
UART1_Write_Text( "1. Grabar un Sector." );
UART1_Write(13);
UART1_Write(10);
UART1_Write_Text( "2. Leer un Sector." );
UART1_Write(13);
UART1_Write(10);
UART1_Write_Text( "Digite una opcion: " );
Menu = 0;
//Bucle para esperar la opcin.
while( Menu==0 )
{
if( UART1_Data_Ready() )
{
Dato = UART1_Read();
UART1_Write(Dato);
UART1_Write(' ');
switch( Dato )
{
case '1': Menu=1; break;
case '2': Menu=2; break;
default: break;
}
}
}
//Envi del enter y retroceso del carro.
UART1_Write(13);
UART1_Write(10);
//Captura del sector de lectura o escritura.
180
UART1_Write_Text( "Digite el numero del sector de memoria, y pulse ENTER: " );
SEC=-1;
NN=0;
Texto[0]=0;
//Bucle para digital el sector.
while( SEC==-1 )
{
if( UART1_Data_Ready() )
{
Dato = UART1_Read();
UART1_Write(Dato);
switch( Dato )
{
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '0': Texto[NN++]=Dato;
Texto[NN]=0;
break;
case 13: SEC=atol(Texto);
default : break;
}
}
}
//Envi del enter y retroceso del carro.
UART1_Write(13);
UART1_Write(10);
//Se graban o se leen los sectores.
if( Menu==1 )
{
UART1_Write_Text( "Se grabara el sector: " );
LongToStr( SEC, Texto);
UART1_Write_Text( Texto );
//Envi del enter y retroceso del carro.
UART1_Write(13);
UART1_Write(10);
//Se borra el Bfer.
for( Cont=0; Cont<512; Cont++ )
Bufer[Cont]=0;
//Bucle para capturar los datos a grabar.
181
while( Menu )
{
if( UART1_Data_Ready() )
{
Dato = UART1_Read();
UART1_Write(Dato);
switch( Dato )
{
case 13: Menu=0; break;
default : Bufer[NN++]=Dato;
break;
}
}
}
//Se graban los 512 datos del sector en la memoria.
Mmc_Write_Sector( SEC, Bufer);
//Envi del enter y retroceso del carro.
UART1_Write(13);
UART1_Write(10);
UART1_Write_Text( "Fin de la grabacion." );
}
else
{
UART1_Write_Text( "Se leera el sector: " );
LongToStr( SEC, Texto);
UART1_Write_Text( Texto );
//Envi del enter y retroceso del carro.
UART1_Write(13);
UART1_Write(10);
//Se leen 512 datos del sector.
Mmc_Read_Sector( SEC, Bufer);
//Bucle para imprimir los datos ledos de la memoria.
for( Cont=0; Cont<512; Cont++ )
UART1_Write( Bufer[Cont] );
}
//Envi del enter y retroceso del carro.
UART1_Write(13);
UART1_Write(10);
//Envi del enter y retroceso del carro.
UART1_Write(13);
UART1_Write(10);
}
}
}
Como medida adicional se debe inicializar el puerto SPI, por medio de la funcin:
SPI1_Init_Advanced. Para comprobar el funcionamiento de de este programa se debe construir en
ISIS, un circuito con los dispositivos: 18F452, MMC, y VIRTUAL TERMINAL, como se puede
apreciar en la siguiente grfica:
182
Circuito 13-9
Para fines de simulacin las conexiones con la memoria se hacen directamente como se puede ver
en el anterior circuito. Sin embargo se debe tener presente que para fines prcticos la memoria
trabaja con 3 voltios, y se debe acoplar con un arreglo de resistencias como el siguiente:
Circuito 13-10
183
13.7 Relojes en tiempo real
Algunas aplicaciones requieren de un reloj en tiempo real, para tener dominio del tiempo de
eventos, acciones, y dems. Este tipo de relojes son circuitos integrados con bateras propias, y
cristales de cuarzo para definir las unidades de tiempo. Los relojes en tiempo real se comunican
por medio del protocolo IC. Una de las referencias comerciales ms populares es el DS1307, que
puede contar aos, meses, das, hora, minutos, y segundos. La apariencia fsica y la vista en ISIS
de estos dispositivos es la siguiente:
Figura 13-15
Este circuito integrado cuenta con dos pines de comunicacin un pin de salida oscilante, y una
entrada para la batera, adems para fines prcticos cuenta con dos terminales para instalar un
cristal de cuarzo de 32,768KHz. El siguiente cdigo fuente en lenguaje C, muestra una serie de
funciones que forman una librera que permiten manipular este tipo de relojes:
//Declaracin de estructuras
typedef struct
{
unsigned short Hor, Min, Seg;
}Hora;
typedef struct
{
unsigned short Dia, Fec, Mes, Ano;
}Fecha;
//Funcin para definir direccin de memoria.
void DS1307SetDir( unsigned short dir )
{
I2C1_Start();
I2C1_Wr(0xD0);
I2C1_Wr(dir);
}
//Funcin para convertir de cdigo Bcd a Entero.
unsigned short BcdToShort( unsigned short bcd )
{
unsigned short LV, HV;
LV = bcd&0x0F;
HV = (bcd>>4)&0x0F;
184
return LV + HV*10;
}
//Funcin para convertir de Entero a Bcd.
unsigned short ShortToBcd( unsigned short valor )
{
unsigned short HV, LV;
HV = valor/10;
LV = valor - HV*10;
return LV + HV*16;
}
//Funcin para inicializar el DS1307.
void DS1307Inicio( void )
{
unsigned short VAL[7], HV, LV, DATO;
I2C1_Init(100000); //Inicio del bus I2C.
delay_ms(50); //Retardo.
//Lectura de las primeras 7 direcciones.
DS1307SetDir(0);
I2C1_Repeated_Start();
I2C1_Wr(0xD1);
VAL[0] = I2C1_Rd(1);
VAL[1] = I2C1_Rd(1);
VAL[2] = I2C1_Rd(1);
VAL[3] = I2C1_Rd(1);
VAL[4] = I2C1_Rd(1);
VAL[5] = I2C1_Rd(1);
VAL[6] = I2C1_Rd(0);
I2C1_Stop();
delay_ms(50); //Retardo.
//Validacin y correccin de informacin,
//como hora y fecha.
DATO = BcdToShort( VAL[0] );
if( DATO > 59 )VAL[0]=0;
DATO = BcdToShort( VAL[1] );
if( DATO>59 )VAL[1]=0;
DATO = BcdToShort( VAL[2] );
if( DATO>23 )VAL[2]=0;
DATO = BcdToShort( VAL[3] );
if( DATO>7 || DATO==0 )VAL[3]=1;
DATO = BcdToShort( VAL[4] );
if( DATO>31 || DATO==0 )VAL[4]=1;
DATO = BcdToShort( VAL[5] );
if( DATO>12 || DATO==0 )VAL[5]=1;
DATO = BcdToShort( VAL[6] );
if( DATO>99 )VAL[6]=0;
//Grabacin de las primeras 7 direcciones.
DS1307SetDir(0);
185
I2C1_Wr(VAL[0]);
I2C1_Wr(VAL[1]);
I2C1_Wr(VAL[2]);
I2C1_Wr(VAL[3]);
I2C1_Wr(VAL[4]);
I2C1_Wr(VAL[5]);
I2C1_Wr(VAL[6]);
I2C1_Wr(0x10); //Se activa la salida oscilante 1Hz.
I2C1_Stop();
delay_ms(50); //Retardo.
}
//Funcin para grabar la hora minutos y segundos.
void DS1307SetHora( Hora h )
{
DS1307SetDir(0);
I2C1_Wr( ShortToBcd(h.Seg) );
I2C1_Wr( ShortToBcd(h.Min) );
I2C1_Wr( ShortToBcd(h.Hor) );
I2C1_Stop();
}
//Funcin para grabar el da, fecha, mes, y ao.
void DS1307SetFecha( Fecha f )
{
DS1307SetDir(3);
I2C1_Wr( ShortToBcd(f.Dia) );
I2C1_Wr( ShortToBcd(f.Fec) );
I2C1_Wr( ShortToBcd(f.Mes) );
I2C1_Wr( ShortToBcd(f.Ano) );
I2C1_Stop();
}
//Funcin para leer la hora minutos y segundos.
Hora DS1307GetHora( void )
{
Hora H;
unsigned short VAL[3];
DS1307SetDir(0);
I2C1_Repeated_Start();
I2C1_Wr(0xD1);
VAL[0] = I2C1_Rd(1);
VAL[1] = I2C1_Rd(1);
VAL[2] = I2C1_Rd(0);
I2C1_Stop();
H.Seg = BcdToShort( VAL[0] );
H.Min = BcdToShort( VAL[1] );
H.Hor = BcdToShort( VAL[2] );
return H;
186
}
//Funcin para leer el da, fecha, mes, y ao.
Fecha DS1307GetFecha( void )
{
Fecha F;
unsigned short VAL[4];
DS1307SetDir(3);
I2C1_Repeated_Start();
I2C1_Wr(0xD1);
VAL[0] = I2C1_Rd(1);
VAL[1] = I2C1_Rd(1);
VAL[2] = I2C1_Rd(1);
VAL[3] = I2C1_Rd(0);
I2C1_Stop();
F.Dia = BcdToShort( VAL[0] );
F.Fec = BcdToShort( VAL[1] );
F.Mes = BcdToShort( VAL[2] );
F.Ano = BcdToShort( VAL[3] );
return F;
}
// Funciones para leer y grabar datos individuales //
//Funcin para leer las horas.
unsigned short DS1307GetHoras( void )
{
Hora h;
h=DS1307GetHora();
return h.Hor;
}
//Funcin para leer los minutos.
unsigned short DS1307GetMinutos( void )
{
Hora h;
h=DS1307GetHora();
return h.Min;
}
//Funcin para leer los segundos.
unsigned short DS1307GetSegundos( void )
{
Hora h;
h=DS1307GetHora();
return h.Seg;
}
//Funcin para grabar las horas.
void DS1307SetHoras( unsigned short ho )
{
Hora h;
h=DS1307GetHora();
187
h.Hor = ho;
DS1307SetHora( h );
}
//Funcin para grabar los minutos.
void DS1307SetMinutos( unsigned short mi )
{
Hora h;
h=DS1307GetHora();
h.Min = mi;
DS1307SetHora( h );
}
//Funcin para grabar los segundos.
void DS1307SetSegundos( unsigned short se )
{
Hora h;
h=DS1307GetHora();
h.Seg = se;
DS1307SetHora( h );
}
//Funcin para leer el da de la semana.
unsigned short DS1307GetDias( void )
{
Fecha f;
f=DS1307GetFecha();
return f.Dia;
}
//Funcin para leer la fecha del mes.
unsigned short DS1307GetFechas( void )
{
Fecha f;
f=DS1307GetFecha();
return f.Fec;
}
//Funcin para leer el mes del ao.
unsigned short DS1307GetMeses( void )
{
Fecha f;
f=DS1307GetFecha();
return f.Mes;
}
//Funcin para leer el ao.
unsigned short DS1307GetAnos( void )
{
Fecha f;
188
f=DS1307GetFecha();
return f.Ano;
}
//Funcin para grabar el dia de la semana.
void DS1307SetDias( unsigned short di )
{
Fecha f;
f=DS1307GetFecha();
f.Dia = di;
DS1307SetFecha(f);
}
//Funcin para grabar la fecha del mes.
void DS1307SetFechas( unsigned short fe )
{
Fecha f;
f=DS1307GetFecha();
f.Fec = fe;
DS1307SetFecha(f);
}
//Funcin para grabar el mes del ao.
void DS1307SetMeses( unsigned short me )
{
Fecha f;
f=DS1307GetFecha();
f.Mes = me;
DS1307SetFecha(f);
}
//Funcin para grabar el ao.
void DS1307SetAnos( unsigned short an )
{
Fecha f;
f=DS1307GetFecha();
f.Ano = an;
DS1307SetFecha(f);
}
Para realizar la simulacin de un ejemplo con este tipo de reloj, se puede implementar la anterior
librera y el siguiente cdigo fuente correspondiente a la funcin main:
void main( void )
{
//Declaracin de variables.
char Text[50];
unsigned short DATO;
//Inicio y configuracin del reloj.
189
DS1307Inicio();
//Inicio y configuracin de la USART a 9600 bps.
UART1_Init(9600);
//Se leen los segundos del reloj.
DATO = DS1307GetSegundos();
while(1) //Bucle infinito.
{
//Se espera el cambio en los segundos.
while( DATO == DS1307GetSegundos() )delay_ms(200);
//Se leen la hora y se transmiten por la USART.
DATO = DS1307GetHoras();
ByteToStr( DATO, Text );
UART1_Write_Text( Text ); UART1_Write_Text(":");
//Se leen los minutos y se transmiten por la USART.
DATO = DS1307GetMinutos();
ByteToStr( DATO, Text );
UART1_Write_Text( Text ); UART1_Write_Text(":");
//Se leen los segundos y se transmiten por la USART.
DATO = DS1307GetSegundos();
ByteToStr( DATO, Text );
UART1_Write_Text( Text ); UART1_Write(13); UART1_Write(10);
}
}
Para realizar la simulacin pertinente en ISIS, se implementan los siguientes dispositivos:
16F877A, RES, LED-RED, DS1307, CRYSTAL, CELL, y los instrumentos virtuales, VIRTUAL
TERMINAL, I2C DEBUGGER. El circuito electrnico correspondiente para simular es el
siguiente:
Circuito 13-11
190
14 Tratamiento digital de
seales
El tratamiento digital de seales es una lnea de la tecnologa demasiado extensa para ser tratada
en un solo captulo; sin embargo, este captulo se centra en las nociones de adquisicin
tratamiento y reconstruccin de seales. Cabe denotar que el alcance de los microcontroladores
PICMicro de baja gama como los 16F y 18F slo permiten realizar tratamientos sobre seales de
baja frecuencia. De todos modos, muchas aplicaciones son de utilidad bajo ests caractersticas
tales como sistemas de comunicacin, generacin de tonos DTMF y adquisicin de seales
bioelctricas, entre otras. Si el desarrollador desea trabajar y tratar seales de mayor espectro,
realizando tratamientos de mayor complejidad ser necesario trabajar con unidades de
procesamiento ms robustas como la familia de microcontroladores PICMicro ds. Estos
microcontroladores no pueden ser programados con el compilador MikroC PRO, para estos se
debe utilizar el compilador MikroC PRO para dsPIC.
Un diagrama en bloques del procesamiento digital de una seal se puede apreciar en la siguiente
figura:
Figura 14-1
14.1 Muestreo
Como primera medida se requiere adquirir muestras peridicamente de la seal anloga, esto se
logra haciendo una conversin anloga digital, con una frecuencia constante denominada
frecuencia de muestreo Fs. El periodo de muestreo T, es el tiempo en segundos que existe entre
muestra y muestra, y a su vez es el inverso de la frecuencia de muestreo T = 1/Fs. El muestreo
permite convertir una seal continua en una seal discreta, es decir que pasa de x(t) a x(Tn),
donde T es el periodo de muestreo, y n es el nmero de la muestra digitalizada. Para definir el
periodo de muestreo T, o lo que es igual la frecuencia de muestreo Fs, se debe tener la siguiente
consideracin: La frecuencia de muestreo debe ser mayor que la mxima componente espectral
contenida en la seal x(t). Por ejemplo, si la mxima frecuencia contenida en la seal x(t) es
500Hz, la frecuencia de muestreo debe ser como mnimo el doble, es decir Fs = 2x500Hz =
1000Hz. Este concepto es conocido como teorema de muestreo de Nyquist. Sin embargo la
frecuencia de muestreo puede ser mayor al doble del mximo en frecuencia de la seal x(t), de
hecho cuanto mayor sea la frecuencia de muestreo mayor ser la fidelidad de la seal
digitalizada, pero a su vez mayor sern los recursos requeridos en velocidad, y memoria de
procesamiento.
MAX
F Fs 2 >
Ecuacin 14-1
191
14.2 Funciones de transferencia
Una funcin de transferencia es la relacin que existe entre la entrada de una seal y su salida al
pasar por el bloque de proceso. Las funciones de transferencia se estudian y se manipulan en
trminos de la frecuencia compleja y no en el dominio del tiempo continuo. Esto se debe a que al
convertir las funciones a la frecuencia compleja las operaciones que implican manipulacin de
nmeros complejos y sistemas integro diferenciales que se hacen lineales, y esto simplifica su
tratamiento. Las funciones de transferencia para el caso de los sistemas de tiempo discreto se
hacen en trminos de la variable compleja z, para el tratamiento de estos sistemas se recurre a la
transformacin z, que representa la frecuencia compleja para el tiempo discreto. Las funciones de
transferencia se denotan por excelencia con la letra H, para las funciones en trminos de la
variable z, y con h, para las funciones en trminos del tiempo discreto Tn. A continuacin se
puede ver un ejemplo:
B
A
z X
z Y
z H = =
) (
) (
) (
Ecuacin 14-2
De la ecuacin anterior se puede deducir que:
) ( ) ( ) ( z Y z X z H =
Ecuacin 14-3
Como se puede ver en la anterior ecuacin la salida Y, de un sistema discreto es igual a la entrada
X, multiplicada por la funcin de transferencia H. Se debe recordar que el tratamiento real y la
programacin se realizan en trminos del tiempo discreto, por est razn siempre se deber
realizar la transformada inversa de z. La transformacin inversa de la ecuacin anterior da como
resultado la siguiente ecuacin en funcin del tiempo discreto Tn:
) ( ) ( * ) ( n y n x n h =
Ecuacin 14-4
De la anterior ecuacin se puede observar que se omite la escritura del periodo T, dado que este
es un valor constante, y no tiene relevancia escribirlo siempre. Por otro lado se puede observar
que la funcin h y la seal x, no se multiplican como en la frecuencia compleja, en este caso al
realizar la transformacin su equivalencia es la convolucin. Para el caso del tratamiento de
seales, la longitud de h(n), es finita, y el nmero mximo que asume n se denomina M, este a su
vez determina el orden de la funcin de transferencia. Por otra parte la seal de entrada x(n), es
una serie de muestras de longitud indeterminada, igual que la salida y(n).
De lo anterior se puede concluir que para realizar un tratamiento digital sobre una seal se debe
realizar la operacin de convolucin continua entre los coeficiente de la funcin h(n) y la seal
x(n). Sin embargo la operacin de convolucin puede ser de dos formas, una en la cual la
convolucin se hace con las muestras pasadas y actuales de la seal x(n), esto se conoce como
sistema sin memoria o sistemas FIR (Respuest Finita al Impulso). Por otra parte cuando la
convolucin requiere informacin de las muestras pasadas de x(n), y de y(n), estos sistemas se
denominan sistemas con memoria o IIR (Respuest Infinita al Impulso). Los sistemas IIR son
sistemticamente ms simples, en su implementacin y requieren de campos de memoria
pequeos, por otra parte realizar su diseo y lograr su estbilidad es ms complicado y requiere
de tediosos procesos matemticos. Los sistemas FIR, ofrecen caractersticas contrarias a los
sistemas IIR, los sistemas FIR, son de fcil implementacin y diseo, pero consumen recursos de
192
memoria y procesamiento mayor, una de las virtudes de estos sistemas es que siempre son
estbles. Los anlisis y ejemplos de este captulo se concentrarn en los sistemas FIR e IIR.
14.3 Convolucin
Para iniciar es importante conocer la estructura de una convolucin continua en forma
matemtica y por medio de un segmento de cdigo en lenguaje C:
| |
+
=
=
k
k n x k h n y ) ( ) ( ) (
Ecuacin 14-5
La ecuacin anterior describe la forma general de la convolucin, sin embargo se debe recordar
que la longitud de la funcin h(n), es finita y su mximo es M, por lo tanto la ecuacin se puede
reescribir de la siguiente forma:
| |
=
=
M
k
k n x k h n y
0
) ( ) ( ) (
Ecuacin 14-6
Cada vez que una muestra de la salida y(n), es calculada por medio de la convolucin, se
requieren M, muestras de la seal x(n), incluida la muestra actual, esto quiere decir que para
hacer la convolucin se debe tener presente la necesidad de un campo de memoria igual a M para
guardar las ltimas muestras durante el proceso.
A continuacin se puede observar un ejemplo de cmo se implementar una convolucin, en
lenguaje C:
//Orden del sistema FIR de orden 17, M=17.
#define M 17
float x[M];
float h[M];
//Rutina para hacer la convolucin.
float yn=0.0;
short k;
for( k=M-1; k>=1; k-- )x[n]=x[n-1];
x[0]=x0;
for( k=0; k<M; k++ )yn += h[k]*x[k];
14.4 Filtros FIR
El diseo de los filtros FIR, es relativamente simple y utiliza estructuras ya definidas para cada
tipo de filtro. Los filtros pueden ser de cinco naturalezas: Pasa bajas, pasa altas, pasa bandas,
rechaza banda, y multi banda. Para el tratamiento de los filtros se debe tener presente las
siguientes consideraciones:
Los clculos de los filtros se hacen en radianes y no en hercios.
193
La frecuencia de muestreo en hercios Fs, es equivalente a una frecuencia en radianes/segundo de
2.
La mxima frecuencia tratada por los filtros es Fs/2, o Radianes.
La relacin que existe entre radianes y hercios es: W = 2F, y F = W/2.
Las frecuencias de corte de los filtros se denotan como Wc, y Fc.
La frecuencia de corte se calcula como Wc = 2 Fc / Fs.
La banda de transicin del filtro se denota como dW en radianes/segundo y dF en hercios.
El orden de los sistemas FIR se denota como M.
Se recomienda usar un nmero impar para M.
A continuacin se estudiar la forma de diseo para cada uno de estos filtros.
14.4.1 Filtro Pasa bajas
Los filtros pasa bajas se caracterizan por tener una frecuencia de corte a partir de la cual las
frecuencias inferiores son permitidas, y las frecuencias superiores son atenuadas. La funcin de
transferencia h(n), para este filtro es:
2 2
0 ,
0 ,
) (
) (
M
n
M
n
w
n
n
n w Sen
n h
c
c
< <
=
=
=
t
t
Ecuacin 14-7
La respuest espectral de este filtro de orden 7, en escala lineal es la siguiente:
Figura 14-2
194
14.4.2 Filtros Pasa Altas
Los filtros pasa altos permiten el paso de las frecuencias superiores a la frecuencia de corte, y
suprimen las inferiores a la misma. El clculo de la funcin de transferencia h(n), para estos
filtros est definida por la siguiente ecuacin:
2 2
0 , 1
0 ,
) (
) (
M
n
M
n
w
n
n
n w Sen
n h
c
c
< <
=
=
=
t
t
Ecuacin 14-8
La respuest espectral en escala lineal de este filtro en orden 17, es la siguiente:
Figura 14-3
14.4.3 Filtro Pasa Banda
Los filtros pasa banda permiten el paso de una porcin de frecuencias entre Wc1 y Wc2, y el
resto de frecuencias son eliminadas. La funcin de transferencia para este tipo de filtros se
calcula por medio de la siguiente ecuacin:
2 2
0 ,
0 ,
) ( ) (
) (
1 2
1 2
M
n
M
n
w w
n
n
n w Sen n w Sen
n h
c c
c c
< <
=
t
t
Ecuacin 14-9
195
La respuest espectral en escala lineal de este filtro en orden 17, es la siguiente:
Figura 14-4
14.4.4 Filtro Rechaza Banda
Los filtros rechaza banda tienen un comportamiento similar a los filtros pasa banda, y su proceder
es inverso a los filtros pasa banda, la funcin que caracteriza los coeficientes de la funcin de
transferencia es la siguiente:
2 2
0 , 1
0 ,
) ( ) (
) (
1 2
2 1
M
n
M
n
w w
n
n
n w Sen n w Sen
n h
c c
c c
< <
=
t
t
Ecuacin 14-10
La respuest espectral en escala lineal de este filtro en orden 17, es la siguiente:
Figura 14-5
196
14.4.5 Filtro Multi Band
Los filtros multi banda son arreglos que integran diferentes filtros en uno solo, estos pueden dar
ganancias arbitrarias en un rango de frecuencias. La siguiente ecuacin integra las ganancias A
del filtro, y las frecuencias de corte w:
2 2
0 , ) (
0 ,
) (
) (
) (
1
1
1
1
M
n
M
n
w
A A
n
n
n w sen
A A
n h
L
l
l
l l
L
l
l
l l
< <
=
(
=
(
=
+
=
+
t
t
Ecuacin 14-11
La siguiente grfica muestra la respuest, de un filtro multi banda de orden 65, con cuatro bandas
diferentes:
Figura 14-6
Para fines de diseo se debe tener presente que la ultima frecuencia calculada debe ser igual a .
Este tipo de filtros son ideales para el diseo de sistemas que requieran efectuar ecualizacin,
sobre una seal.
14.4.6 Ventanas fijas
Las ventanas se aplican a las funciones de transferencia h(n), el objetivo de las ventanas es
mejorar y suavizar la respuest espectral de los filtros FIR. Las ventanas de mayor uso son las
siguientes:
- Rectangular
- Hamming
- Hanning
- Blackman
197
Los filtros que se demostraron anteriormente por defecto son filtros con ventana rectangular.
Estos filtros tienen la menor transicin en la frecuencia de corte, lo que los hace ms cercanos a
los filtros ideales, sin embargo est propiedad produce en los filtros sobresaltos y oscilaciones en
el espectro. Este efecto es conocido como: fenmeno Gibbs. Este efecto puede apreciarse en la
siguiente grfica:
Figura 14-7
La ventana Rectangular ofrece una banda de transicin igual a la siguiente relacin: dW = 1,8/M
14.4.7 Ventanas Rectangulares
Una ventana rectangular ofrece un patrn lineal, y constante. Se debe recordar que al realizar el
clculo de un filtro FIR, por defecto ya se encuentra con una ventana de este tipo.
La aplicacin de las ventanas involucra la creacin de una nueva funcin de factores w(n), que
posteriormente debe ser multiplicada trmino a trmino con la funcin de transferencia h(n), para
crear la funcin h(n) definitiva.
Una ventana Rectangular se representa por medio de la siguiente funcin w(n):
Figura 14-8
La respuest espectral de la ventana Rectangular en escala logartmica es la siguiente:
198
Figura 14-9
La ventana Rectangular ofrece una atenuacin del fenmeno Gibbs de -13dB.
14.4.8 Ventanas Hamming
Para el caso de la ventana Hamming, los factores w(n), se calculan de la siguiente forma:
M n
M n Cos
n w s s
= 0 ,
2
) / 2 ( 1
) (
t
Ecuacin 14-12
La misma respuest espectral aplicando una ventana Hamming, en la figura (14.7) del fenmeno
Gibbs se ve de la siguiente forma:
Figura 14-10
La ventana Hamming ofrece una banda de transicin igual a la siguiente relacin: dW = 6,2/M
Una ventana Hamming se representa por medio de la siguiente funcin w(n):
199
Figura 14-11
La respuest espectral de la ventana Hamming en escala logartmica es la siguiente:
Figura 14-12
En la ventana Hamming se ofrece una atenuacin del fenmeno Gibbs de -31dB.
14.4.9 Ventanas Hanning
Para el clculo de la ventana Hanning, los factores w(n), se deducen de la siguiente forma:
M n
M n Cos
n w s s
= 0 ,
50
) / 2 ( 23 27
) (
t
Ecuacin 14-13
La misma respuest espectral aplicando una ventana Hanning, en la figura (14.7) del fenmeno
Gibbs se ve de la siguiente forma:
200
Figura 14-13
La ventana Hanning ofrece una banda de transicin igual a la siguiente relacin: dW = 6,6/M
Una ventana Hanning se representa por medio de la siguiente funcin w(n):
Figura 14-14
La respuest espectral de la ventana Hanning en escala logartmica es la siguiente:
Figura 14-15
En la ventana Hanning se ofrece una atenuacin del fenmeno Gibbs de -41dB.
201
14.4.10 Ventanas Blackman
Para el diseo de una ventana Blackman, los factores w(n), se calculan de la siguiente forma:
M n
M n Cos M n Cos
n w s s
+
= 0 ,
50
) / 4 ( 4 ) / 2 ( 25 21
) (
t t
Ecuacin 14-14
La misma respuest espectral aplicando una ventana Blackman, en la figura (14.7) del fenmeno
Gibbs se ve de la siguiente forma:
Figura 14-16
La ventana Blackman ofrece una banda de transicin igual a la siguiente relacin: dW = 11/M
Una ventana Blackman se representa por medio de la siguiente funcin w(n):
Figura 14-17
La respuest espectral de la ventana Blackman en escala logartmica es la siguiente:
Figura 14-18
202
La ventana Blackman ofrece una atenuacin del fenmeno Gibbs de -57dB.
14.5 Ejemplos de diseo para filtros FIR
En la siguiente seccin se mostrarn ejemplos de diseo para filtros FIR, implementando un
microcontrolador 18F452, con una fuente de 40MHz como reloj. Para fines prcticos reales la
frecuencia de 40MHz, se logra utilizando un cristal de 10MHz, y activando la fuente de reloj HS-
PLL en el PIC. Est opcin implementa internamente en el PIC, un PLL que multiplica la
frecuencia externa por un factor de cuatro, y el resultado es usado como fuente de reloj para el
procesador del microcontrolador. Para todos los ejemplos FIR que se mostrarn se deben simular
con el mismo arreglo en ISIS, para este fin se implementa un circuito con los dispositivos
18F452, RES, OSCILLOSCOPE, Generador virtual Seno.
Para usar los generadores de seal virtual en ISIS, se debe picar en la barra de herramientas de la
izquierda el icono de Generator Mode, este tiene la siguiente apariencia visual: , dentro de este
se escoge la opcin SINE, y se pega dentro del rea de trabajo. Este generador tiene por defecto
una frecuencia de 1Hz, y una amplitud de 1 voltio. La adquisicin de seales se hace en el
microcontrolador por medio del mdulo AD, los niveles de tensin que las entradas anlogas
admiten, no pueden salirse de los confines de la polarizacin del microcontrolador. En otras
palabras los niveles de las entradas anlogas no pueden ser superiores a 5 voltios, ni voltajes
negativos. Para evitar las circunstancias antes nombradas, se debe manipular la configuracin del
generador virtual de seal, para este propsito, se hace doble clic, sobre el generador y se editan
los parmetros: Offset, y Amplitude. El parmetro offset se configura a 2,5 voltios, y el
parmetro Amplitude a 2 voltios. Est accin evita que las seales generadas se salgan de los
parmetros de PIC. Para fines de simulacin el parmetro Frequency, puede ser alterado al gusto
del desarrollador.
Una vista de est edicin se puede apreciar en la siguiente figura:
Figura 14-19
203
Indiferente al ejemplo que se simule en est seccin, se puede implementar el siguiente circuito
electrnico en ISIS:
Circuito 14-1
Para la reconstruccin de la seal procesada, se configuran 10 bits de salida, para hacer un
convertidor DA, por medio de un arreglo R-2R.
Para todos los ejemplos usados en este apartado, se usar la interrupcin por TIMER 0, para crear
el periodo de muestreo, y por defecto la frecuencia de muestreo.
El siguiente cdigo fuente muestra un ejemplo del muestreo de la seal por medio del TIMER 0:
//Declaracin de varales.
float x0, y0;
unsigned int YY;
//Declaracin de la funcin de interrupciones.
void interrupt ( void )
{
if( INTCON.F2 )
{
TMR0L=135;
//Timer0 con periodo de 774,4u segundo.
// Fs = 1291,32 Hz.
//Adquisicin de una muestra de 10 bits en, x[0].
x0 = (float)(ADC_Read(0)-512.0);
//
//Espacio para procesar la seal.
//
//Reconstruccin de la seal: y en 10 bits.
YY = (unsigned int)(x0+512);
PORTC = (YY>>8)&3;
PORTB = YY&255;
204
INTCON.F2=0;
}
}
void main( void )
{
//Inicio del puerto B como salida.
TRISB = 0;
PORTB = 0;
TRISC = 0;
PORTC = 0;
//Se configura el TIMER 0, su interrupcin.
INTCON = 0b10100000;
T0CON = 0b11000101;
while(1)//Bucle infinito.
{
}
}
14.5.1 Ejemplo de diseo para filtro pasa bajas
Fs = 1291,32KHz.
Fc = 150Hz.
Ventana Rectangular.
Se determina la frecuencia de corte digital:
Wc = 2 Fc / Fs = 2 150 / 1291,32 = 0,72985.
Usando la formula (14.7), se designan los coeficientes de la funcin h(n):
h(-8)=-0.0171035387965417
h(-7)=-0.0419431579233366
h(-6)=-0.0501329294124475
h(-5)=-0.0309497847516785
h(-4)=0.0175345019583181
h(-3)=0.0864308262744764
h(-2)=0.158173992108178
h(-1)=0.212237065988464
h(0)=0.232320416318186
h(1)=0.212237065988464
h(2)=0.158173992108178
h(3)=0.0864308262744764
h(4)=0.0175345019583181
h(5)=-0.0309497847516785
h(6)=-0.0501329294124475
h(7)=-0.0419431579233366
h(8)=-0.0171035387965417
205
Se debe tener presente que para fines de programacin los valores de n no pueden ser negativos,
por est razn se debe iniciar el vector en 0, y para usarlo en el cdigo en lenguaje C, se
implementa de la siguiente manera:
const float h[]=
{
-0.0171035387965417, //h(0)
-0.0419431579233366, //h(1)
-0.0501329294124475, //h(2)
-0.0309497847516785, //h(3)
0.0175345019583181, //h(4)
0.0864308262744764, //h(5)
0.158173992108178, //h(6)
0.212237065988464, //h(7)
0.232320416318186, //h(8)
0.212237065988464, //h(9)
0.158173992108178, //h(10)
0.0864308262744764, //h(11)
0.0175345019583181, //h(12)
-0.0309497847516785, //h(13)
-0.0501329294124475, //h(14)
-0.0419431579233366, //h(15)
-0.0171035387965417 //h(16)
};
El programa definitivo con la funcin de transferencia h(n), ser de la siguiente forma:
#define M 17
//Funcin de trasferencia h[n]
const float h[]=
{
-0.0171035387965417, //h(0)
-0.0419431579233366, //h(1)
-0.0501329294124475, //h(2)
-0.0309497847516785, //h(3)
0.0175345019583181, //h(4)
0.0864308262744764, //h(5)
0.158173992108178, //h(6)
0.212237065988464, //h(7)
0.232320416318186, //h(8)
0.212237065988464, //h(9)
0.158173992108178, //h(10)
0.0864308262744764, //h(11)
0.0175345019583181, //h(12)
-0.0309497847516785, //h(13)
-0.0501329294124475, //h(14)
-0.0419431579233366, //h(15)
-0.0171035387965417 //h(16)
};
206
//Declaracin de varales.
float x0, y0;
float x[M];
unsigned int YY;
unsigned short i;
//Declaracin de la funcin de interrupciones.
void interrupt ( void )
{
if( INTCON.F2 )
{
TMR0L=135;
PORTC.F7=1;
//Timer0 con periodo de 774,4u segundo.
// Fs = 1291,32 Hz.
//Corrimiento continuo de la seal x[n]
for( i=M-1; i!=0; i-- )x[i]=x[i-1];
//Adquisicin de una muestra de 10 bits en, x[0].
x[0] = (float)(ADC_Read(0)-512.0);
//Convolucin contina.
y0 = 0.0; for( i=0; i<M; i++ ) y0 += h[i]*x[i];
//Reconstruccin de la seal: y en 10 bits.
YY = (unsigned int)(y0+512.0);
PORTC = (YY>>8)&3;
PORTB = YY&255;
PORTC.F7=0;
INTCON.F2=0;
}
}
void main( void )
{
//Inicio del puerto B como salida.
TRISB = 0;
PORTB = 0;
TRISC = 0;
PORTC = 0;
//Se configura el TIMER 0, su interrupcin.
INTCON = 0b10100000;
T0CON = 0b11000101;
while(1)//Bucle infinito.
{
}
}
Por limitaciones de velocidad en este microcontrolador, y teniendo presente la frecuencia de
muestreo de 1291,32Hz no es posible usar un orden del filtro superior a 17. Sin embargo es
posible usar rdenes menores como; 15, 13, 11, 9, 7, 5, o 3. Para fines prcticos y didcticos en
los prximos ejemplos se implementarn filtros de orden 17 igual a este.
207
14.5.2 Ejemplo de diseo para filtro pasa altas
Fs = 1291,32KHz.
Fc = 200Hz.
Ventana Hamming.
Se determina la frecuencia de corte digital:
Wc = 2 Fc / Fs = 2 200 / 1291,32 = 0,97314.
Usando la formula (14.8), se definen los coeficientes de la funcin h(n) multiplicados por la
ventana Hamming w(n) de la ecuacin (14.12), dando como resultado la siguiente funcin h(n):
h(-8)=0
h(-7)=-0.000774581987451374
h(-6)=0.00297591407324525
h(-5)=0.0174357425540551
h(-4)=0.0246447931670207
h(-3)=-0.0148886974624375
h(-2)=-0.118648252092459
h(-1)=-0.243426834227261
h(0)=0.684363125797732
h(1)=-0.260893089082499
h(2)=-0.136977589378571
h(3)=-0.0187342667800403
h(4)=0.0345797805794857
h(5)=0.028555061237806
h(6)=0.00631989035694063
h(7)=-0.00299371636029323
h(8)=-0.00134023946307802
La implementacin del cdigo fuente es igual al filtro pasa bajas, sustituyendo el arreglo h[], por
el siguiente:
const float h[]=
{
0, //h(0)
-0.000774581987451374, //h(1)
0.00297591407324525, //h(2)
0.0174357425540551, //h(3)
0.0246447931670207, //h(4)
-0.0148886974624375, //h(5)
-0.118648252092459, //h(6)
-0.243426834227261, //h(7)
0.684363125797732, //h(8)
-0.260893089082499, //h(9)
-0.136977589378571, //h(10)
-0.0187342667800403, //h(11)
0.0345797805794857, //h(12)
0.028555061237806, //h(13)
208
0.00631989035694063, //h(14)
-0.00299371636029323, //h(15)
-0.00134023946307802 //h(16)
};
14.5.3 Ejemplo de diseo para filtro pasa banda
Fs = 1291,32KHz.
Fc1 = 150Hz.
Fc2 = 400Hz.
Ventana Hanning.
Se determinan las frecuencias de corte digital:
Wc1 = 2 Fc / Fs = 2 150 / 1291,32 = 0,72985.
Wc2 = 2 Fc / Fs = 2 400 / 1291,32 = 1,94628.
Usando la formula (14.9), se definen los coeficientes de la funcin h(n) multiplicados por la
ventana Hanning w(n) de la ecuacin (14.13), dando como resultado la siguiente funcin h(n):
h(-8)=0.0018052104538582
h(-7)=0.00905810215732946
h(-6)=0.00179096961917994
h(-5)=0.00393014193876244
h(-4)=0.0307760790492056
h(-3)=-0.0879236273273945
h(-2)=-0.218010454414228
h(-1)=0.078115497545518
h(0)=0.384167993159943
h(1)=0.0832388331308223
h(2)=-0.248392736747743
h(3)=-0.107904878578323
h(4)=0.0411879382357919
h(5)=0.00583790841302624
h(6)=0.00299868100666665
h(7)=0.0163162389068139
h(8)=0.00250614601893693
La funcin h[], para implementar en el cdigo fuente en lenguaje C es:
const float h[]=
{
0.0018052104538582, //h(0)
0.00905810215732946, //h(1)
0.00179096961917994, //h(2)
0.00393014193876244, //h(3)
0.0307760790492056, //h(4)
-0.0879236273273945, //h(5)
-0.218010454414228, //h(6)
0.078115497545518, //h(7)
209
0.384167993159943, //h(8)
0.0832388331308223, //h(9)
-0.248392736747743, //h(10)
-0.107904878578323, //h(11)
0.0411879382357919, //h(12)
0.00583790841302624, //h(13)
0.00299868100666665, //h(14)
0.0163162389068139, //h(15)
0.00250614601893693 //h(16)
};
14.5.4 Ejemplo de diseo para filtro rechaza banda
Fs = 1291,32KHz.
Fc1 = 150Hz.
Fc2 = 400Hz.
Ventana Blackman.
Se determinan las frecuencias de corte digital:
Wc1 = 2 Fc / Fs = 2 150 / 1291,32 = 0,72985.
Wc2 = 2 Fc / Fs = 2 400 / 1291,32 = 1,94628.
Usando la formula (14.10), se definen los coeficientes de la funcin h(n) multiplicados por la
ventana Blackman w(n) de la ecuacin (14.14), dando como resultado la siguiente funcin h(n):
h(-8)=3.13154095338657E-19
h(-7)=-0.00105084724932717
h(-6)=-0.000518135020348656
h(-5)=-0.00174730211401576
h(-4)=-0.0182611591144528
h(-3)=0.0645431455464317
h(-2)=0.186587834540544
h(-1)=-0.0738928265716166
h(0)=0.604271792109402
h(1)=-0.0827284691705043
h(2)=0.234965429330525
h(3)=0.0923521657912548
h(4)=-0.0302353209611255
h(5)=-0.00346395569934133
h(6)=-0.00133318382487159
h(7)=-0.00472035632958784
h(8)=-0.000290742652784183
La funcin h[], para implementar en el cdigo fuente en lenguaje C es:
const float h[]=
{
3.13154095338657E-19, //h(0)
-0.00105084724932717, //h(1)
210
-0.000518135020348656, //h(2)
-0.00174730211401576, //h(3)
-0.0182611591144528, //h(4)
0.0645431455464317, //h(5)
0.186587834540544, //h(6)
-0.0738928265716166, //h(7)
0.604271792109402, //h(8)
-0.0827284691705043, //h(9)
0.234965429330525, //h(10)
0.0923521657912548, //h(11)
-0.0302353209611255, //h(12)
-0.00346395569934133, //h(13)
-0.00133318382487159, //h(14)
-0.00472035632958784, //h(15)
-0.000290742652784183 //h(16)
};
14.5.5 Ejemplo de diseo para filtro multi banda
Fs = 1291,32KHz.
Fc1 = 161Hz.
Fc2 = 322Hz.
Fc3 = 484Hz.
Fc4 = 645.66Hz.
A1 = 1.
A2 = 0,5.
A3 = 0,2.
A4 = 1.
Ventana Rectangular.
Se determinan las frecuencias de corte digital:
Wc1 = 2 Fc1 / Fs = 2 161 / 1291,32 = 0,78337.
Wc2 = 2 Fc2 / Fs = 2 322 / 1291,32 = 1,56675.
Wc3 = 2 Fc3 / Fs = 2 484 / 1291,32 = 2,355.
Wc4 = 2 Fc4 / Fs = 2 645,66 / 1291,32 = .
Usando la formula (14.11), se definen los coeficientes de la funcin h(n):
h(-8)=-0.000403386658426763
h(-7)=-0.00443133542115946
h(-6)=-0.0685784954060509
h(-5)=0.0330418473673128
h(-4)=-0.000367826230314909
h(-3)=-0.0538949660023408
h(-2)=0.207286062892996
h(-1)=0.0275264614524777
h(0)=0.674596536876994
h(1)=0.0275264614524777
h(2)=0.207286062892996
211
h(3)=-0.0538949660023408
h(4)=-0.000367826230314909
h(5)=0.0330418473673128
h(6)=-0.0685784954060509
h(7)=-0.00443133542115946
h(8)=-0.000403386658426763
La funcin h[], para implementar en el cdigo fuente en lenguaje C es la siguiente:
const float h[]=
{
-0.000403386658426763, //h(0)
-0.00443133542115946, //h(1)
-0.0685784954060509, //h(2)
0.0330418473673128, //h(3)
-0.000367826230314909, //h(4)
-0.0538949660023408, //h(5)
0.207286062892996, //h(6)
0.0275264614524777, //h(7)
0.674596536876994, //h(8)
0.0275264614524777, //h(9)
0.207286062892996, //h(10)
-0.0538949660023408, //h(11)
-0.000367826230314909, //h(12)
0.0330418473673128, //h(13)
-0.0685784954060509, //h(14)
-0.00443133542115946, //h(15)
-0.000403386658426763, //h(16)
};
212
14.6 Filtros IIR
Los filtros IIR, son de implementacin computacional ms simple, pero su diseo y sus clculos
son de mayor complejidad. Para disear un filtro IIR, existen diferentes tcnicas, sin embargo
este captulo se centrar en el diseo por medio de la transformacin bilineal. La transformacin
bilineal es una relacin que existe entre la variable compleja s, y z. Esto quiere decir que para
realizar un filtro IIR, se requiere una funcin de transferencia en trminos de la variable s. En
sntesis para iniciar el diseo de un filtro IIR, se requiere como punto de partida, la funcin de
transferencia de un filtro anlogo. Para fines de estudio en este captulo se mostrarn a
continuacin las funciones de transferencia de los filtros bsicos de segundo orden:
Filtro Pasa Bajas:
2 2
2
2
) (
c c
c
s s
s H
O + O +
O
=
,
Ecuacin 14-15
Filtro Pasa Altas:
2 2
2
2
) (
c c
s s
s
s H
O + O +
=
,
Ecuacin 14-16
Filtro Pasa Banda:
2
0
2
) (
O + O +
O
=
s s
s
s H
B
B
Ecuacin 14-17
Filtro Rechaza Banda:
2
0
2
2
0
2
) (
O + O +
O +
=
s s
s
s H
B
Ecuacin 14-18
Las frecuencias estn definidas en radianes/segundo. Las frecuencias c representan la
frecuencia de corte en los filtros pasa bajas, y altas. Las frecuencias o representan la frecuencia
de resonancia en los filtros pasa banda y rechaza banda. Las frecuencias B representan el ancho
de banda de los filtros pasa banda y rechaza banda. El coeficiente , , representa el
amortiguamiento del filtro, el valor que este coeficiente debe tomar es mayor que 0, cuando el
coeficiente de amortiguamiento vale 0, el filtro se convierte en resonante, y tendra un
comportamiento similar a los filtros pasa banda o rechaza banda. Por otra parte el coeficiente de
amortiguamiento no podr ser negativo, esto generara una funcin de transferencia inestable.
Cabe denotar que la implementacin de filtros IIR, produce en la respuesta de la seal
distorsiones mayores a las que se generan con los filtros FIR.
213
14.6.1 Transformacin bilineal
La transformacin bilineal es una relacin matemtica entre las variables complejas s, y z. Est
relacin se rige por las siguientes ecuaciones:
) 1 (
) 1 ( 2
) 1 (
) 1 ( 2
1
1
1
1
=
+
=
z
z F
z T
z
s
s
s
Ecuacin 14-19
En la ecuacin (14.19), se puede observar la relacin entre las dos variables, donde Ts, y Fs, son
respectivamente el periodo de muestreo y frecuencia de muestreo implementado. De la misma
forma existe una relacin entre las frecuencias del filtro anlogo y el filtro digital, est relacin se
puede apreciar en la siguiente ecuacin:
)
2
tan( 2
)
2
tan( 2
d
s
s
d
w
F
T
w
= = O
Ecuacin 14-20
Donde la frecuencia digital es: Wd, la frecuencia anloga es: , y Ts, Fs, son respectivamente el
periodo de muestreo y la frecuencia de muestreo.
De la misma forma que en los filtros FIR, la relacin entre la frecuencia digital y la frecuencia en
hercios es la siguiente:
) tan( 2
) tan( 2
2
s
x
s
s
s
x
x
s
x
d
F
F
F
T
F
F
F
F
w
t
t
t
= = O =
Ecuacin 14-21
Para contextualizar este proceso, se mostrar a continuacin la transformacin bilineal de los
cuatro filtros bsicos en segundo orden.
14.6.2 Filtro Pasa Bajas IIR
Como primera medida, se realiza el reemplazo de variables en la ecuacin (14.15), para obtener
la funcin h(z):
2
1
1
2
1
1
2
) 1 (
) 1 ( 2
2
) 1 (
) 1 ( 2
) (
c
s
c
s
c
z
z F
z
z F
z H
O +
(
O +
(
O
=
,
2 1 2 1 1 2 1 2
2 1 2
) 1 ( ) 1 )( 1 ( 4 ) 1 ( 4
) 1 (
) (
+ O + + O +
+ O
=
z z z F z F
z
z H
c s c s
c
,
) 2 1 ( ) 1 ( 4 ) 2 1 ( 4
) 2 1 (
) (
2 1 2 2 2 1 2
2 1 2
+ + O + O + +
+ + O
=
z z z F z z F
z z
z H
c s c s
c
,
2 2 2 1 2 2 2 2
2 2 1 2 2
] 4 4 [ ] 8 2 [ ] 4 4 [
2
) (
O + O + O + O + O +
O + O + O
=
z F F z F F F
z z
z H
c s c s s c c s c s
c c c
, ,
214
En este punto se tiene una funcin de transferencia con polinomios ordenados en los polos y los
ceros, de la forma H(z) = A(z)/B(z). Para los polinomios A, B, se tiene en este caso expresiones
de segundo orden con la forma:
2
3
1
2
0
1
) (
+ + = z a z a z a z A ,
2
3
1
2
0
1
) (
+ + = z b z b z b z B .
Despus de tener la funcin de transferencia de esta forma se debe implementar una ecuacin en
diferencias para la ejecucin en la programacin, para deducir la ecuacin en diferencias es
necesario forzar el coeficiente del denominador b1 a valer 1. Para lograr este objetivo todos los
coeficientes a y b se dividen en b1. Est condicin aplicada en la ltima ecuacin del filtro pasa
bajas, da como resultado lo siguiente:
2
2 2
2 2
1
2 2
2 2
2
2 2
2
1
2 2
2
2 2
2
] 4 4 [
] 4 4 [
] 4 4 [
] 8 2 [
1
] 4 4 [ ] 4 4 [
2
] 4 4 [
) (
O + O +
O + O
+
O + O +
O
+
O + O +
O
+
O + O +
O
+
O + O +
O
=
z
F F
F F
z
F F
F
z
F F
z
F F F F
z H
c s c s
c s c s
c s c s
s c
c s c s
c
c s c s
c
c s c s
c
,
,
,
, , ,
La misma ecuacin en trminos de los coeficientes, es de la siguiente forma:
2 2
2 2
3
2 2
2 2
2
1
1 3
1 2
2 2
2
1
2
3
1
2
0
1
2
3
1
2
0
1
4 4
4 4
4 4
8 2
1
2
4 4
, ) (
c s c s
c s c s
c s c s
s c
c s c s
c
F F
F F
b
F F
F
b
b
a a
a a
F F
a
z b z b z b
z a z a z a
z H
O + O +
O + O
=
O + O +
O
=
=
=
=
O + O +
O
=
+ +
+ +
=
,
,
,
,
Para realizar la ecuacin en diferencias se hace la siguiente transformacin de z a n.
) ( * ) ( ) ( * ) ( ) ( ) ( ) ( ) (
) (
) (
) (
) (
) ( n a n x n b n y z A z X z B z Y
z B
z A
z X
z Y
z H = = = =
Realizando la transformacin inversa de z, se tiene una doble convolucin, que genera una
ecuacin de la siguiente forma:
) 2 ( ) 1 ( ) ( ) 2 ( ) 1 ( ) (
2 2 1 3 2 1
+ + = + + n x a n x a n x a n y b n y b n y b
En conclusin la salida y(n) queda de la siguiente manera:
) 2 ( ) 1 ( ) 2 ( ) 1 ( ) ( ) (
3 2 2 2 1
+ + = n y b n y b n x a n x a n x a n y
215
14.6.3 Ejemplo de diseo para filtro pasa bajas
Fs = 1291.32Hz.
Fc = 100Hz.
2
2
= , .
Para el caso particular de los filtros pasa bajas, y pasa altas de segundo orden el valor de , debe
ser
2
2 para que la frecuencia de corte no sufra desplazamientos con respecto a las condiciones
establecidas para los filtros en general.
Para deducir la frecuencia de corte anloga en funcin de las frecuencias reales se usa la ecuacin
(14.21), dando como resultado la siguiente frecuencia de corte:
0154 . 641 )
32 , 1291
100
tan( ) 32 , 1291 ( 2 ) tan( 2 = = = O
t t
s
c
s c
F
F
F
El paso siguiente es remplazar las constantes en las relaciones que determinan los coeficientes a,
y b. Este paso se puede apreciar a continuacin:
6363549 0,50294954
) 0154 , 641 ( ) 32 , 1291 )( 0154 , 641 )(
2
2
( 4 ) 32 , 1291 ( 4
) 0154 , 641 ( ) 32 , 1291 )( 0154 , 641 )(
2
2
( 4 ) 32 , 1291 ( 4
4 4
4 4
0532316 -1,3284348
) 0154 , 641 ( ) 32 , 1291 )( 0154 , 641 )(
2
2
( 4 ) 32 , 1291 ( 4
) 32 , 1291 ( 8 ) 0154 , 641 ( 2
4 4
8 2
1
52600961 0,04362868
05201923 0,08725737 2
52600961 0,04362868
) 0154 , 641 ( ) 32 , 1291 )( 0154 , 641 )(
2
2
( 4 ) 32 , 1291 ( 4
) 154 , 641 (
4 4
, ) (
2 2
2 2
2 2
2 2
3
2 2
2 2
2 2
2 2
2
1
1 3
1 2
2 2
2
2 2
2
1
2
3
1
2
0
1
2
3
1
2
0
1
=
+ +
+
=
O + O +
O + O
=
=
+ +
=
O + O +
O
=
=
= =
= =
=
+ +
=
O + O +
O
=
+ +
+ +
=
c s c s
c s c s
c s c s
s c
c s c s
c
F F
F F
b
F F
F
b
b
a a
a a
F F
a
z b z b z b
z a z a z a
z H
,
,
,
,
La implementacin de un filtro IIR, de orden N, requiere un bfer de datos igual a: 2(N+1). En el
caso de un filtro de segundo orden se requieren 3 campos para guardar los ltimos valores de la
entrada x, y 3 campos ms para los 3 ltimos valores de la salida y. Para ilustrar la
implementacin de este proceso se usar la misma arquitectura de software y hardware
implementada en los filtros FIR. A continuacin se puede observar el siguiente ejemplo en
lenguaje C:
//Declaracin de varales.
float x0=0, x1=0, x2=0, y0=0, y1=0, y2=0;
216
unsigned int YY;
//Declaracin de la funcin de interrupciones.
void interrupt ( void )
{
if( INTCON.F2 )
{
TMR0L=135;
//Timer0 con periodo de 774,4u segundo.
// Fs = 1291,32 Hz.
//Adquisicin de una muestra de 10 bits en, x[0].
x0 = (float)(ADC_Read(0)-512.0);
//Implementacin de la ecuacin en diferencias.
y0 = (x0+x2)*0.0436286852600961 + x1*0.0872573705201923 + y1*1.32843480532316
-y2*0.502949546363549;
//Corrimiento de los valores x(n), y y(n).
y2 = y1;
y1 = y0;
x2 = x1;
x1 = x0;
//Reconstruccin de la seal: y en 10 bits.
YY = (unsigned int)(y0+512.0);
PORTC = (YY>>8)&3;
PORTB = YY&255;
INTCON.F2=0;
}
}
void main( void )
{
//Inicio del puerto B como salida.
TRISB = 0;
PORTB = 0;
TRISC = 0;
PORTC = 0;
//Se configura el TIMER 0, su interrupcin.
INTCON = 0b10100000;
T0CON = 0b11000101;
while(1)//Bucle infinito.
{
}
}
14.6.4 Filtro Pasa Altas IIR
De la misma forma que se hizo en el filtro pasa bajas, se realiza el reemplazo de variable en la
ecuacin (14.16), para obtener la funcin h(z):
217
2
1
1
2
1
1
2
1
1
) 1 (
) 1 ( 2
2
) 1 (
) 1 ( 2
) 1 (
) 1 ( 2
) (
c
s
c
s
s
z
z F
z
z F
z
z F
z H
O +
(
O +
(
,
2 1 2 1 1 2 1 2
2 1 2
) 1 ( ) 1 )( 1 ( 4 ) 1 ( 4
) 1 ( 4
) (
+ O + + O +
=
z z z F z F
z F
z H
c s c s
s
,
) 2 1 ( ) 1 ( 4 ) 2 1 ( 4
) 2 1 ( 4
) (
2 1 2 2 2 1 2
2 1 2
+ + O + O + +
+
=
z z z F z z F
z z F
z H
c s c s
s
,
2 2 2 1 2 2 2 2
2 2 1 2 2
] 4 4 [ ] 8 2 [ ] 4 4 [
4 8 4
) (
O + O + O + O + O +
+
=
z F F z F F F
z F z F F
z H
c s c s s c c c s
s s s
, ,
Realizando la normalizacin de los coeficientes se obtiene lo siguiente:
2
2 2
2 2
1
2 2
2 2
2
2 2
2
1
2 2
2
2 2
2
4 4
4 4
4 4
8 2
1
4 4
4
4 4
8
4 4
4
) (
O + O +
O + O
+
O + O +
O
+
O + O +
+
O + O +
O + O +
=
z
F F
F F
z
F F
F
z
F F
F
z
F F
F
F F
F
z H
c s c s
c s c s
c s c s
s c
c s c s
s
c s c s
s
c s c s
s
,
,
,
, , ,
De est forma los coeficientes a, y b quedan definidos as:
2 2
2 2
3
2 2
2 2
2
1
1 3
1 2
2 2
2
1
2
3
1
2
0
1
2
3
1
2
0
1
4 4
4 4
4 4
8 2
1
2
4 4
4
, ) (
c s c s
c s c s
c s c s
s c
c s c s
s
F F
F F
b
F F
F
b
b
a a
a a
F F
F
a
z b z b z b
z a z a z a
z H
O + O +
O + O
=
O + O +
O
=
=
=
=
O + O +
=
+ +
+ +
=
,
,
,
,
14.6.5 Ejemplo de diseo para filtro pasa altas
Fs = 1291.32Hz.
Fc = 200Hz.
218
2
2
= , .
Se determina la frecuencia de corte anloga en trminos de la frecuencia digital:
19404 , 1366 )
32 , 1291
200
tan( ) 32 , 1291 ( 2 ) tan( 2 = = = O
t t
s
c
s c
F
F
F
Seguidamente se determinan los coeficientes del filtro:
7215126 0,26212340
) 19404 , 1366 ( ) 32 , 1291 )( 19404 , 1366 )(
2
2
( 4 ) 32 , 1291 ( 4
) 19404 , 1366 ( ) 32 , 1291 )( 19404 , 1366 )(
2
2
( 4 ) 32 , 1291 ( 4
4 4
4 4
43923452 -0,7099519
) 19404 , 1366 ( ) 32 , 1291 )( 19404 , 1366 )(
2
2
( 4 ) 32 , 1291 ( 4
) 32 , 1291 ( 8 ) 19404 , 1366 ( 2
4 4
8 2
1
7784645 0,49301883
75569289 -0,9860376 2
7784645 0,49301883
) 19404 , 1366 ( ) 32 , 1291 )( 19404 , 1366 )(
2
2
( 4 ) 32 , 1291 ( 4
) 32 , 1291 ( 4
4 4
4
, ) (
2 2
2 2
2 2
2 2
3
2 2
2 2
2 2
2 2
2
1
1 3
1 2
2 2
2
2 2
2
1
2
3
1
2
0
1
2
3
1
2
0
1
=
+ +
+
=
O + O +
O + O
=
=
+ +
=
O + O +
O
=
=
= =
= =
=
+ +
=
O + O +
=
+ +
+ +
=
c s c s
c s c s
c s c s
s c
c s c s
s
F F
F F
b
F F
F
b
b
a a
a a
F F
F
a
z b z b z b
z a z a z a
z H
,
,
,
,
La programacin de este filtro pasa altas, bajo las mismas condiciones del filtro pasa bajas es el
siguiente:
//Declaracin de varales.
float x0=0, x1=0, x2=0, y0=0, y1=0, y2=0;
unsigned int YY;
//Declaracin de la funcin de interrupciones.
void interrupt ( void )
{
if( INTCON.F2 )
{
TMR0L=135;
//Timer0 con periodo de 774,4u segundo.
// Fs = 1291,32 Hz.
//Adquisicin de una muestra de 10 bits en, x[0].
x0 = (float)(ADC_Read(0)-512.0);
//Implementacin de la ecuacin en diferencias.
y0 = (x0+x2)*0.493018837784645 - x1*0.986037675569289 +
y1*0.709951943923452 - y2*0.262123407215126;
//Corrimiento de los valores x(n), y y(n).
219
y2 = y1;
y1 = y0;
x2 = x1;
x1 = x0;
//Reconstruccin de la seal: y en 10 bits.
YY = (unsigned int)(y0+512.0);
PORTC = (YY>>8)&3;
PORTB = YY&255;
INTCON.F2=0;
}
}
void main( void )
{
//Inicio del puerto B como salida.
TRISB = 0;
PORTB = 0;
TRISC = 0;
PORTC = 0;
//Se configura el TIMER 0, su interrupcin.
INTCON = 0b10100000;
T0CON = 0b11000101;
while(1)//Bucle infinito.
{
}
}
14.6.6 Filtro Pasa Banda IIR
Para la funcin de transferencia h(z) en el filtro pasa banda se realiza el cambio de variable
bilineal, tomando como base la ecuacin (14.17):
2
0 1
1
2
1
1
1
1
) 1 (
) 1 (
2
) 1 (
) 1 (
2
) 1 (
) 1 (
2
) (
O +
(
O +
(
O
(
z
z
F
z
z
F
z
z
F
z H
s B s
B s
2 1 2
0
1 1 2 1 2
1 1
) 1 ( ) 1 )( 1 ( 2 ) 1 ( 4
) 1 )( 1 ( 2
) (
+ O + + O +
+ O
=
z z z F z F
z z F
z H
B s s
B s
) 2 1 ( ) 1 ( 2 ) 2 1 ( 4
) 1 ( 2
) (
2 1 2
0
2 2 1 2
2
+ + O + O + +
O
=
z z z F z z F
z F
z H
B s s
B s
2 2
0
2 1 2
0
2
0
2
2
] 2 4 [ ] 2 2 [ ] 2 4 [
2 2
) (
O + O + O O + O + O +
O O
=
z F F z F F F
z F F
z H
B s s B s B s s
B s B s
220
Normalizando la ecuacin se obtiene la siguiente relacin:
2
2
0
2
2
0
2
1
2
0
2
2
0
2
2
0
2 2
0
2
2 4
2 4
2 4
2 2
1
2 4
2
2 4
2
) (
O + O +
O + O
+
O + O +
O O
+
O + O +
O
O + O +
O
=
z
F F
F F
z
F F
F
z
F F
F
F F
F
z H
B s s
B s s
B s s
B s
B s s
B s
B s s
B s
De la anterior ecuacin, se pueden estblecer las siguientes constantes:
2
0
2
2
0
2
3
2
0
2
2
0
2
1
1 3
2
2
0
2 1
2
3
1
2
0
1
2
3
1
2
0
1
2 4
2 4
2 4
2 2
1
0
2 4
2
, ) (
O + O +
O + O
=
O + O +
O O
=
=
=
=
O + O +
O
=
+ +
+ +
=
B s s
B s s
B s s
B s
B s s
B s
F F
F F
b
F F
F
b
b
a a
a
F F
F
a
z b z b z b
z a z a z a
z H
14.6.7 Ejemplo de diseo para filtro pasa banda
Fs = 1291.32Hz.
Fo = 300Hz.
Fb = 10Hz.
A continuacin se determinan las frecuencias anlogas para el diseo del filtro pasa banda:
58 , 2310 )
32 , 1291
300
tan( ) 32 , 1291 ( 2 ) tan( 2
0
0
= = = O
t t
s
s
F
F
F
8442 , 62 )
32 , 1291
10
tan( ) 32 , 1291 ( 2 ) tan( 2 = = = O
t t
s
b
s B
F
F
F
Posteriormente se determinan los coeficientes del filtro:
221
1725574 0.97332963
) 58 , 2310 ( ) 8442 , 62 )( 32 , 1291 ( 2 ) 32 , 1291 ( 4
) 58 , 2310 ( ) 8442 , 62 )( 32 , 1291 ( 2 ) 32 , 1291 ( 4
2 4
2 4
04098491 -0.2187550
) 58 , 2310 ( ) 8442 , 62 )( 32 , 1291 ( 2 ) 32 , 1291 ( 4
) 8442 , 62 )( 32 , 1291 ( 2 ) 58 , 2310 ( 2
2 4
2 2
1
841372129 -0.0133351
0
41372129 0.01333518
) 58 , 2310 ( ) 8442 , 62 )( 32 , 1291 ( 2 ) 32 , 1291 ( 4
) 8442 , 62 )( 32 , 1291 ( 2
2 4
2
, ) (
2 2
2 2
2
0
2
2
0
2
3
2 2
2
2
0
2
2
0
2
1
1 3
2
2 2 2
0
2 1
2
3
1
2
0
1
2
3
1
2
0
1
=
+ +
+
=
O + O +
O + O
=
=
+ +
=
O + O +
O O
=
=
= =
=
=
+ +
=
O + O +
O
=
+ +
+ +
=
B s s
B s s
B s s
B s
B s s
B s
F F
F F
b
F F
F
b
b
a a
a
F F
F
a
z b z b z b
z a z a z a
z H
14.6.8 Filtro Rechaza Banda IIR
Para la funcin de transferencia h(z) en el filtro pasa banda se realiza el cambio de variable
bilineal, tomando como base la ecuacin (14.17):
2
0 1
1
2
1
1
2
0
2
1
1
) 1 (
) 1 (
2
) 1 (
) 1 (
2
) 1 (
) 1 (
2
) (
O +
(
O +
(
O +
(
z
z
F
z
z
F
z
z
F
z H
s B s
s
2 1 2
0
1 1 2 1 2
2 1 2
0
2 1 2
) 1 ( ) 1 )( 1 ( 2 ) 1 ( 4
) 1 ( ) 1 ( 4
) (
+ O + + O +
+ O +
=
z z z F z F
z z F
z H
B s s
s
) 2 1 ( ) 1 ( 2 ) 2 1 ( 4
) 2 1 ( ) 2 1 ( 4
) (
2 1 2
0
2 2 1 2
2 1 2
0
2 1 2
+ + O + O + +
+ + O + +
=
z z z F z z F
z z z z F
z H
B s s
s
2 2
0
2 1 2 2
0
2
0
2
2 2
0
2 1 2 2
0
2
0
2
] 2 4 [ ] 8 2 [ ] 2 4 [
] 4 [ ] 8 2 [ ] 4 [
) (
O + O + O + O + O +
O + + O + O +
=
z F F z F F F
z F z F F
z H
B s s s B s s
s s s
Normalizando la ecuacin se obtiene la siguiente relacin:
2
2
0
2
2
0
2
1
2
0
2
2 2
0
2
2
0
2
2
0
2
1
2
0
2
2 2
0
2
0
2
2
0
2
2 4
2 4
2 4
8 2
1
2 4
4
2 4
8 2
2 4
4
) (
O + O +
O + O
+
O + O +
O
+
O + O +
O +
+
O + O +
O
+
O + O +
O +
=
z
F F
F F
z
F F
F
z
F F
F
z
F F
F
F F
F
z H
B s s
B s s
B s s
s
B s s
s
B s s
s
B s s
s
De la anterior ecuacin, se pueden estblecer las siguientes constantes:
222
2
0
2
2
0
2
3
2
0
2
2 2
0
2
1
1 3
2
0
2
2 2
0
2
2
0
2
2
0
2
1
2
3
1
2
0
1
2
3
1
2
0
1
2 4
2 4
2 4
8 2
1
2 4
8 2
2 4
4
, ) (
O + O +
O + O
=
O + O +
O
=
=
=
O + O +
O
=
O + O +
O +
=
+ +
+ +
=
B s s
B s s
B s s
s
B s s
s
B s s
s
F F
F F
b
F F
F
b
b
a a
F F
F
a
F F
F
a
z b z b z b
z a z a z a
z H
14.6.9 Ejemplo de diseo filtro rechaza banda
Fs = 1291.32Hz.
Fo = 100Hz.
Fb = 10Hz.
A continuacin se determinan las frecuencias anlogas para el diseo del filtro rechaza banda:
015 , 641 )
32 , 1291
100
tan( ) 32 , 1291 ( 2 ) tan( 2
0
0
= = = O
t t
s
s
F
F
F
8442 , 62 )
32 , 1291
10
tan( ) 32 , 1291 ( 2 ) tan( 2 = = = O
t t
s
b
s B
F
F
F
Posteriormente se determinan los coeficientes del filtro:
, ) (
2
3
1
2
0
1
2
3
1
2
0
1
+ +
+ +
=
z b z b z b
z a z a z a
z H
223
901547 0.95518463
) 015 , 641 ( ) 8442 , 62 )( 32 , 1291 ( 2 ) 32 , 1291 ( 4
) 015 , 641 ( ) 8442 , 62 )( 32 , 1291 ( 2 ) 32 , 1291 ( 4
2 4
2 4
6958352 -1.7282689
1
9507735 0,97759231
6958352 -1.7282689
) 015 , 641 ( ) 8442 , 62 )( 32 , 1291 ( 2 ) 32 , 1291 ( 4
) 32 , 1291 ( 8 ) 015 , 641 ( 2
2 4
8 2
9507735 0,97759231
) 015 , 641 ( ) 8442 , 62 )( 32 , 1291 ( 2 ) 32 , 1291 ( 4
) 015 , 641 ( ) 32 , 1291 ( 4
2 4
4
2 2
2 2
2
0
2
2
0
2
3
2 2
1
1 3
2 2
2 2
2
0
2
2 2
0
2
2 2
2 2
2
0
2
2
0
2
1
=
+ +
+
=
O + O +
O + O
=
= =
=
= =
=
+ +
=
O + O +
O
=
=
+ +
+
=
O + O +
O +
=
B s s
B s s
B s s
s
B s s
s
F F
F F
b
a b
b
a a
F F
F
a
F F
F
a
El cdigo fuente en lenguaje C, correspondiente a este diseo es el siguiente:
//Declaracin de varales.
float x0=0, x1=0, x2=0, y0=0, y1=0, y2=0;
unsigned int YY;
//Declaracin de la funcin de interrupciones.
void interrupt ( void )
{
if( INTCON.F2 )
{
TMR0L=135;
//Timer0 con periodo de 774,4u segundo.
// Fs = 1291,32 Hz.
//Adquisicin de una muestra de 10 bits en, x[0].
x0 = (float)(ADC_Read(0)-512.0);
//Implementacin de la ecuacin en diferencias.
y0 = (x0+x2)*0.977592319507735 + (y1-x1)*1.72826896958352 - y2*0.95518463901547;
//Corrimiento de los valores x(n), y y(n).
y2 = y1;
y1 = y0;
x2 = x1;
x1 = x0;
//Reconstruccin de la seal: y en 10 bits.
YY = (unsigned int)(y0+512.0);
PORTC = (YY>>8)&3;
PORTB = YY&255;
INTCON.F2=0;
}
}
void main( void )
{
//Inicio del puerto B como salida.
TRISB = 0;
224
PORTB = 0;
TRISC = 0;
PORTC = 0;
//Se configura el TIMER 0, su interrupcin.
INTCON = 0b10100000;
T0CON = 0b11000101;
while(1)//Bucle infinito.
{
}
}
14.7 Osciladores digitales
Generar una seal seno de forma sinttica, implica usar una matriz de rotacin que incluye dos
valores de salida de la seal y dos valores pasados, de la misma. La forma general de est matriz
se puede apreciar a continuacin:
(
=
(
) 1 (
) 1 (
) (
) (
n x
n y
d c
b a
n x
n y
Los clculos de la matriz de rotacin, permiten crear osciladores de 2 salidas que pueden tener
amplitud equitativa o no y salida en cuadratura o no, as como el nmero de multiplicaciones
requeridas por iteracin. Estas condiciones se resumen en la siguiente tabla:
Propiedades de los osciladores recursivos
Oscilador
Multiplicaciones
por iteracin
Amplitud
equitativa
Salida en
cuadratura
Factores Matriz de rotacin
Doble
cuadrado
2 Si No k=2Cos()
(
0 1
1 k
De acople
en
cuadratura
estndar
4 Si Si k=sen()
(
(
2
2
1
1
k k
k k
Tabla 14-1
Para iniciar el diseo de un oscilador o generador digital se debe definir el valor de la constante k,
y por defecto, el valor del ngulo , este se define por medio de la siguiente ecuacin:
s
g
F
F t
u
2
=
Ecuacin 14-22
225
Donde Fg es la frecuencia en hercios de la seal que se desea generar, y Fs es la frecuencia de
muestreo en hercios. La implementacin de estos generadores siempre usa la misma forma de
operaciones matemticas, que es la siguiente:
) 1 ( ) 1 ( ) (
) 1 ( ) 1 ( ) (
+ =
+ =
n dx n cy n x
n bx n ay n y
Para que el oscilador arranque correctamente es importante dar valores iniciales a las salidas y1, y
y2. Por obvias razones los osciladores de mayor velocidad son los que solo requieren de una
multiplicacin por iteracin.
14.7.1 Ejemplo de diseo oscilador doble cuadrado
Fs = 1291,32Hz.
Fg = 100Hz.
El valor del ngulo , es el que se calcula a continuacin:
4865707421 , 0
32 , 1291
100 2
2
= = =
t
t
u
s
g
F
F
Con el valor se puede calcular el valor de k, que es el siguiente:
k=2Cos(0,4865707421) = 1,76788313
De est manera se tiene la siguiente matriz de rotacin:
(
0 1
1 1,76788313
Las ecuaciones de implementacin son las siguientes:
) 1 ( ) (
) 1 ( ) 1 ( 1,76788313 ) (
=
+ =
n y n x
n x n y n y
Las mismas funciones en trminos de solo la salida y es igual a la siguiente ecuacin:
) 2 ( ) 1 ( 1,76788313 ) ( + = n y n y n y
La condicin para el funcionamiento de este oscilador es que la magnitud de la seal debe ser 1.
Otra condicin para el funcionamiento adecuado de este oscilador es dar valores iniciales a las
salidas y(n-1), y y(n-2), las cuales se pueden iniciar de la siguiente forma:
y(n-1) = Cos(-) = Cos(-0,4865707421).
y(n-2) = Cos(-2 ) = Cos(-2(0,4865707421)).
Para manipular la amplitud se debe multiplicar la salida y(n), por el factor deseado.
226
Para fines de simulacin, se implementarn las mismas condiciones del hardware usado en los
filtros FIR, e IIR, omitiendo el generador de onda seno que se conecta a la entrada anloga.
Teniendo presente las anteriores observaciones se puede implementar el siguiente cdigo fuente
en lenguaje C, para simular este ejemplo:
//Declaracin de varales inicializadas.
float y0, y1=1.0, y2=0.883941565;
unsigned int YY;
//Declaracin de la funcin de interrupciones.
void interrupt ( void )
{
if( INTCON.F2 )
{
TMR0L=135;
//Timer0 con periodo de 774,4u segundo.
// Fs = 1291,32 Hz.
//Implementacin de la ecuacin del oscilador.
y0 = 1.76788313*y1 - y2;
//Se hace el corrimiento de la salida.
y2 = y1;
y1 = y0;
//Reconstruccin de la seal: y en 10 bits, amplificada 500 veces.
YY = (unsigned int)(500*y0+512.0);
PORTC = (YY>>8)&3;
PORTB = YY&255;
INTCON.F2=0;
}
}
void main( void )
{
//Inicio del puerto B como salida.
TRISB = 0;
PORTB = 0;
TRISC = 0;
PORTC = 0;
//Se configura el TIMER 0, su interrupcin.
INTCON = 0b10100000;
T0CON = 0b11000101;
while(1)//Bucle infinito.
{
}
}
14.7.2 Ejemplo de diseo para oscilador de acople en cuadratura
Fs = 1291,32Hz.
Fg = 150Hz.
A = 450.
227
Se calcula el ngulo de paso :
7298561132 , 0
32 , 1291
150 2
2
= = =
t
t
u
s
g
F
F
Posteriormente se calculan las constantes de la matriz:
. 6667624073 , 0 ) (
. 7452703484 , 0 )] 7298561132 , 0 ( [ 1 )] ( [ 1
2 2
= = =
= = = =
u
u
sen c b
sen sen d a
El patrn de la matriz de rotacin es el siguiente:
(
7452703484 , 0 6667624073 , 0
6667624073 , 0 7452703484 , 0
El juego de ecuaciones que rigen las iteraciones del oscilador son las siguientes:
) 1 ( 7452703484 , 0 ) 1 ( 6667624073 , 0 ) (
) 1 ( 6667624073 , 0 ) 1 ( 7452703484 , 0 ) (
+ =
+ =
n x n y n x
n x n y n y
Para dar inicio correcto al oscilador se deben dar valores iniciales a las salidas retardadas y(n-1),
y x(n-1), para este fin se debe tener presente que este oscilador tiene las dos salidas en cuadratura,
es decir que entre las dos salidas siempre existe un desfase de 90 grados. Bajo este concepto se
puede concluir que las dos seales en cuadratura tendrn la misma magnitud a 3/4, de est
manera se asignan los siguientes valores iniciales:
y(n-1) = x(n-1) = ASen(3/4),
y(n-1) = x(n-1) = 450Sen(3/4) = 318,1980515.
Finalmente se implementa, el cdigo fuente en lenguaje C, para este oscilador:
//Declaracin de varales inicializadas.
float y0, y1=318.1980515, x0, x1=318.1980515;
unsigned int YY;
//Declaracin de la funcin de interrupciones.
void interrupt ( void )
{
if( INTCON.F2 )
{
TMR0L=135;
//Timer0 con periodo de 774,4u segundo.
// Fs = 1291,32 Hz.
//Implementacin de las ecuaciones del oscilador.
y0 = 0.7452703484*y1 + 0.6667624073*x1;
x0 = -0.6667624073*y1 + 0.7452703484*x1;
//Se hace el corrimiento de la salida.
228
y1 = y0;
x1 = x0;
//Reconstruccin de la seal: y en 10 bits.
YY = (unsigned int)(y0+512.0);
PORTC = (YY>>8)&3;
PORTB = YY&255;
INTCON.F2=0;
}
}
void main( void )
{
//Inicio del puerto B como salida.
TRISB = 0;
PORTB = 0;
TRISC = 0;
PORTC = 0;
//Se configura el TIMER 0, su interrupcin.
INTCON = 0b10100000;
T0CON = 0b11000101;
while(1)//Bucle infinito.
{
}
}
14.8 Transformada discreta de Fourier DFT
La transformacin de Fourier es un procedimiento matemtico que permite analizar las
componentes espectrales y la intensidad de potencia de una seal anloga, o discreta. Las
aplicaciones de este procedimiento son numerosas en las que se pueden nombrar: Analizadores
de espectro, reconocimiento de patrones, en seales, de comunicaciones, biomdicas, y audio,
entre otras. La transformada de Fourier, es una temtica sumamente densa, sin embargo este
captulo busca mostrar de forma simple la implementacin de est herramienta. La transformada
discreta de Fourier o DTF, est definida por la siguiente ecuacin:
=
1
0
) ( ) (
L
n
jwn
e n x jw X
Ecuacin 14-23
Como se puede apreciar en la anterior ecuacin la potencia de una frecuencia w, se puede evaluar
en un fragmento de seal de longitud L, de igual manera se puede notar que los valores
resultantes de la funcin X(jw), son nmeros complejos, por est razn los anlisis de Fourier se
hacen por excelencia en trminos de la magnitud de estos nmeros complejos. La ecuacin
(15.23) en trminos de un nmero complejo rectangular es la siguiente:
=
=
1
0
)] ( ) )[cos( ( ) (
L
n
wn jsen wn n x jw X
Ecuacin 14-24
229
De est forma la relacin X(jw), puede ser pasada a la magnitud de s misma como |X(jw)|, y su
relacin matemtica es la siguiente:
2
1
0
2
1
0
) ( ) ( ) cos( ) ( | ) ( |
(
+
(
=
=
=
L
n
L
n
wn sen n x wn n x jw X
Ecuacin 14-25
Est ecuacin matemtica permite evaluar la potencia, o la intensidad de la componente w, dentro
de la muestra x(n), de longitud L.
Un fragmento de cdigo en lenguaje C, que realice est operacin se puede implementar con una
funcin como la siguiente:
//Funcin para determinar la intensidad de potencia
//de la componente w, en la seal x_n.
float TDF( float *x_n, float w, unsigned int L )
{
//Declaracion de variables.
unsigned int n;
float R=0.0, I=0.0;
//Bucle for para realizar las sumatorias.
for( n=0; n<L; n++ )
{
//Clculo y sumatoria de los componentes
//reales e imaginarios.
R += cos( w*n );
I += sin( w*n );
}
//Se retorna el valor de la magnitud del
// nmero complejo.
return sqrt( R*R + I*I );
}
El siguiente ejemplo implementa un programa que permite detectar la presencia de tres
frecuencias diferentes en una seal anloga, por medio de la transformada de Fourier. Como
primera medida se definen las tres frecuencias anlogas y sus respectivas frecuencias digitales,
F1=100Hz, F2=200Hz, y F3=300Hz, la frecuencia de muestreo se define de 1291,32Hz, con el
fin de implementar la misma estructura del microcontrolador 18F452, que se us en los filtros
FIR, e IIR.
459712226 , 1
32 . 1291
300 2
9731414842 , 0
32 . 1291
200 2
1 4865770742 , 0
32 . 1291
100 2
3
2
1
= =
= =
= =
t
t
t
W
W
W
230
Para realizar la transformada de Fourier, se usar la funcin antes citada. Una salida del
microcontrolador se activa cuando se detecta la potencia suficiente de la componente espectral.
La seal es adquirida por una entrada anloga del PIC, la cual es la suma de tres fuentes
diferentes. El programa correspondiente para este ejercicio es el siguiente:
//Declaracin de varales inicializadas.
float x[64];
unsigned short i, OK=1;
//Declaracin de la funcin de interrupciones.
//Funcin para determinar la intensidad de potencia
//de la componente w, en la seal x_n.
float TDF( float *x_n, float w, unsigned int L )
{
//Declaracin de variables.
unsigned short n;
float R=0.0, I=0.0;
//Bucle for para realizar las sumatorias.
for( n=0; n<L; n++ )
{
//Clculo y sumatoria de los componentes
//reales e imaginarios.
R += x_n[n]*cos( w*n );
I += x_n[n]*sin( w*n );
}
//Se retorna el valor de la magnitud del
// nmero complejo.
return sqrt( R*R + I*I );
}
void interrupt ( void )
{
if( INTCON.F2 )
{
TMR0L=135;
//Timer0 con periodo de 774,4u segundo.
// Fs = 1291,32 Hz.
if( OK ) //Se evala la adquisicin de muestras.
{
OK++; //Se cuentan las muestras tomadas.
//Se corren las ltimas 64 muestras en el bufer x.
for( i=63; i!=0; i-- )x[i]=x[i-1];
//Se guarda la ltima muestra.
x[0] = ((float)ADC_Read(0)-512.0);
}
INTCON.F2=0;
}
}
231
void main( void )
{
float RES1, RES2, RES3;
//Inicio del puerto B como salida.
TRISB = 0;
PORTB = 0;
//Se configura el TIMER 0, su interrupcin.
INTCON = 0b10100000;
T0CON = 0b11000101;
while(1)//Bucle infinito.
{
while( OK<65 );//Se espera a recibir 64 muestras.
OK =0; //Se suspenden la adquisicin de muestras.
//Se hace la transformada de Fourier, de la componente de 100Hz.
RES1 = TDF( x, 0.4865707421, 64 );
//Se hace la transformada de Fourier, de la componente de 200Hz.
RES2 = TDF( x, 0.9731414842, 64 );
//Se hace la transformada de Fourier, de la componente de 300Hz.
RES3 = TDF( x, 1.459712226, 64 );
OK=1; //Se activa la adquisicin de muestras.
//Se evala la potencia de la seal de 100Hz.
if( RES1>800 )PORTB.F2=1; else PORTB.F2=0;
//Se evalua la potencia de la seal de 200Hz.
if( RES2>800 )PORTB.F1=1; else PORTB.F1=0;
//Se evala la potencia de la seal de 300Hz.
if( RES3>800 )PORTB.F0=1; else PORTB.F0=0;
}
}
Para realizar la simulacin de este ejercicio se implementa en ISIS, los dispositivos: 18F452,
RES, CAP, OP1P, BUTTON, LED-RED, y generador virtual. El circuito correspondiente para
est simulacin es el siguiente:
Circuito 14-2
232
La transformada de Fourier, implica mltiples clculos matemticos, como sumas,
multiplicaciones y evaluaciones trigonomtricas. Estos procesos hacen lento el rendimiento de la
mquina de proceso. Por esta razn la ciencia de tratamiento de seales, se vio en la necesidad de
buscar tcnicas de realizar la transformada de Fourier de forma mucho ms eficiente, de este
esfuerzo, sale como resultado notable el algoritmo de transformacin rpida de Fourier, o FFT.
Este algoritmo se fundamenta en la divisin en segmentos cortos para realizar la evaluacin de la
transformada de Fourier.
14.8.1 Transformada rpida de Fourier FFT
La transformada rpida de Fourier, organiza en una matriz las muestras de entrada y realiza
trasformadas ms pequeas en las filas y posteriormente en las columnas. Las muestras
digitalizadas de la seal anloga se pueden representar de la siguiente forma:
x(0), x(1), x(2), x(3), x(4), x(5),.x(N)
Donde N es el nmero mximo de muestras que se desean analizar.
Las muestras son organizadas en una matriz de L filas, con M columnas. En la siguiente matriz se
puede apreciar el almacenamiento por columnas:
(
(
(
(
=
) 15 ( ) 11 ( ) 7 ( ) 3 (
) 14 ( ) 10 ( ) 6 ( ) 2 (
) 13 ( ) 9 ( ) 5 ( ) 1 (
) 12 ( ) 8 ( ) 4 ( ) 0 (
) , (
x x x x
x x x x
x x x x
x x x x
m l x
Seguidamente se debe realizar la transformacin por filas, haciendo la trasformada de M
muestras. Est operacin se realiza en funcin de la siguiente ecuacin:
| |
)
2
( )
2
cos(
) 1 ( 0
) 1 ( 0
) , ( ) , (
2
1
0
M
mq
jsen
M
mq
e W
M q
L l
W m l x q l F
M
mq
j
mq
M
M
m
mq
M
t t
t
= =
s s
s s
=
Ecuacin 14-26
La matriz F(l,q), es un arreglo de valores complejos correspondiente a las transformadas de M,
puntos sobre cada una de las filas. Seguidamente la matriz F(l,q), se multiplica por los factores de
fase Wn, est operacin se define en la siguiente ecuacin:
)
2
( )
2
cos(
) 1 ( 0
) 1 ( 0
) , ( ) , (
2
N
lq
jsen
N
lq
e W
M q
L l
q l F W q l G
N
lq
j
lq
N
lq
N
t t
t
= =
s s
s s
=
Ecuacin 14-27
233
Por ltimo se realiza la trasformada por columnas de L muestras. Est operacin se resume en la
siguiente ecuacin:
| |
)
2
( )
2
cos(
) 1 ( 0
) 1 ( 0
) , ( ) , (
2
1
0
L
lp
jsen
L
lp
e W
M q
L p
W q l G q p X
L
lp
j
lp
L
L
l
lp
L
t t
t
= =
s s
s s
=
Ecuacin 14-28
La matriz X(p,q), es la transformada final de las N muestras iniciales. Est matriz contiene en
cada uno de sus trminos un nmero complejo que representa la magnitud y la fase de las
componentes espectrales. La matriz X(p,q), se debe leer por filas, como se aprecia en la siguiente
matriz:
(
(
(
(
=
) 15 ( ) 14 ( ) 13 ( ) 12 (
) 11 ( ) 10 ( ) 9 ( ) 8 (
) 7 ( ) 6 ( ) 5 ( ) 4 (
) 3 ( ) 2 ( ) 1 ( ) 0 (
) , (
X X X X
X X X X
X X X X
X X X X
q p X
Cabe denotar que entre ms muestras se ingresen para hacer la transformacin, mayor ser la
resolucin en el espectro, pero a su vez mayor ser la cantidad de recursos de procesamiento y de
memoria requeridos. A continuacin se resume el proceso antes citado:
- Se archiva la seal de x(n), por columnas en la matriz x(l,m).
- Se calcula la transformada de M muestras de cada una de las filas.
- Se multiplican las anteriores transformadas por el factor de fase Wn.
- Se calcula la transformada de L muestras de cada una de las columnas.
- Se leen los datos de la matriz X(p,q), por filas.
El resultado de una transformada de Fourier, entrega un espectro evaluado de 0 a 2, lo que
significa que los valores superiores a , son un espejo de las componentes inferiores causadas por
los armnicos de las frecuencias inferiores a . En conclusin la lectura de la matriz solo se debe
hacer hasta la mitad, por ejemplo si la cantidad de muestras analizadas son 128, solo se deben
leer 64. De la misma manera la resolucin de la transformacin en hercios est definida por la
siguiente ecuacin:
N
F
R
s
Hz
=
Ecuacin 14-29
Donde R, es la resolucin en hercios, o el mnimo ancho de banda que se puede analizar con la
FFT. Fs es la frecuencia de muestreo, y N es el nmero de muestras ingresadas a la FFT.
Tambin cabe denotar que la primera muestra de la FFT, hace alusin a la componente espectral
ms baja incluida la frecuencia 0, o en otras palabras los niveles DC. Ests componentes son las
ms intensas, y para fines prcticos est primera muestra puede ser ignorada.
234
Para realizar un ejemplo con la FFT, se implementar el PIC 18F4585, dada su amplia memoria
RAM de 3328 Bytes, til para los procesos de la FFT. Sin embargo est capacidad de memoria
solo permite hacer una FFT, con mximo 169 muestras.
A continuacin se presentar un ejemplo en lenguaje C, para realizar la transformacin de una
seal de N = ML, muestras:
#define M 16
#define L 8
#define N L*M
#define PI 3.141592654
typedef struct
{
float R, I;
}Complejo;
//Declaracin de varales inicializadas.
unsigned short i, OK=0;
unsigned short Fi=0, Co=0;
//Declaracin de la funcin de interrupciones.
Complejo X[L][M];
Complejo Y[L][M];
//Funcin para realizar una multiplicacin compleja.
Complejo Producto( Complejo A, Complejo B )
{
Complejo Res;
Res.R = A.R*B.R - A.I*B.I;
Res.I = A.R*B.I + A.I*B.R;
return Res;
}
//Funcin para realizar una suma compleja.
Complejo Adicion( Complejo A, Complejo B )
{
Complejo Res;
Res.R = A.R + B.R;
Res.I = A.I + B.I;
return Res;
}
//Funcin para determinar la magnitud de un nmero complejo.
float Magnitud( Complejo A )
{
return sqrt( A.R*A.R + A.I*A.I );
}
235
//Clculo rpido de Fourier, de N muestras.
void FFT( void )
{
unsigned short l,q,m,p;
Complejo WW;
//Tro de bucles for, para ejecutar la
//ecuacin (15.26), la matriz Y[][], representa F(l,q).
for( l=0; l<L; l++ )
{
for( q=0; q<M; q++ )
{
Y[l][q].R = 0.0;
Y[l][q].I = 0.0;
for( m=0; m<M; m++ )
{
WW.R = cos( 2*PI*m*q / M );
WW.I = -sin( 2*PI*m*q / M );
WW = Producto( X[l][m], WW );
Y[l][q] = Adicion( Y[l][q], WW );
}
}
}
//Dupla se bucles for, para realizar la multiplicacin
//de factores Wn (15.27), Y[][] representa la matriz F(l,q), y
//X[][] representa la matriz G(l,q).
for( l=0; l<L; l++ )
{
for( q=0; q<M; q++ )
{
WW.R = cos( 2*PI*l*q / N );
WW.I = -sin( 2*PI*l*q / N );
X[l][q] = Producto( Y[l][q], WW );
}
}
//Tro de bucles for, para ejecutar la
//ecuacin (15.28), la matriz Y[][], representa X(p,q),
//y X[][] representa la matriz G(l,q).
for( p=0; p<L; p++ )
{
for( q=0; q<M; q++ )
{
Y[p][q].R=0.0;
Y[p][q].I=0.0;
for( l=0; l<L; l++ )
{
236
WW.R = cos( 2*PI*l*p / L );
WW.I = -sin( 2*PI*l*p / L );
WW = Producto( X[l][q], WW );
Y[p][q] = Adicion( Y[p][q], WW );
}
}
}
//Doble for anidado para determinar,
//la magnitud de la transformada,
//Este resultado queda en los trminos reales de X[][]
for( l=0; l<L; l++ )
for( m=0; m<M; m++ )
{
X[l][m].R = Magnitud( Y[l][m] );
X[l][m].I = 0.0;
}
}
void interrupt ( void )
{
if( INTCON.F2 )
{
TMR0L=135;
//Timer0 con periodo de 774,4u segundo.
// Fs = 1291,32 Hz.
if( OK ) //Se evala la adquisicin de muestras.
{
//Se hace la adquisicin de las muestras,
//y se archivan por columnas.
X[Fi][Co].R = ((float)ADC_Read(0)-127.0);
X[Fi][Co].I = 0.0;
Fi++;
if( Fi==L )
{
Fi = 0;
Co++;
if( Co==M )
{
Co=0;
OK=0;
}
}
}
INTCON.F2=0;
}
}
237
void main( void )
{
char Text[30];
unsigned short ff, cc, cont;
//Inicio del puerto B como salida.
TRISB = 0;
PORTB = 0;
//Se configura el TIMER 0, su interrupcin.
INTCON = 0b10100000;
T0CON = 0b11000101;
UART1_Init(9600);
while(1)//Bucle infinito.
{
OK = 1; //Se habilita la lectura de muestras.
UART1_Write_Text("// Adquisicion y FFT de:");
IntToStr( N, Text );
UART1_Write_Text(Text);
UART1_Write_Text(" Muestras //");
UART1_Write(13); UART1_Write(10);
while( OK ); //Se espera la adquisicion de las muestras.
FFT(); //Clculo de la FFT.
UART1_Write_Text("// Inicio de las muestras //");
UART1_Write(13); UART1_Write(10);
//La primera componente espectral se ignora y se hace igual a cero.
X[0][0].R = 0.0;
cont = 0;
//Se envan la magnitud de la FFT, hasta N/2
//por medio del puerto serial.
for( ff=0; ff<L; ff++ )
{
for( cc=0; cc<M; cc++ )
{
FloatToStr( X[ff][cc].R, Text );
UART1_Write_Text(Text);
UART1_Write(13); UART1_Write(10);
cont++;
if( cont==N )
{
cc = M;
ff = L;
}
}
}
UART1_Write_Text("// Fin de las muestras //");
UART1_Write(13); UART1_Write(10);
}
}
238
Para simular este ejercicio en ISIS, se implementa un circuito similar al ejercicio anterior de
transformada discreta de Fourier. Sustituyendo el PIC, por un 18F4585, y anexando un
VIRTUAL TERMINAL. El circuito para simular es el siguiente:
Circuito 14-3
14.9 Control digital PID
El en mbito del control automtico la forma de control ms popular es el PID, que significa
proporcional, integral, derivativo. El control es una rama de la fsica y la electrnica que permite
manipular una variable fsica para permanecer en un valor deseado arbitrariamente. Todo sistema
de control cuenta con las siguientes caractersticas:
- Punto de control
- Error
- Controlador (PID)
- Correccin
- Planta
- Variable a controlar
- Sensor o transductor
Ests caractersticas se pueden apreciar en el siguiente diagrama en bloques:
Figura 14-20
239
Para el caso del microcontrolador su funcin est sujeta a la entrada del punto de control, la
lectura del sensor, y la salida de correccin. El punto de partida de un controlador es el
controlador PID anlogo que tiene una funcin de transferencia PID(s), est funcin tiene una
relacin similar a un conjunto de filtros y su tratamiento es equivalente a un filtro IIR. La funcin
de transferencia anloga es la siguiente:
sKd
s
Ki
Kp s PID + + = ) (
Ecuacin 14-30
De la misma forma que se hace con los filtros IIR, se realiza la transformacin bilineal, y este
desarrollo da el siguiente anlisis:
) 1 (
) 1 ( 2
) 1 (
) 1 (
2
) (
) 1 (
) 1 ( 2
) 1 ( 2
) 1 (
) (
) 1 (
) 1 ( 2
) 1 (
) 1 ( 2
) (
1
1
1
1
1
1
1
1
1
1
1
1
+
+
+
+ =
+
+
+
+ =
+
+
+
+ =
z
z FsKd
z
z
Fs
Ki
Kp z PID
z
z FsKd
z Fs
z Ki
Kp z PID
z
z FsKd
z
z Fs
Ki
Kp z PID
Del anterior anlisis se pueden deducir tres funciones de transferencia para el controlador donde
la entrada, es la seal de error para cada una de ellas. Las respectivas operaciones matemticas
para su implementacin son las siguientes:
) ( ) ( ) ( ) (
) 1 ( )] 1 ( ) ( [ 2 ) (
) 1 ( )] 1 ( ) ( [
2
) (
) ( ] [ ) (
n y n y n y n y
n y n e n e FsKd n y
n y n e n e
Fs
Ki
n y
n e Kp n y
d i p pid
d d
i i
p
+ + =
=
+ + =
=
Ecuacin 14-31
Para el caso particular del siguiente ejemplo se emplea la tcnica de conversin digital anlogo
por medio de una salida PWM, y como estrategia para simular el comportamiento de la planta se
usa un circuito RC, de segundo orden. El siguiente cdigo fuente muestra un control PID
correspondiente a la sintonizacin del control PID, cuando su Kp crtico es de 1,8 y un periodo
crtico de 41,2m segundos.
//Declaracin de constantes y variables.
const float Kp=1.08, Ki=52.42718447, Kd=0.005562, Fs = 152.5878906;
//Declaracin de coeficientes de integracin y derivacin.
const float Fi=ki/(2.0*Fs), Fd=2.0*Fs*Kd;
240
float SENSOR, PUNTO_DE_CONTROL=127.0, YN=0.0;
int ADQUI;
unsigned short SALIDA;
float e0=0.0, e1=0.0, yi0=0.0, yi1=0.0, yd0=0.0, yd1=0.0, ypid=0.0;
//Funcin de interrupciones para el Timer 0.
void interrupt()
{
if( INTCON.F2 )// 6,5536ms :: 152,5878906 Hz
{
//Adquisicin de la variable controlada.
SENSOR = (float)((ADC_Read(1)>>2)&0xFF);
//Adquisicin del punto de control.
PUNTO_DE_CONTROL = (float)((ADC_Read(0)>>2)&0xFF);
//Calculo del nivel de error.
e0 = PUNTO_DE_CONTROL - SENSOR;
//Ecuacin en diferencias.
//Ecuacin integral.
yi0=Fi*(e0+e1)+yi1;
//Ecuacin derivativa.
yd0=Fd*(e0-e1)-yd1;
//Resultado PID.
ypid=Kp*e0+yi0+yd0;
//Ajuste y correccin de la SALIDA Y(n)
//delimitada por los lmites 0 y 255.
YN += ypid;
if(YN>255.0)YN=255.0;
if(YN<0.0)YN=0.0;
SALIDA = (unsigned short)(YN);
PWM1_Set_Duty(SALIDA);
//Actualizacin de muestras.
e1=e0;
yi1=yi0;
yd1=yd0;
INTCON.F2=0;
}
}
void main( void )
{
//Configuracin del modulo PWM.
PWM1_Init(10000);
PWM1_Start();
//Configuracin de la interrupcin de Timer 0.
//a 6,5536ms
OPTION_REG = 0b00000110;
INTCON = 0b10100000;
while( 1 ) //Bucle infinito.
241
{
}
}
El circuito para simular implementa los dispositivos: 16F877A, POT-HG, RES, CAP, OP1P La
simulacin trabaja con reloj de 20MHz. El esquemtico del circuito es el siguiente:
Circuito 14-4
Para la sintona del controlador, y establecer las constantes Kp, Ki, y Kd, se puede usar la
siguiente estrategia:
Primero se establece el controlador con las constantes Ki, y Kd igual a 0. Posteriormente se
incrementa el valor de Kp, gradualmente hasta que la salida oscile de forma sostenida. Cuando
esto sucede se mide el periodo de la oscilacin sostenida y se determina el valor de Kp. Estos dos
parmetros se denominan periodo crtico Pc, y Kp crtico Kpc. Posteriormente estos valores se
remplazan en la siguiente tabla, para determinar los valores definitivos de Kp, Ki, y Kd:
Tipo de control Kp Ti Td
P 0,5Kpc Infinito, Ki=0 0
PI 0,45Kpc Pc/1,2 0
PID 0,6Kpc 0,5Pc 0,125Pc
Tabla 14-2
Donde, Ti es el periodo de integracin y Td el periodo derivativo. La relacin de estos periodos
con las constantes Ki, y Kd se especifica en las siguientes ecuaciones:
242
TdKp Kd
Ti
Kp
Ki
=
=
Ecuacin 14-32
243
15 Transmisin de datos
La transmisin de datos es una lnea de las comunicaciones electrnicas que se encarga de
garantizar el transporte de informacin de forma digital. La informacin enviada puede ser
bloques de texto, de audio, video, o cualquier otro tipo de informacin. Para realizar la
transmisin de informacin se pueden seguir diversos formatos y protocolos, sin embargo este
captulo se centra en tcnicas bsicas de transmisin de datos como son, el control de flujo de la
informacin, la transparencia de datos y el control de errores. Las tcnicas de transmisin de
datos permiten optimizar y garantizar el estado correcto de los datos durante una transmisin de
datos. Este es un aspecto importante dado que un medio de transmisin est expuesto a producir
errores por razones de ruido o falta de continuidad en el medio de transmisin de datos. El
siguiente grafico ilustra de forma simple el trfico de informacin entre dos puntos que gestionan
una comunicacin.
Figura 15-1
244
15.1 Control de flujo
El control de flujo permite gestionar el trfico de informacin de forma ordenada. Cuando el
medio de transmisin es altamente confiable, se puede implementar solamente el control de flujo.
Por otro lado es importante tener presente que los ejemplos mostrados en este captulo trafican
con la informacin en cdigo ASCII, y el carcter de reconocimiento positivo ACK, se representa
con el valor 0x06, el carcter de reconocimiento negativo NAK, se representa con el cdigo
0x15, los finales de cadenas de texto o de caracteres se representan con el carcter nulo NULL
que equivale al cdigo 0x00. El siguiente ejemplo muestra una comunicacin simples con el
respectivo control de flujo, implementado con un microcontrolador PIC 16F628A, con oscilador
de 4MHz.
// Declaracin de constantes del LCD
sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D7 at RB7_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D7_Direction at TRISB7_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB4_bit;
//Declaracin de variables de trabajo.
char BUFER[20], Dato, Bandera=0;
unsigned short Estado=0, N=0;
//Declaracin de constantes.
const char ACK='A', NAK='N', ENQ='&', EOT='%', NULL=0x00;
//Vector de interrupciones.
void interrupt()
{
//Se evala la interrupcin por recepcin serial.
if( PIR1.F5 )
{
//Se lee el Dato de entrada.
Dato = UART1_Read();
//Se evala el estado del trfico de informacin.
switch( Estado )
{
//En espera...
case 0: //Se evala si llega una solicitud..
if( Dato == ENQ )
{
//Se cambia al siguiente Estado y se
245
//enva el reconocimiento positivo.
Estado = 1;
N = 0;
UART1_Write(ACK);
}
else
{
//Se enva reconocimiento negativo.
UART1_Write(NAK);
}
break;
//Recibiendo...
case 1: // Se evala si lo que llega es el final de transmisin EOT
if( Dato == EOT )
{
//Llega el fin de la informacin y se vuelve
//al Estado inicial y se activa la Bandera de datos
//de llegada.
BUFER[N] = NULL;
Estado = 0;
Bandera = 1;
}
else
{
//Se archiva el Dato recibido y se incrementa
//el indicador N
BUFER[N] = Dato;
N++;
}
default: break;
}
}
}
void main( void )
{
//Se activan las interrupciones perifricas.
INTCON = 0b11000000;
//Se activa la interrupcin por recepcin serial.
PIE1 = 0b00100000;
//Configuracin del modulo USART a 9600 bps.
UART1_Init(9600);
//Configuracin del LCD.
Lcd_Init();
Lcd_Out(1,1,"Control de Flujo");
while(1) //Bucle infinito.
246
{
//Se evala si la Bandera esta activa.
if( Bandera == 1 )
{
//Se imprime la informacin en el LCD.
Lcd_Out(2,1," ");
Lcd_Out(2,1,BUFER);
Bandera = 0;
}
}
}
Es importante notar que en la declaracin de constantes se usan como caracteres de ACK, NAK,
ENQ y EOT, los caracteres A, N, &, y %, esto solo se realiza en este ejemplo de forma didctica
dado que este tipo de caracteres tienen valores y equivalencias que no se pueden ver ni digitar en
el VIRTUAL TERMINAL.
Para realizar la respectiva simulacin de este ejemplo se implementa en ISIS los dispositivos
PIC16F628A, VIRTUAL TERMINAL, y LM016L, en un circuito como el siguiente:
Circuito 15-1
La transmisin de informacin obedece a la siguiente estructura:
Figura 15-2
247
15.2 Transparencia de datos
La transparencia de datos es la capacidad de empaquetar informacin con un bloque de inicio o
encabezado y un bloque final del paquete de informacin, el xito de la transparencia esta en no
repetir los datos de encabezado o final dentro de la informacin. De esta manera se puede ver de
forma transparente la informacin dentro de los datos de control. Para encabezar la informacin
se implementa el carcter DLE o marcador de transparencia equivalente al cdigo 0x10, STX
comienzo de texto que equivale al cdigo 0x02, y para finalizar el bloque de datos se usa el
carcter ETX que es equivalente a 0x03.
Para demostrar el funcionamiento de la estructura de transparencia se implementan a
continuacin dos programas uno que transmite informacin y otro que la recibe, los programas
esta fundamentados en un microcontrolador PIC 16F628A, y un PIC 16F877A ambos con
oscilador de 4MHz, a continuacin se puede apreciar el cdigo fuente del modulo receptor que es
similar al ejemplo del control de flujo:
// Declaracin de constantes del LCD
sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D7 at RB7_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D7_Direction at TRISB7_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB4_bit;
//Declaracin de variables de trabajo.
char BUFER[20], Dato, Bandera=0;
unsigned short Estado=0, N=0;
//Declaracin de constantes.
const char ACK=0x06, NAK=0x15, ENQ=0x05, EOT=0x04, STX=0x02, ETX=0x03,
DLE=0x10,
NULL=0x00;
//Vector de interrupciones.
void interrupt()
{
//Se evala la interrupcin por recepcin serial.
if( PIR1.F5 )
{
//Se lee el Dato de entrada.
Dato = UART1_Read();
//Se evala el estado del trfico de informacin.
switch( Estado )
248
{
//En espera...
case 0: //Se evala si llega una solicitud..
if( Dato == ENQ )
{
//Se cambia al siguiente Estado y se
//enva el reconocimiento positivo.
Estado = 1;
UART1_Write(ACK);
}
else
{
//Se enva reconocimiento negativo.
UART1_Write(NAK);
}
break;
//Delimitador de transparencia...
case 1: // Se evala si lo que llega es DLE.
if( Dato == DLE )
{
//Se cambia al siguiente Estado...
Estado = 2;
}
else
{
//Se identifica un error de orden en los datos
//y se transmite un reconocimiento negativo y se
//reanuda al Estado inicial.
//Se reinicia de nuevo al Estado inicial.
Estado = 0;
UART1_Write(NAK);
}
break;
// Recibiendo informacin...
case 2: // Se evala si lo que llega es STX.
if( Dato == STX )
{
//Se inicia la cadena de informacin y se
//pasa al Estado 3
N=0;
BUFER[N]=NULL;
Estado = 3;
}
else
{
//Se identifica un error de orden en los datos
//y se transmite un reconocimiento negativo y se
//reanuda al Estado inicial.
//Se reinicia de nuevo al Estado inicial.
249
Estado = 0;
UART1_Write(NAK);
}
break;
// Esperando datos y delimitador de transparencia.
case 3: //Se evala si el Dato que llega es un DLE.
if( Dato == DLE )
{
//Se cambia al Estado siguiente.
Estado = 4;
//Se finaliza el BUFER de datos;
BUFER[N]=NULL;
}
else
{
//Se anexa un nuevo Dato al BUFER.
BUFER[N]=Dato;
//Se incrementa el ndice de los datos.
N++;
}
break;
// Esperando fin de cadena...
case 4: // Se evala si llega un ETX
if( Dato == ETX )
{
//Se cambia al Estado siguiente.
Estado = 5;
}
else
{
//Se cambia de nuevo al Estado inicial.
Estado = 0;
//Se transmite reconocimiento negativo.
UART1_Write(NAK);
}
break;
//Esperando fin de transmisin...
case 5: //Se evala si llega el EOT...
if( Dato == EOT )
{
//Se activa la Bandera de llegada de informacin.
Bandera = 1;
//Se transmite reconocimiento positivo.
UART1_Write(ACK);
}
else
{
//Se transmite reconocimiento negativo.
UART1_Write(NAK);
250
}
Estado = 0;
break;
default: break;
}
}
}
void main( void )
{
//Se activan las interrupciones perifricas.
INTCON = 0b11000000;
//Se activa la interrupcin por recepcin serial.
PIE1 = 0b00100000;
//Configuracin del modulo USART a 9600 bps.
UART1_Init(9600);
//Configuracin del LCD.
Lcd_Init();
//Texto de inicio.
Lcd_Out(1,1,"Transparencia");
while(1) //Bucle infinito.
{
//Se evala si la Bandera esta activa.
if( Bandera == 1 )
{
//Se imprime la informacin en el LCD.
Lcd_Out(2,1," ");
Lcd_Out(2,1,BUFER);
Bandera = 0;
}
}
}
El siguiente programa est diseado para un microcontrolador PIC 16F877A, el cual toma la
lectura de un sensor LM35, y la transmite con el respectivo control de flujo y transparencia:
//Declaracin de constantes.
const char ACK=0x06, NAK=0x15, ENQ=0x05, EOT=0x04, STX=0x02, ETX=0x03,
DLE=0x10, NULL=0x00;
void main( void )
{
char BUFER[10];
int adc;
float Temp;
//Se configura el modulo ADC, con el pin
//AN3 como voltaje de referencia.
ADCON1 = 0b11000001;
251
//Se inicia el modulo USART a 9600 bps.
UART1_Init(9600);
delay_ms(500);
while(1)//Bucle infinito.
{
OTRO:
//Lectura del canal 0
adc = ADC_Read(0);
//Se calcula el valor de la temperatura.
Temp = 0.244*adc;
//Se escribe la temperatura en el BUFER.
FloatToStr( Temp, BUFER );
//Retardo de lectura de 400m segundos
delay_ms(100);
//Se transmite el ENQ...
UART1_Write(ENQ);
//Se espera el ACK...
while( !UART1_Data_Ready() );
//Se verifica si llega un ACK...
if( UART1_Read() != ACK )goto OTRO;
//Se transmite un DLE...
UART1_Write(DLE);
//Se transmite un STX...
UART1_Write(STX);
//Se transmite la informacin del BUFER...
UART1_Write_Text(BUFER);
//Se transmite un DLE...
UART1_Write(DLE);
//Se transmite el ETX...
UART1_Write(ETX);
//Se transmite el fin de transmisin...
UART1_Write(EOT);
//Se espera el ACK
while( !UART1_Data_Ready() );
//Se verifica si llega un ACK...
if( UART1_Read() != ACK )goto OTRO;
}
}
La estructura para la transparencia de datos obedece a la siguiente forma:
Figura 15-3
252
Para realizar la respectiva simulacin se realiza el siguiente circuito que tiene los dispositivos,
PIC 16F628A, PIC 16F877A, RES, LM016L, LM35:
Circuito 15-2
15.3 Control de errores CRC
El control de errores en una transmisin es de suma importancia y ms cuando la calidad del
medio de transmisin no es confiable. Para detectar los errores de transmisin existen diferentes
tcnicas entre las cuales se pueden citar, VRC o verificacin de redundancia vertical, esta
estrategia anexa un bit ms a cada paquete de informacin el cual representa el nmero par o
impar de unos en el paquete. LRC o Verificacin de redundancia longitudinal la cual verifica el
nmero de bits pares o impares en un grupo de bytes, para este fin se realiza la operacin lgica o
exclusiva, entre ellos. Por ltimo se puede hablar del CRC, o verificacin de redundancia cclica,
que es la estrategia de mayor efectividad, y que es la tcnica en la cual se centra el ejemplo de
este captulo. Para llegar al resultado del CRC, se efecta una divisin binaria entre el paquete de
datos que se desean transmitir y un polinomio fijo que debe respetar algunas condiciones.
Despus de hacer la divisin el residuo de la misma es anexado al paquete de informacin y este
es el CRC. El ente receptor realiza la misma divisin con el mismo polinomio y despus de
culminarla el resultado consignado en el residuo debe ser 0 si los datos han llegado sin ningn
error, de lo contrario los datos del paquete estn deteriorados.
La estructura de informacin con el CRC incorporado se implementa en la forma que se puede
apreciar en la siguiente figura:
253
Figura 15-4
Los polinomios que se implementan en el clculo del CRC se denotan en trminos de X, en el
cual cada X, es un 1 en el polinomio, para ilustrar esta situacin se puede apreciar el siguiente
ejemplo:
Este polinomio equivale al siguiente nmero binario:
10100111
Para que los polinomios funciones de forma adecuada deben cumplir con las siguientes
condiciones:
- Debe empezar y terminar con un 1.
- No debe ser divisible por X, es decir por 10.
- Debe ser divisible por X+1, es decir por 11.
Los siguientes son polinomios estndar para diferente nmero de bits:
CRC-4
CRC-8
CRC-12
CRC-16
CRC-32
El siguiente ejemplo aritmtico muestra una divisin para generar el CRC, y su respectiva
verificacin:
254
La implementacin de una divisin de este modo es demasiado compleja. Cuanto ms larga sea
la trama ms difcil es realizarla, por eso es ms simple realizar una operacin lgica con
registros de desplazamiento como estrategia para determinar el residuo de la divisin. El
siguiente diagrama muestra un circuito para el polinomio:
Figura 15-5
Usando como estrategia de programacin el corrimiento de bits como lo muestra la figura se
puede hacer un conjunto de funciones que calculen el CRC, sobre una trama de longitud
indefinida teniendo como base mnima un byte y polinomios con orden mltiplo de 8, tales como
8, 16, 24, 32. Para comprender con claridad este concepto se puede observar el siguiente ejemplo
que usa un polinomio de orden 8:
Polinomio:
100110001
Informacin 1 0 1 1 0 1 0 1 1
Polinomio 1 0 0 1 1
1 0 1 1 0 1 0 1 1 0 0 0 0 1 0 1 1 0 1 0 1 1 1 1 0 0
1 0 0 1 1 1 0 0 1 1
0 1 0 1 1 0 1 0 1 1
0 0 0 0 0 0 0 0 0 0
1 0 1 1 0 1 0 1 1 0
1 0 0 1 1 1 0 0 1 1
0 1 0 1 1 0 1 0 1 1
0 0 0 0 0 0 0 0 0 0
1 0 1 1 1 1 0 1 1 1
1 0 0 1 1 1 0 0 1 1
0 1 0 0 0 0 1 0 0 1
0 0 0 0 0 0 0 0 0 0
1 0 0 0 0 1 0 0 1 1
1 0 0 1 1 1 0 0 1 1
0 0 1 1 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 1 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0 Chequeo
Calculo del CRC Chequeo del CRC
Se cambia el polinomio por 0
dado que el bit mas
significativo es cero
CRC
255
unsigned short CRC=0;
//Funcin para insertar in bit en el clculo del CRC.
void CorrerBitCRC( char _bit )
{
unsigned short CRC2=0;
CRC2 = CRC2 | (CRC<<1)&128; //Set X7
CRC2 = CRC2 | (CRC<<1)&64; //Set X6
CRC2 = CRC2 | ((CRC<<1)^(CRC>>2))&32; //Set X5
CRC2 = CRC2 | ((CRC<<1)^(CRC>>3))&16; //Set X4
CRC2 = CRC2 | (CRC<<1)&8; //Set X3
CRC2 = CRC2 | (CRC<<1)&4; //Set X2
CRC2 = CRC2 | (CRC<<1)&2; //Set X1
CRC2 = CRC2 | ((CRC>>7)^_bit)&1; //Set X0
CRC = CRC2;
}
//Funcin para insertar un Byte al clculo del CRC.
void CorrerByteCRC( char Byte )
{
short B;
for( B=7; B>=0; B-- )
CorrerBitCRC( (Byte>>B)&1 );
}
//Funcin para calcular el CRC de una trama de texto.
unsigned short CalcularRCR( char *trama, unsigned char FINAL )
{
unsigned short N=0;
CRC = 0;
while( trama[N]!=0 )
{
CorrerByteCRC( trama[N] );
N++;
}
CorrerByteCRC( FINAL );
return CRC;
}
Para realizar la implementacin de este ejemplo, se usa el mismo hardware del ejemplo de
transparencia, el cdigo fuente para el microcontrolador transmisor implementando el CRC es el
siguiente:
//Funcin para insertar un Byte al clculo del CRC.
void CorrerByteCRC( char Byte )
{
short B;
for( B=7; B>=0; B-- )
CorrerBitCRC( (Byte>>B)&1 );
}
256
//Funcin para calcular el CRC de una trama de texto.
unsigned short CalcularRCR( char *trama, unsigned char FINAL )
{
unsigned short N=0;
CRC = 0;
while( trama[N]!=0 )
{
CorrerByteCRC( trama[N] );
N++;
}
CorrerByteCRC( FINAL );
return CRC;
}
void main( void )
{
char BUFER[10];
int adc;
float Temp;
//Se configura el modulo ADC, con el pin
//AN3 como voltaje de referencia.
ADCON1 = 0b11000001;
//Se inicia el modulo USART a 9600 bps.
UART1_Init(9600);
delay_ms(500);
while(1)//Bucle infinito.
{
OTRO:
//Lectura del canal 0
adc = ADC_Read(0);
//Se calcula el valor de la temperatura.
Temp = 0.244*adc;
//Se escribe la temperatura en el BUFER.
FloatToStr( Temp, BUFER );
//Calculo del CRC.
CalcularRCR( BUFER, 0 );
//Retardo de lectura de 400m segundos
delay_ms(100);
//Se transmite el ENQ...
UART1_Write(ENQ);
//Se espera el ACK...
while( !UART1_Data_Ready() );
//Se verifica si llega un ACK...
if( UART1_Read() != ACK )goto OTRO;
//Se transmite un DLE...
UART1_Write(DLE);
//Se transmite un STX...
UART1_Write(STX);
//Se transmite la informacin del BUFER...
257
UART1_Write_Text(BUFER);
//Se transmite el CRC...
UART1_Write(CRC);
//Se transmite un DLE...
UART1_Write(DLE);
//Se transmite el ETX...
UART1_Write(ETX);
//Se transmite el fin de transmisin...
UART1_Write(EOT);
//Se espera el ACK...
while( !UART1_Data_Ready() );
//Se verifica si llega un ACK...
if( UART1_Read() != ACK )goto OTRO;
}
}
El cdigo fuente para el microcontrolador receptor con la implementacin del CRC es el
siguiente:
// Declaracin de constantes del LCD
sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D7 at RB7_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D7_Direction at TRISB7_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB4_bit;
//Declaracin de variables de trabajo.
char BUFER[20], Dato, Bandera=0;
unsigned short Estado=0, N=0;
//Declaracin de constantes.
const char ACK=0x06, NAK=0x15, ENQ=0x05, EOT=0x04, STX=0x02, ETX=0x03,
DLE=0x10,
NULL=0x00;
unsigned short CRC=0, CRC_2, Lon;
//Funcin para insertar in bit en el clculo del CRC.
void CorrerBitCRC( char _bit )
{
unsigned short CRC2=0;
258
CRC2 = CRC2 | (CRC<<1)&128; //Set X7
CRC2 = CRC2 | (CRC<<1)&64; //Set X6
CRC2 = CRC2 | ((CRC<<1)^(CRC>>2))&32; //Set X5
CRC2 = CRC2 | ((CRC<<1)^(CRC>>3))&16; //Set X4
CRC2 = CRC2 | (CRC<<1)&8; //Set X3
CRC2 = CRC2 | (CRC<<1)&4; //Set X2
CRC2 = CRC2 | (CRC<<1)&2; //Set X1
CRC2 = CRC2 | ((CRC>>7)^_bit)&1; //Set X0
CRC = CRC2;
}
//Funcin para insertar un Byte al clculo del CRC.
void CorrerByteCRC( char Byte )
{
short B;
for( B=7; B>=0; B-- )
CorrerBitCRC( (Byte>>B)&1 );
}
//Funcin para calcular el CRC de una trama de texto.
unsigned short CalcularRCR( char *trama, unsigned char FINAL )
{
unsigned short N=0;
CRC = 0;
while( trama[N]!=0 )
{
CorrerByteCRC( trama[N] );
N++;
}
CorrerByteCRC( FINAL );
return CRC;
}
//Vector de interrupciones.
void interrupt()
{
//Se evala la interrupcin por recepcin serial.
if( PIR1.F5 )
{
//Se lee el Dato de entrada.
Dato = UART1_Read();
//Se evala el estado del trfico de informacin.
switch( Estado )
{
//En espera...
case 0: //Se evala si llega una solicitud..
if( Dato == ENQ )
{
//Se cambia al siguiente Estado y se
259
//enva el reconocimiento positivo.
Estado = 1;
UART1_Write(ACK);
}
else
{
//Se enva reconocimiento negativo.
UART1_Write(NAK);
}
break;
//Delimitador de transparencia...
case 1: // Se evala si lo que llega es DLE.
if( Dato == DLE )
{
//Se cambia al siguiente Estado...
Estado = 2;
}
else
{
//Se identifica un error de orden en los datos
//y se transmite un reconocimiento negativo y se
//reanuda al Estado inicial.
//Se reinicia de nuevo al Estado inicial.
Estado = 0;
UART1_Write(NAK);
}
break;
// Recibiendo informacin...
case 2: // Se evala si lo que llega es STX.
if( Dato == STX )
{
//Se inicia la cadena de informacin y se
//pasa al Estado 3
N=0;
BUFER[N]=NULL;
Estado = 3;
}
else
{
//Se identifica un error de orden en los datos
//y se transmite un reconocimiento negativo y se
//reanuda al Estado inicial.
//Se reinicia de nuevo al Estado inicial.
Estado = 0;
UART1_Write(NAK);
}
break;
// Esperando datos y delimitador de transparencia.
case 3: //Se evala si el Dato que llega es un DLE.
260
if( Dato == DLE )
{
//Se cambia al Estado siguiente.
Estado = 4;
//Se finaliza el BUFER de datos;
BUFER[N]=NULL;
}
else
{
//Se anexa un nuevo Dato al BUFER.
BUFER[N]=Dato;
//Se incrementa el ndice de los datos.
N++;
}
break;
// Esperando fin de cadena...
case 4: // Se evalua si llega un ETX
if( Dato == ETX )
{
//Se cambia al Estado siguiente.
Estado = 5;
}
else
{
//Se cambia de nuevo al Estado inicial.
Estado = 0;
//Se transmite reconocimiento negativo.
UART1_Write(NAK);
}
break;
//Esperando fin de transmisin...
case 5: //Se evala si llega el EOT...
if( Dato == EOT )
{
//Se mide la longitud de la trama.
Lon = strlen(BUFER);
//Se filtra el CRC, que est en la ltima posicin.
CRC_2 = BUFER[Lon-1];
BUFER[Lon-1]=0;
//Se calcula el CRC...
CalcularRCR( BUFER, CRC_2 );
// Se verifica que el chequeo sea cero...
if( CRC==0 )
{
//Se activa la Bandera de llegada de informacin.
Bandera = 1;
//Se transmite reconocimiento positivo.
UART1_Write(ACK);
}
261
else
{
//Se transmite reconocimiento negativo.
UART1_Write(NAK);
}
}
else
{
//Se transmite reconocimiento negativo.
UART1_Write(NAK);
}
Estado = 0;
break;
default: break;
}
}
}
void main( void )
{
//Se activan las interrupciones perifricas.
INTCON = 0b11000000;
//Se activa la interrupcin por recepcin serial.
PIE1 = 0b00100000;
//Configuracin del modulo USART a 9600 bps.
UART1_Init(9600);
//Configuracin del LCD.
Lcd_Init();
//Texto de inicio.
Lcd_Out(1,1,"Transparencia");
while(1) //Bucle infinito.
{
//Se evala si la Bandera esta activa.
if( Bandera == 1 )
{
//Se imprime la informacin en el LCD.
Lcd_Out(2,1," ");
Lcd_Out(2,1,BUFER);
Bandera = 0;
}
}
}
262
16 Actuadores y potencia
Los actuadores son dispositivos elctricos o electrnicos que permiten crear un cambio fsico
sobre una variable. Est pueden ser temperatura, velocidad, presin, luminosidad, humedad,
posicin angular o lineal, entre otras. Los actuadores pueden ser de accionamiento AC, o DC. Los
actuadores DC, son aquellos como motores, servomotores, lmparas incandescentes, solenoides,
relevadores, entre otros. Los actuadores AC, son aquellos como motores AC, lmparas
incandescentes, resistencias elctricas, entre otros. Por otra parte la potencia es la cantidad
energa elctrica requerida para realizar un trabajo determinado. En el caso puntual de la
electricidad la potencia est definida como:
R I
R
V
VI P
e
2
2
= = = Ecuacin 16-1
Donde Pe es la potencia elctrica en vatios, V es la diferencia de potencial elctrico sobre una
carga elctrica con resistencia R, por la cual circula una corriente I. En el caso de un
microcontrolador el uso de un arreglo de potencia se hace indispensable cuando un actuador
requiere ms voltaje o corriente, que la que puede entregar un pin del PIC. La tensin que
entregan las salidas del PIC siempre es de 5 voltios y la corriente que puede suministrar solo
puede ser del orden de pocos miliamperios.
16.1 Actuadores DC
Los actuadores DC, requieren de corriente siempre directa es decir que siempre circula en la
misma direccin. Para el uso de estos actuadores se implementan esencialmente dos tipos de
dispositivos, los transistores de potencia o los relevadores. Los transistores pueden ser BJT, o
MOSFET. Un transistor BJT, se caracteriza por controlar una corriente por medio de otra
corriente. Los MOSFET, permiten controlar un flujo de corriente por medio de una diferencia de
potencial. Los transistores funcionan en tres zonas, conocidas como corte, saturacin y activa. La
zona activa es comn en los sistemas de amplificacin de seal. Sin embargo para el caso de los
actuadores se requieren en la mayora de los casos ser activados y desactivados, o tener un
comportamiento ON, OFF. En otras palabras los transistores se usan en corte y saturacin. Bajo
estos trminos los transistores trabajan como interruptores de corriente, en las zonas de corte y
saturacin. La vista de los transistores en ISIS es la siguiente:
Figura 16-1
263
Los transistores MOSFET, controlan la corriente que circula entre la fuente S, y el drenador D,
por medio de la diferencia de potencial elctrico sobre la compuerta G. Los transistores BJT,
controlan la corriente que fluye entre el colector C, y el emisor E, por medio de la corriente que
circula por la base B.
El uso de cargas inductivas como motores, relevadores o solenoides, tienen la propiedad de
almacenar energa en forma de campo electromagntico, esto implica que cuando las cargas
inductivas son des energizadas, ests devuelven su energa por medio de una corriente inversa,
este fenmeno puede causar daos en los sistemas controlados con transistores, para evitar este
problema se debe usar un diodo rectificador polarizado en inverso para descargar las cargas
inductivas, este arreglo se muestra en el siguiente circuito:
Circuito 16-1
16.1.1 Relevadores
Los relevadores son dispositivos electromecnicos, que tienen un electroimn con el cual se
cierra o se abre un circuito elctrico por medio de uno o varios contactos. Los relevadores son
ideales para aislar los circuitos de potencia con la etapa de control electrnico. De igual manera
son dispositivos de bajo rendimiento, dado que no pueden hacer cambios de estdo veloces, y con
el uso constante los contactos elctricos se deterioran con el tiempo. La apariencia fsica y la vista
en ISIS, de estos dispositivos es la siguiente:
Figura 16-2
Por ltimo el uso de estos dispositivos se debe hacer de forma final como se puede observar en el
siguiente circuito, que tiene una carga de 120V AC:
264
Circuito 16-2
16.1.2 Motores DC
Los motores DC, son de naturaleza inductiva y por consiguiente merecen el mismo tratamiento
de los relevadores. En el siguiente ejemplo se puede apreciar como un microcontrolador hace
cambios de velocidad en un motor DC, para este fin se implementa el mdulo PWM de un
microcontrolador 16F628A, con oscilador de 4MHz. El cdigo fuente en lenguaje C es el
siguiente:
void main( void )
{
unsigned short CU=0;
OPTION_REG = 0; //Se activan las resistencias PULL-UP.
PWM1_Init( 500 ); //Se inicia el mdulo PWM a 500Hz.
PWM1_Set_Duty(CU);
PWM1_Start();
while(1) //Bucle infinito.
{
//Bucle de incremento del PWM cuando se pulsa RB1.
while( Button( &PORTB, 1, 10, 0 ) )
{
CU++; if( CU==0 )CU=255;
PWM1_Set_Duty(CU);
delay_ms(10);
}
//Bucle de decremento del PWM cuando se pulsa RB0.
while( Button( &PORTB, 0, 10, 0 ) )
{
CU--; if( CU==255 )CU=0;
PWM1_Set_Duty(CU);
delay_ms(10);
}
}
}
265
Para poder hacer la simulacin de este ejemplo se debe implementar en ISIS los dispositivos:
16F628A, BUTTON, RES, 2N3904, 1N4001, y MOTOR ACTIVE. Configurados como se puede
apreciar en el siguiente circuito:
Circuito 16-3
En funcin de la intensidad de corriente se puede cambiar el transistor para optimizar el
funcionamiento de los sistemas. Un transistor como el 2N3904 puede controlar una corriente de
200m Amperios, y un TIP31 puede controlar una corriente de 3 Amperios, en funcin de la
referencia y sus caractersticas, se puede asumir un mximo de corriente.
16.1.3 Puente H
Los puentes H son arreglos transistorizados que permiten invertir la polaridad sobre una carga
elctrica, con el suministro de solo una fuente sencilla. Los puentes H, se pueden implementar en
discreto con transistores o usar mdulos integrados que se pueden conseguir comercialmente.
Estos arreglos cuentan con dos seales de control que permiten activar la polaridad positiva, y
negativa. Un diseo discreto de este arreglo se puede apreciar en el siguiente circuito:
Circuito 16-4
266
Para activar una polaridad positiva, se activa el control 1, y se apaga el control 2, para activar la
polaridad negativa se hace la configuracin contraria con los pines de control. Se debe tener
presente que nunca se podrn activar los dos puntos de control al mismo tiempo, est accin
genera un corto circuito entre Vcc, y referencia, produciendo daos considerables sobre los
transistores.
El siguiente ejemplo muestra el control de giro sobre un motor DC, por medio de un
microcontrolador 16F628A:
void main( void )
{
OPTION_REG = 0; //Se activan las resistencias PULL-UP.
//Configuracin de salida y entrada del puerto B.
PORTB = 0;
TRISB = 0x0F;
PORTB = 0;
while(1) //Bucle infinito.
{
//Bucle para detectar el botn de giro a la izquierda.
while( Button( &PORTB, 0, 10, 0 ) )
{
PORTB = 0; //Se apagan los pines de control.
PORTB.F7 = 1; //Se activa el pin de control 1.
}
//Bucle para detectar el botn de detener.
while( Button( &PORTB, 1, 10, 0 ) )
{
PORTB = 0; //Se apagan los pines de control.
}
//Bucle para detectar el botn de giro a la derecha.
while( Button( &PORTB, 2, 10, 0 ) )
{
PORTB = 0; //Se apagan los pines de control.
PORTB.F6 = 1; //Se activa el pin de control 2.
}
}
}
267
La simulacin en ISIS, se realiza por medio del siguiente circuito electrnico:
Circuito 16-5
16.1.4 Motores Paso
Los motores paso, son dispositivos electromecnicos que permiten hacer giros fraccionados por
grados, los motores paso son de dos naturalezas; unipolares y bipolares. Un motor unipolar
cuenta con cuatro embobinados, que se energizan uno o dos a la vez, y siempre con la misma
polaridad. Los motores paso bipolares cuentan con solo dos bobinas, las cuales se polarizan al
mismo tiempo, pero alternando la polaridad. Este efecto genera una secuencia en las bobinas y su
polaridad. Manipulando la velocidad de la secuencia se controla la velocidad de giro del motor, y
con el orden de la secuencia se controla la direccin de giro del motor.
En las siguientes grficas se puede apreciar la apariencia fsica de estos motores y su vista en
ISIS:
Figura 16-3
Los motores unipolares, cuentan generalmente con 5 o 6 terminales, de las cuales 4 corresponden
a los embobinados, y 1 o 2 son terminales comunes. Las bobinas de un motor unipolar se pueden
apreciar en el siguiente circuito:
268
Circuito 16-6
La secuencia de activacin para los motores unipolares puede ser de dos formas; con una sola
entrada activa, o dos entradas activas simultneamente. Cuando se activan dos entradas
simultneamente el torque del motor es mayor pero al mismo tiempo la corriente es mayor. La
siguiente tabla muestra la forma de activar las secuencias en los dos casos:
Secuencias para motores paso unipolares
PASO
Secuencia con una activacin Secuencia con dos activaciones
L A L B L C L D L A L B L C L D
1 ON OFF OFF OFF ON ON OFF OFF
2 OFF ON OFF OFF OFF ON ON OFF
3 OFF OFF ON OFF OFF OFF ON ON
4 OFF OFF OFF ON ON OFF OFF ON
Tabla 16-1
El siguiente ejemplo muestra como realizar el control de un motor unipolar con un PIC 16F628A,
que cuenta con una frecuencia de reloj de 4MHz, para este fin la secuencia del motor se guarda
en un arreglo. El cdigo en lenguaje C es el siguiente:
//Constantes con la secuencia de pasos.
const unsigned short PASOS[4] =
{
0b00000001,
0b00000010,
0b00000100,
0b00001000
};
void main( void )
{
//Declaracin de variables.
unsigned short PASO=0;
//Inicio del puerto
TRISB = 0xF0;
PORTB = 0;
OPTION_REG = 0; //Activacin de las resistencias PULL-UP.
269
while(1)//Bucle infinito.
{
//Bucle while para hacer girar en un sentido
//por medio del pin RB6
while( Button( &PORTB, 6, 100, 0) )
{
PORTB = PASOS[PASO];
PASO++;
if( PASO==4 )PASO=0;
}
//Bucle while para hacer girar en un sentido contrario
//por medio del pin RB7
while( Button( &PORTB, 7, 100, 0) )
{
PORTB = PASOS[PASO];
PASO--;
if( PASO==255 )PASO=3;
}
}
}
Para simular este ejercicio se implementa en ISIS, el siguiente circuito electrnico, con el
MOTOR-STEPPER, BUTTON, y el driver ULN2003A:
Circuito 16-7
Para realizar el ejercicio con la secuencia de doble activacin simplemente se cambia la
secuencia en el arreglo del mismo programa y se usa la misma simulacin. El nuevo arreglo es el
siguiente:
//Constantes con la secuencia de pasos.
const unsigned short PASOS[4] =
{
0b00000011,
0b00000110,
270
0b00001100,
0b00001001
};
Para los motores bipolares se implementa un puente H doble, de tal forma que se pueda hacer una
secuencia con doble polaridad. La distribucin elctrica de este tipo de motores es la siguiente:
Circuito 16-8
Para el control de este tipo de motores se requiere de la siguiente secuencia de polaridad:
PASO
Secuencia para Bipolar
L A L B L C L D
1 +V -V +V -V
2 +V -V -V +V
3 -V +V -V +V
4 -V +V +V -V
Tabla 16-2
Para realizar el ejercicio con este motor se implementa el mismo programa del motor unipolar y
se altera el arreglo de la secuencia, en este nuevo arreglo se asume un 1 lgico para los +V, de la
tabla y un 0 lgico para los V. De esta forma se obtiene el siguiente arreglo:
//Constantes con la secuencia de pasos.
const unsigned short PASOS[4] =
{
0b00000101,
0b00001001,
0b00001010,
0b00000110
};
Para la simulacin del sistema se implementa en ISIS un circuito similar, pero con un motor
bipolar y un driver para puente H integrado. Este integrado es el L293D, que es un circuito
integrado que tiene en su interior dos puentes H simultneamente, caracterstica que lo hace ideal
para este tipo de motores. La simulacin en ISIS, implementa el 16F628A, BUTTON, MOTOR-
BISTEPPER, y el L293D. El circuito para simular es el siguiente:
271
Circuito 16-9
16.1.5 Servomotores
Los servomotores son sistemas integrados que tienen un control de posicin angular, y un sistema
mecnico de piones para ofrecer mayor fuerza pero menor velocidad. Un servomotor tiene
incorporado un control de posicin angular, que puede ser gobernado por medio de una seal
PWM. Las aplicaciones de los servomotores estn desde la robtica hasta los modelos a escala
como aviones, helicpteros y carros. Los servomotores cuentan con un terminal de tres pines para
la alimentacin, la referencia y la seal de control PWM. La apariencia fsica y la vista en ISIS de
estos dispositivos es la siguiente:
Figura 16-4
La caracterstica de la seal de control es su periodo de PWM de 16m a 18m segundos y el
periodo til puede variar de 1 a 2 milisegundos, esto hace referencia respectivamente a 0 y 180
grados en la posicin angular. La siguiente grfica ilustra est situacin:
Figura 16-5
272
A continuacin se muestra un ejemplo en lenguaje C, para controlar la posicin de un
servomotor:
//Funcin para generar el PWM de
//baja frecuencia, ajustado para
//cristal de 20MHz.
void Pwm_Sevo( float ang )
{
unsigned int n, max;
max = 1.61*ang;
PORTB.F0 = 1;
delay_ms(1);
for( n=0; n<max; n++ )
delay_us(1);
PORTB.F0=0;
delay_ms(15);
}
void main( void )
{
//Angulo inicial.
float ANGULO=90;
//Inicio del puerto
TRISB.F0 = 0;
//Se activan las resistencias PULL-UP.
OPTION_REG=0;
while(1)//Bucle infinito.
{
Pwm_Sevo(ANGULO); //Se genera un pulso.
//Si se pulsa el botn de RB6
//se decrementan 10 grados.
if( PORTB.F6==0 )
{
ANGULO-=10.0;
if( ANGULO<0.0 )ANGULO=0.0;
while( Button(&PORTB,6,5,0) );
}
//Si se pulsa el botn de RB7
//se incrementan 10 grados.
if( PORTB.F7==0 )
{
ANGULO+=10.0;
if( ANGULO>180.0 )ANGULO=180.0;
while( Button(&PORTB,7,5,0) );
}
}
}
273
Para simular este ejercicio, se implementa en ISIS, el PIC 16F628A, con frecuencia de reloj de
20MHz, MOTOR-PWMSERVO, y el BUTTON. El circuito correspondiente es el siguiente:
Circuito 16-10
16.2 Actuadores AC
Para el uso de actuadores AC, se pueden usar esencialmente dos tcnicas, la primera es la
implementacin de relevadores con la limitacin de que solo pueden hacerse acciones de
conmutacin ON, OFF. Sin embargo se pueden implementar dispositivos en estdo solid como
los TRIAC, estos dispositivos permiten manipular cargas AC, y pueden regular su potencia
haciendo recorte de fase de la seal AC, que generalmente es de 60Hz. Los TRIAC son de fcil
implementacin y su uso puede hacerse aislando las corrientes de potencia con opt acopladores
como los MOC3011, 3010, 3021, etc. Los TRIAC se pueden adquirir en capacidad de la mxima
corriente que pueden soportar. Un TRIAC cuenta con tres terminales que son: A1, A2, y gate, los
TRIAC cortocircuitan las terminales A1, y A2, cuando una corriente circula entre el gate y A1. y
solo se desconecta cuando la corriente de A2 se hace 0, esto es cosible cuando la seal AC, hace
su cruce por cero.
La apariencia fsica y la vista en ISIS de estos dispositivos es la siguiente:
Figura 16-6
Como se puede observar en la grfica los MOC, son dispositivos que internamente tienen un
TRIAC, pero la corriente que pueden soportar es relativamente pequea, y a su vez lo
suficientemente grande para disparar otro TRIAC de mayor potencia. Tambin se puede observar
274
que la compuerta gate de los MOC, se activa por medio de la luz emitida por un LED, este
tambin est incorporado en el mismo encapsulado. En conclusin un TRIAC de gran potencia
puede ser activado por medio de un circuito digital con solo la activacin de un LED.
Para entender este arreglo de forma clara, se puede observar el siguiente circuito:
Circuito 16-11
Para lograr la regulacin de la potencia sobre una carga AC, se hace necesario hacer un recorte
sobre la fase, de la seal de poder seno. La red elctrica comercial tiene 120V AC, y una
frecuencia de 60Hz. Lo que indica que un siclo de la red elctrica dura 1/60, es decir 16,666m
segundos. El trabajo de recorte de la fase se debe hacer sobre cada medio siclo es decir en
8,333m segundos. Lo anterior indica que el recorte de fase se hace entre 0 y 180 grados, y se
repite igual entre 180 y 360 grados. Para comprender de forma clara este concepto se puede
observar la siguiente grfica:
Figura 16-7
275
Para poder realizar el recorte de fase, es indispensable detectar el cruce por cero de la seal seno,
para sincronizarse con ella. Para detectar el cruce por cero existen diversas estrategias, sin
embargo en el prximo ejemplo se mostrar una que implica la implementacin de opto
acopladores. El uso de opto acopladores es ideal para hacer un aislamiento elctrico de la etapa
de potencia con la etapa de electrnica de control. El siguiente programa usa un PIC 16F628A,
con frecuencia de reloj de 20MHz:
//Variables globales.
unsigned short PWM=41, CONT=0;
//Funcin de interrupciones.
void interrupt()
{
//Interrupcin externa por RB0.
if( INTCON.F1 )
{
//Se apaga el pin de disparo.
PORTB.F7=0;
//Se reinicia el contador.
CONT = 0;
//Se apaga la bandera de la interrupcin
//externa.
INTCON.F1=0;
}
//Interrupcin por Timer 0 a 102.4u Seg.
if( INTCON.F2 )
{
//Se incrementa el contador.
CONT ++;
//Se compara el contador con el punto,
//PWM, y se apaga el disparo y es mayor el contador.
if( CONT > PWM )PORTB.F7=1;
//Se apaga la bandera de la interrupcin por
//Timer 0.
INTCON.F2 =0;
}
}
void main( void )
{
//Configuracin de puertos.
TRISB = 0b01111111;
PORTB = 0;
//Activacin del Timer0, y flanco de
//interrupcin externa.
OPTION_REG = 0b01000000;
INTCON = 0b10110000;
while( 1 )// Bucle infinito.
{
276
//Pulsador de menor potencia.
while( Button( &PORTB, 1, 10, 0 ) )
{
//Decremento del recorte de fase.
PWM ++; if( PWM > 84 )PWM=84;
delay_ms(10); //Retardo de cambio.
}
//Pulsador de mayor frecuencia.
while( Button( &PORTB, 2, 10, 0 ) )
{
//Incremento del recorte de fase.
PWM --; if( PWM == 255 )PWM=0;
delay_ms(10); //Retardo de cambio.
}
}
}
Para realizar la simulacin de este ejercicio se implementa en ISIS los dispositivos: 16F628A,
RES, BUTTON, MOC3023, Q4006L4, B80C1000, OPTOCOUPLER-NPN, VSINE, y el
OSCILLOSCOPE. El circuito electrnico es el siguiente:
Circuito 16-12
Despus de correr la simulacin se puede apreciar en el osciloscopio virtual, la siguiente vista:
277
Figura 16-8
El canal A representa la seal sobre la carga de potencia y se puede apreciar sobre est, el recorte
de fase. El canal B, muestra un pico cuando la seal seno presenta su cruce por cero, este pico es
usado por el microcontrolador para sincronizarse con la red por medio de la interrupcin externa.
El canal C, muestra la seal de control que dispara el juego de TRIACs.
278
279
17 Anexos
17.1 Tabla ASCII
ASCII
Hex
Smbolo
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
NUL
SOH
STX
ETX
EOT
ENQ
ACK
BEL
BS
TAB
LF
VT
FF
(Enter)
SO
SI
ASCII
Hex
Smbolo
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
10
11
12
13
14
15
16
17
18
19
1A
1B
1C
1D
1E
1F
DLE
DC1
DC2
DC3
DC4
NAK
SYN
ETB
CAN
EM
SUB
ESC
FS
GS
RS
US
ASCII
Hex
Smbolo
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
20
21
22
23
24
25
26
27
28
29
2A
2B
2C
2D
2E
2F
(Espacio)
!
"
#
$
%
&
'
(
)
*
+
,
-
.
/
ASCII
Hex
Smbolo
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
30
31
32
33
34
35
36
37
38
39
3A
3B
3C
3D
3E
3F
0
1
2
3
4
5
6
7
8
9
:
;
<
=
>
?
ASCII
Hex
Smbolo
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
40
41
42
43
44
45
46
47
48
49
4A
4B
4C
4D
4E
4F
@
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
ASCII
Hex
Smbolo
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
50
51
52
53
54
55
56
57
58
59
5A
5B
5C
5D
5E
5F
P
Q
R
S
T
U
V
W
X
Y
Z
[
\
]
^
_
ASCII
Hex
Smbolo
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
60
61
62
63
64
65
66
67
68
69
6A
6B
6C
6D
6E
6F
`
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
ASCII
Hex
Smbolo
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
70
71
72
73
74
75
76
77
78
79
7A
7B
7C
7D
7E
7F
p
q
r
s
t
u
v
w
x
y
z
{
|
}
~
280
281
Bibliografa
Behrouz A. Forouzan, Transmisin de datos y redes de comunicaciones, Segunda Edicin, Mc
Graw Hill, ISBN 84-481-3390-0.
Boylestd Robert, Electronica: Teoria de Circuitos, Sexta Edicion, PRENTICE HALL, ISBN
968-880-805-9.
Coughlin Robert, Amplificadores operacionales y circuitos integrados lineales, Quinta Edicion,
PRENTICE HALL, ISBN 970-17-0267-0.
Dorf Richard, CIRCUITOS ELECTRICOS Introduccin al Analisis y Diseo, Tercera Edicion,
Alfaomega, ISBN 970-15-0517-4.
Galeano Gustavo, Programacin de Sistemas Embebidos en C, Primera Edicion, Alfaomega,
ISBN 978-958-682-770-6.
Ogata Katsuhiko, Ingenieria de Control Moderna, Tercera Edicion, PRENTICE HALL, ISBN
970-17-0048-1.
M. Morris Mano, Logica Digital y Diseo de Computadores, Primera Edicion, PRENTICE
HALL, ISBN 968-880-016-3.
Oppenheim Alan, Seales y Sistemas, Segunda Edicion, PEARSON PRENTICE HALL, ISBN
970-17-0116-X.
Proakis John, Tratamiento digital de seales, Cuarta Edicion, PEARSON PRENTICE HALL,
ISBN 978-84-8322-347-5.
282
283
ndice
1
16F628A 58, 162, 166, 176, 264, 265, 266, 268, 270, 273,
275, 276
16F84A 39, 46, 47, 49, 52, 58
16F877A 65, 71, 75, 77, 79, 89, 94, 110, 113, 118, 120,
121, 123, 124, 126, 129, 130, 133, 137, 140, 146, 170,
174, 189, 241
18F2550 88, 95, 96
18F452 71, 150, 159, 181, 202, 229, 231
18F4550 88, 95
18F4585 234, 238
2
24LC00 89
7
74LS04 176
A
ACK 88, 141, 143, 244, 245, 246, 247, 248, 249, 250,
251, 256, 257, 259, 260, 279
acknowledge 88
Actuadores AC 273
Actuadores DC 262
Actuadores y potencia 262
AD 109, 128, 129, 132, 136, 139, 202
ADC 17, 109, 124, 128, 129, 130, 133, 136, 137, 140,
173, 203, 206, 216, 218, 223, 230, 236
ADC_Read 109
ADCON1 90, 129, 136
AND 25, 26, 27, 30, 177
Anexos 279
ASCII 20, 21, 50, 54, 59, 60, 61, 85, 86, 87, 94, 95, 126,
149, 175, 244, 279
ASK 161, 174, 175
B
Bibliografa 281
bilineal 212, 213, 219, 221, 239
bit 20, 21
BJT 262, 263
Button 74, 76, 91, 173, 264, 266, 269, 272, 276
BUTTON 35, 37, 75, 79, 89, 118, 126, 166, 174, 231,
265, 269, 270, 273, 276
ByteToStr 59, 80, 189
C
CAP 113, 174, 231
Caractersticas bsicas del ISIS para simular 35
Ch
char 20, 21
C
COM 47, 167
COMPIM 159
Comunicacin con dispositivos 147
Comunicacin con memorias SD 177
Comunicacin RS 485 172
Comunicaciones seriales 88
Condicionales e iteraciones en lenguaje C 30
Control de display de 7 segmentos 45
Control de displays 7 segmentos dinmicos 47
Control de errores 252
Control digital PID 238
Conversin AD y DA 109
Conversin AD, o ADC 109
Conversin DA con arreglo R-2R 114
Conversin DA con PWM 110
Conversin DA o DAC 110
Convolucin 192
coordenadas 55, 72, 73, 148, 149, 151, 153, 155, 158
CRC 252, 253, 254, 255, 256, 257, 258, 260
Creacin de caracteres propios 59
Creacin de condiciones lgicas en lenguaje C 30
Creacin de un programa en lenguaje C 29
Creacin del primer programa en MikroC PRO 38
cruce por cero 273, 275, 277
D
DA 110, 114, 203
DB9 92
Declaracin de variables en lenguaje C 20, 244, 247, 252
Definit.h 99, 100
delay_ms 46, 47, 48, 73, 91, 99, 130, 133, 137, 140, 142,
144, 145, 164, 165, 173, 176, 184, 185, 189, 264, 272,
276
delay_us 46, 113, 116, 142, 163, 164, 272
DIN 84
Dip-Switch 76, 77, 78
display 44, 45, 46, 47, 48, 50, 51, 52, 53, 54, 64, 65, 70,
73, 79, 83, 87, 154, 158, 159
Display de 7 segmentos 44
Display LCD de caracteres 50
Display LCD grficos 64
284
double 20, 21
DS1307 183, 184, 189
DTF 228
E
EEPROM 117, 118
EEPROM_Read 117
EEPROM_Write 117
Ejemplo de diseo filtro rechaza banda 222
Ejemplo de diseo oscilador doble cuadrado 225
Ejemplo de diseo para filtro multi banda 210
Ejemplo de diseo para filtro pasa altas 207, 217
Ejemplo de diseo para filtro pasa bajas 204, 215
Ejemplo de diseo para filtro pasa banda 208, 220
Ejemplo de diseo para filtro rechaza banda 209
Ejemplo de diseo para oscilador de acople en cuadratura
226
Ejemplos de diseo para filtros FIR 202
El autor 11
El ciclo iterativo for 33
El ciclo iterativo while y do while 32
El compilador MikroC PRO 18
El microcontrolador PICMicro 17
El simulador ISIS de Proteus 34
ENQ 246
EOT 244, 245, 246, 247, 249, 250, 251, 257, 260, 279
F
FFT 232, 233, 234, 235, 237
Filtro Multi Band 196
Filtro Pasa Altas IIR 216
Filtro Pasa Bajas IIR 213
Filtro Pasa Banda 194
Filtro Pasa Banda IIR 219
Filtro Rechaza Banda 195
Filtro Rechaza Banda IIR 221
Filtros FIR 192
Filtros IIR 212
Filtros Pasa Altas 194
FIR 191, 192, 193, 196, 197, 202, 212, 213, 215, 226, 229
FLASH 117, 118, 119, 120
FLASH_Read 119, 120
FLASH_Write 118, 120
float 20, 21
FloatToStr 58, 146, 154, 157, 158, 237
Formatos numricos usados en el lenguaje C 23
FSK 161
funcin de transferencia 131, 134, 135, 136, 137, 191,
193, 194, 195, 197, 205, 212, 214, 219, 221, 239
Funciones de transferencia 191
Funciones en lenguaje C 27
Funciones para imprimir cadenas de texto 55
Funciones para imprimir caracteres 54
Fundamentos de lenguaje C 20, 243
G
Gibbs 197, 198, 199, 200, 201, 202
GIE 124, 125
GLCD 65, 66, 67, 69, 71
GLCD Bitmap Editor 66
Glcd_Box 72, 73
Glcd_Circle 72, 73
Glcd_Dot 72, 73
Glcd_Fill 70, 71, 73
Glcd_Init 65, 70, 73
Glcd_Line 72, 73
Glcd_Rectangle 72
GP2D12 134, 137
GPS 88, 147, 148, 149, 152, 160, 161
GROUND 36
H
HID 88, 98, 99, 100, 101, 103, 104, 105, 107, 108
HID Terminal 100, 107
Hid_Disable 99
Hid_Enable 98, 99
Hid_Read 99
Hid_Write 99
I
I2C 17, 88, 90, 184, 189
IC 88, 141, 183
I2C1_Init 88, 90, 184
I2C1_Is_Idle 88
I2C1_Rd 88, 90, 184, 185, 186
I2C1_Repeated_Start 88, 90, 184, 185, 186
I2C1_Start 88, 90, 91, 183
I2C1_Stop 89, 91, 184, 185, 186
I2C1_Wr 89, 90, 91, 183, 184, 185, 186
I2CDEBUGGER 89
IEEE 801.15.4 167
IIR 191, 212, 215, 226, 229, 239
Impresin de valores numricos 57
infrarrojos 174, 176
int 20, 21
I NTCON 98, 124, 125, 126, 150, 158, 203, 204, 206, 216,
218, 219, 223, 224, 226, 227, 228, 230, 231, 236, 237,
275
INTE 124, 125
Interrupciones 124
INTF 100, 103, 104, 124, 125
Introduccin 15
IntToStr 57, 58, 130, 133, 137, 153, 156, 157, 159, 237
IRLINK 175, 176
ISIS 1, 5, 34, 35, 37, 40, 47, 49, 50, 52, 57, 61, 63, 64, 65,
71, 73, 75, 76, 77, 79, 84, 89, 91, 94, 96, 110, 116, 118,
120, 123, 126, 128, 130, 131, 133, 134, 137, 138, 140,
141, 146, 147, 159, 160, 161, 167, 175, 176, 181, 183,
189, 202, 203, 231, 238, 262, 263, 265, 267, 269, 270,
271, 273, 276
K
Keypad_Init 79
Keypad_Key_Click 79
Keypad_Key_Press 79, 80, 82, 83
285
L
L293D 241, 270
La sentencia condicional if e if else 31
La sentencia switch case 32
LCD 44, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 61, 62, 63,
64, 65, 71, 72, 73, 80, 82, 83, 86, 87, 129, 132, 136, 137,
139, 140, 146, 154, 158, 159, 169, 170
LCD Custom character 60
Lcd_Chr 54, 55, 59, 83, 87
Lcd_Chr_Cp 54, 55, 59
Lcd_Cmd 64, 80, 83, 87, 129, 132, 137, 140, 146, 158
Lcd_Init 51, 52, 54, 55, 56, 57, 58, 61, 63, 80, 83, 87, 129,
132, 136, 140, 146, 158, 169
Lcd_Out 55, 56, 57, 58, 80, 83, 87, 129, 130, 132, 133,
137, 140, 146, 158, 159, 170
Lcd_Out_Cp 55, 57
LDR 138, 139, 140
LED 35, 44, 75, 77, 89, 96, 110, 118, 126, 166, 189, 231,
274
Library Manager 51
LM35 128, 130, 131
long 20, 21
LongToStr 59, 140, 180, 181
LongWordToStr 59
M
main 29, 30, 39, 46, 48, 49, 52, 54, 55, 56, 57, 58, 61, 63,
65, 70, 72, 75, 76, 77, 80, 83, 84, 87, 90, 94, 98, 109,
112, 115, 117, 119, 122, 124, 126, 129, 132, 136, 139,
145, 150, 158, 165, 166, 169, 172, 175, 178, 188, 204,
206, 216, 219, 223, 226, 228, 231, 237, 264, 266, 268,
272, 275
matriz de rotacin 224, 225, 227
MAX232 93
MAX485 172, 173, 174
MAX487 174
MCLR 40
Memoria EEPROM 117
Memoria FLASH 118
Memorias EEPROM y FLASH 117
MikroC PRO 1, 5, 13, 15, 18, 20, 38, 45, 50, 51, 59, 62,
65, 66, 71, 72, 74, 79, 80, 84, 88, 89, 93, 96, 98, 99, 109,
112, 117, 124, 177, 190
Mmc_Init 178
Mmc_Read_Sector 178, 181
Mmc_Write_Sector 178, 181
MOC3011 273
MODEM 167
Mdulo de acople con un ordenador personal 168
Modulo serial IC 88
Mdulo USART 91
Mdulo USB 95, 108
Mdulos GPS 147
Mdulos inalmbricos bidireccionales 167
Mdulos inalmbricos infrarrojos 174
Mdulos inalmbricos unidireccionales 161
Mdulos Timer 121
MOSFET 262, 263
MOTOR 265, 269, 270, 273
motor unipolar 267, 268, 270
Motores AC 262
motores bipolares 270
Motores DC 264
Motores Paso 267
MPX4115 131, 133
Muestreo 190
N
NAK 244, 245, 246, 247, 248, 249, 250, 257, 259, 260,
261, 279
NOT 25, 26, 30
Nyquist 190
O
Operadores en lenguaje C 23
OPTI ON_REG 122, 126, 165, 173, 264, 266, 268, 272,
275
opto acopladores 275
OR 25, 26, 27, 30
Osciladores digitales 224
OSCILLOSCOPE 113, 123, 126, 202, 276
P
PICMicro 17, 18, 34, 38, 109, 190
PID 99, 103, 238, 239, 241
PI E1 98, 124, 125, 126, 150, 158
PI E2 98, 124, 125, 126, 150, 158
PI R1 98, 124, 125, 126, 150, 157, 158
PI R2 98, 124, 126, 150, 158
PLL 98, 202
PORTA 48, 49, 90, 91
PORTB 30, 39, 40, 46, 48, 75, 76, 77, 90, 91, 98, 99, 109,
115, 116, 117, 119, 122, 125, 126, 158, 165, 166, 172,
173, 203, 204, 206, 216, 219, 223, 224, 226, 228, 231,
237, 264, 266, 268, 269, 272, 275, 276
POWER 36, 100
Prologo 13
PS2 74, 84, 86, 122
Ps2_Config 84
Ps2_Key_Read 84, 87
Puente H 265
PULL-UP 165, 173, 174, 264, 266, 268, 272
PWM 17, 109, 110, 111, 112, 113, 114, 115, 116, 162,
173, 175, 176, 264, 271, 272, 275, 276
PWM1_Init 112, 173, 175, 264
PWM1_Set_Duty 112, 113, 173, 176, 264
PWM1_Start 112, 173, 175, 264
PWM1_Stop 112
R
R-2R 114, 203
RAM 18, 59, 63, 103, 177, 234
RCIE 124, 125
RCIF 124, 125
recorte de fase 273, 274, 275, 276, 277
Relevadores 263
286
reloj 84, 88, 91, 98, 121, 141, 142, 143, 145, 159, 162,
178, 183, 188, 189, 202, 241, 268, 273, 275
Relojes en tiempo real 183
RES 35, 47, 49, 75, 77, 79, 89, 96, 110, 113, 118, 126,
130, 137, 140, 146, 166, 174, 176, 189, 202, 231, 265,
276
RS 485 172
RS232 34, 92, 93
S
SD 88, 105, 177, 178, 179
Sensor de temperatura LM35 128
Sensores 128
Sensores de distancia 134
Sensores de humedad y temperatura 141
Sensores de presin 131
Sensores LDR 138
Servomotores 271
short 20, 21
ShortToStr 59
SHT71 146
SHT7x 141, 145, 146
SPI 88, 177, 178, 181
SPI1_Init_Advanced 178, 181
switch case 30, 32, 82, 83
T
teclado 18, 78, 79, 80, 81, 82, 83, 84, 86, 87
Teclados y sistemas de entrada de datos 74
Timer 17, 121, 122, 125, 126, 275
Timer 0 121, 122
TMR0IE 124, 125
TMR0IF 124, 125
Transformacin bilineal 213
Transformada discreta de Fourier DFT 228
Transformada rpida de Fourier FFT 232
Transmisin 243
Tratamiento digital de seales 190
TRIAC 273
TRISA 49
TRISB 30, 39, 40, 46, 49, 75, 76, 77, 90, 98, 109, 115,
117, 119, 122, 126, 158, 165, 166, 172, 204, 206, 216,
219, 223, 226, 228, 231, 237, 266, 268, 272, 275
TRISE 90
TTL 172
typedef struct 22
U
UART1_Data_Ready 93, 95, 119, 170, 173, 179, 180, 181
UART1_Init 93, 94, 119, 126, 150, 158, 169, 173, 175,
178, 189, 237
UART1_Read 93, 95, 119, 126, 150, 157, 170, 173, 179,
180, 181
UART1_Read_Text 93
UART1_Tx_Idle 93
UART1_Write 93, 94, 95, 119, 120, 126, 170, 173, 176,
178, 179, 180, 181, 189, 237
UART1_Write_Text 94, 95, 119, 120, 126, 170, 176, 178,
179, 180, 181, 189, 237
unsigned char 21
unsigned int 21
unsigned long 21
unsigned short 21
USART 17, 18, 58, 88, 91, 93, 94, 124, 149, 169, 172,
173, 175, 189
USB 18, 34, 88, 95, 96, 98, 99, 100, 101, 102, 103, 105,
107
USBCONN 96
USBdsc.c 99, 107
Uso anidado de ciclos iterativos 33
Uso de Dip-Switch 76
Uso de pulsadores 74
Uso de teclados matriciales 78
Uso de teclados PS2 o Din 84
V
variable compleja 191, 212
VARs.h 99, 104
Ventanas Blackman 201
Ventanas fijas 196
Ventanas Hamming 198
Ventanas Hanning 199
Ventanas Rectangulares 197
VIP 99
VIRTUAL TERMINAL 94, 120, 126, 170, 176, 181, 189,
238
Visualizacin de datos 44
VSINE 276
VUSB 96
W
WordToStr 59
www.digi.com 167
www.labcenter.com 34
www.mikroe.com 18
www.virtual-serial-port.com 147
X
XBee 88, 167, 169
XBee PRO 167
X-CTU 167, 169
Z
Zigbee 169
287
288
289