-[ 0x0C ]-------------------------------------------------------------------- -[ Curso de electronica 07 ]------------------------------------------------- -[ by elotro ]-------------------------------------------------------SET-36-- _____________________________________________ Electronica - Septima Entrega _____________________________________________ #include <16f877.h> #use delay(clock=20000000) #fuses XT,NOWDT,losotrosquenomelosacuerdo #define use_portb_lcd true #include void main(){ lcd_init(); printf(lcd_init,"Hola display!!"); } Ahora que comprendo que esta es la 7¦ entrega, comienzo a creer que realmente tengo bastante tiempo libre como para ponerme a escribir de cosas que solamente me interesan a mi (y a un par de almas por ahi) Si viajamos al pasado en nuestra maquina jamaiquina del tiempo, recordaremos que en la entrega numero 29 de SET, mas precisamente en el articulo 0x0A, nuestro amigo blackngel trato el tema de los microcontroladores, centrandose en el modelo PIC16F84, de la empresa Microchip. Yo voy a aportar mi [humilde] granito de arena, retomando el tema de la programacion de microcontroladores, y el disenyo de circuitos electronicos con ellos. Si recuerdan bien, blackngel hizo uso del lenguaje Basic para la programacion, mientras que yo hare mi humilde intento con C. Para ello vamos a valernos de herramientas informaticas muy utiles, y de facil acceso en la web (lo que no quiere decir que sea soft libre..) Antes de comenzar: """""""""""""""""" > Entorno de desarrollo CCS PICC, de la empresa Custom Computer Services [doy fe que anda pirateado por ahi, si no lo encuentran, pedirlo a mi ] > MPLAB, de la empresa Microchip. Disponible gratuitamente en su web. > Winpic 800, disponible tambien de forma gratuita en su web. [instalar primero mplab, luego ccs, y luego winpic800] > Algun programador de PIC, el que prefieran. Recomendados JDM Programmer (el esquema esta en el articulo de blackngel), o ProPic2. > Un microcontrolador PIC16F628, o similar Este uC es la version mejorada del famoso 16F84, y cuenta con mas pines de I/O que su predecesor, y sorprendentemente, es mas barato. (alrededor de 7 U$S) > Opcional: PROTEUS, es un software de simulacion electronica que permite simular distintos modelos de procesadores, ademas de circuitos analogicos y digitales. (recomendado) Aclaro: Desconozco si este articulo acompanyara al de disenyo electronico (incluso desconozco si llega a madfran, su email y yo no nos llevamos muy bien..) En ese articulo no trate la simulacion con proteus por 2 razones: - No lo conocia - Lo voy a hacer aca. ->->->->->->->->->->->->->->->->->->->->-> Herramientas de Trabajo ->->->->->->->->->->->->->->->->->->->->-> Comencemos por PICC: Es un entorno de desarrollo integrado para la creacion de binarios para microcontroladores, usando el lenguaje C. [con unas pequenyas variaciones] Cuenta con una amplia variedad de modelos de microcontroladores soportados, y variadas herramientas internas que nos facilitaran la tarea a la hora de programar. Sobre MPLAB, nada que decir. Assembler y mas assembler, con un gran soporte de la empresa fabricante. Y Winpic800 es un programador de microcontroladores muy potente, que realiza autodeteccion del dispositivo programador, y del dispositivo a programar. Soporta una amplia gama de programadores, y la libreria se puede ampliar a gusto del usuario. La empresa fabricante tambien distribuye un programador por puerto USB, que esta a un precio normal para la versatilidad que presenta. Yo usare el programador ProPIC 2, que es uno de los mas versatiles que conozco. Se vende en comercios del ramo, y es muy sencillo de utilizar, [tambien pueden encontrarlo bajo el nombre de pic programmer 3] ->->->->->->->->->->->->->->->->->->->->-> Domando a la bestia ->->->->->->->->->->->->->->->->->->->->-> Los microcontroladores son los dispositivos [en mi opinion] mas versatiles que ofrece la electronica. Para aquel que no sepa que es un microcontrolador [muy largo, uC en adelante], se lo resumo en una sola idea. Ordenador en una pastilla. [ojo con las pastillas muchachos..] [no sea que explotes de extasis..] Pero claro, este ordenador tiene su propio procesador, con su juego de instrucciones. Aparte de tener una memoria de programa ROM limitada, y una RAM que tambien esta limitada. Como todo ordenador, tiene comunicacion con el exterior, que consta de salidas/entradas digitales [analogicas..no se, busquen ustedes], igual que un ordenador normal. En el caso de los uC que veremos aqui, la familia PIC, nuestro ordenador tiene un potente [si, y que] procesador RISC [ay, que emocion...!!], con un juego de instrucciones que ronda las 35 - 50 instrucciones en la gran, gran mayoria de modelos. Supongo que alguno habra escuchado de los registros de trabajo de los x86, los famosos AX,BX (16bit) o EAX,EBX (32), y otros mas. Nuestro pic tambien tiene esos registros...pero solo 1. El registro W. [de Work, trabajo en ingles] [que inmaginacion esta gente....!!] Bue, yasta! Me estoy llendo por las ramas, y estos aspectos tecnicos de los pics no nos interesan cuando programamos en alto nivel, especialmente con picc, ya que la gente que se puso a hacer este programita se tomo el arduo trabajo de hacer lo mas complicado por nosotros. En nuestro caso, que usamos el PIC16F628 (con la letra A, o no..segual) vamos a tener....: - 35 instrucciones del procesador - Una rom de 2048 palabras - Una ram de 224 bytes - Y otras cositas mas de regalo como: - Memoria EEPROM de 128 bytes, que podemos modificar en tiempo de ejecucion - Una USART (como la uart de la pc, pero tambien sincrona) - Un modulo de captura y comparacion - Salida PWM - 2 Comparadores de tension (como el que explique en el articulo de operacionales, pa que vean que no les miento) - Y 2 temporizadores (+o- como los que explique con 555) Y para comunicarnos con el exterior tenemos 2 puertos de comunicacion de 8 bits, que podemos configurar a piachere como entradas o salidas [ bueno, casi ] La disposicion de pines de este aparatito es algo mas o menos asi: ________ RA2-| o |-RA1 RA3-| |-RA0 RA4-| |-RA7 RA5-| |-RA6 GND-| |-V+ RB0-| |-RB7 RB1-| |-RB6 RB2-| |-RB5 RB3-| |-RB4 `--------' Los algunos pines tienen caracteristicas especiales, que hacen que sirvan de entradas/salidas controladas normales, o entradas/salidas especiales por programa, o que afectan directamente al hard. RB1/RX/DT RB2/TX/CK RB3/CCP1 RA3/AN3/CMP1 RA4/TOCKI/CMP2 RA5/MCLR/VPP RB0/INT RA2/AN2/VREF RA6/OSC2/CLKOUT RA7/OSC1/CLKIN RA1/AN1 RA0/AN0 RB6/T1OSO/T1CKI/PGC RB7/T1OSI/PGD RB4/PGM Por ahora, vamos a dejar de lado las funciones especiales de los pines, hasta que tomemos practica con la programacion. [mmm...tal vez haya algo de rx/tx, o int.. ya veremos si tengo ganas] Lo que estoy totalmente seguro que si vamos a usar en algun momento, va a ser la funcion MCLR de RA5. Que es MCLR? Master CLear Reset, o sea un reset general del pic. Reinicia el programa desde la direccion de memoria 0x00, y pone todos los registros internos a 0 (algunos inician en valores particulares). En el caso que se especifique que el pin mclr cumplira la funcion de reset, deberemos tener en cuenta que la entrada se debe mantener siempre en un estado alto, y debe pasar a bajo cuando se necesite el reset, o sea: o V+ | _____ \ R1 | / de unos | \ 10K | |-------------| MCLR | | _|o Switch | |o Reset |____ | [na] | GND El microcontrolador PIC16f628 cuenta con otras caracteristicas muy notables: Seleccion de oscilador interno o externo - Oscilador interno de 4MHz calibrado a ñ1% - Oscilador interno de bajo consumo de 37KHz - El oscilador externo puede ser por pulsos, cristal o red RC - Modo SLEEP de bajo consumo - Pullups programables en el puerto B - El MCLR se puede multiplexar en tiempo - El oscilador del wdt es independiente a la cpu - Programacion ICSP - Proteccion de codigo - Reset browuout (fallo de alimentacion) - Reset al arranque - Temporizador PUT al arranque - Opera desde 2.0 a 5.5 V - 100.000 ciclos de escritura de Flash garantizados - 1.000.000 ciclos de escritura de eeprom, tambien garantizados - Ambas memorias retienen los datos por 100 anyos (asi dicen...) Consumo en modo sleep: - 100 nA a 2.0V, tipico (no garantido) La 'cpu' consume en modo sleep - 12æA a 32 kHz, 2.0V - 120æA a 1 MHz, 2.0V El wdt consume - 1 æA a 2.0V El timer1 consume - 1.2æA a 32 kHz, 2.0V - 4 æs para pasar de sleep a modo normal ->->->->->->->->->->->->->->->->->->->-> Identico, pero no tanto ->->->->->->->->->->->->->->->->->->->->-> Este programa es el idem del 'Hola mundo' en un PC. <++>picc/basico.c #include <16f628.h> //Cabecera, definiciones [ver el arch para mas info] #use delay(clock=4000000) //Frecuencia de reloj en Hz #fuses intrc_io,nowdt,noput,nomclr,nolvp,brownout //''Fusibles'' // [entre muchas comillas] //Bucle principal void main(){ do{ //Hasta el fin de los tiempos output_high(PIN_A0) //Poner en alto RA0 delay_ms(1000); //Esperar 1 segundo output_low(PIN_A0) //Ponerlo en bajo delay_ms(1000); //Esperar otro segundo }while(true) //Repetir eternamente } <++> Y el circuito que tendriamos que montar seria: ________ | 220 Led [faltan las alimentaciones, A0 |------\/\/\---->|----. por los pines que indique PIC | | arriba. 5V (no mas,ojo!) ] 16f628 | | ________| gnd Supongo que a estas alturas de la vida, te debes estar preguntando que joracas sucedio con el programa de arriba..que adonde esta stdio.h, que de donde saque esas funciones no definidas[ni incluidas,ni nada], y que quieren decir esos preprocesadores mas raros que la mier.. #include <16f628.h> Aqui indicamos el modelo de pic a utilizar. Consulten la ayuda de picc [para algo la trae no?] para saber que modelos son soportados Se declaran constantes que sirven para facilitar el manejo del pic, aparte del tipo boolean, que no existe en picc, al menos en mi version. Boolean equivale a un int de 1 bit de largo. [tambien hay otras cosas,superfluas] #use delay(clock=4000000) Este tal #use es un preprprpprprp ejem! .. preprocesador [ahora si] que es interpretador por el compilador de picc. Tiene muchas variantes que nos permiten controlar el hard, o hacer tareas de software de manera muy sencilla. En este caso, definimos la frecuencia de reloj a la que trabajara el pic. 4000000 Hz = 4MHz #fuses .......... Es la palabra de configuracion del pic. Cada pic tiene sus parametros especiales, que podemos consultar en el ide del picc, en View\Valid Fuses En este caso es: intrc_io -> oscilador interno [no necesita xtal ni nada] nowdt -> sin temp. watchdog noput -> sin temp. de arranque nomclr -> mclr desactivado nolvp -> para programar en circuito. Desactivado brownout -> brownout reset. Reset total cuando hay un fallo de alimentacion output_high(....) Pone en estado alto (5V) el pin seleccionado. Ver el archivo de cabecera del pic para obtener las constantes de los pines, pero generalmente se indican como PIN_Xx, donde X es el puerto, y x es el bit. Por ejemplo, PIN_B7 = RB7 delay_ms(....) Realiza una demora de .... milisegundos. Necesita la declaracion #use delay para funcionar correctamente. } Ah,este no era... o si..? Si todo salio bien, una vez que montamos el circuito en la vida real o en proteus, vamos a ver que el led se enciende y apaga en intervalos de 1 segundo. ->->->->->->->->->->->->->->->->->->->->-> Las 7 de oro ->->->->->->->->->->->->->->->->->->->->-> En el 98.7897897899593% de los programas [mentira, que se yo] vamos a utilizar 5 funciones integradas de picc para hacer toda la tarea: > output_high(PIN_Xx) Pone en alto un pin > output_low(PIN_Xx) Pone en bajo un pin > output_x(int Dato) Pone el puerto x en el estado que indique el int dato, siendo el lsb el bit 0, y el msb el bit 7 (o el mas alto del puerto, algunos llegan hasta 5 solamente) > dato = input(PIN_Xx) Devuelve un valor booleano que indica el estado de PIN_Xx, donde X es el puerto, x el bit [ como mas arriba ] > dato = input_x() Devuelve un int con el estado del puerto x > delay_AA(tiempo) Realiza una demora en la ejecucion del programa, segun AA y tiempo. AA puede ser en ms o us. Tiempo un valor < 65535 y >0. > delay_cycles(xx) Realiza una demora en la ejecucion del programa, de xx ciclos de programa , que debe ser menor que 65535 y mayor que 0. A aprenderlas de memoria eh! ->->->->->->->->->->->->->->->->->->->->-> Facil como 1+1 ->->->->->->->->->->->->->->->->->->->->-> Una vez conocidas las funciones anteriores ya estan en condiciones de ir por algo un poco mas complejo, como un contador de eventos por ejemplo. Vamos a hacer un contador que cuente los pulsos aplicados a una entrada(ct_eventos), y luego, cuando se active otra entrada(contar), prenda y apague un led tantas veces como pulsos se aplicaron. Lo no explicado, c comun y corriente. [ puede que en este o en cualquier otro programa haya haya errores o mejores maneras de hacer lo mismo. correcciones son aceptadas de muy buena gana, no soy guru de c] <++>picc/contador.c #include <16f628.h> #use delay(clock=4000000) #fuses intrc_io,nowdt,noput,nomclr,nolvp,brownout #define ct_eventos PIN_A0 //Si, definicion de una definicion #define contar PIN_A1 //picc acepta eso #define led PIN_A2 void main(){ int eventos=0; int a; do{ do{ if ( input(ct_eventos) ) eventos++; delay_ms(200); }while( !input(contar) ); for(a=0;a<=eventos;a++){ output_high(led); delay_ms(500); output_low(led); delay_ms(500); } eventos=0; }while(true); } <++> No comente, porque no hay que comentar.. Picc acepta esas cosas algo extranyas como un #define de un #define, y algo bastante extranyo es que [ al menos el que yo tengo ] es totalmente indiferente al uso de mayusculas o minusculas a la hora de referirse a funciones, preprocesadores o variables. Asi que ojo, porque output_high(PIN_A0) es lo mismo que OUTPUT_HIGH(PIN_A0) y int a; es lo mismo que int A; [ repito: al menos en el que yo tengo, v3.6..y algo] ->->->->->->->->->->->->->->->->->->->->-> A practicar ->->->->->->->->->->->->->->->->->->->->-> Si hay algo que odio desde que hago el intento de aprender lenguajes de programacion, es el no saber que programar para practicar, o no tener ejercicios o problemas de programacion. Asi que les dejo algunas ideas: -Hacer que 8 leds prendan en secuencia como la del auto fantastico -Hacer que el pic memorice 4 entradas en cualquier pin del puerto a, y haga la misma secuencia en el puerto b -Hacer un generador de onda cuadrada [mas o menos] de 1 KHz Propongo las soluciones al final del articulo. ->->->->->->->->->->->->->->->->->->->->-> Mini proyecto ->->->->->->->->->->->->->->->->->->->->-> Este codigo nacio como parte de un trabajo escolar que nos encargo nuestro profesor LG. Se trata de un sistema de control de acceso a una planta industrial, mediante un teclado matricial y un pic. Debe tener una clave de 4 digitos, que conoceran aquellos que esten autorizados a entrar al lugar, y al cabo de 3 intentos erroneos, debe activarse una alarma. Un teclado matricial es una matriz de contactos, organizados de esta manera [se me va un ascii larrrrrgo] (*) = Conexion | | | | | | | | | | | | o-------(*)-----------(*)-----------(*) | | | | | | | | | | | | o-------(*)-----------(*)-----------(*) | | | | | | | | | | | | o-------(*)-----------(*)-----------(*) Este es un teclado de 3 columnas por 3 filas. Yo utilizare uno de 4x3, como el de un telefono. Bah, estoy usando el de un telefono. El mismo que se hace llamar keypad-phone en proteus. El metodo que voy a usar para leerlo es el siguiente: activar columna1 a=1 hasta 100 si (fila 1) tecla=1 si (fila 2) tecla=4 si (fila 3) tecla=7 si (fila 4) tecla=* si (tecla) a=100 ---> sale del bucle repetir a desactivar columna1 si (!tecla) activar columna2 a=1 hasta 100 si (fila 1) tecla=2 si (fila 2) tecla=5 si (fila 3) tecla=8 si (fila 4) tecla=0 si (tecla) a=100 ---> sale del bucle repetir a desactivar columna2 si (!tecla) activar columna3 a=1 hasta 100 si (fila 1) tecla=3 si (fila 2) tecla=6 si (fila 3) tecla=9 si (fila 4) tecla=# si (tecla) a=100 ---> sale del bucle repetir a desactivar columna2 si (!tecla) ve al principio, y repite Y este pseudo-pseudocodigo es un diagrama de flujo a las apuradas, que no tiene nada de diagrama de flujo. Pero se puede trasladar facilmente a C. <++>picc/lector_teclado.c int get_teclado(){ int a,tecla; tecla=0; do{ output_high(Columna1); for(a=1;a<=100;a++){ if(input(Fila1)) tecla = 1 ; if(input(Fila2)) tecla = 4 ; if(input(Fila3)) tecla = 7 ; if(input(Fila4)) tecla = 10 ; if(tecla) a=100; } output_low(Columna1); if(!tecla){ output_high(Columna2); for(a=1;a<=100;a++){ if(input(Fila1)) tecla = 2 ; if(input(Fila2)) tecla = 5 ; if(input(Fila3)) tecla = 8 ; if(input(Fila4)) tecla = 20 ; if(tecla) a=100; } output_low(Columna2); } if(!tecla){ output_high(Columna3); for(a=1;a<=100;a++){ if(input(Fila1)) tecla = 3 ; if(input(Fila2)) tecla = 6 ; if(input(Fila3)) tecla = 9 ; if(input(Fila4)) tecla = 11 ; if(tecla) a=100; } output_low(Columna3); } }while(!tecla); if(tecla==20) tecla=0; return tecla; } <++> En este caso, para poder utilizar un solo tipo de dato, y no tener que hacer conversiones que nos consuman ciclos de reloj, interpreto el * como un 10, y el # como un 11. Y para no tener que inventar la rueda nuevemente (no me gusta como suena reinventar), doy valor de 20 al 0, y luego lo establezco como 0 al final de la rutina. Por supuesto, para incluir esta funcion en algun programa falta: #define Columna1 PIN_Xx #define Columna2 PIN_Xx #define Columna3 PIN_Xx #define Fila 1 PIN_Xx #define Fila 2 PIN_Xx #define Fila 3 PIN_Xx #define Fila 4 PIN_Xx Se los dejo a su eleccion. Para el programa final (en pseudoloqueseacodigo), podria hacerse algo asi: #incluir funcion get_teclado() establecer pass1,pass2,pass3,pass4 /*caracteres de la clave*/ inicializar pass_ing1, pass_ing2, pass_ing3, pass_ing4 /*ingresados*/ inicializar intentos hacer: pass_ing1 = get_teclado() retardo antirebote pass_ing2 = get_teclado() retardo antirebote pass_ing3 = get_teclado() retardo antirebote pass_ing4 = get_teclado() retardo antirebote si (pass1=pass_ing1) si (pass2=pass_ing2) si (pass3=pass_ing3) si (pass4=pass_ing4) abrir_puerta esperar por reset externo (cerrado de puerta) intentos++ si (intentos=3) activar_alarma esperar por reset externo volver al principio Y en C lo plantee de la siguiente manera: [completo] <++>picc/teclado1.c /******************************************************************************/ // // Sistema de acceso con teclado - Grado 1 // by elotro, 2008 - // // Original : 23/08/08 // Rev 1 : 25/08/08 // Rebuild : 27/08/08 // /******************************************************************************/ //Config PIC #include <16f628a.h> #use delay(clock=4000000) #fuses INTRC_IO,NOWDT,NOPUT,MCLR,NOLVP,NOPROTECT,BROWNOUT //Conexionado #define Puerta PIN_A0 #define Sirena PIN_A1 #define Columna1 PIN_B0 #define Columna2 PIN_B1 #define Columna3 PIN_B2 #define Fila1 PIN_B3 #define Fila2 PIN_B4 #define Fila3 PIN_B5 #define Fila4 PIN_B6 //Funcion lectura teclado matricial int get_teclado(); //Bucle principal void main(void){ //Variables locales superartoautoexplicativas int pass1,pass2,pass3,pass4; int pass_ing1,pass_ing2,pass_ing3,pass_ing4; int intentos; intentos=0; //Primer numero pass1 = 1 ; /******************************/ pass2 = 5 ; /* Aqui ingrese el password */ pass3 = 9 ; /* de a un numero por renglon */ pass4 = 0 ; /******************************/ //Ultimo numero do{ //Recoger clave pass_ing1=get_teclado(); delay_ms(500); pass_ing2=get_teclado(); delay_ms(500); pass_ing3=get_teclado(); delay_ms(500); pass_ing4=get_teclado(); delay_ms(500); //Clave correcta? if(pass_ing1==pass1){ if(pass_ing2==pass2){ if(pass_ing3==pass3){ if(pass_ing4==pass4){ //Abrir puerta output_high(puerta); while(1); } } } } //Inc intentos intentos++; //Fallo 3 veces? if(intentos==3){ //Sonar sirena output_high(sirena); while(1); } }while(1); } //No tengo ganas de comentar int get_teclado(){ int a,tecla; tecla=0; do{ output_high(Columna1); for(a=1;a<=100;a++){ if(input(Fila1)) tecla = 1 ; if(input(Fila2)) tecla = 4 ; if(input(Fila3)) tecla = 7 ; if(input(Fila4)) tecla = 10 ; } output_low(Columna1); if(!tecla){ output_high(Columna2); for(a=1;a<=100;a++){ if(input(Fila1)) tecla = 2 ; if(input(Fila2)) tecla = 5 ; if(input(Fila3)) tecla = 8 ; if(input(Fila4)) tecla = 20 ; } output_low(Columna2); } if(!tecla){ output_high(Columna3); for(a=1;a<=100;a++){ if(input(Fila1)) tecla = 3 ; if(input(Fila2)) tecla = 6 ; if(input(Fila3)) tecla = 9 ; if(input(Fila4)) tecla = 11 ; } output_low(Columna3); } }while(!tecla); if(tecla==20) tecla=0; return(tecla); } <++> ->->->->->->->->->->->->->->->->->->->->-> Ejem! Permiso.... ->->->->->->->->->->->->->->->->->->->->-> Nuestro microcontrolador 16f628 tambien cuenta con interrupcciones internas y externas, como la gran mayoria de uC y microprocesadores. Una de las interrupciones mas utiles es la que se activa por un flanco externo. Que significa esto? Significa que cuando el pic recibe un pulso [flanco] en un pin, que normalmente es B0, ejecutara el codigo que nosotros hayamos asociado a la interrupcion, sin importar que joracas estuviera haciendo en el momento que el pulso se aplica. Picc cuenta con una funcion interna asociada al manejo de las interrupciones. enable_interrupts(.....); Donde ... puede variar mucho depende de las capacidades de nuestro pic. Los pics mas modernos y completos cuentan con interrupciones que se activan cuando hay actividad de comunicacion, tal como I2C, SPI, o incluso hasta los mas basicos cuentan con interrupciones que se activan cuando se detecta actividad RS232. Por supuesto, los pics se van adaptando a las tecnologias, y existen varios modelos de pic que cuentan con modulos de comunicacion USB, y por supuesto, tambien tienen el manejo de interrupciones adecuado cuando se detecta actividad USB. Ahora que ya termine de irme por las ramas, volvamos al tema de la interrupcion externa. En picc se activa mediante la siguiente secuencia de instrucciones: enable_interrupts(INT_EXT); enable_interrupts(GLOBAL); Voy a ser sincero: No soy ningun guru de la programacion de pic, y sinceramente no tengo la mas pu.idea de porque se deben activar las interrupciones globales despues de haber activado la interrupcion externas. Pero vaya a saber porque, si no se hace de esta manera, funciona en el asombroso 0% de los casos. En resumen: Haganlo asi, y no van a tener ningun problema. Un sencillo ejemplo del uso de las interrupciones externas puede ser el armado de un contador como el anterior, pero ahora usando las interrupciones. Tu diras.. ?Pero pa que carajos usamos interrupciones si el anterior funcionaba a las mil maravillas? Prueben con y sin, y saquen sus propias conclusiones. Van a darse cuenta que las interrupciones son mucho mas utiles de lo que parecen. El codigo del contador con interrupciones seria algo asi: <++>picc/contador_int.c #include <16f628a.h> #use delay(clock=4000000) #fuses INTRC_IO,NOWDT,NOPUT,MCLR,NOLVP,NOPROTECT,BROWNOUT #define Contar PIN_A0 #define Led PIN_A1 int eventos=0; #INT_EXT void contador(){ eventos++; } void main(){ int a; enable_interrupts(INT_EXT); enable_interrupts(GLOBAL); if(input(contar)){ for(a=1;a<=eventos;a++){ output_high(Led); delay_ms(500); output_low(Led); delay_ms(500); } } } <++> Seguro que vieron algo raro... [no el <++>, el #int_ext!!!!!] #INT_EXT: Indica donde comienza el codigo a ejecutar cuando sucede una interrupcion externa. Debajo de esta[nosecomosellame] podemos tipear [ay, que elegante!] la funcion que nosotros queramos, del tipo que queramos, que haga lo que queramos, cuando nosotros queramos.. ->->->->->->->->->->->->->->->->->->->->-> A dormir...tengo mucho sue¤o.. ->->->->->->->->->->->->->->->->->->->->-> Amigos de set, los dejo practicando con su pic [o su proteus] y nos veremos otro dia, a la misma hora y por el mismo canal, con mas del embolante mundo de la electronica. Saludos. ->->->->->->->->->->->->->->->->->->->->-> Data ->->->->->->->->->->->->->->->->->->->->-> Antes de que cierren este archivo y comiencen a decir: que articulo boludo.. les dejo uuencodeados los circuitos de proteus que sirven para los ejemplos anteriores. UUDECODEeen, y despues me cuentan. Hasta otra.. begin 666 circuit.rar M4F%R(1H' #O0!3LY = M,P, $--5 E!3+Z0NZ#!V!:!(FBN41$-\^&'BWM@S#?_:9<\@SE7 M\1H70;;I@BWD3IMT@( J .<0 !Z2P I%9-_%MJSDY'34* " !B87-I M8V\N1%-.YQ@320R.UDPF/9@HG+5@0.HM=UDF;1*>;?^BE>>&NE=F*]OG_<#3 M1'KO,\"M+#">&D\*&6:D!(,VPX=!M1D'[X=7<*B1*+B, Z XONJK_Z4[,W6+,;&1$*:-W5MMZTN4[J\ M90U!D$&"-UT-*:"+/9%\0&[,RS'G":Z=C:U)O#!P&=#HT9OYQ/RYL75$5SFM MEB""H\0(OC]WDB0 $47AIK:OY7,);)J9+VURI-E8.%,6C\RN3Z(JT7T[U2L,$."!5J_CE"]8Q4O_3B[0@2CFTZBX., M8Y,?Y&0-B&>NGI7F9/)YB2$LS(Q-09/3'[?C7.M^QFKP.96E-O=&N1'V1IS) M5%O)*+@,4O)G9JKG*XN.53:/AB"IJ]+LFE%B(HUGTK[C R0"(Q]P'L8[?OF8 M+;2H,T[V>&%10E&*TG 774RK]O6#D]>,$X%@1_I<-;@UW^V!_=3&V68WL J!":Q343!< ^L\X=@>,"$Z M:P!L\(#Q>Q^+G&6?@-J('D^:$."!N-0L&;$X&F1J1(Y2_8PV*)TVL.>#\3\S M@Q=Z#]UU$-M.._)2ZJ& G)_8S4AITV^ K'+H*^"( !4_IH_:XY&"N![Q=H&W M$+?KCM +G\)H2 !&&S4'6M8G4>B*P8ZW,VY;*;"U,8OJ@':;,%@DB?7,O1# M^'%8/@LL@6^D=4*#X!SE)YKH&2'R@VW&!+H3M:MS6.A0W:2"E-U GMLU'?]3 M<"EUI#]/PSD:LI$\0%& 6VCN[A!8:$V/QO++[HNPZF0Y_L%B&M"*.Q5XY3Y= MIQN7>O$>;*3T'0G;ID587+\;22>S&L-?2ZA5ZKDP>U6GZ]2M0\"ZYZUC;JL"0U&(K_Y+H(DY]\>MZL! MW4LB1/TIW S76M*A2Q]/P<)+C94WR,4^+5[YDP:^'!9'%WK @KQ_[N%.M?B4 MZ?519MB4)/HN>QI_MJ5T;U$$AT]]T59(V9."=N7P(1O?Q/CH685ZYDU,=O<. M[ _F8]]1[E$[,DDA/[D99%$%&JBUCX&T$HI5R M*=:!"N10?XL=!303&0C)/XIHRV)4\QUC3WX%,H R*EM59GR7$V:WEJO=R58E M9(O+6XX5&MI81=/;8M]/F[!@O.X"MUDVJ'"E^S"3899,>%-PO>;>_ MHZ0@YT*,$UU.8<5Y!0EMLP"/]1\5_&!"6-T0'7[@:X_V,(F6)?J%O$46F6S# M,=Q^8DTO<:/0#7U<(-6V64M),V;=L7!OPXJ6,)2&Z^JZDH%%*%1EQT?#LTLF MNDV069T)34-GX>S:VXOL/(GE\FW*N..K9%2AIL>18%0YDN#1XF/5A#D(>DH0 M 7W(W04V==?'1!E_\DN"!QC)C)JZK[QR._+%R7[;/8]CO@)AXWTOXT0[TGG. M]&':EKK;1#Z)R!2> GD-#'+()3[M0#_PI_DO4%6 U: "7;G7MI]X\6=),G,7 MI8FVQ#J8DW=&4F,,J:GD_:?:-^=\$3 (1&\TF-!V]/AGFH3SR:#F$@?R3"T7'K['E8R:TEO+TCRM\EKD^ M"W8]T]Y T#3]D*.&LLO1G"-1Z5U:WC4%UJDY'3\@-+U=M.MD= MN%#R50XZ\7_?*[@EU\TQ]#\EQ4Y\#,QK7RMLY;('8=R7&ZC7(=1%%-C M_ZSD#3\:^[+R,!ZA2_(/))Z%8Q^?:M7@(^X*B%MED6W76K/FWT288XYC6"YL MKJ=0FMGID(JY8+MZ&C>64\8WE8=47Q1![3$;A2\?YJ#1 4V8IGL' &=!EU1V329F$]X3H_'6!4:?\;$S M'V[\;Y+0IS\89C(LZR[51,@T3#_=J'P<2?!GRE>9[@=LPT<(9(%X M ZX.5> M<.[WPI(,\B^+A3(NY':Y=(H"2V2(@+PF=\:DYH?SPKH0EP!/QR?]DN:'H7,O MXWJ1K69>?^=Y8P<0?EU1UIA&0@RL&)M"'G4%W)B(1H,1"(@^,^A^N388P OV MY:M+$-RNH-EU$](>D/1-RG*NBJV2B (W*C_@0B6AKI'^UI$;E!6S7?07CI(6?7VU(/Y.!0VPQW0J6"[LB+\#QOFWK\$;CEA MBC>^_A=C@PW:0/S^XX.Z&7)2Q.(&9?34,-AK+Y?1:Q'D-H+2H+^B%I-B^7#' M*GJ4B'A0P1T!-_BT3S60(.-?F9F<*=W_[:BN+.!H;CN^AUS' 1$PK^BW"%KW MEL[:S+/O*<]XO>0T8@]\;=?3F1< 0G[]8[06_I]]D*$:72WJ4\?>ZOG5B4MA M.OQ1-5H1V?YE)OYC/K2C_3N'WK)D2/F%OXI4X/_Q %S5(1D%LLDNL49\1 S? MP:U*;P1O>EFOT$SF*!U1-^==Z/??W;B]E[S G.WLT.=D]4O[7F*:Q,4;8$WI MP7PV;H20>V[/UL01P?:@% MK(0K;E6ZO7:P*P,P,V)[Y+>:["D!?L;!P ;O9K+M$J;[!#G_O6H8DCI)/U(' M2QJXY'&KX+(" +[:P\,>YX$4AJ.0>+G/@TO!=^J0;#W_TM(S_E=&0725.%V* M2, 9.DO\ZFACD70-*/6___:SKDUPH"\02C!P'@%_EE MHG115T$D9Z1$QF<@.,^$-/#<8^*PYP;U+%'!P,G44TX**U?0NW94!FX^MUB(H4IK^%;Y M,%@ @H\@(WX5>&2.I')))J[XYXP1:SK>)C'J."@T/E]B/++8"F)R!#&71[&D MH#5DPBM MTWK"MF];TQ*T*"G+EC) A+';605[BA_&H,U>F:N]FX=RZU:NM1"X"_$^1P#B M#'L^P^R+QA$FEI9P8/%^[MI2M+())R@^W,Y>I-"?[2.5#&2&YOFP!96 -1!H MR'H(7"&+XFW\(' _E6J%1*WES=@[#\>K]PP&S7?E?X0 M#7I\34[G=1FSUKX'P[\920>%+Y/4;'V'IB-93:"*3WUO%="*H2 ^][P M@P)>A7;E([VK+"8@J@O^9Q:N&J..LFN&774V&;AH$7S4#1_!M!YQ#IC\\%ZQ)?RP8Q M3NO1+9#)]ALF8^4:@(NX\QBUV;KL[LZ$7H@P5Q9B[8>X14#UBLA"2^HG,8EH M,1O3SPN/Z./?"ZD*O\W>>R( M.&^TZ6 &"SY@,.!H[J'_FCOI=C.Q7!MVQ(U,$.MPM7G9S8._EYW(]J^./T,1 M=GE34F5F'";?-'(Y[*0;,](:P3T'4K4R6Q.[V##;X'TM0#BH@$.+(Y5M=I>,S)3,3B;50HQ2D_#ZFL@@%3JU>K^(HCF__O9R34L* B$+*\,V[V=R& MKIO;O=_W6"Q2=,L2^;,AM?=MGBALD,EQ*)523)Q%VQ3+S1/2*S=RX%9=3OD\ M^:-1^%/*'T'3LM$WNS^!HA5M$7E3+D8E,4=!=/K3U\!C*2BV!T?Z]3.:L5M._%>V0Z,((.<6 MYEF_\D"^A8?B5RRESW0&./H9,,GBTDC74=,]**#R5D8H12]?& MK@%]K-DXXIX2HK/-84D?1 4Z;9!T ^JJ0@ML5 J$[X1J-^+-R$9&7Q^_4,FM M(.H_"]=I^OSJ$50+U?(.\="-]>138]YSE8QMFF>>UT8*?[/!2VC!?C=O,N-B MF9\D9<'5IBVL&8,9&/B9^P\V0!!ULDAYD M/>D.X],=$[=$,Q\H)SY;QRQ&,$KHG?'!Q$+?5.G)1JKRZCFG'YTY5M.57YGT>PU\2 MU+GV GNJW,>1P9QJ%U@Q?%E5]T8E#A<[#JS"-;"0!:RH(YH%)!N8'(FB^?*G M0C0AQH3I]Q3@\0ZT:&UMM6^,W01 AJ((NO1%;.U%<:M6^,G'@YB".WNH8-.^ M+]0!&J2W('C[/=R7=.)^%9D61!KHY1KMPL!^]3N^NS?ATZ8"&GBIY6$:78ZG M-5B;.G.A?6OX]ML2[_L"$UV5-A$71@$S^7KV>5MP7<\N;$@U^W]059O-6;4(H)9_CDZ_"Z'LV8$>EIN,]/38YOH MP.]MJ!Z[5^C<^/W9\11%YX@ZD&9:Y^SSN(L9?09=#8EJG!POI2U2<8 WDM4] M*,;FV/+T,63KG8J \ /'X>!9 M+=A.8#P ]V]\-[>WOCN[WK__V,MYW-X'G MP\Z'GV&&&&&).N E)P[96?_?T?Q^R]OYQ5T[LPQQT.\-GF50HC+FH,^5+*/9[ MK=6$7^#JO*VW;3%4=T7.]MF!_7\>V;./4)+!RF[N*IGT]W,96]!EU8B]5Q]_],EY*^PV*)IF&&CHDGK1 M%H$/*RB[I.M!">(%:,+W;:QQCZFF2SF/HQ[2UC=F_BM-4.$^B=$CW(\T=HFT M"I6M+.,%_B.*I(_(-_VDVKWI=:DJPPPPPPPPP'8ZVFKX4-_"L;&*F6OW/XO> M[FIUB0=.'+E!:DT$ZX*8+U>9L?.RQ@E@AQ_A-9;?I\Z ]'[U2_9Y)4F2>6U' MZS9!8GO_[O.D]W]&4QW=G^=3KQ"]A\#SY./W.F M%C)>)+A\G5JU9NX['HD--L*X=-<-EZY>MS?X?_9+=P-?_@UDT47G44>#+S_" M9%_&#AW 0EX=<:GI;;QS3+L*RLJ*PR?IO"SML7"[!4)ML7?Q\>B".S"E>HLG MM(:J@E'GPKC2\20'W[1!V3)<9NS)8O/A5ZSC:'! S!CJN9$ITF!J&L%4^'1? M9C(2"M_,$?7[8ZM2TJ5O!",Y4='5$%? A4*.>JFI9/6!-&)Q>$%.T)86#3&I$V(D>VMS62-EC556OMIYGC:0'L:5RQC*>9:^VST*PKXT) MI\;F^OY]EV//$*.E[Q+[$PK^YXC^VN<'@3&8:5-/!Z%F2YT"J>>+&4#?Y6RO MC5 76'(!DP-'A] (]]@7C^'(P<3%N9QGIK:_/.%[];F8RA8KB6T*&R)^7)^" MS$4!=? Q)BH/65N8O5NC5>0]W9V$>7>1=L%>^".Z]4+8S]EJ_RE['=R+_%Q' MD=&/"_\S@ZPV=F&Z\0M.3OR3._(#/'/6-S/["(;/EN;HW;.T(WY\[PU--^"V M90(Q?/?3=XSW;=X6^^XRF8=[2\0P'Q[5+V1;8N,@2+Q5""P]:[MLU(2"M_.$ M='C\U""ZJ5OP3$)5T9NV^[!>A*&*KUEG%X0>P^"[7A?=A]2HKV9>&."S\F[P MR-DP2;-%I6$BYNW^6-:ZH*\>JA=-X1L2H] M,LMVZ2<=,MK1;R-5QM>]B-,MB]N,Z+?# SBEQ(\R2 MLT?+X_(Z*=/PS\K^&$._X^N55"Y>%TBG7B%X6S"BM)C_QUJW+[['%<[J_R-= MTB&)*D^[TBHW.68K'*N]\CT)*W UIM5F)(XO,+.68K(*ST?-DWO@TBG22YN^ M]@JAM_"ZA[41_2]+I0;C?'105D"#F?[].2]Q\KJ 8Y9BLK)D K'*M!Q]4B M@K'%XA K'&XF/[CV8+\9]^L#N^1[0&I/U_: N86)P_VBH*W,B=8+( M!6.5:#E^-U8+G%XARS%8XW$W'5%05O$^Y3 V/\[8@OQ\&F!KCHJ9["K,+(Y5 MEL077Z;9 R 5CE6(_[_K 7.+Q$ K'&XG=_FZX%Z3ONO!MQW50"_+[+KU(0W_ MMLA7,+$H_UD4%;A_DJ!8Y9BL(N#_\58,OW-6]A5F%D?%_MVX+T?OU;!V'+,ECE6)C[ J"L<7B$" ML<;B;[W>W4Z^9V"T.!QZQDW5-]/[&?*3J]8_2S[+]A)(<58:*Q*RN4\/6*[3R_/D\O5 MZA3KQ"SG&E$]3@,\X*0EQJG4J"THQ0*Q@9B?,;8B$CUO8\T3. S=:IH@!+S0 M0FY'6>H7FE'&>2G"SSHP/66G1ZU%&J:((;^<"==SH#4IS@1)H-7=H4V"7=4) M314A^TD/Y=R'GP[RJ#]O64[])#Y[0FXKYPJ$9VK -4T58?QZ,BTG9\?JZ8!G M2)&J:-K0Q[H?/A]9MA[?U0HL]=U]I_4C"O5E#5T=+V-'#ZS;C\5Z[CH0_],! M=;AS$6,T)._G/E*-=-NMR!@!WTD-;\CJB";,EZ>!!S1$%*L. MO/(C/K::OB.5CU]+5K+?8".('8X#;-%AV/A_-!'2ZL>3#&EXD@?/AY?P CZ^ MK')M8[W#6=^W;:<,6P\98YX6.S^4).BLW_""E7I!6.EYK&5$#%/+%_$#F^"O MQ C$#L9RP%T&K.:75B\8888#W+A@A>C9^.A5BY\8(Z*W*'1A8MO6&;^AZQ9\ M //^J*Q*1 Q3]X3KX,-^BE;;[K=#;Y.G"G>OFR6'RCUNG>ZQ$4GR?+DM)7!Y M/A]::J,.@>J 9,F2-M^$#T)UO**$JJ9C_BUZU^RV:'3N0_E%'N)L]SL?>'<1 MCE_Y9K#1G(N39V3LXER<:)"F/ _(/6'8)$J-W1+U4D^;I(I MZ)UJ,IE;VBJ0:=?-*CD!?0[/NSWP,W-M%M4Y[(?"D?M6\^*?WV"_KN+2T]?9 M-EN0LC60B-&3GD<*[N\@V)B/]_Q,65_ 9>:[.]NK3U@AS@ARR0+,Z>+&TC[W M(1&Q9&$_D8+&-VO:WF&_O,#"//HJVSLS$X>>HY6\5I<#+MJN/A2FKKGJ^R*S M.*>9Q! ISW\+WEM"M+#*HW4>NR+V5YPG]_E&Y&[GM*GZ>T9-)QF@4^&D M=+EW"G"/>:(=@+G_3E'$";'1M:J?-8TE-E M9VL;\;]/D@ MQ I-V6Y!8,S"TK_HUQCG)9+ H!#=%9*],"$"L=R/$(%:T]KU0,(*S7%&(@ED MK8H(0(^Z.7Q3YG;AC"29(;\[IQ>&A0!@ZW'&%!&#HJ5$*I&#IQ5]A50P.KV/ M6K"!U7QZ[4('5#'KM@LE6Q)>!-+A6!!TXN.PMN,'3BXM"@+S'@R( >D ('*4 M<$$(,B"'I4A!D08]*H(,B$'I5K*RRLX_.OBV*6MMXRU:O[I>HJ-M[R8\3(S' MC #@<2' >/CE&"'00>-2#[)VPV\2PA9M>EUX(=SD"5A"[*PWLQZ//CUAN[Y- MV7N;]^KB9S@7F#BNMTMSK=$$B!=L+S9QH=?SVG_Y6T7[B*\WVJRWU>J;PMHT M@=4SCUAT^$'(Z;6S%)F:72Y*R\G8&FZA8[($0@4DHR^>71H#@=XA9_P@@K'JS ANBL8GQ"!62C:8A K&-L0@5 MC!V_1+&_SE>=+YNO4+,<8A K&0N(0*QV((A K'D9(A K'9,B$"D<5G0^@>M$ M: PM!G]*RT>LQGB(!.Q1^=8V;GDR7&P.W#E[X72R3#E0(\@QL$$^+UE&&P(8 MWB7)Q'M+8G,6"%R<1"Y.=3Y"Y.TF 9+M;')"NXV//>TMFP0S-SV#"<1"Y.=@ MPAP83B(7)S?*%W#$2'M+9L$,T<]@ MPG$0N3H$+DXB%R=);=WORPH=2O'Z;T!9Y08V"=Y[XK7OD>@J%!="IQU73CE]\BR$VP3A=+SB:NO@H<*"Z$YT,ZGEG6)AN*DX&;?XY4)M7J'N+-L$X7$F9<6AFG14G SJ>NU*PM\0K"HT";S4 MZHF2C""&*XJ3@9SOH%1O,"$;#0)MOA(M1_E"A,-Q4G SQ]QJU3N.^MHV&@3J M'^L6%N#ZF+#<5)P,^G_F5";L>B>XLVP0[BV<&3OS:1T!NX]CPA2T=?/#OSOF MK0@ZZY9#&#KKA:9@[34NVI^1K,/S0G4WTN[I**T9!F_;/P0?AC6T/L:5KV.[ MQ4O<3?M=WGE.1&H&0(R6$5%$RUE^YW>JN1UXL3#@KDZ"[[E4MF_;ECSW<*P" MXU'+:6<8+C4<$.NA<\;O("RZ[>>-;V(,-1QLB::]CL\52G9==O.J496+%6M2 MA(+&W(&M#-6A<@L97(+%#*Y!8VA1D%C)U>QV>)7AAEAAHR,*\S5 DFD!^C6; M+"/Y_DH%+,<<\6\5P8D7!-5X%YJN0NYK8+N:S,"HO-FNO4N:Q"\R MKB:5?3*L#CY*C)>94YJZB94E@05YE1*8!UH1K6%%KU2\PL.8!0YN-881AL*) MWV;4!1 Y1"C$8B* V953:$!>PIJ_H#'CQ;:R?M\5TC2LWV2RWU>G66U[*$#_ M4]B%(U![0%*YY:E1?\4)'9(9*-._6],&W;S6SBRWV_P-I_C/H3N(UQN%5&R,]I(_3](S'<&QQ/];Y@2^;V'_;'*[/\H:>6S_X_;^4,O??O?]#+7^9^ M'/4?MT_HVN/]Y<=<=T68"U@#!T67^U@C!T67ZUJ1@Z++[:U0P=.I2MK5C!TZE M&VNU&#IU*%M=L-C_AM.:DK"C>G)XFEOLOZFW*ZFRYCU%7KK.PB3'BR.ET8C\ MW(MF9<]$UG;QQIYFF==4'/.YTYW'FRT$503)4T+(1G5B7<_JHYL*?3T!U:8E M[;7.*F*IK4L\H>V9>*FX#CS5 *8O'\FFY>5(!],O<&YOS;@]%X;/P?VDC$-N M*E+3P7'VV5YP M,CUF'1L/*K#K"Q.)@W3]WB.-EGBJ9X&ER$IZH>CF3ZN@^\ M8]7W5U #?QCZS[7EW+H2K[*.V*1)%RGTH4TC&:;L=D4OL%^W,-J;[3%%E<88 M69_V>1'"QL6:ZCLS@YVGEBR'];(Q;W*AE,945S@RH*W&Q%"=7BL\&_XBA M,. ?&:^Z9U+,RFY59R=?L]1,I&'E3765;A8M+/=2VLL?.TZ^HM(]D]6\'F6[ M 7@U5.O,+3:JLM:?#,*_@5$%=?MZ[BSA6E7T$J%\"NXLY0(O.$NKS19*\V/I MTTLKI::O3S@UR:9O2R>;1K+:FCEKFCW23]OLQV7# @STE5_"ZB<:!RKE6RI" M/60^YFEC12BGR413L&T)QS?304HP8E+AC=P?&RB*7[5$VMUI#Q@MPJ; G8^A MIP[.-X&I6MO U,U]8I-+@*;I&!XU&'&;2_S-A7X7V5D,E-.'J%F!G&9P&A)# MB/6-R<,9I;QB<8YD,Q#DGD*WB7K&A6-ID'4F,D:YP,*_3 MM>_>7;AKH,&G4%IPOMS='/RGA*; M*MFRDW)0EB[DR5D^U-N6+AWQH6[K[:/;IQH;7)UDCQTF7^/+L,RIZ+?/<\5# MS+]O-A-QW51EC,%)IJ56!F>."STE)FHY7R)SMPOVH0N)'F2S_9W><_1GC3F. MZ*._;7$1FP3-X.I]"VCQA@ZV&DVI9)6WG""W%.9TP.:5X#BC]>916O,'C/FY6A2)"E MM36V\>44?X 2^&F^.56G$H@:A-MT7'9#2!@> M-:.^!IV.7-UXW_\\(3$-T5C QX? #-VO36 M"5:P(T;%5:3S6E'O#"YVVQ7V4]W59<>: !@N_ECQMY*FAIO]D;A2H[J]/!]G M@+G?8_([ !E\)O[/6IA%.!1<6#;?BF7SF5._M,;$O4Z5KBXLB=[E&S+VM,G= M:0HT9+M/;-29;G SLBVJ9J??@.)=P,"?O7>EW\%]&&&&&&&&&&&&&*5A@/G] M6%LA?9^#YUQ#^7^H/X+Y^0'GPD)((S?\%\DO7.'X+XP%% >J_;G!,;Z7?PBH MTO%:#Y]AAAAAAAAAAA@/.AY]AAA@/Y/Y->^#%T2VH#S[ ?_W%UV0[;]'Z?1/ MLP!I-%;0-ANN\DX7G7K1*-"?A%0<"[&FNA[8X.QX?:#_KF1&/RO*XOPI/D_8 MNUNY]$.)THT>F?#^^F!L*\PF&W=Q[Z_5^$6'+WWQY/*XEL'9'!7#\"P'M3@V MN^U7#[F9&(_(G1HK\(5GQ<#(![W.! M$JG6TIMZ+/XENM2'[%M-V2H1F_PBH MYON>\DJX32OAW<[R3WWUXJG4L]2HTQU[[PY/,^5AT.4>J >1]V_ST4,RK=1P M5,.*/@2>?=+!7092*Z)I7^.1^Q_6HQN9HC52R@:3:]$^6KM< M^58C0<>C^M)XWPK<)&F3KQ1P)6?7L\]4@RT(N.#:/\79Z%6(DR(QVK4.]- ? M**8AF)T<\VZM0:C6;[/&=.FC7>:U\=7:D_PY833@$>U."A]E,B#L#@0>X.#1_W3(C'Y,Z.1?6-]K*UOO#7X+%(>L8+^5^VM M-=J0#M@$]4!^/\O]VA_Q I\%)#SXX@\7VW#6,]$9%Y_8K^S:\9F8Q^E5\%3I MP"W!.;A)ST$-T4J)3Y/!S-@-(KV4OMW3\12C%!A;^"$G[>M"YW'C>:UFA+[> MM)([ET((W!):AA(@I#?3=E+ 7QQYR?Q[Y1\@[8+BZ[.=3IPXZ7?Q2688#0]L'2)UO]\GM^#VP'_R#95'20@# 5@$ M *<4 0 "BQ^TH0:L.3D=-1 ( &-O;G1A9&]R7VEN="Y$4TX-W1#4R;V- M)*2OZ2LI^#@)9.#EY>4EAP:5%)P(M$A$H$)"166B$BLHG#3A!0"_9L*"D4F/WMU_I;_*/QV/@ 1T M+^P)3X(Z(^ 1V/@CL?1V/@$=C]_3*GR.Q\$=7]B*G4?".K^P53J/A'8^ MCL? 1TCXCHCZ.H^1V/@$=CX 1V_H73X OZ$4^ G =T?3E\F/]O_(< MO^KL]?GFD&S;J39I6^V4U55X/_T2)9EK71GCP]4C69U(LU5YFRHJHVC-?W9L M5\LM8MHM[G_1IY/3-J!?FMY:S/%X[^E?D%M?N_+M@QQ^7'/BC\OGT& JGY:] MN/I%^@F0K\+]">]GM:PLDSXM74WDQU2-J8MOWAEYOM=/(OG[:S^ LL_J"E211*Y%&)55NIM-N=(ZS"TB2NW>/$\74U3W<2R>: M)/S4D^+6>S=WNW>[>[M[CR:49X K. M.[N?MS,]GP]GMW,W<_('^-]^]]\]@][]GT[.WSM_#YJJ"4B!^L-8.; M67_GXFV];TP_^;N@!/S&,!Z!^8QC&,8QC&,8QC&"U>3,"F>%>8%*;UC0FEN] MD>J-KE5$2BQ/V[$KX*5+DI+&[E_/Q[M\_'G[FR^U8E)L0,=B%>>^Y>[)Y(]_ MM>RAU&@-O@3]_ @:XX@0+&$>G:D)32V)2+T"4HM^;FON1NS:@N/(WP'&4J=, MDKUX1K"=I22_^RR;[! 3R4Z?QN%(;R'W++KP^[?P>880(%E6DK9*2A720A^R;&RMT=J M*6YHB5?'5K;V/E;JLE==*5S9*M7I.%V/\Y9VK8F_'O1JK?NF21J])\?&,8#T M#\QC!U\OO>9'_3 _ ],8VKZ8<)^8/6S /P?Z(GPXEC>X$_ ]-J^F,B>F _,& M_\P#T-CHR>_Y+'F$)^8#T#\QC&,8QC&,!Z!^8QC&,8#T#_5\FD3\Q@/0/S&! M^_M _#VKHGO)':*WL"?@>F,8P'Y@]';@?AFT1/<"6 O^M@)^!Z;5],9$],!^ M8-R\0#T.YHB>TR6!?Y430_)@-TW6.H5[5:T7"6GA=H?7'X'WE\\D]9(1GC<) M$$NR GJ_(WRZ?9\Q&E^OD/04B%7"?1/5;CBJF3U<(JY/6=C=$W>HM%(*V;WR M[C0C(U+4B/;Q(%#=Z)K:0G>DJ97Z")Q.[UY5ZC#P7LO@3\QC!_LJ'*L:(:\- M%->FOC1J>3G&J'.V3F%_4\Z6AT6,D?'['$Y15M:M)AQ2$XD%:2_-0TXOK6=! M;NY"/OW5=DXD-9%MB"H"CYU>$X&41,+!S\UAB>G^H"KTG+^'BN]1A MXO-]W0J$Y0M&__&V#>H_\31B*;(3M8AC6GIXNM&-9\QL=9'<0B")M"^=+_Q/ M<*A.UB&%*H()NQ""F*#912V#QH)-$(/DV0$[7,MGH[6"F*A-<(I'"#-*(PT1 MW)0T1>&4LA0?D[3+M; GAG)J=EP?6@5!B=QT2M4\K^N1U=]UZ4JTV\0Y"O8G M3YD4)*;I\OO)!>9*6?\(GYC&,8QC&,8QC&,8QC&#^3_0#\Q@('@@N0NE=_Y" M?F,8#T#\#T#]3U0]O1$%JDIZ6MD"?4;PZ*?J:@PZD)C #F@!S^#K:;AY5$)> MR @K!Z4NZ1"'"?9!-:.*L"03<037)!.9/FFD$[N"";Q0J?I!.&[PT3VII Q7 MNHQ!R[3G#:V-0(&<=(QC4]"(SQ+[#<3?Z-V[Q$N[EVAO1 W!5D?OA/PVSY6L M _ UK:I\]P2!&5+*1)BWD;K ?#P.U1/4^S0-]Q^O0R8_.]6JP\;7J!$2U$T8 MH$ST)=M=\)4L<&*L)V[/IVG6FJ#-KU &(/OGQ@E\5W=C&L"(*HMK5^->NG65 MP/RV'U15R%%D[UN"W+_,XS.2DJ*GH4G'(_[4&O"4B*># >-1NOA4F1U["Q7& M1PKANE5;5K'6"K8YTX"9.CE\>CU0KR,[0*BFWKY"SN+G>*A1VQYFF*C4#E,Z M>PK7"PJ "%<7JT7C>'0@_O.+]J/]$#\QC!J^2!^'Z5+7>X7 G;P;J9B('Q5X M>PV2BG-V#68>HI\RT44[FN\+Q(T05)=D7I''344\X:$V"SPSG6181*5XJLIX M:8$_)NE2=CTMOAB*_?DW:GTQ^OV=8HK64((Q[,+)M\"R6#31AU461YBRB5LF M8KP>%DP&&5X?7%D>8LHI]<61YBRO3ZZ,3VBR8##*^/KBR/,648^N+(\Q97Y] M>']_^885K+XQ,=817,6H9]=ADQ,67=O'ASI0/M:?AM$\JVWAVR7:Q?A(XY_[ MOV9IQ]"W]0^F44;;\4Z9=%?XG]'V&-0-3='D;)(5$BJE,BAS-:\+B&5:AGH^B=GGPG4Z'P23 MJ=#X3J=#X3J=#X,$ZG0^$ZG0^$ZG0^!^K\V]S/(T,OASU^4NX1F>B$0N-E\C M1SN5"\9/ A<1#&YT,W/X^95FH44PR@D=F8?91@O9ZA+:=NB_POQ5E&C.YO@L M691L,557.Z+4%_=!U\Q*\ #:,XH ;F)EJ>I/:G?L"^,Z#XTC '8E/W=^4I]V M(BA+<%NAN&:6Q$>]O=]V"%\H:AA"NB_GZO21*S >@?F,8QC&,;5\A ]CA@?@ M2(U_<=>R1,6:-M=9'3R86_[P+, _#UF0*ZOF%J&TD@^^V%G"'A$RP![=]L+* M'J^H/PNRC]N^V%=@"?A=I!V[[85LP3\+O-#MWVPJ\H3\+N@';OMA4Z&KZW/A M=ZY^W?;"GTA/PNF@_R!RD(RU?,*4/\O;\X=-84=$P<$PL5@PK[EA1>.Y*'4[ MZS^G@>@'H_\P;OPGGRI8KB>\!S50GWQ]D^E%,4]_C3O\GB3A\CDZ*,>J3^1R M2RSSGD]D>_N:L3Y=J,H2AKW6HM?"C@AY^4[OT M0]'_L!^&OJ H=*L9WI 5S[)BAWZ@'Y@:J!J*!Y M4C*#\C)?O"P6B@2&PJ.10(J,6^Z9N=QM#B MYG&S..5S4J4H'8B7,*TR7GB;)09X5E<73/_81;.R]"Z03I[381,^A(S@#;?+ M/H2LB\A8.80"FH81Z"Q2YF$G7HT]0*G 2HG]7I1O ;G7A/X.OQ/V*(H"0_'[ MMB7C])6;PW54NK4:FI6I5&JKW3 K25#?7@H#9A*0H#65+I"@-)4MZ)R.E2WH MG(]*ETTG(U=Y)R,7IY0%R]-* O2I=&4!;*ETI0%DJ72E 5RI=(4!5*ENB@*9 M4MT4!1*ETXH">5+>2@)ID*X0KG=ZV3DD7[KKFBU,H!.5+I"@$2I=(4 D\H=6 MO::A]?4Y#RT9Z0_5#@6AA]UE0P7P8J""W9/$Y_APA*\HI=9Y0 M-1%%#'>A> MT4 "@B2IE !3T?TKD]4HNWY\,,?TWP<$;K\CU4+U@X8@8[P+VB?WPU$3^ZHI MX\-Y)_,_24M@Y.5?_(F^CX_ KXDR(:R#,WYZXNQ!T;U)=>DF4[0_S0$5P28O M^" &ZJ66KA0NI;,1THA-W=A]SR5AH63F>+Q\"-':*6"M_[]4:+#*%;M04J"AZ\JCM@57IT4#&I_[S2)!8Y?YA^ M;_N@2T][T_U071[D$\_N#?>VYNT!1'_-QU/D75(11+>6]#9VDU3*5]XIYFTV MM?T@) 8D?9:BH\.0/)LW65?R,^- M"H&I)&)G_/'10)D&VD($] %_U-;,+AB$%&B<_F^%-TOE?WS0ZA T;T_ZPD/7 M(.M/O_<"0L+9WT'4]53T%,10_?;[<\8D;RM '$@87D@X7D:AVOU^? MQ0I:3R65/@(JY<8\KSV;+2!Q(&%Y(.%Y&H=K\V_Y84V%"R1[ KT>V",7G_(Y MP.+ %Y8 O(U#M>5Z7[84@SR9;WIH4+ESRO?EXGT@<2!A>2#A>1J':\#E_1"F MQGE-<_'0KEBHE_.1^?5MWX3Y83Z1V(,V @%6D%]/G=LS6<[=%FY-A0'X%D^FP%7>"XHN M>GG *UD.-OV[-JK\OMW[$AL#; 5=X+BBYZ>< E7^<%S7[8K)[P,X9M@#Y!<4 M(;>('F?O^%-Z65M4L#(KI9Y>W8SB?2/"?S8!CFUQ=MN%V-9ZW[4UMTGT_0&M M!$7$I'9_\G7+Z@=#X6^+PE;][;LW?>9W#]B.P!#8 Y/H\R )G'T=E]^?W#-[*^!W+\*3[Z7A\!,3B=( V%/N*Z"DPO,^9S MIK;M8@&9QQ17;>$TU$=H/M'N6;\K[#^B.4C0@G2 -A3&8@KXQ!1C+;M8@&:: M91';>$U*)S;Q A?J?-+UP:)H<2 7X_O6,[2]GAA G2 -A570ML_.W"8G$[L M_XLU0GT,WR UI%-1%$=@.>>0)FW_@30]]5IC_EX3]B=,VV6$"=( V%,9".V] MQ!.X'E<5LL[9^@+(NX5"B<3HC0X/TAHY@9LRG#-9[1NRI:-#@5VIK+> R MANK45BF.Y7U^:ET@FTQ_5&,XOF6G FYOZOE5^E-("XXWQ+ %ADD%^S^Y7Z3: M'@>,]57HIW!1,*<]>/ZX^E;'$^FP%7>-M^+ MU T_;^P/(Y!%7!$Z5MR3Z/,@$ J[HHD)_]^$78@ZX[K_<6^YK"M-HX@/B=KT>VTDJB"=:\=\#,KDR1>2V)]>"ITE_6K]/YK* M/P@GZ'-_LU%,"&.] M0%JRXUG "^3##![P"O2*@/V,^4#%SS9:[=$6OBS4USP6NM:*63P6N2DM>U'7 MKUDZVS1:^\77C;L4]%N%+VS"VU3?DQ2^M MV19A)"D;8!;;*;&A$7:D6;(*7 M]J%OZ*FT<%M;]H6,:2M6]DZX?M5-J$%JV_E_4*4G[2(^)[IMN\;!\!1/EZ^C M'6\+!PDE7IH+)P1:(N3"BW<.#W]5^04EG/^^A"F][[@S-'/X>9\'@KZ&=XN9 MP6N4X*^/.)G^+=PN/GWYG(G5ZM70"'3(Q)15 MBUSD8LM+N3UG%\+JGD]4>!'Q<4!O]RDS0%UU)=>#CO;Y]KM]@]^MU')G2AW< M;J>( +]\3VENXHJ=!@@,DR0&'CX,')G-A#2+IAPA$5^!:&>,O.9XW4\?"P_: MB'XSL<3B8GO]-?#Q"Y/B20IX591\3#)59J&(H+"J, M,Z$LRT5GE2UW7TCC*5O:J+QVDL)^U/Y_F8N#00TLRF5:'47E*DA)=EX1]&7I MD>&G8>,_(=NYMY O$W\0-=4(*A14+XT.*JYB]":B_L;-ZZG&O_<'E&))5U!$ M^[DJC97ATW%"X)7,4IUD%"_)$@SU_ MR#/7ZT2W=3@[_P"J"W5H"&E[H"H^F,G2ZPG82IBJ&U\DLN_:=:L^\]W.[T^-YHF*%N2<1LNLKO-,]8'B1OP2#N,?"P! !P# end *EOF*