Vous êtes sur la page 1sur 155

CURSO MICROCONTROLADOR PIC16F84

INDICE
TEMA 1: HARDWARE 1.1. Arquitectura Harvard. 1.2. Mapa de memoria. 1.3. Registros. 1.4. Temporizador / contador (TMP0, WDT y SLEEP). 1.5. Puertos de entrada / salida. 1.6. Interrupciones. PROGRAMACIN EN ASM 2.1. Instrucciones ASM del PIC 16F84
2.1.1. De control y manejo de literales. 2.1.2. Orientadas a registros. 2.1.3. Orientadas a bits.

TEMA 2:

2.2 Modos de direccionamiento. 2.3. Tcnicas de programacin en ASM. 2.4. Ejemplos de programas ASM. TEMA 3: ESCRITURA DE PROGRAMAS EN ASM 3.1. Uso del block de notas con Windows 3.2. Programa MPLAB
3.2.1. Herramientas del MPLAB. 3.2.2. Funciones del MPLAB (mens). 3.2.3. Gua de uso del ensamblador MPASM (tutorial). Crear proyecto. Introducir cdigo Ensamblado (compilar) Simulador: registros, Watch Window, break points.

Hardware
1.1 Arquitectura Harvard
La arquitectura tradicional de computadoras y microprocesadores est basada en la arquitectura Von Neumann, en la cual la unidad central de proceso (CPU), est conectada a una memoria nica donde se guardan las instrucciones del programa y los datos. El tamao de la unidad de datos o instrucciones est fijado por el ancho del bus que comunica la memoria con la CPU. As un microprocesador de 8 bits con un bus de 8 bits, tendr que manejar datos e instrucciones de una o ms unidades de 8 bits (bytes) de longitud. Si tiene que acceder a una instruccin o dato de ms de un byte de longitud, tendr que realizar ms de un acceso a la memoria. Y el tener un nico bus hace que el microprocesador sea ms lento en su respuesta, ya que no puede buscar en memoria una nueva instruccin mientras no finalicen las transferencias de datos de la instruccin anterior. Resumiendo todo lo anterior, las principales limitaciones que nos encontramos con la arquitectura Von Neumann son : 1. La limitacin de la longitud de las instrucciones por el bus de datos, que hace que el microprocesador tenga que realizar varios accesos a memoria para buscar instrucciones complejas. 2. La limitacin de la velocidad de operacin a causa del bus nico para datos e instrucciones que no deja acceder simultneamente a unos y otras, lo cual impide superponer ambos tiempos de acceso.
Arquitectura Von Newmann

La arquitectura Harvard tiene la unidad central de proceso (CPU) conectada a dos memorias (una con las instrucciones y otra con los datos) por medio de dos buses diferentes. Una de las memorias contiene solamente las instrucciones del programa (Memoria de Programa) y la otra, slo almacena datos (Memoria de Datos). Ambos buses son totalmente independientes y pueden ser de distintos anchos. Para un procesador de Set de Instrucciones Reducido, o RISC (Reduced Instruccin Set Computer), el set de instrucciones y el bus de memoria de programa pueden disearse de tal manera que todas las instrucciones tengan una sola posicin de memoria de programa de longitud. Adems, al ser los buses independientes, la CPU puede acceder a los datos para completar la ejecucin de una instruccin, y al mismo tiempo leer la siguiente instruccin a ejecutar. Ventajas de esta arquitectura: 1. El tamao de las instrucciones no esta relacionado con el de los datos, y por lo tanto puede ser optimizado para que cualquier instruccin ocupe una sola posicin de memoria de programa, logrando as mayor velocidad y menor longitud de programa.

2. El tiempo de acceso a las instrucciones puede superponerse con el de los datos, logrando una mayor velocidad en cada operacin. Una pequea desventaja de los procesadores con arquitectura Harvard, es que deben poseer instrucciones especiales para acceder a tablas de valores constantes que pueda ser necesario incluir en los programas, ya que estas tablas se encontraran fsicamente en la memoria de programa (por ejemplo en la EPROM de un microprocesador).
Arquitectura Harvard

El microcontrolador PIC 16F84 posee arquitectura Harvard, con una memoria de datos de 8 bits, y una memoria de programa de 14 bits.
Diagrama de bloques del microcontrolador PIC16F84

En la figura anterior vemos la arquitectura interna organizada en bloques interconectados, en donde se incluye la memoria RAM, la memoria EEPROM, los puertos de entrada y salida (I/O), etc.

1.2. MAPA DE MEMORIA


MEMORIA RAM: El microcontrolador PIC16F84 puede direccionar 128 posiciones diferentes de memoria RAM; pero Microchip Tecnologies solamente ha implementado 80 posiciones para este PIC. Esta memoria esta dividida en dos partes: La primera parte consta de 12 registros que sern utilizados por funciones especiales del microcontrolador. Comienza en la direccin 00h y termina en la 0Bh. La segunda parte consta de 68 registros de memoria RAM que sern utilizados para almacenar datos temporales requeridos por los programas. Comienza en la direccin 0Ch y termina en la posicin 4Fh

Este tipo de memoria (RAM), se caracteriza por perder los datos si se llegase a desconectar el microcontrolador o la tensin baja por debajo de los lmites mnimos. La memoria RAM as como algunos registros especiales son los mismos en los dos bancos del mapa de memoria del PIC. MEMORIA DE PROGRAMA TIPO EEPROM: Esta memoria tiene 1 K x 14 Bits de memoria tipo Flash. Esta memoria es la que utilizaremos para almacenar nuestro programa dentro del microcontrolador PIC16F84. El tipo de memoria utilizada en este microcontrolador, podr ser grabada o borrada elctricamente. La memoria tipo Flash tiene la caracterstica de poderse borrar en bloques completos y no podrn borrarse posiciones concretas o especficas. Este tipo de memoria no es voltil, es decir, no pierde los datos si se interrumpe la energa. En la siguiente imagen se muestra como est organizada la memoria dentro del microcontrolador.

La memoria del programa comienza en la posicin 000h y termina en la posicin 03FFh.


Nota: El contador de programa PC del microcontrolador PIC16F84 tiene una longitud de 13 Bits por lo que implica que podr direccionar cualquier posicin comprendida en un rango de los 8 K x 14; pero la empresa Microchip Tecnologies slamente ha implementado internamente 1 K que representa desde 000h hasta 03FFh. En el caso de que se direccione fuera de este rango, automticamente causar un solapamiento.

La memoria para almacenar el programa, tipo EEPROM (Electrical Erasable Programmable Read Only Memory), que puede ser reescrita, nos resultar perfecta para realizar pruebas y experimentos, adems de para la programacin on-board (actualizacin del programa interno de chip sin necesidad de retirarlo del circuito de prueba). La memoria de programa siempre est direccionada desde el Contador de Programa (PC), mientras que la memoria de datos puede direccionarse directamente desde parte del cdigo OP de la instruccin o indirectamente a travs de un registro denominado FSR (Registro de Seleccin del Banco). Y aqu tenemos una vista exterior de los pins del PIC16F84:

El PIC16F84 esta dotado de un total de 18 pines distribuidos en dos filas paralelas de 9 pines cada una. Los pines marcados con AZUL representan las lneas de I/O disponibles para nuestras aplicaciones, los pines ROJO y NEGRO son los pines de alimentacin, los pines en VERDE estn reservados para el funcionamiento del PIC (MCLR para el reset y OSC1-2 para el reloj ).

1.3. REGISTROS
ORGANIZACION: La memoria interna de datos, tambin llamada archivo de registros (register file), esta dividida en dos grupos: Los registros especiales (8 registros). Los registros de propsito generales (72 registros).

Los registros especiales ocupan las 8 primeras posiciones que van desde la 00 a la 07, y los registros de propsito generales las posiciones que siguen, de la 08 a la 4F. Los registros especiales contienen la palabra de estado (STATUS), los registros de datos de los tres puertos de entrada salida (Puerto A, Puerto B, Puerto C), los 8 bits menos significativos del Program Counter (PC), el contador del Real Time Clock/Counter (RTCC) y un registro puntero llamado File Select Register (FSR). La posicin 00 no contiene ningn registro en especial y es utilizada en el mecanismo de direccionamiento indirecto. Los registros de propsito general se dividen en dos grupos: los registros de posicin fija (8 registros). Los bancos de registros (64 registros).

Los primeros ocupan las 8 posiciones que van de la 08 a la 0F. Los bancos de registros consisten en hasta cuatro grupos o bancos de 16 registros cada uno, que se encuentran superpuestos en las direcciones que van de la 10 a la 4F. Se puede operar con un solo banco a la vez, el cual se selecciona mediante los bits 5 y 6 del File Select Register (FSR) Otros registros especiales: Las ocho primeras posiciones del rea de datos estn reservadas para alojar registros de propsito especial, quedando las restantes libres para contener los datos u operandos que se desee (registros de propsito general). El registro INDF que ocupa la posicin 0 no est implementando fsicamente y, como se ha explicado, se le referencia en el direccionamiento indirecto de datos aunque se utiliza el contenido de FSR. En la direccin 01 est el registro TMR0 (Temporizador) que puede ser ledo y escrito como cualquier otro registro. El PC ocupa la posicin 2 del rea de datos en donde se halla el registro PCL al que se aaden 3 bits auxiliares y se conectan con los dos niveles de la Pila en las instrucciones CALL y RETLW. El registro de Estado (STATUS) ocupa la posicin 3 y entre sus bits se encuentran los sealizadores C, DC y Z y los bits IRP, RP1 y RP0 que seleccionan la pgina en la memoria de programa. FRS se ubica en la direccin 4 y puede usarse para contener la direccin del dato en las instrucciones con direccionamiento indirecto y tambin para guardar operandos en sus 5 bits de menos peso. Los registros que ocupan las posiciones 5 y 6 soportan los Puertos A y B de E/S.

Pueden ser ledos y escritos como cualquier otro registro y manejan los valores de los bits que entran y salen por los pines de E/S del microcontrolador.

Registros especiales del PIC16F84


Los registros especiales (SFR o Special Function Registers) son una serie de registros usados por el PIC para funciones de control de funcionamiento del hardware, direccionamiento especial, etc. En la siguiente tabla estn los registros especiales disponibles.

REGISTROS DE FUNCIONES ESPECIALES: Acumulador y registro W. Los siguientes grficos representan un diagrama simplificado de la arquitectura interna del camino de los datos en la CPU de los microcontroladores PIC y de los microprocesadores tradicionales. Observamos que la principal diferencia entre ambos se encuentra en la ubicacin del registro de trabajo, que para los PICs se denomina W (Working Register), y para los tradicionales es el Acumulador.

En los microcontroladores tradicionales todas las operaciones se realizan sobre el acumulador. La salida del acumulador esta conectada a una de las entradas de la Unidad Aritmtica y Lgica (ALU), y por lo tanto ste es siempre uno de los dos operandos de cualquier instruccin. Por convencin, las instrucciones de simple operando (borrar, incrementar, decrementar, complementar), actan sobre el acumulador. La salida de la ALU va solamente a la entrada del acumulador, por lo tanto el resultado de cualquier operacin siempre quedara en el acumulador. Para operar sobre un dato de memoria, despus de realizar la operacin tendremos que mover siempre el acumulador a la memoria con una instruccin adicional. En los microcontroladores PIC, la salida de la ALU va al registro W y tambin a la memoria de datos, por lo tanto el resultado puede guardarse en cualquiera de los dos destinos. En las instrucciones de doble operando, uno de los dos datos siempre debe estar en el registro W, como

ocurra en el modelo tradicional con el acumulador. En las instrucciones de simple operando el dato en este caso se toma de la memoria (tambin por convencin). La gran ventaja de esta arquitectura es que permite un gran ahorro de instrucciones ya que el resultado de cualquier instruccin que opere con la memoria (sea de simple o doble operando), puede dejarse en la misma posicin de memoria o en el registro W, segn se seleccione con un bit de la misma instruccin. Las operaciones con constantes provenientes de la memoria de programa (literales) se realizan slo sobre el registro W. En la memoria de datos de los PICs se encuentran ubicados casi todos los registros de control del microprocesador y sus perifricos autocontenidos, y tambin las posiciones de memoria de usos generales.

Contador de Programa. Este registro, normalmente denominado PC, es equivalente al de todos los microprocesadores y contiene la direccin de la prxima instruccin a ejecutar. Se incrementa automticamente al ejecutar cada instruccin, de manera que la secuencia natural de ejecucin del programa es lineal, una instruccin despus de la otra. Algunas instrucciones (que llamaremos de control) cambian el contenido del PC alterando la secuencia lineal de ejecucin. Dentro de estas instrucciones se encuentran GOTO y CALL que permiten cargar en forma directa un valor constante en el PC haciendo que el programa salte a cualquier posicin de la memoria. Otras instrucciones de control son los SKIP o saltos condicionales, que producen un incremento adicional del PC si se cumple una condicin especfica, haciendo que el programa salte, sin ejecutar, la instruccin siguiente. El PC es un registro de 13 bits en el 16F84, lo que permite direccionar 8.192 posiciones de memoria de programa, pero que internamente solamente podr direccionar 1.024.. A diferencia de la mayora de los microprocesadores convencionales, el PC es tambin accesible al programador como registro de memoria interna de datos, en la posicin 02. Es decir que cualquier instruccin comn que opere sobre registros puede ser utilizada para alterar el PC y desviar la ejecucin del programa. Stack: En los microcontroladores PIC el stack es una memoria interna dedicada, de tamao limitado, separada de las memorias de datos y de programa, inaccesible al programador, y organizada en forma de pila, que es utilizada solamente, y en forma automtica, para guardar las direcciones de retorno de subrutinas e interrupciones. Cada posicin es de 11 bits y permite guardar una copia completa del PC. Como en toda memoria tipo pila, a los datos se accede de forma LIFO (Last In First Out) de manera que el ltimo en entrar es el primero en salir. El tamao del stack en los 16F84 es de 8 posiciones. El stack y el puntero interno que lo direcciona, son invisibles para el programador, solo se accede a ellos automticamente para guardar o rescatar las direcciones de programa cuando se ejecutan las instrucciones de llamada o retorno de subrutinas, cuando se produce una interrupcin o cuando se ejecuta una instruccin de retorno de ella.

Palabra de Estado del Procesador (STATUS): La palabra de estado del procesador contiene los tres bits de estado de la ALU (C, DC y Z), y otros 5 bits que se incluyeron en este registro. Registro STATUS 7 6 5 4 3 2 1 0

IRP RP1 RP0 TO PD Z DC C El bit Z indica que el resultado de la ltima operacin fue CERO. El bit C indica acarreo del bit ms significativo (bit 7) del resultado de la ltima operacin de suma. En el caso de la resta se comporta a la inversa, C resulta 1 si no hubo pedido de prstamo. El bit DC (digit carry) indica acarreo del cuarto bit (bit 3) del resultado de la ltima operacin de suma o resta, con un comportamiento anlogo al del bit C, y es til para operar en BCD (para sumar o restar nmeros en cdigo BCD empaquetado). El bit C es usado adems en las operaciones de rotacin derecha o izquierda como un paso intermedio entre el bit 0 y el bit 7. El bit PD (POWER DOWN) sirve para detectar si la alimentacin fue apagada y encendida nuevamente, tiene que ver con la secuencia de inicializacin, el watch dog timer y la instruccin sleep, y su uso se detallar en la seccin referida al modo POWER DOWN. El bit TO (TIME-OUT) sirve para detectar si una condicin de reset fue producida por el watch dog timer (perro guardin), est relacionado con los mismos elementos que el bit anterior y su uso se detallar en la seccin referida al WATCH DOG TIMER. Los bits de seleccin de pagina RP0/RP1/IRP se utilizan en las instrucciones de salto GOTO y CALL, Manipulando el bit nmero 5 (RP0) del registro STATUS podremos indicar al microcontrolador si queremos trabajar en el banco "0" o en el "1". La operacin normal del microcontrolador se efecta en el banco "0". Pero cuando nos cambiamos del banco "0" al banco "1" es para efectuar ciertos cambios que definen como estarn configurados los puertos del microcontrolador.

En la siguiente imagen vemos la asignacin que tienen cada uno de los ocho bits del registro STATUS:

Si observamos de nuevo la tabla de registros del PIC16F84 vemos que existen algunas diferencias entre el banco "0" y el banco "1". Los registros denominados OPTION, TRISA, TRISB, EECON1 y EECON2 no existen en el banco 0. Si necesitamos acceder al registro TRISA, que solamente se encuentra en el banco "1", obligatoriamente habr que cambiarse del banco 0 al banco 1 por medio de las instrucciones del microcontrolador. Y tendremos que acceder al banco 1 solamente para utilizar los registros que no se encuentran en el banco 0. Una vez utilizados esos registros ( y modificados si fuese necesario), regresaremos al banco 0 para que el microcontrolador siga con su tarea asignada en la memoria del programa. En el caso de los registros OPTION y TRISA y B no ser necesario realizar el cambio de banco, ya que tenemos dos instrucciones que podremos utilizar para hacerlo, a pesar de que Microchip recomienda no usarlas para mantener la compatibilidad con el juego de instrucciones del microprocesador 16CXX.

1.4. TEMPORIZADOR/CONTADOR (TMP0, WDT Y SLEEP) EL REGISTRO CONTADOR TMR0:


El registro TMR0 es un contador de 8 bits, es decir un particular tipo de registro cuyo contenido es incrementado con una cadencia regular y programable directamente por el hardware del PIC. Este registro puede usarse para contar eventos externos por medio de un pin de entrada especial (modo contador) o para contar pulsos internos de reloj de frecuencia constante (modo timer). Adems, en cualquiera de los dos modos, se puede insertar un prescaler, es decir un divisor de frecuencia programable que puede dividir por 2, 4, 8, 16, 32, 64, 128 o 256. Este divisor puede ser utilizado alternativamente como prescaler del TMR0 o como postscaler del Watch Dog Timer, segn se lo programe.

En la prctica, a diferencia de los otros registros, el TMR0 no mantiene inalterado el valor que tiene memorizado, sino que lo incrementa continuamente. Si por ejemplo escribimos en l el valor 10, despus de un tiempo igual a cuatro ciclos de maquina, el contenido del registro comienza a ser incrementado a 11, 12, 13 y as sucesivamente con una cadencia constante y totalmente independiente de la ejecucin del resto del programa. Una vez alcanzado el valor 255, el registro TMR0 es puesto a cero automticamente comenzando entonces a contar desde cero y no desde el valor originalmente cargado.

La frecuencia de conteo es directamente proporcional a la frecuencia de reloj aplicada al chip y puede ser modificada programando adecuadamente algunos bits de configuracin. En la figura siguiente est representada la cadena de bloques internos del PIC que determinan el funcionamiento del registro TMR0.

Los bloques Fosc/4 y T0CKI, mostrados en azul, representan las dos posibles fuentes de seal de reloj, para el contador TMR0. Fosc/4 es una seal generada internamente por el PIC tomada del circuito de reloj y que es igual a la frecuencia del oscilador dividida por cuatro. T0CKI es una seal generada por un posible circuito externo y aplicada al pin T0CKI correspondiente al pin 3 del PIC16F84. Los bloques T0CS y PSA mostrados en verde son dos conmutadores de seal en cuya salida se presenta una de las dos seales de entrada en funcin del valor de los bits T0CS y PSA del registro OPTION. El bloque PRESCALER es un divisor programable cuyo funcionamiento veremos ms en detalle.
A continuacin veremos como es posible dividir posteriormente la frecuencia de conteo, interna externa, activando el PRESCALER.

EL PRESCALER: El PRESCALER consiste en un divisor programable de 8 bits a utilizar en el caso de que la frecuencia de conteo enviada al contador TMR0 sea demasiado elevada para nuestros propsitos. Se configura a travs de los bits PS0, PS1 y PS2 del registro OPTION. La frecuencia Fosc/4 es una cuarta parte de la frecuencia de reloj. Utilizando un cristal de 4Mhz tendremos una Fosc/4 igual a 1 MHz. Tal frecuencia es enviada directamente al registro TMR0 sin sufrir ningn cambio. La cadencia de conteo que se obtiene es por lo tanto igual a 1 milln de incrementos por segundo del valor presente en TMR0, que para muchas aplicaciones podra resultar demasiado elevada. Con el uso del PRESCALER podemos dividir posteriormente la frecuencia Fosc/4 configurando oportunamente los bits PS0, PS1 y PS2 del registro OPTION segn la siguiente tabla.

PS2 PS1 PS0 DIVISOR FREC. SALIDA PREESCALER (Mhz.) 0 0 0 2 500.000 0 0 1 4 250.000 0 1 0 8 125.000 0 1 1 16 62.500 1 0 0 32 31.250 1 0 1 64 15.625 1 1 0 128 7.813 1 1 1 256 3.906 Ejemplo prctico: introducir un retardo igual a un segundo utilizando el registro TMR0. Debemos programar el bit T0CS a 0 para seleccionar como fuente de conteo el reloj del PIC, el bit PSA a 0 para asignar el PRESCALER al registro TMR0 en lugar de al Watch Dog Timer (del que trataremos ms adelante) y los bits de configuracin del PRESCALER a 100 para obtener una frecuencia de divisin igual a 1:32. La frecuencia que obtendremos en TMR0 ser igual a: Fosc = 1Mhz / 32 = 31.250 Hz Memorizamos en TMR0 el valor 6 de modo que el registro TMR0 alcanza el cero despus de 250 cuentas (256 - 6 = 250) obteniendo as una frecuencia de paso por cero del TMR0 igual a: 31.250 / 250 = 125 Hz El siguiente paso ser memorizar en un registro de 8 bits el valor 125 de tal modo que, decrementando este registro en 1 por cada paso por cero de TMR0, se obtenga una frecuencia de pasos por cero del registro igual a: 125/125 = 1Hz (1 segundo). En resumen: se trata de controlar si TMR0 ha alcanzado el cero, luego de reinicializarlo a 6 y decrementar el valor contenido en un registro con valor 125. Cuando el registro alcance tambin el valor cero, entonces habr trascurrido un segundo. FUNCIONAMIENTO DEL POWER DOWN MODE: El Power Down Mode o Sleep Mode, es un estado particular de funcionamiento del PiC, utilizado para reducir el consumo de corriente en los momentos que no realiza ninguna tarea o est a la espera de un suceso externo. Si tomamos como ejemplo un control remoto para TV, veremos que la mayor parte del tiempo el micro permanece a la espera de la presin de alguna tecla. Apenas oprimida, efecta una breve transmisin y queda nuevamente a la espera de la presin de otra tecla. El tiempo de uso efectivo de la CPU del micro est por tanto, limitado a unos pocos milisegundos necesarios para efectuar la transmisin mientras que durante varias horas no efecta ninguna tarea particular (en el caso de utilizar la tcnica secaremote, en la que se hace un uso ms intensivo del mando, ocurre todo lo contrario!). Para no consumir intilmente la energa de las bateras, es posible apagar varios de los circuitos del micro y reencenderlos slo en correspondencia con algn suceso externo.

Veamos como. La instruccin SLEEP La instruccin SLEEP es utilizada para colocar el PIC en Power Down Mode y reducir la corriente absorbida, que pasar de unos 2 mA (a 5 volt y el clock en 4MHz) a unos 2uA, o sea, unas 1000 veces menos. Para entrar en Power Down Mode basta insertar la instruccin SLEEP en cualquier parte del programa. Cualquier instruccin siguiente a SLEEP no ser efectuada por el PIC el cual finalizar en este punto la ejecucin, apagar los circuitos internos, excepto aquellos necesarios para mantener el estado de los puertos de I/O y aquellos que lo sacarn de esa condicin, los cuales comentaremos a continuacin. Para despertar al PIC se utilizan diversas tcnicas: 1. Reset del PIC llevando a cero el pin 4 (MCLR). 2. Timeout del Watch Dog Timer (si est habilitado). 3. Verificacin de una interrupcin (interrupcin desde el pin RB0/INT, cambio de estado en el puerto B, finalizacin de la escritura sobre la EEPROM). En los dos primeros casos, el PIC es reseteado y la ejecucin es retomada en la situacin 0 de memoria.
En el tercer caso, el PIC se comporta como en el caso de una interrupcin normal, siguiendo primeramente el Interrupt handler, retomando la ejecucin despus de la instruccin SLEEP. Para que el PIC sea despertado por una interupt deben ser habilitados los flag del registro INTCON.

CLRWDT (CleaR Watch Dog Timer) La cual pone a cero en intervalos regulares el WDT, no permitindole llegar al final de su temporizacin. Si la CPU no realiza esta instruccin antes del trmino de la temporizacin, entonces, se asume que el programa se ha bloqueado por algn motivo y se efecta el reset de la CPU. El periodo mnimo alcanzado el cual la CPU es reseteada es de unos 18 ms (depende de la temperatura y de la tensin de alimentacin). Es posible, sin embargo, asignar el prescaler al WDT a fin de obtener retardos mayores (hasta unos 2,3 segundos). Para habilitar el WDT debemos, en la fase de programacin, habilitar el flag WDTE de la palabra de configuracin. La modalidad de activacin de este flag, depende del programador usado. Asignacin del prescaler al WDT Actuando sobre el bit PSA del registro OPTION_REG es posible asignar el prescaler al WDT para obtener tiempos de intervencin mayores. El bit PSA va seteado a uno con la instruccin: BSF OPTION_REG,PSA En caso contrario, el prescaler ser asignado al TIMER 0. Obviamente, asignando el prescaler al WDT, no ser posible usarlo con el TIMER 0 y viceversa.

Segn los valores de los bits PS0, PS1 y PS2 del OPTION_REG podremos obtener distintos intervalos de retardo. La eleccin correcta deber ser hecha teniendo en cuenta el mximo retardo que logramos obtener en nuestro programa tras la ejecucin de dos instrucciones CLRWDT sucesivas. En la tabla siguiente vemos los retardos, segn los valores de PS0, PS1 y PS2: PS2 PS1 PS0 0 0 0 0 0 1 0 1 0 0 1 1 1 0 0 1 0 1 1 1 0 1 1 1 DIVISOR 1 2 4 8 16 32 64 128 Retardo (ms) . 18 36 72 144 288 576 1.152 2.304

EL WATCH DOG TIMER (WDT): El Watch Dog Timer (que podra traducirse como temporizador perro guardin) es un oscilador interno al PIC, pero completamente independiente del resto de la circuitera, cuya funcin es eliminar eventuales bloqueos de la CPU del PIC y resetearlo para que retome la ejecucin normal del programa. Para poder eliminar un eventual bloqueo de la CPU durante la ejecucin del programa principal, se inserta en l una instruccin especial:

1.5. PUERTOS DE ENTRADA/SALIDA (I/O).


Los microprocesadores PIC16F84 tienen 2 puertos de entrada/salida paralelos de usos generales denominados Puerto A y Puerto B. El Puerto A es de 4 bits y el Puerto B es de 8 bits. Los puertos del microcontrolador PIC16F84 son el medio de comunicacin con el mundo exterior, en ellos podremos conectar los perifricos o circuitos necesarios como por ejemplo los mdulos LCD, motores elctricos, etc; pero estas conexiones no se podrn realizar arbitrariamente. Existen unas reglas bsicas que debern cumplirse para que el microcontrolador no sufra daos o se destruya. Para ello es necesario conocer los limites de corriente que puede manejar el microcontrolador. LIMITE DE CORRIENTE PARA LOS PUERTOS "A" Y "B". Los puertos "A" y "B" del microcontrolador podrn ser programados como entradas y salidas indiferentemente. Para el caso de que sean programados como salida se denominan "Modo Fuente" por que suministran corriente y cuando son programados como entrada se denominan "Modo Sumidero" por que reciben corriente. La mxima corriente que puede suministrar una lnea programada como salida es de 20 mA, pero si utilizamos todas las lneas del puerto "A" programadas como salidas, no deber exceder 50mA para el puerto "A". El puerto "B" no deber exceder de 100 mA. Si las programamos como entradas (Sumidero), la corriente mxima que puede manejar una sola lnea es de 25 mA. Para el caso del puerto "A" programado con todas sus lneas como entrada, la mxima es de 80 mA. En el caso del puerto "B" es de 150 mA. En caso de querer utilizar perifricos que manejen mayor cantidad de corriente de la especificada, habr que aplicar un circuito acoplador como por ejemplo los buffers, transistores que se encarguen de controlar la corriente, etc. Identificacin de los Pines utilizados para los puertos de entrada y salida. En la imagen siguiente se podr observar claramente que el microcontrolador tiene dos puertos denominados "A" y "B". El puerto "A" tiene 5 lneas disponibles (RA0, RA1, RA2, RA3, RA4) y el puerto "B" tiene 8 lneas disponibles (RB0, RB1, RB2, RB3, RB4, RB5, RB6, RB7). Ambos Puertos suman un total de 13 lneas que podrn ser programadas independientemente como entradas o como salidas. Estas son las lneas que estarn destinadas a comunicar el microcontrolador con el mundo exterior, como por ejemplo motores, diodos luminosos "Leds", mdulos LCD, teclados matriciales, etc.

Tambin hay que hacer mencin a que el Pin nmero 3 perteneciente al puerto "A" (RA4) tambin tiene otra nomenclatura denominada "TOCKI", lo cual quiere decir que esta lnea se puede programar como entrada, salida y temporizador/contador. Configuracin de los puertos de Entrada/Salida. Los bits de cada puerto se configuran mediante los bits correspondientes de un registro de control asociado que recibe el nombre de TRIS. En realidad cada puerto soporta dos registros: 1. El registro de datos, al que se denomina Puerto A o B (PortA o PortB). 2 El registro de control TRISA o TRISB, con el que se programa el sentido (Entrada o Salida) de las lneas de cada puerto. Los Puertos A y B se corresponden con las posiciones 5 y 6 del rea de datos. Cada uno de sus bits puede programarse como una lnea de Entrada o de Salida, segn se ponga un 1 un 0 en el bit del registro de control TRIS correspondiente. Un 1 en el bit "x" del registro TRISA pone en alta impedancia (Entrada) la lnea asociada "x" del Puerto A. Si en el bit "x" de TRISA hubiese un 0, el contenido del biestable de datos correspondiente del Puerto A pasara a la patita de E/S externa. Cualquier lnea puede funcionar como Entrada o Salida. Sin embargo, si acta como Entrada, la informacin que se introduce desde el exterior no se memoriza o graba, pasa simplemente por un dispositivo triestado por lo cual el valor de dicha informacin debe mantenerse hasta que sea leda. La lectura se realiza en "tiempo real". Cuando una patita de E/S funciona como salida, el bit que proviene del bus de datos se guarda en el biestable del dato con lo cual la informacin que ofrece esta patita permanece invariable hasta que se reescriba otro bit. Para configurar la patita como Entrada, hay que cargar un 1 en el biestable de control de E/S mientras que hay que cargar un 0 si se desea que sea Salida. Cada lnea de E/S de los puertos se programa de forma independiente y puede ser Entrada o Salida. Cuando se produce un reset, todos los bits de los registros TRIS pasan a tener el valor 1 y todas las lneas de E/S actan como Entrada por evidentes motivos de seguridad para evitar daos irreparables. Los puertos que E/S necesitan una atencin especial al escribir el programa. Instrucciones como bsf y bcf comienzan leyendo el valor del puerto y cargndolo en el registro W; all ejecutan la puesta a 1 a 0 del bit seleccionado y, luego, depositan el registro W en el puerto. Tambin hay que tener en cuenta las modificaciones que se produzcan en las patitas que son entrada y pasan a salida, pues pueden estar presentes datos antiguos en el registro de salida del puerto al ser memorizados. Hay que prestar mucha atencin a las operaciones que, tras una lectura de un puerto. sigue una escritura de la misma. Se debe dejar pasar un tiempo determinado para que se estabilice el voltaje de las patitas. Insertando entre la lectura y la escritura una instruccin NOP o cualquier otra que no implique a los puertos, se eliminan estos errores potenciales.

1.6. INTERRUPCIONES.
El sistema de interrupciones consiste en un mecanismo por el cual un evento interno o externo, asncrono respecto del programa, puede interrumpir la ejecucin de ste produciendo automticamente un salto a una subrutina de atencin, de manera que pueda atender inmediatamente el evento, y retomar luego la ejecucin del programa exactamente en donde estaba en el momento de ser interrumpido. Este mecanismo es muy til por ejemplo para el manejo de timers o rutinas que deben repetirse peridicamente (refresh de display, antirebote de teclado, etc.), deteccin de pulsos externos, recepcin de datos, etc.

Funcionamiento
Las interrupciones se comportan casi exactamente igual que las subrutinas. Desde el punto de vista del control del programa, al producirse una interrupcin se produce el mismo efecto que ocurrira si el programa tuviese un CALL 0004h en el punto en que se produjo la interrupcin. En uno de los registros de control del sistema de interrupciones existe un bit de habilitacin general de interrupciones GIE, que debe ser programado en 1 para que las interrupciones puedan actuar. Al producirse una interrupcin, este bit se borra automticamente para evitar nuevas interrupciones. La instruccin RETFIE que se utiliza al final de la rutina de interrupcin, es idntica a un retorno de subrutina, salvo que adems coloca en uno automticamente el bit GIE volviendo a habilitar las interrupciones. Dentro de la rutina de interrupcin, el programa deber probar el estado de los flags de interrupcin de cada una de las fuentes habilitadas, para detectar cual fue la que caus la interrupcin y as decidir que accin tomar.

Lgica de interrupciones para los controladores PIC16F8X

Fuentes.
La seal que produce la interrupcin es en realidad una sola, que resulta de la combinacin de todas las fuentes posibles y de los bits de habilitacin. Existen dos grupos de fuentes, unas que se habilitan con solo colocar en uno el bit GIE, y otras que adems necesitan que este puesto a uno el bit PEIE. Adems, cada fuente de interrupciones tiene su respectivo bit de habilitacin individual.

Las fuentes de interrupcin varan con cada versin, y pueden ser por ejemplo: Interrupcin externa por pin RB0/INT. Desborde del Timer 0 (TMR0). Cambio en el estado de los bits 4 a 7 del puerto B. Desborde del timer 1. Desborde del timer 2. Interrupcin del capture/compare 1. Interrupcin del capture/compare 2. transmisin o recepcin de un carcter por la interface serie sincrnica. transmisin o recepcin de un carcter por la interface serie asincrnica. Fin de conversin A/D. Lectura/escritura del puerto paralelo de comunicacin con otros microprocesadores. Escritura de EEPROM finalizada.

2.1. INSTRUCCIONES ASM DEL PIC16F84


El microcontrolador PIC 16F84 tiene un total de 37 instrucciones de una sola palabra, y adems otras 28 instrucciones especiales que se corresponden con combinaciones de 2 3 instrucciones simples. Las instrucciones tienen letras relacionadas (parmetros) y que tienen una interpretacin diferenciada. La letra W es el registro ms importante que tiene el PIC y se le denomina ACUMULADOR, ya que las operaciones pasan a travs de l. La letra k es un literal (valor numrico) que puede contener cualquier valor asignado por el programador entre 0 y 255 (es el mximo que se puede representar con un byte). La letra f es cualquier nombre dado a un registro. La letra d indica en que lugar se almacenar el resultado de la instruccin (en el acumulador W o en el registro f). Si d = 0, el resultado se almacenar en W. Si d = 1, el resultado se almacenar en f.

Instrucciones orientadas a los bytes


Mnemnico Parmetros Descripcin
ADDWF ANDWF CLRF CLRW COMF DECF DECFSZ INCF INCFSZ IORWF MOVF MOVWF NOP RLF RRF SUBWF SWAPF XORWF
f, d f, d f f, d f, d f, d f, d f, d f, d f, d f f, d f, d f, d f, d f, d Add W and f AND W with f Clear f Clear W Complement f Decrement f Decrement f, Skip if 0 Increment f Increment f, Skip if 0 Inclusive OR W with f Move f Move W to f No Operation Rotate left f through carry Rotate right f through carry Subtract W from f Swap nibbles in f Exclusive OR W with f

Ciclos Banderas
1 1 1 1 1 1 1(2) 1 1(2) 1 1 1 1 1 1 1 1 1 C, DC, Z Z Z Z Z Z None Z None Z Z None None C C C, DC, Z None Z

Instrucciones orientadas a los bits


Mnemnico Parmetros Descripcin
BCF BSF BTFSC BTFSS
f, b f, b f, b f, b Bit Clear f Bit Set f Bit Test f, Skip if Clear Bit Test f, Skip if Set

Ciclos Banderas
1 1 1 (2) 1 (2) None None None None

Operaciones con literales y de control


Mnemnico Parmetros Descripcin
ADDLW ANDLW CALL CLRWDT GOTO IORLW MOVLW RETFIE RETLW RETURN SLEEP SUBLW XORLW
k k k k k k k k k Add literal and W AND literal with W Call subroutine Clear Watchdog Timer Go to address Inclusive OR literal with W Move literal to W Return from interrupt Return with literal in W Return from Subroutine Go into standby mode Subtract W from literal Exclusive OR literal with W

NroCic. Banderas
1 1 2 1 2 1 1 2 2 2 1 1 1 TO,PD None Z None None None None TO,PD C, DC, Z Z C, DC, Z Z

Las instrucciones TRIS y OPTION recomienda Microchip no utilizarlas, para mantener la compatibilidad con el PIC16CXX. Aunque eso no significa que tengamos que hacer caso y no usarlas.

Instrucciones Especiales
Mnemnico Parmetros Descripcin
ADDCF ADDDCF B BC BDC
f, d f, d K K K Add Carry to File Add Digit Carry to File Branch Branch on Carry Branch on Digit Carry

Operacin Equivalente
BTFSC INCF BTFSC INCF GOTO BTFSC GOTO BTFSC 3,0 f,d 3,1 f,d k 3,0 k 3,1

Banderas
Z Z -

GOTO

k 3,0 k 3,1 k 3,2 k 3,2 k 3,0 3,1 3,2 Z Z Z Z Z

BNC BNDC BNZ BZ CLRC CLRDC CLRZ LCALL LGOTO MOVFW NEGF SETC SETDC SETZ SKPC SKPDC SKPNC SKPNDC SKPNZ SKPZ SUBCF SUBDCF TSTF

K K K K

Branch on No Carry Branch on No Digit Carry Branch on No Zero Branch on Zero Clear Carry Clear Digit Carry Clear Zero

BTFSS GOTO BTFSS GOTO BTFSS GOTO BTFSC GOTO BCF BCF BCF

Long CALL

BSF/BCF 0A,3 BSF/BCF 0A,4 CALL k BSF/BCF 0A,3 BSF/BCF 0A,4 GOTO k MOVF COMF INCF BSF BSF BSF f,0 f,1 f,d 3,0 3,1 3,2

K F f, d

Long GOTO Move File to W Negate File Set Carry Set Digit Carry Set Zero Skip on Carry Skip on Digit Carry Skip on No Carry Skip on No Digit Carry Skip on Non Zero Skip on Zero

BTFSS 3,0 BTFSS 3,1 BTFSC 3,0 BTFSC 3,1 BTFSC 3,2 BTFSS 3,2 BTFSC 3,0 DECF f,d BTFSC 3,1 DECF f,d MOVF f,1

f,d f,d f

Substract Carry from File Substract Digit Carry from File Test File

2.1.1. DE CONTROL Y MANEJO DE LITERALES. INSTRUCCIN: Descripcin: Operacin: ADDLW k (hex = 3E kk) Sumar al acumulador el valor k. W=W+k Esta instruccin suma un valor de un literal al contenido del registro W y lo guarda en W. Ejemplo: MOVLW 3 ; carga el acumulador W con el valor 3. ADDLW 1 ; suma 1 al acumulador. Al final el acumulador tendr el valor 4. Registro STATUS: Modifica los bits Z, DC y C. Z vale 1 si el resultado de la operacin es 0. DC vale 1 si el resultado de la operacin es un nmero superior a 15. C vale 1 si el resultado de la operacin es positivo o el bit 7 del registro que contiene el resultado vale 0. En caso contrario C vale 0 (resultado negativo).

INSTRUCCIN: Descripcin: Operacin:

Ejemplo:

ANDLW k (hex = 39 kk) Operacin lgica AND entre el acumulador W y el literal k W = W AND k Esta instruccin realiza una operacin lgica AND entre el contenido de W y k. El resultado se guarda siempre en el acumulador W Si cargamos el acumulador con el binario 10101010B y hacemos un AND con el binario 11110000B, nos quedar el resultado de la operacin en el acumulador W. MOVLW 10101010B ANDLW 11110000B El resultado de la operacin queda en W = 10100000B. Explicacin de la operacin AND:

Tenemos 4 posibles combinaciones entre dos bits


0 AND 0 = 0 0 AND 1 = 0 1 AND 0 = 0 1 AND 1 = 1 Vemos que solamente en el caso de que ambos bits sean 1, el resultado ser 1. Esta instruccin compara dos bytes, bit a bit. Registro STATUS: Modifica el bit Z. Z vale 1 si el resultado de la operacin es 0.

INSTRUCCIN: Descripcin: Operacin:

CALL k (hex = 2k kk) Llama a una subrutina en la direccin k. CALL k...RETURN PC+1. Esta instruccin llama a un grupo de instrucciones (subrutina) que comienzan en la direccin k, donde k puede ser un valor numrico o una etiqueta. Siempre termina con la instruccin de retorno (RETURN o RETLW). Definicin de subrutina: son un grupo de instrucciones que forman un programa dentro del programa principal y que se ejecutan cuando las llama el programa principal. Utilidad: sirven para utilizarlas varias veces en cualquier parte del programa, sin necesidad de tener que copiar las mismas instrucciones, con el consiguiente ahorro de memoria. Funcionamiento: cuando un programa ejecuta una instruccin CALL, guarda en el stack el valor del registro PC+1 (PC = Program Counter) de manera que al regresar de la subrutina contina con la instruccin siguiente recuperndola del stack, ejecutando la instruccin de retorno RETURN o RETLW. Limitaciones: en el PIC16F84 tenemos disponibles 8 niveles de stack, por lo que el nmero mximo de CALL reentrantes (instrucciones CALL que contengan otra instruccin CALL) queda limitado a 8. PRINCIPAL: etiqueta que identifica una direccin de memoria. RETARDO: etiqueta que identifica el comienzo de una subrutina. BUCLE: etiqueta que identifica una direccin de memoria. PRINCIPAL CALL RETARDO BTFSC PORTB, RB0 GOTO PRINCIPAL * * * RETARDO CLRF CONTADOR BUCLE DECFSZ CONTADOR, 1 GOTO BUCLE RETURN

Ejemplo:

En este listado vemos que la subrutina RETARDO salta a un grupo de instrucciones que forman un bucle y cuando ste termina regresa para seguir con la instruccin siguiente al salto (BTFSC...). Registro STATUS: No modifica ningn bit de estado.

INSTRUCCIN: Descripcin: Operacin:

Ejemplo:

CLRWDT (hex = 00 64) Pone el temporizador WDT a cero. WDT = 0 Esta instruccin se utiliza cuando programamos el PIC con la opcin Watch Dog habilitada. Para evitar el reset del PIC, el programa debe contener cclicamente la instruccin CLRWDT para ponerlo a cero. Si no se pone a cero a tiempo, el WDT interpretar que se ha bloqueado el programa y ejecutar un reset para desbloquearlo. Bucle CLRWDT * * * GOTO Bucle

Registro STATUS: No modifica ningn bit de estado.

INSTRUCCIN: Descripcin: Operacin:

Ejemplo:

GOTO k (hex = 28 kk) Salto incondicional a k. Salto k Esta instruccin ejecuta un salto del programa a la direccin k. El parmetro k puede ser un valor numrico o una etiqueta. INSTRUCCIN 1 GOTO ABAJO INSTRUCCIN 3 INSTRUCCIN 4 INSTRUCCIN 5 ABAJO INSTRUCCIN 6

Primero se ejecuta la instruccin 1, despus GOTO y contina con la instruccin 6 saltndose las instrucciones 3, 4 y 5. Registro STATUS: No modifica ningn bit de estado.

INSTRUCCIN: Descripcin: Operacin:

Ejemplo:

IORLW k (hex = 38 kk) Operacin lgica OR entre el acumulador W y el literal k W = W OR k Esta instruccin realiza un OR inclusivo entre el contenido del acumulador W y el literal k. El resultado se guarda siempre en el acumulador (k es un valor, no un registro). Si cargamos el acumulador con el binario 11110000B y k= 00001111B, nos quedar el resultado de la operacin en el acumulador W. MOVLW 11110000B IORLW 00001111B El resultado de la operacin queda en W = 11111111B. Explicacin de la operacin OR:

Tenemos 4 posibles combinaciones entre dos bits


0 OR 0 = 0 0 OR 1 = 1 1 OR 0 = 1 1 OR 1 = 1 Vemos que solamente en el caso de que ambos bits sean 0, el resultado ser 0. Esta instruccin compara dos bytes, bit a bit. Registro STATUS: Modifica el bit Z. Z vale 1 si el resultado de la operacin es 0.

INSTRUCCIN: Descripcin: Operacin:

Ejemplo:

MOVLW k (hex = 30 kk) Mover el literal k al acumulador. W=k Esta instruccin asigna al acumulador W el valor del literal k (entre 0 y 255). Si tenemos el acumulador a cero o con cualquier valor, y queremos que contenga el que le asignemos nosotros directamente entonces usaremos esta instruccin: W = 0. Valor a asignar = 100. Instruccin: MOVLW 100 El acumulador valdr 100 (W = 100).

Con distinto valor de partida del acumulador: W = 225. MOVLW 100 El acumulador valdr 100 (W = 100). Registro STATUS: No modifica ningn bit de estado.

INSTRUCCIN: Descripcin: Operacin:

Ejemplo:

OPTION (hex = 00 62) Guarda el valor del acumulador en el registro OPTION. OPTION = W. Esta instruccin guarda en el registro especial OPTION el valor contenido en el acumulador W. MOVLW 10H ; carga el acumulador con el valor 10H. OPTION ; carga el registro OPTION con el acumulador. Esta instruccin existe para mantener la compatibilidad con los PIC producidos con anterioridad, y como en el futuro podra dejar de implementarse, Microchip aconseja realizar el ejemplo anterior de esta otra forma: BSF STATUS, RP0 ; activa el banco 1. MOVLW 10H ; carga el acumulador con 10H. MOVWF OPTION_REG ; carga OPTION con el acumulador.

Registro STATUS: No modifica ningn bit de estado.

INSTRUCCIN: Descripcin: Operacin:

Ejemplo:

RETFIE (hex = 00 09) Retorna de una interrupcin. FIN INTERRUPCION. Esta instruccin devuelve el control al programa principal despus de ejecutarse una subrutina de gestin de interrupcin. ORG 00H BUCLE GOTO BUCLE ; bucle infinito. ORG 04H; vector de interrupcin. RETFIE ; retorna de la interrupcin

Este cdigo de programa ejecuta un bucle infinito. Si habilitamos una de las interrupciones del 16F84, en cuanto sta se produzca pasar el control al programa situado en la direccin 04H y la instruccin RETFIE regresa de la interrupcin. Al ejecutarse una interrupcin, el bit GIE del registro INTCON se pone a 0 y as evita que otra interrupcin se produzca mientras ya est con una en marcha. Con la instruccin RETFIE ponemos de nuevo el bit GIE a 1 para as atender de nuevo a futuras interrupciones. Registro STATUS: No modifica ningn bit de estado.

INSTRUCCIN: Descripcin: Operacin:

Ejemplo:

RETLW (hex = 34 kk) Retorno de subrutina y carga literal k en el acumulador. RETORNO con W = k. Esta instruccin retorna de una subrutina al programa principal, cargando el acumulador W con el literal k. Es la ltima instruccin que forma una subrutina (al igual que RETURN). Y para qu me sirve regresar de una subrutina con un determinado literal en el acumulador? Nos ser muy til al programar con TABLAS. CALL SUBRUT1 ; llama a Subrut1. MOVWF DATO 1 ; carga W en Dato1. CALL SUBRUT2 ; llama a Subrut2. MOVWF DATO2 ; carga W en Dato2. * * SUBRUT1 RETLW 0A ; carga W = 0A y retorna. SUBRUT2 RETLW 0B ; carga W = 0B y retorna.

Registro STATUS: No modifica ningn bit de estado.

INSTRUCCIN: Descripcin: Operacin:

RETURN (hex = 00 08) Retorno de subrutina. RETORNO. Esta instruccin retorna de una subrutina al programa principal en la instruccin siguiente a la llamada de la subrutina, tomando el valor almacenado en el stack para continuar. Es la ltima instruccin que forma una subrutina (al igual que RETLW). CALL COMPARA ; llama a Compara. INSTRUCCION1 INSTRUCCION2 * * COMPARA INSTRUCCIN R1 INSTRUCCIN R2 RETURN

Ejemplo:

Aqu llamamos a la subrutina COMPARA, se ejecutan las instrucciones R1 y R2 y con el RETURN regresa a la instruccin siguiente al CALL y ejecuta las instrucciones 1, 2 y sigue con el programa. Registro STATUS: No modifica ningn bit de estado.

INSTRUCCIN: Descripcin: Operacin:

SLEEP (hex = 00 63) En modo reposo.. EN ESPERA. Esta instruccin detiene la ejecucin del programa y deja el PIC en modo suspendido. No ejecuta ninguna instruccin hasta que sea nuevamente reinicializado (reset). Durante este modo, el contador del Watch Dog (WDT) sigue trabajando, y si lo tenemos activado el PIC se resetear por este medio. El consumo de energa es mnimo.

Ejemplo: Registro STATUS: No modifica ningn bit de estado.

INSTRUCCIN: Descripcin: Operacin:

SUBLW k (hex = 3C kk) Resta al literal k el valor del acumulador. W=k-W Esta instruccin resta al literal k el valor almacenado en el acumulador W y el resultado se guarda en el acumulador. Ejemplo: MOVLW 10 ; carga el acumulador W con el valor 10. SUBLW 15 ; resta a 15 el valor del acumulador. Al final el acumulador tendr el valor W = 5. Registro STATUS: Modifica los bits Z, DC y C. Z vale 1 si el resultado de la operacin es 0. DC vale 1 si el resultado de la operacin es un nmero superior a 15. C vale 1 si el resultado de la operacin es positivo o el bit 7 del registro que contiene el resultado vale 0. En caso contrario C vale 0 (resultado negativo).

INSTRUCCIN: Descripcin: Operacin:

Ejemplo:

TRIS f (hex = 00 6F) Guarda el acumulador en uno de los registros de TRIS. TRIS de f = W. Esta instruccin guarda el valor del acumulador W en uno de los registros especiales de TRIS que indicamos en el parmetro f. Los registros TRIS determinan el funcionamiento como entrada y salida de las lneas I/O del PIC. MOVLW 16H ; carga el acumulador W con el valor 16H. TRIS PORTA ; carga el registro PORTA con el acumulador.

Esta instruccin existe para mantener la compatibilidad con los PIC producidos anteriormente,y como en el futuro podra dejar de implementarse, Microchip aconseja realizar el ejemplo anterior de esta otra forma (aunque ocupa ms memoria...): BSF STATUS, RP0 ; activa el banco 1. MOVLW 16H ; carga el acumulador con el valor 16H MOVWF TRISA ; carga el registro PORTA con W. Registro STATUS: No modifica ningn bit de estado.

INSTRUCCIN: Descripcin: Operacin:

XORLW k (hex = 3A kk) Operacin lgica OR exclusivo entre el acumulador y el literal k

W = W XOR k
Esta instruccin realiza un OR exclusivo entre el contenido del acumulador W y el valor del literal k. El resultado se guarda siempre en el acumulador (k es un literal, no un registro). Si cargamos el acumulador con el binario 11110000B y hacemos un XOR con el binario 10101010B, nos quedar el resultado de la operacin en el acumulador W. MOVLW 11110000B XORLW 10101010B El resultado de la operacin queda en W = 01011010B. Explicacin de la operacin XOR:

Ejemplo:

Tenemos 4 posibles combinaciones entre dos bits


0 XOR 0 = 0 0 XOR 1 = 1 1 XOR 0 = 1 1 XOR 1 = 0 Vemos que si ambos bits son iguales el resultado ser 0. Y si ambos son diferentes, el resultado ser 1. Esta instruccin compara dos bytes, bit a bit. Registro STATUS: Modifica el bit Z. Z vale 1 si el resultado de la operacin es 0.

2.1.2.ORIENTADAS A REGISTROS.

INSTRUCCIN: Descripcin: Operacin:

ADDWF f,d (hex = 07 ff) Suma el acumulador y el registro f. d = W + f (d puede ser W f). Esta instruccin suma el contenido del acumulador con el registro f, y el resultado se guarda dependiendo del valor de d. Si d = 0, se guarda en W. Si d = 1, se guarda en f. Si no se pone nada, el valor por defecto es 1 y se guarda en f. Tambin se puede indicar directamente W f. Ejemplo: Si tomamos como valores iniciales W = 5 y DATO = 10. ADDWF DATO ; DATO = 15 y W = 5. ADDWF DATO, 1; DATO = 15 y W = 5. ADDWF DATO, 0; W = 15 y DATO = 10. ADDWF DATO, W; W = 15 y DATO = 10. Registro STATUS: Modifica los bits Z, DC y C. Z vale 1 si el resultado de la operacin es 0. DC vale 1 si el resultado de la operacin > 15. C vale 1 si el resultado de la operacin es positivo o el bit 7 del registro que contiene el resultado vale 0. En caso contrario C vale 0 (resultado negativo).

INSTRUCCIN: Descripcin: Operacin:

Ejemplo:

ANDWF f,d (hex = 05 ff) Operacin lgica AND entre el acumulador y el registro f. d = W AND f (d puede ser W o f). Esta instruccin realiza una operacin lgica AND entre el contenido del acumulador W y el registro f. El resultado se guarda segn sea el valor de d. Si d = 0, se guarda en W. Si d = 1, se guarda en f. Si no se pone nada, el valor por defecto es 1 y se guarda en f. Tambin se puede indicar directamente W f. Si queremos extraer los 4 bits menos significativos de un registro, podremos utilizar una mscara para obtenerlos. Usamos el valor 00001111B para realizar la operacin ADN y as obtenerlos (para los 4 bits ms significativos utilizaramos el valor 11110000B). Cargamos el valor del cual queremos extraer los 4 bits menos significativos en f (f = 10101010B). Cargamos el acumulador con la mscara (W = 00001111B). ANDWF f,W El resultado queda guardado en el acumulador (W = 00001010B).
Explicacin de la operacin AND: 4 posibles combinaciones entre dos bits

0 AND 0 = 0 0 AND 1 = 0 1 AND 0 = 0 1 AND 1 = 1 Vemos que solamente en el caso de que ambos bits sean 1, el resultado ser 1. Esta instruccin compara dos bytes, bit a bit. Registro STATUS: Modifica el bit Z. Z vale 1 si el resultado de la operacin es 0. INSTRUCCIN: Descripcin: Operacin: CLRF f (hex = 01 8f) Pone a cero el registro f. F = 0. Esta instruccin pone a cero el valor contenido en el registro direccionado por el parmetro f. Puede decirse que borra el registro f. Si queremos poner a cero el registro TMR0, cuya direccin es 01H, tendramos que utilizar

Ejemplo:

CLRF 01H
Si hemos incluido al inicio del cdigo fuente el fichero PIC16F84.INC, podemos utilizar el nombre simblico de dicho registro: CLRF TMR0 Registro STATUS: Modifica el bit Z y lo pone a 1 (ya que el resultado de la operacin es 0).

INSTRUCCIN: Descripcin: Operacin:

Ejemplo:

CLRW (hex = 01 00) Pone el acumulador a cero. W=0 Esta instruccin pone a cero el valor contenido en el registro W (acumulador) No es necesario

Registro STATUS: Modifica el bit Z y lo pone a 1 (ya que el resultado de la operacin es 0).

INSTRUCCIN: Descripcin: Operacin:

COMF f,d (hex = 09 ff) Complementa el registro f. d = NOT f (d puede ser W f). Esta instruccin efecta el complemento del valor contenido en el registro direccionado por el parmetro f. La operacin de complementar consiste en invertir los bits: poner los ceros a unos y los unos a ceros. El parmetro d determina el destino del valor obtenido. Si d = W, el resultado se almacena en el acumulador. Si d = f, el resultado se almacena en el propio registro f. Ejemplo: Si tenemos en PORTA el valor 00001111B, al ejecutar: COMF PORTA El resultado ser PORTA = 11110000B. Si aplicamos para el mismo valor inicial, la instruccin: COMF PORTA, W El resultado ser W = 11110000B y PORTA = 00001111B. Registro STATUS: Modifica el bit Z. Z vale 1 si el resultado de la operacin es 0.

INSTRUCCIN: Descripcin: Operacin:

DECF f,d (hex = 03 ff) Decrementa en 1 el registro f. d = f 1 (d puede ser W f). Esta instruccin decrementa en uno el contenido del registro direccionado por el parmetro f. El parmetro d determina el destino del valor obtenido. Si d = W, el resultado se almacena en el acumulador. Si d = f, el resultado se almacena en el propio registro f. Ejemplo: Si tenemos un registro DIA = 7. Aplicando la instruccin DECF DIA, 0, tendremos W = 6 y DIA = 7. Si aplicamos esta otra DECF DIA, 1, tendremos DIA = 6. Registro STATUS: Modifica el bit Z. Z vale 1 si el resultado de la operacin es 0.

INSTRUCCIN: Descripcin: Operacin:

Ejemplo:

DECFSZ f,d (hex = 0B ff) Decrementa en 1 a f, y si f = 0 salta la siguiente instruccin. d = f 1, si d = 0 SALTA (d puede ser W f). Esta instruccin decrementa el contenido del registro direccionado por el parmetro f, y si el resultado es 0 se salta la instruccin siguiente. El parmetro d determina el destino del valor obtenido. Si d = W, el resultado se almacena en el acumulador. Si d = f, el resultado se almacena en el propio registro f. DECFSZ VALOR, W INSTRUCCION 1 INSTRUCCIN 2

Si el contenido del registro VALOR al decrementarlo en 1 es igual a 0, se guarda el resultado en el acumulador y sigue con la INSTRUCCION2, saltndose la INSTRUCCION1. Si el resultado que guardamos en W no es 0, sigue con la INSTRUCCION1 y despus con la INSTRUCCION2 (no se salta la inmediata siguiente). Registro STATUS: No modifica ningn bit de estado.

INSTRUCCIN: Descripcin: Operacin:

INCF f,d (hex = 0A ff) Incrementa en 1 el registro f. d = f + 1 (d puede ser W f). Esta instruccin incrementa en uno el contenido del registro direccionado por el parmetro f. El parmetro d determina el destino del valor obtenido. Si d = W, el resultado se almacena en el acumulador.

Si d = f, el resultado se almacena en el propio registro f.


Ejemplo: Si tenemos un registro DIA = 7. Aplicando la instruccin INCF DIA, 0, tendremos W = 8 y DIA = 7. Si aplicamos esta otra INCF DIA, 1, tendremos DIA = 8. Registro STATUS: Modifica el bit Z. Z vale 1 si el resultado de la operacin es 0.

INSTRUCCIN: Descripcin: Operacin:

Ejemplo:

INCFSZ f,d (hex = 0F ff) Incrementa en 1 a f, y si f = 0 salta la siguiente instruccin d = f + 1, si d = 0 SALTA (d puede ser W f). Esta instruccin incrementa en uno el contenido del registro direccionado por el parmetro f, y si el resultado es 0 se salta la instruccin siguiente. El parmetro d determina el destino del valor obtenido. Si d = W, el resultado se almacena en el acumulador. Si d = f, el resultado se almacena en el propio registro f. INCFSZ VALOR, W INSTRUCCION 1 INSTRUCCIN 2

Si el contenido del registro VALOR al incrementarlo en 1 es igual a 0, se guarda el resultado en el acumulador y sigue con la INSTRUCCION2, saltndose la INSTRUCCION1. Si el resultado que guardamos en W no es 0, sigue con la INSTRUCCION1 y despus con la INSTRUCCION2 (no se salta la inmediata siguiente). Registro STATUS: No modifica ningn bit de estado.

INSTRUCCIN: Descripcin: Operacin:

IORWF f,d (hex = 04 ff) Operacin lgica OR inclusivo entre el acumulador y un registro d = W OR f (d puede ser W f). Esta instruccin realiza una operacin lgica OR inclusivo entre el acumulador W y el registro direccionado por el parmetro f. El parmetro d determina donde se almacenar el resultado de la operacin. Si d = 0, se guarda en W. Si d = 1, se guarda en f. Si no se pone nada, el valor por defecto es 1 y se guarda en f. Tambin se puede indicar directamente W f. Ejemplo: Si asignamos los valores W = 10101010B y f = 01010101B. IORWF f ; W = 10101010B y f = 11111111B. IORWF f, 1; W = 10101010B y f = 11111111B. IORWF f, 0; f = 01010101B y W = 11111111B. IORWF f, W; f = 01010101B y W = 11111111B. Registro STATUS: Modifica el bit Z. Z vale 1 si el resultado de la operacin es 0.

INSTRUCCIN: Descripcin: Operacin:

MOVF f,d, (hex = 08 ff) Mueve el contenido de f al acumulador o al propio registro f. d = f (d puede ser W f). Esta instruccin copia el contenido del registro direccionado por el parmetro f en el acumulador W o en el mismo registro f. El parmetro d determina el destino. Si d = 0, se guarda en W. Si d = 1, se guarda en f. Si no se pone nada, el valor por defecto es 1 y se guarda en f. Tambin se puede indicar directamente W f.

El motivo para copiar el contenido de un registro sobre si mismo, no es otro que poder comprobar en el registro STATUS el estado del bit Z. Ejemplo: Si tenemos el registro EDAD = 38. ;) MOVF EDAD, 0 ; hace que W = 38. MOVF EDAD, 1 ; hace que EDAD = 38. MOVF EDAD, W ; hace que W = 38. MOVF EDAD ; hace que EDAD = 38. Registro STATUS: Modifica el bit Z. Z vale 1 si el resultado de la operacin es 0.

INSTRUCCIN: Descripcin: Operacin:

Ejemplo:

MOVWF f (hex = 00 8f) Mueve el contenido de W al registro f. f = W. Esta instruccin copia el contenido del acumulador W en el registro direccionado por el parmetro f. Si queremos escribir el valor 10H en el registro TMR0, que est situado en la direccin 01H, tendremos que cargar primero el valor en el acumulador y despus copiarlo al registro. MOVWF 10H ; cargar el valor 10H en el acumulador. MOVWF 01H ; copia el acumulador en la direccin 01H.

Con los registros utilizados por el PIC para funciones especficas, es habitual no escribir directamente su direccin, sino el nombre simblico definido en el fichero PIC16F84.INC. En el ejemplo anterior nos quedara as: MOVWF 10H ; cargar el valor 10H en el acumulador. MOVWF TMR0 ; copia el acumulador en el registro TMR0. Registro STATUS: No modifica ningn bit de estado.

INSTRUCCIN: Descripcin: Operacin:

NOP (hex = 00 00) No opera. -----Esta instruccin no realiza ninguna funcin especfica, pero consume 4 ciclos de reloj completos. Es til para insertar un retardo igual a un ciclo de mquina. Ejemplo: Utilizando un cristal de cuarzo de 4 Mhz. en el oscilador, podremos obtener un retardo igual a un microsegundo por cada instruccin NOP que insertemos en el cdigo del programa: RETARDO NOP NOP NOP RETURN Cada vez que llamemos a la subrutina RETARDO, obtendremos 3 microsegundos de demora. Registro STATUS: No modifica ningn bit de estado.

INSTRUCCIN: Descripcin: Operacin:

RLF f,d (hex = 0D ff) Rota a la izquierda el registro f. d = << 1 (d puede ser W f). Esta instruccin rota a la izquierda todos los bits del registro direccionado en el parmetro f pasando por el bit CARRY del registro STATUS (o si se prefiere, desde los bits menos significativos a los ms significativos). Es como si multiplicramos por dos el contenido del registro. Veamos el registro f de forma grfica:

El D7 pasa al CARRY del registro STATUS, el contenido del CARRY pasa al D0, el D0 al D1, etc. El parmetro d determina el destino. Si d = 0, se guarda en W. Si d = 1, se guarda en f. Si no se pone nada, el valor por defecto es 1 y se guarda en f. Tambin se puede indicar directamente W f. Ejemplo: Si tenemos el registro VALOR = 00000001B y aplicamos la instruccin RLF VALOR el resultado ser VALOR = 00000010B y el bit C = 0. Si tenemos el registro VALOR = 10000000B y aplicamos la instruccin RLF VALOR El resultado ser VALOR = 00000000B y el bit C = 1. Registro STATUS: Modifica el bit C (CARRY).

INSTRUCCIN: Descripcin: Operacin:

RRF f,d (hex = 0C ff) Rota a la derecha el registro f.

d = f >> 1 (d puede ser W f).


Esta instruccin rota a la derecha todos los bits del registro direccionado en el parmetro f pasando por el bit CARRY del registro STATUS (o si se prefiere, desde los bits ms significativos a los menos significativos). Es como si dividiramos por dos el contenido del registro. Veamos el registro f de forma grfica:

El bit C del registro STATUS pasa al D7, el D0 pasa al bit C, el D1 al D0, etc. El parmetro d determina el destino. Si d = 0, se guarda en W. Si d = 1, se guarda en f. Si no se pone nada, el valor por defecto es 1 y se guarda en f. Tambin se puede indicar directamente W f. Ejemplo: Si tenemos el registro VALOR = 00000001B y aplicamos la instruccin RRF VALOR el resultado ser VALOR = 00000000B y el bit C = 1. Si tenemos el registro VALOR = 10000000B y aplicamos la instruccin RRF VALOR El resultado ser VALOR = 01000000B y el bit C = 0. Registro STATUS: Modifica el bit C (CARRY).

INSTRUCCIN: Descripcin: Operacin:

SUBWF f,d (hex = 02 ff) Resta el acumulador del registro f.

d = f W (d puede ser W f).

Esta instruccin resta el valor contenido en el acumulador W del valor contenido en el registro direccionado por el parmetro f. El parmetro d determina el destino. Si d = 0, se guarda en W. Si d = 1, se guarda en f. Si no se pone nada, el valor por defecto es 1 y se guarda en f. Tambin se puede indicar directamente W f. Ejemplo: Segn sean los valores de W y el registro DATO, si aplicamos SUBWF DATO, obtendremos diferentes resultados en el bit CARRY. Si DATO = 3 y W = 2; el resultado ser DATO = 1 y C = 1. Si DATO = 2 y W = 2; el resultado ser DATO = 0 y C = 1. Si DATO = 1 y W = 2; el resultado ser DATO = FFH y C = 0. Vemos que C = 1 porque el resultado es positivo y C = 0 cuando el resultado es negativo. Registro STATUS: Modifica los bits Z, DC y C. Z vale 1 si el resultado de la operacin es 0. DC vale 1 si el resultado de la operacin es un nmero superior a 15. C vale 1 si el resultado de la operacin es positivo o el bit 7 del registro que contiene el resultado vale 0. En caso contrario C vale 0 (resultado negativo).

INSTRUCCIN: Descripcin: Operacin:

SWAPF f,d (hex = 0E ff) Intercambia los 4 bits ms significativos con los 4 menos (nibbles)

f = 0123 SWAP 4567 de f.

Esta instruccin intercambia el valor de los 4 bits ms significativos (D7-D4) contenidos en el registro direccionado por el parmetro f, con los 4 bits menos significativos (D3-D0) del mismo. El parmetro d determina el destino. Si d = 0, se guarda en W. Si d = 1, se guarda en f. Si no se pone nada, el valor por defecto es 1 y se guarda en f. Tambin se puede indicar directamente W f. Ejemplo: Si tenemos VALOR = 00001111B y W = 00000000B, al aplicar SWAPF VALOR ; VALOR = 11110000B y W = 00000000B. SWAPF VALOR, W; VALOR = 00001111B y W = 11110000B. Con la primera instruccin modificamos el valor del registro DATO, y en la segunda instruccin modificamos el valor del acumulador sin que vare el registro DATO . Registro STATUS: No modifica ningn bit de estado.

INSTRUCCIN: Descripcin: Operacin:

XORWF f,d (hex = 06 ff) Operacin lgica XOR entre el acumulador y f.

d = f XOR W (d puede ser W f).


Esta instruccin efecta la operacin lgica XOR (OR exclusivo) entre el valor contenido en el acumulador W y el valor contenido en el registro direccionado por el parmetro f. El parmetro d determina el destino. Si d = 0, se guarda en W. Si d = 1, se guarda en f. Si no se pone nada, el valor por defecto es 1 y se guarda en f. Tambin se puede indicar directamente W f. Si tenemos el registro VALOR = 11110000B y W = 11111111B, al aplicar la instruccin XORWF VALOR ; hace VALOR = 00001111B y W no vara. XORWF VALOR, W ; hace W = 00001111B y VALOR no vara. Explicacin de la operacin XOR:

Ejemplo:

Tenemos 4 posibles combinaciones entre dos bits


0 XOR 0 = 0 0 XOR 1 = 1 1 XOR 0 = 1 1 XOR 1 = 0 Vemos que si ambos bits son iguales el resultado ser 0. Y si ambos son diferentes, el resultado ser 1. Esta instruccin compara dos bytes, bit a bit. Esto nos sirve para comparar dos valores y comprobar si son iguales o no. Supongamos que tenemos el registro NUMERO y queremos comprobar si es igual a 26H. Tendramos que efectuar las siguientes instrucciones: MOVLW 26H; carga el acumulador con el valor a comparar. XORWF NUMERO, W ; compara el acumulador con NUMERO. BTFSS STATUS, Z ; salta la instruccin siguiente si XOR = 0. GOTO DISTINTO ; salta a DISTINTO si XOR no es 0. GOTO IGUAL ; salta a IGUAL. Registro STATUS: Modifica el bit Z. Z vale 1 si el resultado de la operacin es 0.

2.1.3. ORIENTADAS A BITS.

INSTRUCCIN: Descripcin: Operacin:

Ejemplo:

BCF f,b (hex = 1B ff) Pone a cero el bit b del registro f. F(b) = 0 Esta instruccin pone a cero un bit que hayamos elegido de un registro determinado. BCF PORTA, RA4 ; pone a 0 el bit RA4 del registro PORTA BCF PORTA, 4 ; igual, si no conocemos en nombre del bit

Si en el PORTA tenemos como valor inicial 11111111B, despus de aplicar el ejemplo anterior, PORTA = 11101111B. Registro STATUS: No modifica ningn bit de estado.

INSTRUCCIN: Descripcin: Operacin:

Ejemplo:

BSF f,b (hex = 1B ff) Pone a uno el bit b del registro f. F(b) = 1 Esta instruccin pone a uno un bit que hayamos elegido de un registro determinado. BSF PORTA, RA0 ; pone a 1 el bit RA0 del registro PORTA BSF PORTA, 0 ; igual, si no conocemos en nombre del bit

Si en el PORTA tenemos como valor inicial 00000000B, despus de aplicar el ejemplo anterior, PORTA = 00000001B. Registro STATUS: No modifica ningn bit de estado.

INSTRUCCIN: Descripcin: Operacin:

Ejemplo:

BTFSC f,b (hex = 1B ff) Comprueba un bit b del registro f y se salta la instruccin siguiente si vale 0. F(b) = 0 ? SI, salta una instruccin Esta instruccin comprueba el valor del bit b en el registro f, y si b = 0 entonces se salta la siguiente instruccin. Si b = 1 no salta y sigue con su ejecucin normal. BTFSC PORTA, 2 INSTRUCCIN 1 INSTRUCCIN 2

Si en PORTA tenemos como valor inicial 11111011B, el programa contina con la instruccin 2, saltndose la instruccin 1 Si en PORTA tenemos el valor 00000100B, el programa sigue con la instruccin 1 y despus la instruccin 2. Registro STATUS: No modifica ningn bit de estado.

INSTRUCCIN: Descripcin: Operacin:

Ejemplo:

BTFSS f,b (hex = 1B ff) Comprueba un bit b del registro f y se salta la instruccin siguiente si vale 1. F(b) = 1 ? SI, salta una instruccin. Esta instruccin comprueba el valor del bit b en el registro f, y si b = 1 entonces se salta la siguiente instruccin. Si b = 0 no salta y sigue con su ejecucin normal. BTFSS PORTB, 7 INSTRUCCIN 1 INSTRUCCIN 2

Si en PORTB tenemos como valor inicial 10000000B, el programa contina con la instruccin 2, saltndose la instruccin 1. Si en PORTB tenemos el valor 01111111B, el programa sigue con la instruccin 1 y despus la instruccin 2. Registro STATUS: No modifica ningn bit de estado.

2.2 MODOS DE DIRECCIONAMIENTO Direccionamiento directo: la memoria de datos (RAM). La memoria interna se direcciona en forma directa por medio de los 8 bits f contenidos en las instrucciones que operan sobre registros. De esta manera se puede direccionar cualquier posicin desde la 00 a la FF. En los microcontroladores que tengan ms de un banco, antes de acceder a alguna variable que se encuentre en la zona de los bancos de registros, el programador deber asegurarse de haber programado los bits de seleccin de banco en el registro FSR. Direccionamiento indirecto: el registro FSR. El registro FSR sirve como puntero para direccionamiento indirecto adems de servir para seleccionar el banco activo. La posicin 00 del mapa de RAM es la llamada direccin indirecta. Si en cualquier instruccin se opera con la direccin 00, en realidad se estar operando con la direccin a donde apunte el contenido del FSR. Por ejemplo si el FSR contiene el valor 1Ah, una instruccin que opere sobre la direccin 0, en realidad lo har sobre la direccin 1Ah. Puede decirse que la posicin 1Ah de memoria fue direccionada en forma indirecta a travs del puntero FSR. Ejemplo : ; Este programa borra 8 posiciones de memoria a partir de la direccin 1A FSR equ 04 ;(definicin del puntero FSR) ;............................................................................................. movlw 8 ;prepara para repetir 8 veces movwf DATO ;(el registro DATO es el contador del bucle) movlw 1Ah ;apunta a la direccin 1Ah movwf FSR ;guarda en FSR la direccin 1Ah bucle clrf 0 ;borra una posicin de memoria (pone a cero) incf FSR ;apunta a la siguiente decfsz DATO ;si todava no borr todas (an no es cero) goto bucle ;salta a bucle (sigue borrando) El direccionamiento indirecto es muy til para procesar posiciones consecutivas de memoria (como en el ejemplo) o para el direccionamiento de datos en subrutinas. Direccionamiento inmediato: El dato utilizado por la instruccin se codifica al mismo tiempo que la propia instruccin. En este caso, al dato se le denomina literal.

Direccionamiento relativo: No existe este modo de direccionamiento en los microprocesadores PIC.

2.3 TECNICAS DE PROGRAMACION


SUBRUTINAS Y LLAMADAS: La mayora de los microcontroladores incluyen en su repertorio de instrucciones algunas que permiten saltar a una rutina y, cuando se completa su ejecucin, retornar al programa principal. El empleo de subrutinas aporta muchas ventajas entre las que se destacan las siguientes: 1. Se pueden escribir como subrutinas secciones de cdigo y ser empleadas en muchos programas ( por ejemplo, la subrutina de exploracin de un teclado ). 2. Dan a los programas un carcter modular, es decir, se pueden codificar diferentes mdulos para utilizarlos en cualquier programa. 3. Se reduce notablemente el tiempo de programacin y la deteccin de errores, utilizando repetidamente una subrutina. 4. El cdigo es ms fcil de interpretar, dado que las instrucciones de las subrutinas no aparecen en el programa principal, slo figuran las llamadas (CALL). LAS INSTRUCCIONES CALL Y RETURN: La instruccin CALL (llamada a subrutina) consigue que la ejecucin del programa contine en la direccin donde se encuentra la subrutina a la que hace referencia. Es similar a GOTO pero coloca en la pila la direccin de la siguiente instruccin que se debe ejecutar despus de terminar con la subrutina. La subrutina finaliza con la instruccin RETURN (retorno de la subrutina) que retoma la direccin guardada en la pila y la coloca en el contador del programa PC continuando el flujo de control con la instruccin que sigue a CALL. En la familia PIC de gama media la pila tiene ocho niveles de memoria del tipo LIFO (ltimo en entrar, primero en salir). Si se produce la llamada a una subrutina durante la ejecucin de otra subrutina, la direccin de retorno de esta segunda es colocada en la cima de la pila sobre la direccin anterior. Esta segunda direccin es la primera en salir de la pila mediante la instruccin RETURN. Con la pila de ocho niveles, una subrutina puede llamar a otra y sta, a su vez, llamar a otra hasta un mximo de ocho. CONSULTA A TABLAS: En muchas ocasiones es necesario para un programador efectuar una coincidencia entre alguna cantidad de valores conocidos y un nmero desconocido que se tiene como ndice. Por ejemplo: basados en el contenido de una posicin de memoria RAM (ndice) se puede obtener de una serie consecutiva de datos almacenados en memoria de programa (a los datos "conocidos" almacenados se le denomina tabla), el dato desplazado n posiciones hacia delante desde el comienzo de la tabla. El nmero n corresponde al contenido de la posicin de memoria RAM ndice.

Programa ejemplo: offset equ 0Ch ; posicin de memoria RAM w equ 0 ; destino W f equ 1 ; destino F ................ ................ ................ movf offset,w ; tomamos a W el nmero n utilizado como ndice call tabla ; posicin en donde se encuentra la serie de datos ; en este sitio luego del retorno de la subrutina se tiene en W el dato ; ledo de la tabla ................ ................ ................ tabla addwf PCL,f ; se suma al PC el W obteniendo como resultado un salto indexado retlw 30h ; s W sumado al PCL es 0 se retorna en esta posicin, W=30h retlw 31h ; s W sumado al PCL es 1 se retorna en esta posicin, W=31h retlw 32h ; s W sumado al PCL es 2 se retorna en esta posicin, W=32h retlw 33h ; s W sumado al PCL es 3 se retorna en esta posicin, W=33h retlw 34h ; s W sumado al PCL es 4 se retorna en esta posicin, W=34h retlw 35h ; s W sumado al PCL es 5 se retorna en esta posicin, W=35h ; ... . Para terminar, despus de observar el ejemplo anterior, debemos tener en cuenta que antes de llamar a la subrutina tabla, se debe cargar en el registro de trabajo W el valor del ndice y una vez se retorne de dicha subrutina, es en este mismo registro de trabajo en donde se obtiene el resultado de la consulta a la tabla (vemos que la sucesin de instrucciones retlw k se encuentra en memoria de programa).

CONVERSIN A ASCII: El conjunto de caracteres ASCII (American Standard Code for Information Interchange) es el cdigo de representacin en hexadecimal del alfabeto, los nmeros del 0 al 9, los principales smbolos de puntuacin y algunos caracteres de control.

Conjunto de carcteres ASCII Como vemos en la tabla anterior, podemos dividir a cada carcter representado en hexadecimal como una parte alta de 3 bits (Most significant carcter = nmeros del 0 al 7) y una parte baja de 4 bits (Least significant carcter = nmeros del 0 al F). En total, la representacin la hacemos con 7 bits. De los problemas usuales en la programacin est el convertir un nmero hexadecimal representado en 8 bits a dos caracteres ASCII los cuales sean la representacin de dicho nmero para permitir su visualizacin en pantallas LCD, monitores, impresoras, etc. Ejemplo: Para representar el nmero hexadecimal 70h que en binario es 01110000b como los dos caracteres ASCII "7" y "0", grficamente: 7 0 en hexadecimal (8 bits) en ascii (16 bits) ascii en hexadecimal (16 bits)

"7" "0" 37h 30h

Transportndolo a un programa: ; posicin donde se almacena el nmero a convertir NumHex equ 0Ch ; posicin donde se almacena el resultado parte alta AsciiH equ 0Dh AsciiL equ 0Eh ; posicin donde se almacena el resultado parte baja ....................... ....................... movlw 0Fh ; dato para enmascarar parte alta andwf NumHex,0 ; se enmascara la parte alta del nmero hexa y pasa a W iorlw 30h ; convierte el nmero en ascii

movwf AsciiL movlw 0F0h andwf NumHex,1 swapf NumHex,0 iorlw 30h movwf AsciiL ..................... .....................

; el nmero queda salvado en la variable de salida ; dato para enmascarar parte baja ; se enmascara la parte baja del nmero hexa y queda all ; se invierten parte alta y baja ; convierte el nmero en ascii ; el nmero queda salvado en la variable de salida.

El ejemplo anterior funciona de forma correcta siempre y cuando los nibbles del nmero hexadecimal a convertir estn en el rango de 0 a 9. Habr que realizarse un tratamiento adicional a stos si se encuentran en el rango de Ah a Fh.

RAMIFICACIN MLTIPLE. Cuando se tiene que solucionar un diagrama de flujo como el de la figura, en el cual tenemos tres posibles respuestas a una pregunta, se plantean las soluciones aqu presentadas.

Tres posibilidades para una pregunta.

Una de las formas de solucionar en un programa este problema es: Solucin 1. Determinando para la opcin 1, la opcin 2 y la opcin 3 un valor consecutivo como: opcin1 opcin2 opcin3 equ equ equ 0 1 2

Uno de estos posibles valores llevarlo a W y en una parte del programa tratarlo as:

Decisin: addwf goto goto goto

;sitio en donde la pregunta "?" tendra solucin PCL,1 Accin1 Accin2 Accin3

Accin1: ............................... ............................... ............................... goto encuentro Accin2: ............................... ............................... ............................... goto encuentro Accin3: ............................... ............................... ............................... encuentro: ............................... ...............................

;instrucciones correspondientes a la Accin 1

;instrucciones correspondientes a la Accin 2

;instrucciones correspondientes a la Accin 3

;sitio de encuentro luego de una de las acciones ;continuacin del programa

Solucin 2. Otra forma posible es comparando uno por uno los valores de las diferentes opciones almacenadas en memoria RAM en una variable llamada OPCION movlw Opcin1 xorwf OPCION,0 ; se realiza la verificacin de OPCION respecto a W btfsc STATUS,Z ; verificando la bandera Z goto Accin1 movlw Opcin2 xorwf OPCION,0 ; se realiza la verificacin de OPCION respecto a W btfsc STATUS,Z ; verificando la bandera Z goto Accin2 movlw Opcin3 xorwf OPCION,0 ; se realiza la verificacin de OPCION respecto a W btfsc STATUS,Z ; Verificando la bandera Z goto Accin3 Accin1: ............................... ; instrucciones correspondientes a la Accin 1 ...............................

............................... goto encuentro Accin2: ............................... ............................... ............................... goto encuentro Accin3: ............................... ............................... ............................... encuentro: ............................... ...............................

; instrucciones correspondientes a la Accin 2

; instrucciones correspondientes a la Accin 3

; sitio de encuentro luego de una de las acciones ; continuacin del programa

Aunque este ltimo mtodo es ms largo que el anterior, es vlido cuando los valores de las diferentes opciones no son consecutivos entre si.

ARITMTICA: Dentro de los microcontroladores PIC se cuenta con instrucciones aritmticas tales como: ADDWF y ADDLW para efectuar operaciones de suma. SUBWF y SUBWF para efectuar operaciones de resta. RLF para realizar multiplicaciones por 2. RRF para realizar divisiones entre 2. Hasta este punto podramos ver el conjunto de instrucciones un poco limitado. Sin embargo, utilizando tcnicas avanzadas de programacin podemos obtener operaciones ms complejas. Podemos obtener varias rutinas matemticas generales de los PIC 16CXX y 17CXX en estas direcciones: http://www.iespana.es/portosin/MATEMATICAS16CXX http://www.iespana.es/portosin/MATEMATICAS17CXX

TEMPORIZACIN: A veces se necesita realizar un retardo de tiempo cuando programamos. Los retardos de tiempo se pueden obtener mediante hardware o por medio de ciclos repetitivos basados en software. La precisin de los retardos generados por software depende en esencia del tipo de oscilador que se utilice como base de tiempo en el microcontrolador (la mayor precisin se obtiene de los cristales de cuarzo).

La velocidad a la que se ejecuta el cdigo (instrucciones) depende de la velocidad del oscilador y del nmero de ciclos de mquina ejecutados. Las instrucciones necesitan 1 2 ciclos de mquina para ser ejecutadas. Un ciclo de mquina es un tiempo utilizado por el microcontrolador para realizar sus operaciones Tciclo mq = 4 / fosc internas y equivale a cuatro ciclos del oscilador. Por tanto: Tciclo mq.= 4 * Tosc El nmero de ciclos de mquina utilizados por una instruccin para ser ejecutada depende de la misma. Las instrucciones que modifican el contador de programa necesitan dos (2) ciclos de mquina, mientras que todas las dems necesitan tan solo uno (1). El hecho de generar ciclos repetitivos por medio del programa y calcular el tiempo total de ejecucin nos puede ayudar a generar tiempos precisos.

Ciclo repetitivo de retardo El ciclo repetitivo de retardo de la figura se tomar un nmero de ciclos as: Operacin la carga de k en W la carga de W en el contador el decremento del contador mientras no llegue a cero el decremento del contador cuando llegue a cero el salto a Loop Total: N de ciclos 1 1 k-1 2 2 * (k-1) 3*k+1

Por cada instruccin agregada debe incluirse en la cuenta total el nmero de ciclos correspondiente a dicha instruccin. Trabajando a 4 Mhz y asumiendo que k se remplaza por el valor 15d en el ejemplo tendramos un tiempo igual a: Nmero de ciclos = (3*15) +1 = 46 ciclos de mquina, Tciclo mq.= 4 / 4 Mhz = 1 segundo, el tiempo total entonces ser de 46 segundos.

EJEMPLO 1: ;Almacenar el valor 26h en 15 posiciones contiguas de la memoria de datos, ;empezando desde la direccin 0x10 List p=16F84 include "P16F84.INC" Contador Primera equ equ 0x10 org Inicio movlw movwf movlw movwf movlw movwf incf decfsz goto end 0x0c ;Tipo de procesador ;Definiciones de registros internos ;Contador interno ;Posicin inicial ;Vector de Reset ;Carga el acumulador con 15 (decimal) ;Carga el contador con 15 (decimal) ;Inicia puntero con direccin inicial ;Carga valor a almacenar ;Almacena valor en pos. indicada por FSR ;Incrementa el puntero FSR ;Decrementa contador hasta llegar a 0 ;Regresa a Bucle si Contador no es 0 ;Fin del programa fuente

0x00 .15 Contador Primera FSR 0x26 INDF FSR,F Contador,F Bucle

Bucle

EJEMPLO 2: ;Sumar dos valores (3 y 9) y guardar el resultado en la posicin 0x10 List p=16F84 include "P16F84.INC" Total equ org Inicio 0x10 0x00 ;Tipo de procesador ;Definiciones de registros internos ;Define la posicin del resultado ;Vector de Reset ;Carga 1er. sumando en W ;Suma el 2 sumando ;Guarda el resultado en el registro Total ;Fin del programa fuente

movlw 0x03 addlw 0x09 movwf Total end

EJEMPLO 3: ;Tres valores A,B y C guardados ya en memoria. Aplicar la ecuacin: (A+B)-C

List p=16F84 include "P16F84.INC" Dato_A equ Dato_B equ Dato_C equ Resultado 0x10 0x11 0x12 equ org Inicio movf

;Tipo de procesador ;Definiciones de registros internos ;Define la posicin del dato A ;Define la posicin del dato B ;Define la posicin del dato C ;Define la posicin del resultado ;Vector de Reset ;Carga 1er.sumando

0x13 0x00

Dato_A,W

addwf movwf movf subwf end

Dato_B,W Resultado Dato_C,W Resultado,F

;Suma 2 sumando ;Almacena resultado parcial ;Carga sustraendo ;Resta del minuendo y almacena ;Fin del programa fuente

EJEMPLO 4: ;Comparar dos nmeros A y B. Si A=B, el resultado es 0. Si A > B, el resultado ;es A-B. Si A < B el resultado es A+B. Al salir de esta rutina tendremos el ;valor en el registro Resultado. ; ;Hay que destacar que, al no haber instrucciones de comparacin, esta se realiza ;mediante restas. List p=16F84 include "P16F84.INC" Dato_A equ Dato_B equ Resultado 0x10 0x11 equ org Inicio movf ;Tipo de procesador ;Definiciones de registros internos

0x12 0x00

;Variable del dato A ;Variable del dato B ;Variable para el resultado ;Vector de Reset ;Carga el dato B ;Resta/compara con dato A ;Son iguales (Z=1)?? ;Si, entonces salta a A_igual_B ;No. A mayor que B (C=0)?? ;Si, entonces salta a A_mayor_B ;No, A es menor que B ;Suma a ms B ;Guarda el resultado

Dato_B,W subwf Dato_A,W btfsc STATUS,Z goto A_igual_B btfsc STATUS,C goto A_mayor_B movf addwf movwf goto Dato_A,W Dato_B,W Resultado Salida

A_menor_B

A_mayor_B

movwf Resultado goto Salida clrf end Resultado

;Guarda el resultado

A_igual_B Salida EJEMPLO 5:

;Pone a 0 el resultado ;Fin del programa fuente

;Sumar dos nmeros A y B, de 16 bits cada uno. ; List p=16F84 include "P16F84.INC" Dato_A_L Dato_A_H Dato_B_L Dato_B_H Resultado_L Resultado_H equ equ equ equ equ equ org 0x10 0x11 0x12 0x13 0x14 0x15 0x00 ;Tipo de procesador ;Definiciones de registros internos ;Define la posicin del dato A (bajo) ;Define la posicin del dato A (alto) ;Define la posicin del dato B (bajo) ;Define la posicin del dato B (alto) ;Define la posicin del resultado (bajo) ;Define la posicin del resultado (alto) ;Vector de Reset

Inicio

movf addwf movwf movf btfsc addlw addwf movwf end

Dato_A_L,W Dato_B_L,W Resultado_L Dato_A_H,W STATUS,C 1 Dato_B_H,W Resultado_H

;Carga menos peso del dato A ;Suma menos peso del dato B ;Almacena el resultado ;Carga ms peso del dato A ;Hubo acarreo anterior ?? ;Si, suma 1 al acumulador ;Suma ms peso del dato B ;Guarda el resultado ;Fin del programa fuente

EJEMPLO 6: ;Restar dos nmeros, A y B, de 16 bits cada uno. ;Aunque este ejercicio es similar al anterior, se debe apreciar que, el contenido del acumulador acta ;como sustraendo y el operando, como minuendo. ;Igualmente hay que apreciar que el flag CARRY se debe interpretar de forma inversa a como se hace con ;la suma (a "0" hay desbordamiento). List p=16F84 include "P16F84.INC" Dato_A_L Dato_A_H Dato_B_L Dato_B_H Resultado_L Resultado_H equ equ equ equ equ equ org Inicio movf subwf movwf movf btfss addlw subwf movwf end 0x10 0x11 0x12 0x13 0x14 0x15 0x00 Dato_B_L,W Dato_A_L,W Resultado_L Dato_B_H,W STATUS,C 1 Dato_A_H,W Resultado_H ;Tipo de procesador ;Definiciones de registros internos ;Define la posicin del dato A (bajo) ;Define la posicin del dato A (alto) ;Define la posicin del dato B (bajo) ;Define la posicin del dato B (alto) ;Define la posicin del resultado (bajo) ;Define la posicin del resultado (alto) ;Vector de Reset ;Carga menos peso del dato B (sustraendo) ;Resta menos peso del dato A (minuendo) ;Almacena el resultado ;Carga ms peso del dato B (sustraendo) ;Hubo acarreo (CARRY = 0) anterior ?? ;Si, aade 1 al acumulador (sustraendo) ;Resta ms peso del dato A (minuendo) ;Guarda el resultado ;Fin del programa fuente

EJEMPLO 7: OPERACIONES LOGICAS EN PROGRAMACION En programacin a veces nos encontramos con la necesidad de comparar valores para tomar decisiones. A este tipo de decisiones les llamamos operaciones lgicas y las que nos podemos encontrar son: A igual a B A distinto de B A igual o mayor que B A mayor que B A menor o igual a A menor que B

Todas estas operaciones tienen solucin en programacin utilizando instrucciones de ensamblador y las posibilidades que nos da el Registro de Estado. El Registro de Estado (ya lo hemos visto antes) ocupa la posicin 0x03 del Banco 0 y 0x83 del Banco 1. Sus 8 bit son: bit 7 IRP Selecciona bancos para direccionamiento indirecto. bit 6 RP1 Seleccin pgina de memoria de programa. bit 5 RP0 Seleccin pgina de memoria de programa. bit 4 TMR0 Timer. bit 3 PD Power Down. bit 2 Z Zero 1 Si el resultado de una operacin es 0. 0 Si el resultado de una operacin es distinto de 0. bit 1 DC Acarreo en el 4 bit de menos peso. bit 0 C Acarreo en el 8 bit 1 acarreo en la suma y no en al resta. 0 acarreo en la resta y no en la suma. De todos estos registros vamos a utilizar el bit 2 y el bit 0. La "bandera" es el "bit de un registro que se pone a 0 o a 1 cuando se ejecuta un determinado tipo de instrucccin". Para este tipo de operaciones la carga de la bandera es normalmente automtica. Es recomendable comprobar el estado de la bandera antes de realizar la instruccin para tener la certeza de su estado posterior. Como vamos a comparar 2 valores, a estos los llamaremos A y B y al Registro de Trabajo le llamaremos W (acumulador).

Operacion A=B movf A,W subwf B,W btfsc Status,Z ;Carga W con magnitud A ;Resta a B el registro W ;Comprueba el bit 2 si es 0 salta. Pero como Z=1 porque ;resultado de la operacin =0 no salta y va a la ;siguiente instruccin que es goto goto donde_sea

Operacion A<B movf B,W subwf A,W btfss Status,C goto donde_sea ;Carga W con valor B ;Resta a A el Registro de Trabajo W ;Comprueba el bit C de Estado y si es 1 salta pero al ;ser A menor que B no hay acarreo por lo que C = 0

Operacion A>B movf A,W subwf B,W btfsc Status,C goto donde_sea ;Carga A en W ;Resta a B el Registro de Trabajo W (o sea A) ;Comprueba el bit C del registro Estado y como C = 0 no ;hay salto

Resumiendo: Logica Nemotecnico A=B btfsc Operacion Bandera A->W (B-A) Z=1

A>B A<B

btfsc btfss

A->W (B-A) B-> W (A-B)

C=0 C=0

EJEMPLO 8: Operaciones Entrada / Salida Objetivos: Verificar el modo en el que se debe programar el sentido de los puertos. Realizar las entradas por puerto mediante la lectura de interruptores. Escribir sobre un puerto de salida.

Procedimiento: En el proceso de utilizacin de un puerto debe tenerse en cuenta como primera instancia la programacin del sentido en que dicho puerto va a utilizarse. Una vez encendido el microcontrolador todos y cada uno de los puertos quedan programados como entrada, entonces tan solo deben programarse los que se quieren utilizar como salida. El programa debe entonces en un bucle infinito leer el nivel lgico que colocan los switch y pasar este resultado al puerto A complementando el estado de la informacin puesto que de acuerdo a la disposicin de los LEDs un estado bajo en el puerto enciende el LED correspondiente y un estado alto en el puerto, apaga el LED. Programa: status optionr trisa porta trisb portb equ equ equ equ equ equ 03h 81h 85h 05h 86h 06h

;Inicio: bsf clrf movlw movwf bcf bcf Loop comf movwf goto end

status,5 trisa 0Fh trisb optionr,7 status,5 portb,0 porta Loop

;se pasa al banco 1 de RAM ;se programa el puerto A como salida ;dato para la programacin del puerto B ;parte alta como salida y baja como entrada ;se habilitan resistencias de Pull Up ;se pasa al banco 0 de RAM ;lee puerto B, compl. valor y resultado a W ;se pasa el resultado de W al puerto A ;ejecuta un ciclo infinito

EJEMPLO 9:

;************************************************ ; ESTE PROGRAMA ENCIENDE DOS LEDS DESDE EL CENTRO ; DEL PUERTO B Y LOS ROTA HASTA LOS EXTREMOS CADA ; VEZ QUE EL MICRO TIENE UN CERO EN EL PIN RA4 ;************************************************ LIST P=16F84 STATUS PORTA TRISA PORTB TRISB RP0 EQU EQU EQU EQU EQU EQU 3 5 5 6 6 5 ; REGISTRO GENERAL PARA EL RETARDO ; REGISTRO GENERAL PARA EL RETARDO ; REGISTRO GENERAL PARA EL RETARDO ; ; ; ; ; ; ; ; ; ; ; ; ; ; ENTRA EN EL BANCO 1 MUEVE 1Fh A W CONFIGURA EL PUERTO A COMO ENTRADA MUEVE 00 A W CONFIGURA EL PUERTO B COMO SALIDA SALE DEL BANCO 1 LIMPIA EL PUERTO B PREGUNTA SI EL PIN 4 DEL PUERTO A ES CERO SALTA A LA ETIQUETA OTRA MUEVE 18h A W CARGA W EN EL PUERTO B LLAMA A LA ETIQUETA RETARDO PREGUNTA SI EL PIN 4 DEL PUERTO A ES CERO SALTA A LA ETIQUETA OTRA1

ORG 0XC CONTA1 RES 1 CONTA2 RES 1 CONTA3 RES 1 ORG 0X00 INICIO BSF STATUS,RP0 MOVLW 0X1F MOVWF TRISA MOVLW 0X00 MOVWF TRISB BCF STATUS,RP0 CLRF PORTB OTRA BTFSC GOTO MOVLW MOVWF CALL BTFSC GOTO MOVLW MOVWF CALL BTFSC GOTO MOVLW MOVWF CALL BTFSC GOTO MOVLW MOVWF CALL OTRA1 RETARDO RET3 MOVLW MOVWF MOVLW 0X32 CONTA3 0X05 CLRF GOTO PORTA,4 OTRA 0X18 PORTB RETARDO PORTA,4 OTRA1 0X24 PORTB RETARDO PORTA,4 OTRA1 0X42 PORTB RETARDO PORTA,4 OTRA1 0X81 PORTB RETARDO PORTB OTRA

; MUEVE 24h A W ; CARGA W EN EL PUERTO B ; LLAMA A LA ETIQUETA RETARDO ; ; ; ; ; ; ; ; ; ; PREGUNTA SI EL PIN 4 DEL PUERTO A ES CERO SALTA A LA ETIQUETA OTRA1 MUEVE 42h A W CARGA W EN EL PUERTO B LLAMA A LA ETIQUETA RETARDO PREGUNTA SI EL PIN 4 DEL PUERTO A ES CERO LLAMA A MUEVE 81h A W CARGA W EN EL PUERTO B LLAMA A LA ETIQUETA RETARDO

; LIMPIA EL PUERTO B ; SALTA A LA ETIQUETA OTRA ; MUEVE 32h A W ; CARGA W A CONTA3 ; MUEVE 05h

RET2 RET1

MOVWF MOVLW MOVWF NOP NOP NOP NOP NOP NOP DECFSZ GOTO DECFSZ GOTO DECFSZ GOTO RETURN END

CONTA2 0XDA CONTA1

CONTA1,1 RET1 CONTA2,1 RET2 CONTA3,1 RET3

; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;

CARGA W A CONTA2 MUEVE DAh A W CARGA W A CONTA1 NO OPERA NO OPERA NO OPERA NO OPERA NO OPERA NO OPERA DECREMENTA CONTA1 EN 1 Y SALTA SI ES CERO SALTA A LA ETIQUETA RET1 DECREMENTE CONTA2 EN 1 Y SALTA SI ES CERO SALTA A LA ETIQUETA RET2 DECREMENTA CONTA3 EN 1 Y SALTA SI ES CERO SALTA A LA ETIQUETA RET3 RETORNA

EJEMPLO 10: ;=================================; ; PROYECTO SEMFORO: 16 LEDS ; ; FORMANDO 4 ESQINAS DE UN CRUCE. ; ;=================================; STATUS PORTA EQU TRISA EQU PORTB EQU TRISB EQU RB0 RB1 RB2 RB3 RB4 RB5 RB6 RB7 EQU EQU EQU EQU EQU EQU EQU EQU ORG CONTAD CONTAD1 ORG EQU 0x5 0x5 0x6 0x6 0 1 2 3 4 5 6 7 0x0C RES RES 0 1 1 0x3

; ; ; ; ; ; ; ;

ROJ0_1 AMARILLO_1 VERDE_1 CRUCE_1 ROJO_2 AMARILLO_2 VERDE_2 CRUCE_2

BSF CLRF CLRF BCF INICIO

STATUS,5 TRISA TRISB STATUS,5 CLRF CLRF PORTA PORTB

SEMA1 BSF BSF CALL BCF BSF CALL BCF BSF BSF CALL BCF BCF BSF CALL BCF BSF CALL BCF BSF BSF CALL BCF GOTO RETARDO CALL RETARDO1 DECFSZ CONTAD,1 GOTO RETARDO MOVLW 50 MOVWF CONTAD RETURN RETARDO1 DECFSZ CONTAD1,1 GOTO RETARDO1 MOVLW 50 MOVWF CONTAD1 RETURN END EJEMPLO 11: PORTB,RB0 PORTB,RB6 RETARDO PORTB,RB6 PORTB,RB5 RETARDO PORTB,RB5 PORTB,RB4 PORTB,RB3 RETARDO PORTB,RB0 PORTB,RB3 PORTB,RB2 RETARDO PORTB,RB2 PORTB,RB1 RETARDO PORTB,RB1 PORTB,RB0 PORTB,RB7 RETARDO PORTB,RB7 INICIO ; LUZ AMARILLA_1 APAGADA ; LUZ ROJA_1 ENCENDIDA ; LUZ DE CRUCE_2 ENCENDIDA ; LUZ VERDE_1 APAGADA ; LUZ AMARILLA_1 ENCENDIDA ; LUZ ROJA_1 APAGADA ; LUZ DE CRUCE_1 APAGADA ; LUZ VERDE_1 ENCENDIDA ; LUZ AMARILLA_2 APAGADA ; LUZ ROJA_2 ENCENDIDA ; LUZ DE CRUCE_1 ENCENDIDA ; LUZ VERDE_2 APAGADA ; LUZ AMARILLA_2 ENCENDIDA ; LUZ ROJA_1 ENCENDIDA ; LUZ VERDE_2 ENCENDIDA

;*****************************************; ;Control de puertas de entrada por LED: ; ;Controlar por un LED si cierto numero de ; ;interruptores cambian de abiertos a ; ;cerrados. Cada vez que cambia la Puerta ; ;de salida lo indica. ; ;*****************************************; LIST P=16F84 RADIX HEX ;ETIQUETAS DEL PROGRAMA W EQU 0x00 F EQU 0x01 STATUS EQU 0x03 ; Registro de destino W : d=0 ; Registro de destino F : d=1 ; El registro ESTADO ocupa la direccin 0X03 de los ; dos bancos PTA_TRISA EQU 0x05 ; La PUERTA A ocupa la direccin 0X05 del banco 0 ; y su registro de configuracin la direccin 0X05 del ; banco 1 (direccin sobre banco 1 = 0x85) PTB_TRISB EQU 0x06 ; La PUERTA B ocupa la direccin 0X06 del banco 0 ; y su registro de configuracin la direccin 6 del ; banco 1 (direccin sobre banco1 = 0x086) AUX EQU 0x0C ; Registro auxiliar en el que se carga el estado de ; los interruptores ;PROGRAMA PRINCIPAL ORG 0 ; El programa comienza en la direccion 0 ; Se emplea el PIC16F84 ; Sistema de numeracin hexadecimal

INICIO bsf

BUCLE

LUZ

PUESTA1

PUESTA0 ACTUAL

; Seleccin del banco 1 al poner a 1 el bit 5 de 0x03 ; Se carga W con el dato literal 00000111 ; Se carga TRISA con el dato 00000111 en puerta A ; quedan configurados como entrada los bites RAO, ;RA1 y RA2 clrf PTB_TRISB ; TRISB se carga con 00000000 y se configura como ;salida bcf STATUS,5 ; Seleccin del banco 0 al poner a 0 el bit 5 de ;STATUS clrf PTA_TRISA ; Registro 0X05=PUERTAA=00000000 clrf PTB_TRISB ; Registro 0X06=PUERTAB=00000000 clrf AUX ; Registro 0X0C=AUX=00000000 movf PTA_TRISA,W ; Se carga W con el dato de la PUERTA A xorwf AUX,W ; XORWF entre W y el registro de AUX btfsc STATUS,2 ; Detecta si se ha activado el bit 2 (Z) de STATUS ; al realizarse la operacin XORWF si es 0 salta goto BUCLE ; Si no ha cambiado sigue hasta que uno cambie btfss PTB_TRISB,0 ; Si el bit 0 de PUERTAB = 1 salta. Se comprueba ;si el LED esta encendido para saber si hay que ;apagarlo o encenderlo goto PUESTA1 ; Se llama a la rutina Puesta1 (enciende el LED) goto PUESTA0 ; Se llama a la rutina Puesta0 (apaga el LED) bsf PTB_TRISB,0 ; Se pone a 1 el bit 0 de la puerta B (LED). Se ;enciende LED goto ACTUAL bcf PTB_TRISB,0 ; Se pone a 0 el bit 0 de la puerta B (LED). Se ;apaga LED movf PTA_TRISA,W ; W= datos de PUERTAA

STATUS,5 movlw b'00000111' movwf PTA_TRISA

movwf AUX goto END EJEMPLO 12:

; Se carga AUX con valor W luego se comprobar si ;ha cambiado BUCLE ; Salto a bucle para empezar de nuevo

;******************************************************************************; ;Control de 5 entradas y avisador de cada entrada por LED y avisador acstico ; ;Este programa no funciona en realidad pero son rutinas que sirven de ejemplo. ; ;******************************************************************************; list p=16c84 radix hex status equ pta_trisa ptb_trisb tmr0 intcon equ contador equ 0x03 equ equ equ 0x0b 0x0c org

0x05 0x06 0x01

inicio

bsf clrf movlw movwf bcf clrf clrf

status,5 ;ir al banco 1 de la memoria ptb_trisb ;Ccnfigura la puerta b de salida b'00011111' ;W=00011111 tambin poda usar movlw 0x1f pta_trisa ;configura la puerta A de entrada status,5 ;ir al banco 0 pta_trisa ;pta_trisa=00000000 ptb_trisb ;ptb_trisb=00000000 ;controla la pata 0 de Puerta A ;controla la pata 1 de Puerta A ;controla la pata 1 de Puerta A ;controla la pata 1 de Puerta A ;controla la pata 1 de Puerta A

control

ra0

ra1

ra2

ra3

btfsc pta_trisa,0 call ra0 btfsc pta_trisa,1 call ra1 btfsc pta_trisa,2 call ra2 btfsc pta_trisa,3 call ra3 btfsc pta_trisa,4 call ra4 goto control bsf ptb_trisb,0 bsf ptb_trisb,6 clrf pta_trisa return bsf ptb_trisb,1 bsf ptb_trisb,6 clrf pta_trisa return bsf ptb_trisb,2 bsf ptb_trisb,6 clrf pta_trisa return bsf ptb_trisb,3 bsf ptb_trisb,6 clrf pta_trisa return

;enciende led ;activa el buzzer

;enciende led ;activa el buzzer

;enciende led ;activa el buzzer

;enciende led ;activa el buzzer

ra4

bsf bsf clrf return end

ptb_trisb,4 ptb_trisb,6 pta_trisa

;enciende led ;activa el buzzer

EJEMPLO 13: ;********************************************************; ;Control de los leds RB0 y RB1 desde el interruptor RA0. ; ;RB0 refleja el estado de RA0, RB1 el complemento de RA0.; ;********************************************************; List p=16F84 Include "P16F84.INC" org Inicio clrf bsf clrf movlw movwf bcf 0x00 PORTB STATUS,RP0 TRISB b'00011111' TRISA STATUS,RP0 ;Tipo de procesador ;Definiciones de registros internos

;Vector de Reset ;Borra los latch de salida ;Selecciona banco 1 ;Puerta B se configura como salida ;Puerta A se configura como entrada ;Selecciona banco 0 ;Refresca el WDT timer ;RA0 = 1 ?? ;Si ;No, desconecta RB0 ;Conecta RB1 ;Buble sin fin ;Activa RB0 ;Activa RB1 ;Bucle sin fin ;Fin del programa fuente

Loop

clrwdt btfsc PORTA,0 goto RA0_es_1 bcf PORTB,0 bsf PORTB,1 goto Loop bsf bcf goto end PORTB,0 PORTB,1 Loop

RA0_es_1

EJEMPLO 14: ;************************************************; ; ESTE PROGRAMA HACE UN CONTADOR DECIMAL DE UN ; ; DISPLAY DE 7 SEGMENTOS, SE INCREMENTA CADA VEZ ; ; QUE EL MICRO TIENE UNA INTERRUPCION POR EL PIN ; ; RBO/INT ; ;************************************************; LIST P=16F84 STATUS PORTA TRISA PORTB TRISB INTCON CONTA LOOPS LOOPS2 EQU EQU EQU EQU EQU EQU EQU EQU EQU 03h 05h 05h 06h 06h 0Bh 0Ch 0Dh 0Eh

OPCION EQU Z W RESET EQU EQU

01h 02h 00h ; VECTOR DE RESET ; SALTA AL INICIO DEL PROGRAMA ; VECTOR QUE ATIENDE LA INTERRUPCION ; LLAMA A RETARDO ; PREGUNTA POR EL PIN RB0 ; SALTA A LA ETIQUETA SALE ; CONFIRMA SI LA INTERRUPCION FUE ;CAUSADA POR EL PIN INT ; ; ; ; ; ; SALTA A LA ETIQUETA SALE INCREMENTA EL CONTADOR CARGA W CON EL CONTADOR XOR PARA VER SI ES IGUAL A 0Ah PRUEBA SI EL CONTADOR LLEG A 0Ah SI LLEG A 10 PASA A 0

ORG 0X00 GOTO INICIO ORG 0X04 CALL BTFSC GOTO BTFSS GOTO INCF MOVF XORLW BTFSC CLRF MOVF MOVWF CALL SALE BCF INTCON,1 RETFIE RETARDO TOP2 TOP MOVLW MOVWF MOVLW MOVWF NOP NOP NOP NOP NOP NOP DECFSZ GOTO DECFSZ GOTO RETLW BSF MOVLW MOVWF MOVLW MOVWF MOVLW MOVWF BCF MOVLW MOVWF CLRF .100 LOOPS .110 LOOPS2 RETARDO PORTB,0 SALE INTCON,1 SALE CONTA CONTA,W 0X0A STATUS,Z CONTA CONTA,W PORTA RETARDO

; PASA EL DATO AL DISPLAY ; LLAMA A RETARDO ; PONE A CERO LA BANDERA DE INTERRUPCION ; REGRESA AL PROGRAMA PRINCIPAL

LOOPS2 TOP LOOPS TOP2 0 STATUS,5 0F0H TRISA 0FFH TRISB 80H OPCION STATUS,5 90H INTCON CONTA ; ; ; ; ; ; ; ; ; ; ; ENTRA AL BANCO 1 CARGA 0Fh EN W CONFIGURA EL PUERTO A COMO SALIDA CARGA 0FFh EN W CONFIGURA EL PUERTO B COMO ENTRADA CARGA 80h EN W CONFIGURA FLANCO DE BAJADA PARA INT SALE DEL BANCO 1 CARGA 90h EN W MUEVE W AL REGISTRO INTCON INICIA CONTADOR EN CERO

INICIO

MOVF MOVWF CICLO NOP NOP GOTO END

CONTA,W PORTA

; PASA EL VALOR DEL CONTADOR A W ; CARGA W EN EL DISPLAY

CICLO

EJEMPLO 15: ;Sobre el display de ctodo comn conectado a la puerta B, se desea ;visualizar el estado lgico "0" o "1" del interruptor RA0. Mediante ;el interruptor RA1 se activa o no el punto decimal. List p=16F84 ;Tipo de procesador include "P16F84.INC" ;Definiciones de registros internos org goto org Inicio clrf bsf clrf movlw movwf bcf 0x00 Inicio 0x05 PORTB STATUS,RP0 TRISB b'00011111' TRISA STATUS,RP0 ;Vector de Reset ;Salva el vector de interrupcin ;Borra los latch de salida ;Selecciona banco 1 ;Puerta B se configura como salida ;Puerta A se configura como entrada ;Selecciona banco 0 ;Refresca el WDT ;Chequea RA0 ;Es nivel "1" ;Visualiza el dgito 0

Loop

clrwdt btfsc PORTA,0 goto RA0_es_1 movlw b'00111111' movwf PORTB goto Test_RA1

RA0_es_1 Test_RA1

movlw b'00000110' movwf PORTB ;Visualiza el dgito 1 btfsc goto bcf goto bsf goto end PORTA,1 RA1_es_1 PORTB,7 Loop PORTB,7 Loop ;Chequea RA1 ;Est a "1" ;Desconecta punto decimal ;Activa punto decimal ;Fin del programa fuente

RA1_es_1:

EJEMPLO 16:

;El Display de 7 segmentos. Decodificador hex. a 7 segmentos. ;Mediante los cuatro interruptores RA0-RA3 se introduce un valor ;hexadecimal de 4 bits que debe visualizarse sobre el display List p=16F84 Include "P16F84.INC" org 0x00 ;Tipo de procesador ;Definiciones de registros internos

;Vector de Reset

;********************************************************************* ;Tabla: Esta rutina convierte el cdigo binario presente en los 4 bits ;de menos peso del reg. W en su equivalente a 7 segmentos. El cdigo 7 ;segmentos retorna tambin en el registro W. ;********************************************************************* Tabla: addwf retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw clrf bsf clrf movlw movwf bcf PCL,F b'00111111' b'00000110' b'01011011' b'01001111' b'01100110' b'01101101' b'01111101' b'00000111' b'01111111' b'01100111' b'01110111' b'01111100' b'00111001' b'01011110' b'01111001' b'01110001' PORTB STATUS,RP0 TRISB b'00011111' TRISA STATUS,RP0 ;Desplazamiento sobre la tabla ;Dgito 0 ;Dgito 1 ;Dgito 2 ;Dgito 3 ;Dgito 4 ;Dgito 5 ;Dgito 6 ;Dgito 7 ;Dgito 8 ;Dgito 9 ;Dgito A ;Dgito B ;Dgito C ;Dgito D ;Dgito E ;Dgito F ;Borra los latch de salida ;Selecciona banco 1 ;Puerta B se configura como salida ;Puerta A se configura como entrada ;Selecciona banco 0 ;Refrescar el WDT ;Lee el cdigo de RA0-RA3 ;Convierte a 7 segmentos ;Visualiza sobre el display ;Fin del programa fuente

Inicio

Loop

clrwdt movf PORTA,W andlw b'00001111' call Tabla movwf PORTB goto Loop end

EJEMPLO 17:

Visualizacin 7 segmentos
Objetivos:
Realizar la decodificacin de BCD a 7 segmentos por software Multiplexar en el tiempo la informacin para 2 dgitos 7 segmentos

Procedimiento: El mtodo utilizado para la visualizacin dinmica consiste en visualizar cada dgito durante un instante de tiempo y a una velocidad tal que gracias a la persistencia del ojo el efecto final es que todos los dgitos estn encendidos al tiempo. Listado del programa del display en assembler
;rutina de display dinmico de #define BANK0 bcf STATUS,RP0 #define BANK1 bsf STATUS,RP0 Cont2 equ 0x0D Dato1 equ 0x0E Dato2 equ 0x0F Del1 equ 0x10 Del2 equ 0x11 Display BANK1 clrf TRISA clrf TRISB BANK0 movlw 0x03 movwf PORTA ; movlw .10 movwf Cont2 LoopDisp ; ;Sacar al puerto el Dato 1 por ; movf Dato1,W call Tabla movwf PORTB bcf PORTA,0 call RetDig bsf PORTA,0 nop nop nop nop ; ;Sacar al puerto el Dato 2 por ; movf Dato2,W call Tabla movwf PORTB bcf PORTA,1 call RetDig bsf PORTA,1 nop nop nop nop decfsz Cont2,F goto LoopDisp dos dgitos

;puerto A como salida ;puerto B como salida ;inhabilita transistores ;valor de repeticiones

un tiempo especfico ;Dato para decodificar ;Decodificacin del dato ;Dato decodificado a puerto ;Habilita Q dato 1 ;Retardo de dgito ;Inhabilita Q dato 1 ;Retardo de apagado

un tiempo especfico ;Dato para decodificar ;Decodificacin del dato ;Dato decodificado a puerto ;Habilita Q dato 2 ;Retardo de dgito ;Inhabilita Q dato 2 ;Retardo de apagado

;Decrementa Cont2, elude sig. s cero ;Repite ciclo

return Tabla addwf retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw ; RetDig movlw movwf Loop1 movlw movwf Loop2 decfsz goto decfsz goto return Del2,F Loop2 Del1,F Loop1 .50 Del2 2 Del1 PCL,F 0x01 0x4F 0x12 0x06 0x4C 0x24 0x20 0x0F 0x00 0x04 0x08 0x60 0x31 0x42 0x30 0x38 ;Cuando ;Cuando ;Cuando ;Cuando ;Cuando ;Cuando ;Cuando ;Cuando ;Cuando ;Cuando ;Cuando ;Cuando ;Cuando ;Cuando ;Cuando ;Cuando el el el el el el el el el el el el el el el el dgito dgito dgito dgito dgito dgito dgito dgito dgito dgito dgito dgito dgito dgito dgito dgito es es es es es es es es es es es es es es es es 0 1 2 3 4 5 6 7 8 9 A B C D E F

El listado anterior puede utilizarse como subrutina cargando previamente las variables dato1 y dato2 con los valores hexadecimales que se desea visualizar.
EJEMPLO 18: ;Generacin de nmeros aleatorios ; ;Cada vez que se aplique un pulso por RA0, se genera un nmero binario ;de 8 bits aleatorio que ser visualizado sobre los 8 leds conectados ;en la puerta B, durante 3 segundos. ; ;Entre las diferentes tcnicas, la empleada para obtener el nmero, ;consiste en capturar el valor del TMR0 en un momento dado. List p=16F84 Include "P16F84.INC" Numero Delay_Cont equ equ org 0x0c 0x0d 0x00 ;Tipo de procesador ;Definiciones de registros internos

;Nmero aleatorio ;Contador de intervalos ;Vector de Reset

;********************************************************************* ;Delay_20_ms: Esta rutina de temporizacin tiene por objeto eliminar ;el "efecto rebote" de los perifricos electromecnicos. Realiza un ;delay de 20 mS. Si el PIC trabaja a una frecuencia de 4MHz, el TMR0 ;evoluciona cada uS. Si queremos

temporizar 20000 uS (20 mS) con un ;preescaler de 256, el TMR0 deber contar 78 eventos (78 * 256). El ;valor 78 equivale a 0x4e hex. y como el TMR0 es ascedente habr que ;cargar su complemento a 1 (0xb1 hex.). ;********************************************************************* Delay_20_ms bcf INTCON,T0IF ;Desconecta el flag de rebosamiento movlw 0xb1 ;Complemento hex. de 78 movwf TMR0 ;carga el TMR0 Delay_20_ms_1 clrwdt ;Refrescar el WDT btfss INTCON,T0IF ;Rebasamiento del TMR0 ?? goto Delay_20_ms_1;Todava no return ;********************************************************************* ;Delay_var: Esta rutina de propsito general realiza una temporizacin ;variable entre 50 mS y 12.8". Se emplea un preescaler de 256 y al ;TMR0 se le carga con 195. La velocidad de trabajo es de 4Mhz y por ;tanto el TMR0 se incrementa cada uS. De esta forma, el TMR0 debe ;contar 195 eventos que, con un preescaler de 128 hace un intervalo ;total de 50000 uS/50 mS (195 * 256). El valor 195 hay que expresarlo ;en Hex. (c3) y como el TMR0 es ascendente habr que cargar su ;complemento (3C hex.). ;Dicho intervalo de 50 mS se repite tantas veces como indique la ;variable "Delay_cont", es por ello que el delay mnimo es de 50 mS ;(Delay_cont=1) y el mxima de 12.8" (Delay_cont=255). ;********************************************************************* Delay_var Intervalo bcf INTCON,T0IF ;Desconecta el flag de rebosamiento movlw 0x3c ;Complemento hex. de 195 movwf TMR0 ;carga el TMR0 clrwdt ;Refresca el WDT btfss INTCON,T0IF ;Rebasamiento del TMR0 ?? goto Intervalo ;Todava no decfsz Delay_Cont,F ;Decrementa contador de intervalos goto Delay_var ;Repite el intervalo de 50 mS return clrf bsf clrf movlw movwf movlw movwf bcf PORTB STATUS,RP0 TRISB b'00011111' TRISA b'00000111' OPTION_REG STATUS,RP0 ;Borra los latch de salida ;Selecciona banco 1 ;Puerta B se configura como salida ;Puerta A se configura como entrada ;Preescaler de 256 para el TMR0 ;Selecciona banco 0 ;Refresca el WDT ;Activado RA0 ?? ;Todava No ;Ahora si. ;Captura el valor del TMR0 (N aleatorio) ;Elimina rebotes ;Refresca el WDT ;Desactivado RA0 ?? ;Todava no ;Se ha producido un impulso en RA0, se

Inicio

Loop

clrwdt btfss PORTA,0 goto Loop movf TMR0,W movwf Numero call Delay_20_ms clrwdt btfsc PORTA,0 goto RA0_1 movf Numero,W ;lee

RA0_1

movwf PORTB movlw movwf call clrf goto end EJEMPLO 19: d'60' Delay_Cont Delay_var PORTB Loop

;el valor capturado del TMR0 ;(N aleatorio) ;y se saca por los leds de la PUERTA B ;Inicia variable de temporizacin ;Temporiza 3 segundos ;Desconecta las salidas ;Fin del programa fuente

;Generacin de nmeros aleatorios. El dado electrnico ; ;Se trata de generar un nmero aleatorio entre 1 y 6. Cuando RA0 est ;a "1", sobre el display de 7 segmentos conectado a la puerta B, se ;van visualizando de forma secuecial los nmeros del 1 al 6, con ;intervalos de 0.05". Al pasar RA0 a nivel "0", se visualiza el ;nmero aleatorio obtenido durante un tiempo de 3". Luego el display ;se apaga y la secuencia se repite. List p=16F84 include "P16F84.INC" Numero Delay_Cont Temporal equ equ equ org 0x0c 0x0d 0x0e 0x00 ;Tipo de procesador ;Definiciones de registros internos

;Nmero aleatorio ;Contador de intervalos ;Variable temporal ;Vector de Reset

;********************************************************************* ;Tabla: Esta rutina convierte el cdigo binario presente en los 4 bits ;de menos peso del reg. W en su equivalente a 7 segmentos. El cdigo 7 ;segmentos retorna tambin en el reg. W Tabla: addwf retlw retlw retlw retlw retlw retlw retlw PCL,F b'00111111' b'00000110' b'01011011' b'01001111' b'01100110' b'01101101' b'01111101' ;Desplazamiento sobre la tabla ;Dgito 0 ;Dgito 1 ;Dgito 2 ;Dgito 3 ;Dgito 4 ;Dgito 5 ;Dgito 6

;********************************************************************* ;Delay_20_ms: Esta rutina de temporizacin tiene por objeto eliminar ;el "efecto rebote" de los perifricos electromecnicos. Realiza un ;delay de 20 mS. Si el PIC trabaja a una frecuencia de 4MHz, el TMR0 ;evoluciona cada uS. Si queremos temporizar 20000 uS (20 mS) con un ;preescaler de 256, el TMR0 deber contar 78 eventos (78 * 256). El ;valor 78 equivale a 0x4e hex. y como el TMR0 es ascedente habr que ;cargar su complemento a 1 (0xb1 hex.). Delay_20_ms bcf INTCON,T0IF ;Desconecta el flag de rebosamiento movlw 0xb1 ;Complemento hex. de 78 movwf TMR0 ;carga el TMR0 Delay_20_ms_1 clrwdt ;Refresca el WDT btfss INTCON,T0IF ;Rebasamiento del TMR0 ?? goto Delay_20_ms_1 ;Todava no return

;********************************************************************* ;Delay_var: Esta rutina de propsito general realiza una temporizacin ;variable entre 50 mS y 12.8". Se emplea un preescaler de 256 y al ;TMR0 se le carga con 195. La velocidad de trabajo es de 4Mhz y por ;tanto el TMR0 se incrementa cada uS. De esta forma, el TMR0 debe ;contar 195 eventos que, con un preescaler de 128 hace un intervalo ;total de 50000 uS/50 mS (195 * 256). El valor 195 hay que expresarlo ;en Hex. (c3) y como el TMR0 es ascendente habr que cargar su ;complemento (3C hex.). ;Dicho intervalo de 50 mS se repite tantes veces como indique la ;variable "Delay_cont", es por ello que el delay mnimo es de 50 mS ;(Delay_cont=1) y el mximo de 12.8" (Delay_cont=255). Delay_var: Intervalo bcf INTCON,T0IF ;Desconecta el flag de rebosamiento movlw 0x3c ;Complemento hex. de 195 movwf TMR0 ;carga el TMR0 clrwdt ;Refresca el WDT btfss INTCON,T0IF ;Rebasamiento del TMR0 ?? goto Intervalo ;Todava no decfsz Delay_Cont,F ;Decrementa contador de intervalos goto Delay_var ;Repite el intervalo de 50 mS return clrf bsf clrf movlw movwf movlw movwf bcf PORTB STATUS,RP0 TRISB b'00011111' TRISA b'00000111' OPTION_REG STATUS,RP0 ;Borra los latch de salida ;Selecciona banco 1 ;Puerta B se configura como salida ;Puerta A se configura como entrada ;Preescaler de 256 para el TMR0 ;Selecciona banco 0 ;Refresca el WDT ;Activado RA0 ?? ;Todava No ;Ahora si. ;Captura el valor del TMR0 (N aleatorio) ;Elimina rebotes

Inicio

Loop

clrwdt btfss PORTA,0 goto Loop movf TMR0,W movwf Numero call Delay_20_ms

;El nmero aleatorio es, mediante restas consecutivas, dividido entre ;6. De esta forma el ltimo resto ser entre 0 y 5 que ser ;incrementado en una unidad para que definitivamente salga un nmero ;entre 1 y 6. Divide: movlw subwf movwf sublw btfss goto incf d'6' Numero,W Numero d'5' STATUS,C Divide Numero,F ;Resta 6 al nmero aleatorio ;lo guarda ;Mira si es menor de 5 ;No ;El nmero queda entre 1 y 6

;Esta secuencia de instrucciones tiene por misin presentar sobre el ;display los nmeros del 1 al 6 a intervalos de 0.05" con objeto de ;dar una sensacin de movimiento del dado. Dicho movimiento se ;mantiene mientras RA0 est a "1". Al ponerse a "0" se presenta el ;nmero aleatorio capturado previamente desde el TMR0.1+23 Dado: RA0_1 movlw d'6' movwf Temporal clrwdt ;Inicia el contador del dado ;Refresco del WDT

btfss PORTA,0 goto Salida movf Temporal,W call Tabla movwf PORTB movlw d'1' movwf Delay_Cont call Delay_var decfsz Temporal,F goto RA0_1 goto Dado call Salida: movf call movwf movlw movwf call clrf goto end EJEMPLO 20:

;Mira si RA0 est a 1 ;No, visualiza el aleatorio ;Nmero a visualizar ;Conversin a BCD ;Visualiza sobre el display ;Variable de temporizacin ;temporiza 0.05" ;Siguiente nmero

Delay_20_ms ;Elimina rebotes Numero,W Tabla PORTB d'60' Delay_Cont Delay_var PORTB Loop ;Recoge el aleatorio ;Lo convierte en 7 segmentos ;Salida a Display ;Inicia variable de temporizacin ;Temporiza 3" ;Desconecta la salida ;Fin del programa fuente

;El programa realiza una temporizacin de 0.5 segundos. Se supone una ;frecuencia de trabajo del PIC de 4 MHz, por lo que el TMR0 evoluciona ;cada 1 uS (4Tosc=1uS ). ; ;Al TMR0 se le carga con 250 - 2 (su complemento, 7) y se selecciona ;un preescaler de 8. La temporizacin as obtenida es de unos 1990 uS. :Si esta se repite 250 veces, se obtiene una temporizacin total en :torno a los 500000uS. List p=16F84 include "P16F84.INC" Contador equ org Inicio bsf movlw movwf bcf 0x10 0x00 ;Tipo de procesador ;Definiciones de registros internos

;Variable para el contador ;Vector de Reset

STATUS,RP0 ;Selecciona banco 1 de datos b'11000010' OPTION_REG ;Configura preescaler de 8 asignado a TMR0 STATUS,RP0 ;Selecciona banco 0 de datos

Bucle1

movlw .250 movwf Contador ;Inicia la variable contador clrf INTCON ;Desconecta flag del TMR0 e ;interrupciones movlw .7 movwf TMR0 ;Carga el TMR0 con complemento de 250 btfss INTCON,T0IF goto Bucle2 decfsz Contador,F goto Bucle1 end ;Fin del TMR0 (flag T0IF=1) ?? ;No, esperar ;Si. Repetir tantas veces como indique el contador ;Fin del programa fuente

Bucle2

EJEMPLO 21: ;Juego de luces. ;Se desea realizar una rotacin secuencial en el encendido de cada led ;contectado a la puerta B. Si RA0 = 0, la rotacin ser de derecha a ;izquierda y viceversa. Cada led permanece encendido 0.25 segundos (250 ;mS) List p=16F84 include "P16F84.INC" Contador equ org 0x0c 0x00 ;Tipo de procesador ;Definiciones de registros internos

;Variable para la temporizacin ;Vector de Reset

;********************************************************************* ;Delay es una rutina que realiza una temporizacin de 250 mS que es el ;tiempo en que han de permanecer encendidos cada uno de los leds. ; ;Si el PIC trabaja a una frecuencia de 4MHz, el TMR0 evoluciona cada ;uS. Si se desea temporizar 25000 uS (25mS) con un preescaler de 128, ;el TMR0 deber contar 195 eventos (195 * 128 = 24960). El valor 195 ;equivale a 0xc3 y, como el TMR0 es ascendente, habr que cargar su ;complemento (0x3c). Esta temporizacin habr que repetirla 10 veces ;para conseguir el total deseado (250000). Delay Delay_0 Delay_1 movlw .10 movwf Contador bcf INTCON,T0IF movlw 0x3c movwf TMR0 clrwdt btfss INTCON,T0IF goto Delay_1 decfsz Contador,F goto Delay_0 return clrf bsf clrf movlw movwf movlw movwf bcf bsf call btfsc goto rlf goto rrf goto end EJEMPLO 22: ;Contador UP/DOWN binario PORTB STATUS,RP0 TRISB b'00011111' TRISA b'00000110' OPTION_REG STATUS,RP0 STATUS,C Delay PORTA,0 A_Dcha PORTB,F Loop PORTB,F Loop ;Carga el contador con 10 ;Desconecta el flag de rebosamiento del TMR0 ;carga el TMR0 ;Refresco del WDT ;Rebasamiento del TMR0 ?? ;Todava no han pasado los 25 mS ;Decrementa contador. Se ha repetido 10 veces ? ;Todava no, temporiza 25 ms ;Ahora si ;Borra los latch de salida ;Selecciona banco 1 ;Puerta B se configura como salida ;Puerta A se configura como entrada ;Preescaler de 128 para el TMR0 ;Selecciona banco 0 ;Activa el carry ;Temporiza 250mS ;Est a 0 RA0 ?? ;No, rotacin a derecha ;Si, rotacin a izquierda ;Rotacin a derechas ;Fin del programa fuente

Inicio

Loop A_Izda A_Dcha

;Sobre los 8 leds de salida conectados a la puerta B se visualizar, ;en binario, el nmero de pulsos aplicados por la entrada RA0. RA1 ;determina si la cuenta es ascendente (a "1") o descendente. List p=16F84 include "P16F84.INC" org 0x00 ;Tipo de procesador ;Definiciones de registros internos ;Vector de Reset

;********************************************************************* ;Delay_20_ms: Esta rutina de temporizacin tiene por objeto eliminar ;el "efecto rebote" de los perifricos electromecnicos. Realiza un ;delay de 20 mS. Si el PIC trabaja a una frecuencia de 4MHz, el TMR0 ;evoluciona cada uS. Si queremos temporizar 20000 uS (20 mS) con un ;preescaler de 128, el TMR0 deber contar 156 eventos (156 * 128). El ;valor 156 equivale a 9c hex. y como el TMR0 es ascedente habr que ;cargar su complemento a 1 (63 hex.). Delay_20_ms bcf INTCON,T0IF movlw 0x63 movwf TMR0 Delay_20_ms_1 clrwdt btfss INTCON,T0IF goto Delay_20_ms_1 bcf INTCON,T0IF return Inicio clrf bsf clrf movlw movwf movlw movwf bcf PORTB STATUS,RP0 TRISB b'00011111' TRISA b'00000110' OPTION_REG STATUS,RP0 ;Desconecta el flag de rebosamiento ;Complemento hex. de 156 ;carga el TMR0 ;Refrescar el WDT ;Rebasamiento del TMR0 ?? ;Todava no ;Ahora si, reponer el flag ;Borra los latch de salida ;Selecciona banco 1 ;Puerta B se configura como salida ;Puerta A se configura como entrada ;Preescaler de 128 para el TMR0 ;Selecciona banco 0 ;Refrescar el WDT ;Subida de la seal RA0 ? ;No ;Elimina rebotes ;Refrescar el WDT ;Bajada de RA0 (pulso) ?? ;No ;Ha habido pulso, eliminar rebotes ;RA1 = 1 ;No, cuenta descendente ;Cuenta ascendente ;Cuenta descendente ;Fin del programa fuente

Loop

clrwdt btfss PORTA,0 goto Loop call Delay_20_ms clrwdt btfsc PORTA,0 goto Loop_2 call Delay_20_ms btfss PORTA,1 goto Down

Loop_2

Up Down

incf goto decf goto end

PORTB,F Loop PORTB,F Loop

EJEMPLO 23: ;Contador UP/DOWN decimal de un dgito ;

;Sobre el display 7 segmentos conectado a la puerta B se visualizar ;el nmero de pulsos aplicados por la entrada RA0. RA1 determina si la ;cuenta es ascendente (a "1") o descendente. List p=16F84 include "P16F84.INC" Contador equ org 0x0c 0x00 ;Tipo de procesador ;Definiciones de registros internos

;Variable del contador ;Vector de Reset

;********************************************************************* ;Tabla: Esta rutina convierte el cdigo BCD presente en los 4 bits de ;menos peso del reg. W en su equivalente a 7 segmentos. El cdigo 7 ;segmentos retorna tambin en el reg. W. Tabla: addwf retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw PCL,F b'00111111' b'00000110' b'01011011' b'01001111' b'01100110' b'01101101' b'01111101' b'00000111' b'01111111' b'01100111' ;Desplazamiento sobre la tabla ;Dgito 0 ;Dgito 1 ;Dgito 2 ;Dgito 3 ;Dgito 4 ;Dgito 5 ;Dgito 6 ;Dgito 7 ;Dgito 8 ;Dgito 9

;************************************************************************ ;Delay_20_ms: Esta rutina de temporizacin tiene por objeto eliminar ;el "efecto rebote" de los perifricos electromecnicos. Realiza un ;delay de 20 mS. Si el PIC trabaja a una frecuencia de 4MHz, el TMR0 ;evoluciona cada uS. Si queremos temporizar 20000 uS (20 mS) con un ;preescaler de 128, el TMR0 deber contar 156 eventos (156 * 128). El ;valor 156 equivale a 9c hex. y como el TMR0 es ascedente habr que ;cargar su complemento a 1 (63 hex.). Delay_20_ms bcf INTCON,T0IF ;Desconecta el flag de rebosamiento movlw 0x63 ;Complemento hex. de 156 movwf TMR0 ;carga el TMR0 Delay_20_ms_1 clrwdt ;Refrescar el WDT btfss INTCON,T0IF ;Rebasamiento del TMR0 ?? goto Delay_20_ms_1 ;Todava no bcf INTCON,T0IF ;Ahora si, reponer el flag return Inicio clrf bsf clrf movlw movwf movlw movwf bcf clrf PORTB STATUS,RP0 TRISB b'00011111' TRISA b'00000110' OPTION_REG STATUS,RP0 Contador ;Borra los latch de salida ;Selecciona banco 1 ;Puerta B se configura como salida ;Puerta A se configura como entrada ;Preescaler de 128 para el TMR0 ;Selecciona banco 0 ;Puesta a 0 del contador ;Convierte ;Visualiza ;Refrescar ;Subida de ;No BCD a 7 segmentos el valor del contador el WDT la seal RA0 ?

Loop Wait_0

movf Contador,W call Tabla movwf PORTB clrwdt btfss PORTA,0 goto Wait_0

call Wait_1

Delay_20_ms ;Elimina rebotes ;Refrescar el WDT ;Bajada de RA0 (pulso) ?? ;No ;Ha habido pulso, eliminar rebotes ;RA1 = 1 ;No, cuenta descendente ;Incrementa contador ;Es mayor de 9 ?? ;No ;Si, puesta a 0 del contador ;Decrementa el contador ;Es menor de 0 ?? ;No ;Si, puesta a 9 del contador ;Fin del programa fuente

clrwdt btfsc PORTA,0 goto Wait_1 call Delay_20_ms btfss PORTA,1 goto Down

Up

incf movlw subwf btfss goto clrf goto decf movlw subwf btfss goto movlw movwf goto end

Contador,F .10 Contador,W STATUS,Z Loop Contador Loop Contador,F 0xff Contador,W STATUS,Z Loop 0x09 Contador Loop

Down

EJEMPLO 24: ;Generacin de ondas cuadradas de diferentes frecuencias variando el ;valor del TMR0. ;La lnea de salida RB0 cambiar de estado a una frecuencia ;determinada por el valor introducido mediante los 3 interruptores ;RA0-RA2: ; ;RA2 RA1 RA0 Frecuencia Periodo Semiperiodo ;--- -------------- ----------------;0 0 0 0 KHz ----;0 0 1 1 KHz 1000 uS 500 uS ;0 1 0 2 KHz 500 uS 250 uS ;0 1 1 3 KHz 333 uS 166 uS ;1 0 0 4 KHz 250 uS 125 uS ;1 0 1 5 KHz 200 uS 100 uS ;1 1 0 6 KHz 166 uS 83 uS ;1 1 1 7 KHz 143 uS 71 uS ; ;En el tratamiento de interrupcin que provocar el desbordamiento del ;TMR0, se puede apreciar como se salva el W y el registro de estado, ;para recuperarlos posteriormente. Es lo que se llama "salvar el ;contexto".

List p=16F84 include "P16F84.INC" Valor equ W_Temp equ Status_Temp equ org goto org goto 0x0c 0x0d 0x0e

;Tipo de procesador ;Definiciones de registros internos

;Variable de frecuencia ;W temporal ;Registro de estado temporal

0x00 ;Vector de Reset Inicio 0x04 ;Vector de interrupcin Interrupcion

;********************************************************************* ;Tabla: esta rutina devuelve el valor a cargar en el TMR0 segn la ;frecuencia seleccionada. Partiendo de una frecuencia general de 4 ;MHz, el TMR0 evoluciona cada 1 uS. Se selecciona una preescaler de 4. ;El valor a cargar en TMR0 se obtiene de dividir el semiperiodo de la ;frecuencia deseada entre el preescaler. Al valor obtenido se le resta ;2 por motivos de sincronismo interno del PIC, se convierte a hex. y ;se complementa. Tabla: addwf retlw retlw retlw retlw retlw retlw retlw retlw PCL,F 0x00 0x86 0xc5 0xda 0xe4 0xea 0xee 0xf1 ;Calcula desplazamiento de la tabla ;0 KHz ;1 KHz ;2 KHz ;3 KHz ;4 KHz ;5 KHz ;6 KHz ;7 KHz

Interrupcion movwf W_Temp ;Salva el W swapf STATUS,W movwf Status_Temp ;Salva el registro de estado movf movwf bcf movlw xorwf swapf movwf swapf swapf Valor,W TMR0 ;Recarga el TMR0 INTCON,T0IF ;Desactiva el flag TMR0 b'00000001' PORTB,F ;Bascula RB0 Status_Temp,W STATUS ;Recupera el registro de estado W_Temp,F W_Temp,W ;Recupera el registro W

retfie Inicio clrf bsf clrf movlw movwf movlw movwf bcf movlw movwf PORTB STATUS,RP0 TRISB b'00011111' TRISA b'00000001' OPTION_REG STATUS,RP0 b'00100000' INTCON ;Borra los latch de salida ;Selecciona banco 1 ;Puerta B se configura como salida ;Puerta A se configura como entrada ;Preescaler de 4 para el TMR0 ;Selecciona banco 0 ;Interrupcin TMR0 habilitada ;Refrescar el WDT

Loop

clrwdt

movf andlw btfss goto bcf goto Salida_On call movwf bsf goto end EJEMPLO 25:

PORTA,W b'00000111' STATUS,Z ;RA0-RA2 = 0 ?? Salida_On ;No, salida de frecuencia INTCON,GIE ;Si, interrupciones OFF, frecuencia OFF Loop Tabla Valor INTCON,GIE Loop ;Determina valor a cargar en TMR0 ;Carga la variable ;Interrupciones ON ;Fin del programa fuente

;El TMR0 como contador de eventos externos ;Un sensor optoelectrnico conectado a RA4 genera un pulso cada vez ;que un objeto se interpone entre el emisor y el receptor de luz. El ;TMR0 se encarga de contarlos dependiendo del valor del preescaler. ;Dicho valor se ajusta mediante 3 interruptores (RA0-RA2) conectados a ;la Puerta A, existiendo as 8 predivisiones: ; ; I2 I1 I0 Divisin ; ----------; 0 0 0 1:2 ; 0 0 1 1:4 ; 0 1 0 1:8 ; 0 1 1 1:16 ; 1 0 0 1:32 ; 1 0 1 1:64 ; 1 1 0 1:128 ; 1 1 1 1:256 ; ;El contaje se va visualizando en binario sobre los leds conectado a ;la Puerta B y debe multiplicarse por el valor del preescaler ;seleccionado, para determinar el nmero total de pulsos. El contador ;se resetea al poner RA3 a "1". Debe tenerse en cuenta el "efecto ;rebote" que se produce en el interruptor RA4. List p=16F84 ;Tipo de procesador include "P16F84.INC" ;Definiciones de registros internos org 0x00 ;Vector de Reset Inicio clrf bsf clrf movlw movwf movlw movwf bcf Loop Loop1: PORTB STATUS,RP0 TRISB b'00011111' TRISA b'00110000' OPTION_REG ;RA4 STATUS,RP0 ;Borra los latch de salida ;Selecciona banco 1 ;Puerta B se configura como salida ;Puerta A se configura como entrada ;TMR0 contador sensible al descendente de ;Selecciona banco 0 ;Puesta a 0 del contador ;Refresca el WDT ;Mira si I3 est activo (RESET) ;Si Cuenta detenida y puesta a 0

clrf TMR0 clrwdt btfsc PORTA,3 goto Loop

movf andlw bsf iorwf bcf movf

PORTA,W b'00000111' STATUS,RP0 OPTION_REG,F STATUS,RP0 TMR0,W

;No, leer I2-I0 para formar el nuevo valor ;del preescaler ;Selecciona pgina 1 ;Actualiza el nuevo valor del preescaler ;Selecciona pgina 0 ;Lee el valor del contador

movwf PORTB goto Loop1 end EJEMPLO 26:

;Salida a leds ;Fin del programa fuente

EL CONTROL DEL TIEMPO EN UN MICROCONTROLADOR Medidas de tiempo estndar: 1 microsegundo = 0,000.001 segundos 1 nanosegundo = 0,000.000.001 segundos La medida del tiempo en un microPic esta sujeta a 3 temas: 1- El oscilador externo 2- El TMR0 3- El Divisor de frecuencias El oscilador externo depende del tipo del sistema de oscilacin. Vamos a considerar exclusivamente el tipo XT a cristal de 4 Mhz. Recordemos que cada ciclo de instruccin tarda en hacerse 4 periodos de reloj por lo que con un oscilador de 4 Mhz.: 1 Periodo = 1segundo/4.000.000=0,000.000.25 segundos = 0,25 microsegundos 4 Periodos = 1 ciclo instruccin = 0,25 msg. x 4 = 1 msg. = 1000 nanosegundos El contador TMR0 o temporizador lo vamos a observar solo en este caso como medidor basndose en el reloj y se da cuando el bit T0CS (5) de OPTION ( Banco1 registro 81 H) es igual a 0. El TMR0 que es un registro fsico de la memoria SFR Banco0 posicin 01 H aumenta de valor hasta llegar a 255 en cada ciclo de instruccin, cuando llega a 255 provoca un desbordamiento controlable en el bit T0IF (2) de INTCON que se pone a 1 despus del desbordamiento. El TMR0 se puede cargar con cualquier registro de 0 a 255. El divisor de frecuencia es un sistema por el que segn ciertas combinaciones se aplican divisores de tiempo que nos permiten ralentizar los ciclos de instrucciones. Estas combinaciones se obtienen con los bits 0,1 y 2 del Registro OPTION (81 H) FORMULA PARA CALCULAR EL TIEMPO: Tiempo = 4 x Tiempo de cada ciclo x Valor a contar de TMR0 x Divisor de frecuencia Explicacin: 4 ciclo de instruccin = 4 ciclos de reloj Tiempo de cada ciclo 1/Valor del oscilador Valor a contar de TMR0 Valor introducido en el TMR0 que asciende hasta 255 Divisor de frecuencia Factor constante aplicado para alargar los periodos del reloj Por lo que el mximo tiempo controlable por un programa cargado el TMR0 con 255 el divisor de frecuencia con el valor (111) o sea 255 y un oscilador de 4 Mhz. sera:

Tiempo= 4 x 1/4000000 x 255 x 255 = 0,065025 segundos = 65,025 microsegundos. Ejemplo: Para conseguir un segundo de tiempo. (No es exactamente un segundo pero vale para el ejemplo, con otras combinaciones u otros cristales es fcil de conseguir): ;Programa en ensamblador para conseguir 1 segundo + ;Despus de provocar un RESET se encender un LED a 1 segundo ;Al programar el microcontrolador desconectar el WDT list p=16c84 radix tmr0_opt status intcon ptb aux org hex equ equ equ equ equ 0

0x01 0x03 0x0b 0x06 0x0e

inicio

unsgd conta

bsf clrf movlw movwf bcf clrf movlw movwf bcf movlw movwf

status,5 ptb b00000111 tmr0_opt status,5 ptb 0x64 aux intcon,2 0xd8 tmr0_opt intcon,2

conta1

btfss

goto decfsz

conta1 aux,1

goto movlw movwf end resumiendo:

conta 0xff ptb

;pone bit 5 de status = 1 . Ir al Banco 1 ;selecciona puertaB como salida ;w=00000111 ;carga el divisor de frecuencias con 111 (1:255) ;pone bit 5 de status = 0 . Ir al banco 0 ;Registro de Puerta B = 0 ;Carga W con 0x64 (en decimal 100) ;Carga el registro aux (0x0e) con el valor 0x64 (100) ;pone a 0 el bit 2 de INTCON .Sealizador de ;desbordamiento del TMR0 = 0 ;carga W con valor literal 0xd8 (216 en decimal) ;Carga el TMR0 con el valor 0xd8 (216) lo que da un ;periodo hasta el desbordamiento de 255-216=39 ;Comprueba si T0IF a cambiado a 1 si es asi es ;porque hubo desbordamiento del TMR0 y en ese caso ;se produce un brinco ;En cada ciclo de instruccin el TMR0 sube una unidad ;hasta llegar a 255 ;decrementa una unidad por cada ciclo de instruccin ;y recarga el registro aux con el nuevo valor. ;por ciclo aux=aux-1 si llega a 0 brinca ;vuelve al bucle de 39 en el TMR0 ;carga W con 11111111 ;enciende los LED

tiempo = 4 x 1/4000000 x 39 x 100 x 255 = 0,9945 segundos

EJEMPLO 27: ;Control de tiempo, mide 1 segundo mas o menos (exactamente 0,9945 de ;segundo). ;Reloj XT a 4Mhz. WDT-deshabilitado list p=16c84 radix hex

tmr0_opt status intcon ptb aux org

equ equ equ equ equ 0

0x01 0x03 0x0b 0x06 0x0e

inicio bsf status,5 clrf ptb movlw b'00000111' movwf tmr0_opt bcf status,5 clrf ptb unsgd movlw 0x64 movwf aux conta bcf intcon,2

;pone bit 5 de status = 1 . Ir al Banco 1 ;selecciona puertaB como salida ;w=00000111 ;carga divisor de frec. con 111 (1:255) ;pone bit 5 de status = 0 . Ir al banco 0 ;Registro de Puerta B = 0

;Carga W con 0x64 (en decimal 100) ;Carga reg. aux(0x0e)con valor 0x64(100) ;pone a 0 el bit 2 de INTCON .Sealizador ;de desbordamiento del TMR0 = 0 movlw 0xd8 ;carga W con literal 0xd8(216 en decimal) movwf tmr0_opt ;Carga TMR0 con valor 0xd8 (216)lo que da ;un periodo hasta desbordamiento de ;255-216=39. conta1 btfss intcon,2 ;Comprueba si T0IF a cambiado a 1 si es ; as es porque hubo desbordamiento del ;TMR0 y en ese caso se produce un salto goto conta1 ;En cada ciclo de instruccin el TMR0 ;sube ;una unidad hasta llegar a 255 decfsz aux,1 ;decrementa una unidad por cada ciclo de ;instruccin y recarga el registro aux con nuevo valor. ;por ciclo aux=aux-1 si llega a 0 salta goto conta ;vuelve al bucle de 39 en el TMR0 movlw 0xff ;carga W con 11111111 movwf ptb ;enciende los LED end

;el

EJEMPLO 28: Calculo de tiempo en bucles de retardo anidados. Bsicamente la precisin del tiempo en los microcontroladores depende del tipo de oscilador y es en los osciladores XT o sea los controlados por cristal de cuarzo en los que se obtiene mejor precisin. Se puede encontrar mas informacin sobre los osciladores acudiendo a la pagina de microchip Estamos todos de acuerdo en que las instrucciones de los programas son de 1 o 2 ciclos de instruccin y tambin estamos de acuerdo que cada instruccin equivale a 4 ciclos de reloj. Y si no lo estamos es preferible que no sigas leyendo. Partamos de un oscilador tipo bsico de 4 Mhz, lo que nos dara: TR (Tiempo Reloj)= Periodo de oscilador/Frecuencia oscilador TR=1sg/4.000.000 de ciclos por segundo= 0,00000025 TR en nanosegundos= 1.000.000.000/4.000.000=250 nanosegundos TI (Tiempo Instruccion)=4 x TR= 4 x 250 nsg =1000 nsg = 1microsegundo = 1usg. Resumiendo: cada instruccin tarda segn el tipo entre 1usg. y 2 usg. en ejecutarse. Veamos cuando tardan cada instruccin de programa: Goto, Call, Return, RetlW, Retfie --------> Tardan 2 ciclos de instruccin

Decfsz, Incfsz, Btfsc, Btfss ----------------> Tardan 1 o 2 ciclos segn instruccin Todas las dems ordenes tardan 1 ciclo de instruccin. Ahora vamos a estudiar un bucle de retardo anidado tipo. Primero empezamos con las rutinas de inicio de configuracin de posiciones de memoria, tanto de cont1 como de cont2, eliminado TMRO y WDT, y realizado un inicio de programa bsico, en cualquier programa llamamos a un bucle de tiempo. Debemos suponer tambin que cargamos cont1 y cont2 con 255 y que hemos dado en el registro OPTION la orden de que el conteo es descendente. --------------CARGAR movwf --------------------------- movwl ------------- BUCLE decfsz --------------------------- goto --------------------------- decfsz --------------------------- goto --------------------------- return 0xFF,w CONTt1 CONT1,1 BUCLE CONTt2,1 CARGAR

;carga CONT1 con 255

El bucle de cont1 necesita 3 ciclos para ejecutarse 1 ciclo ------> decfsz conta1,1 2 ciclos ----> goto bucle esto durante 255 veces la vez 256 necesita solo 2 ciclos porque llega a 0 y salta la instruccin goto bucle, esto nos dara en forma matemtica (2 x 255)+ 2 = 767 o en forma de frmula (conta1 x 3)+2= ciclos bucle conta1 Seguimos ahora con el bucle conta2: El bucle conta2 necesita 3 ciclos y vuelve al bucle anterior de conta1. Decrementa 1 en conta2 y repite el ciclo anterior en conta1 1 ciclo ------- > decfsz conta2,1 2 ciclos -----> goto bucle Estos ciclos se repiten 255 veces en conta2 lo que matemticamente da: ( 255 ( 767 + 3 )) + 2 = total ciclos que en forma de formula nos dara ( conta2 ((( conta1 x 3) + 2) + 3) + 2 = total ciclos instruccin Total ciclos instruccin x 4 x tiempo de reloj = tiempo total Es decir que podemos precargar las posiciones de conta1 y conta2 con determinados valores que servirn para conseguir el periodo de tiempo que nos interese. Este bucle con estas formulas aadiendo contadores y bloqueando la funcin de interrupcin del TMR0 y WDT, permite alargar indefinidamente el tiempo de conteo dado que si aadimos una nueva posicin o Conta3 al bucle anterior, este se repetira 256 veces mas lo que nos llevara a minuto y con otro bucle a las 3 horas, al mes, etc. etc. etc. y con 10 bucles un buen montn de aos.

EJEMPLO 29: Programa Contador mediante TMR0 El programa se basa en un simple contador configurado a nivel descendente de una seal cuadrada controlada. La caracterstica principal del programa es la de, en un tiempo establecido por la pausa del programa, controlar la cuenta de las oscilaciones de una forma "regular" visualizndola por un juego de 8 LEDS (RB0-RB7). As, estos nos mostraran la cantidad de pulsos en un tiempo determinado. Se ha de tener en cuenta que configurando el contador mediante el OPTION_REG del banco1( lneas 34-35 ), se anula el divisor de frecuencia del reloj interno y se vincula al contador externo.

Esto hace que el oscilador interno funciona a 4 ciclos por instruccin, lo que significa que el micro-controlador funciona a mxima velocidad. Teniendo esto en cuenta, la pausa que se realiza para contar ciclos a de ser excesivamente superior a lo normal cuando el divisor de frecuencias se vincula al contador del programa, para este bucle de tiempo hemos creado una pausa anidada de 255 veces 255, 2 veces ( lneas 40-51). Para controlar la cuenta en el periodo de tiempo establecido, esta se lleva a cabo mediante una limpieza del TMR0 (el propio contador) y crear un bucle infinito en la misma lnea de forma como aparece en la lnea 54-55 del programa adjunto. As se fuerza a que las puertas de salida muestren el ltimo dato descargado en el acumulador, en este caso la cuenta del TMR0 (lneas 52-53). PROGRAMA ASM: ;CONTADOR CON TMR0 ;CRISTAL 4MHz WDT=OFF(DESCONECTAMOS EL PERRO GUARDIAN)

LIST P=16F84 LIST C=132 RADIX HEX TMR0 ESTADO PA_TA PB_TB OPTION_REG TRISA TRISB INTCON DELAY2 DELAY3 DELAY4 DELAY1 ORG INICIO CLRF BSF CLRF MOVLW MOVWF MOVLW MOVWF BCF EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU 0X00 PB_TB ;BORRAR LAS PUERTAS DE SALIDA ESTADO,5 ;SELECCION DEL BANCO 1 DE MEMORIA TRISB ;CONFIGURAMOS PUERTA B DE SALIDA 0x1F ;0X1F=00011111 TRISA ;CONFIGURAMOS PUERTA A DE ENTRADA 0X30 ;0X30=00110000 OPTION_REG ;CONFIGURAMOS TMR0 COMO CONTADOR ;DESCENDENTE ESTADO,5 ;SELECCION DEL BANCO 0 DE MEMORIA 0X01 0X03 0X05 0X06 0X81 0X85 0X86 0X0B 0X0C 0X1C 0X3C 0X0D ;REGISTRO DE TIMER ;DIRECCION DE ESTADO ;PUERTA A ;PUERTA B ;REGISTRO OPTION ;TRIS A ;TRIS B ;REGISTRO DE INTERRUPCIONES ;VALOR DEL RETRASO2 ;VALOR DEL RETRASO3 ;VALOR DEL RETRASO3 ;VALOR DEL RETRASO1

CONTROL PAUSA PAUSA2

CLRF TMR0 MOVLW 0X02 MOVWF DELAY1 MOVLW 0XFF MOVWF DELAY2 MOVLW 0XFF MOVWF DELAY3

;LIMPIAMOS TMR0 ;0X02=00000010 ;CARGAMOS LA CUENTA DE W AL REGISTRO ;0XFF=11111111 ;CARGAMOS LA CUENTA DE W AL REGISTRO ;0XFF=11111111 ;CARGAMOS LA CUENTA DE W AL REGISTRO

PAUSA1

PARADA

DECFSZ DELAY3,1 ;DECREMENTAMOS EN LA UNIDAD EL REGISTRO GOTO PAUSA1 ;SALTAMOS A LA ETIQUETA DECFSZ DELAY2,1 ;DECREMENTAMOS EN LA UNIDAD EL REGISTRO GOTO PAUSA2 ;SALTAMOS A LA ETIQUETA DECFSZ DELAY1,1 ;DECREMENTAMOS EN LA UNIDAD EL REGISTRO GOTO PAUSA ;SALTAMOS A LA ETIQUETA MOVF TMR0,0 ;CARGAMOS CUENTA DEL CONTADOR AL ;ACUMULADOR MOVWF PB_TB ;MUESTRA INFORMACION DE W EN PUERTAS ;SALIDA CLRF TMR0 ;LIMPIEZA DEL TMR0(COMIENZO DE BUCLE ;INFIN.) GOTO PARADA ;RETORNAMOS LINEA ANTERIOR END ;Fin del programa fuente

EJEMPLO 30: El timer es un elemento que forma parte de los microcontroladores, es el responsable de dos posibilidades segun configuracin el de determinar intervalos concretos de tiempo como temporizador o para contar impulsos producidos en el exterior como contador.

De este dispositivo hay que considerar dos cosas: una de ellas es el contador propiamente dicho o TMR0 y otro su configuracion. El TMR0 ocupa la posicion 01 del Banco 0, la configuracion basica se localiza en el registro OPTION que ocupa la posicion 81 del Banco 1 . El registro TMR0 es leible y escribible y tiene 8 bits. Para configurar el timer se deben de tener en cuanta los siguientes registros del PIC: 1 El registro OPTION para su configuracion 2 El registro INTCON para que controle las interrupciones 3 El WDT (Perro guardian) Ahora vamos a explicar tres formas basicas para controlar el tiempo en un programa 1) Sin rebosamiento (flag) ni interrupcion Como deciamos el TMR0 es el registro 01 de 8 bits del Banco 0. Si consideramos el resgistro en binario este numero ira del 0000 0000 al 1111 1111. Bueno el sistema consiste en controlar este registro y ver cuando una posicion del mismo en su rutina de incremento cambia de 0 a 1. CLRF TMR0 ;Registro TMR0 = 0000 0000 BTFSS TMR0,5 ;Explora si el Bit 5 si esta a 1 salta GOTO CONTROL ;Vuelve a la rutina de controlar el bit 5 RETURN

CONTROL

Rutina simple de control de tiempo que admite modificaciones en funcin del inters del programa, como siempre ojo con el WDT. 2) Control del tiempo con rebosamiento y sin interrupcin En este sistema nos vamos a basar en el flag o bandera del TMR0 que es el bit 2 del Registro INTCON. Se debe tener en cuenta la bandera que debe de estar a 0 dado que solo se puede hacer por software Un posible ejemplo sera: Queremos controlar periodos de tiempo de 50 ms y para ello hemos configurado el divisor de tiempos a 1:256 y flanco ascendente. Trasladamos la cifra de 50 milisegundo a microsegundo lo que nos da 50.000 us lo dividimos por 256 que es el divisor de tiempos configurado, o sea 50ms=50000us ----> 50000/256= +-195 es decir 195 pulsos hasta cambio de bandera de 0 a 1, es decir que rebose los 255 de registro de TMR0, pero primero debemos buscar el complemento a partir de donde deberemos sumar 255 es decir 255-195=60. 60 en hexadecimal es 0x3c. La rutina en ensamblador seria la siguiente:

viene de una instruccin CALL CONTROL BCF INTCON,T01F MOVLW 0X3C MOVWF TMR0 TIEMPO BTFSS INTCON,T0IF GOTO TIEMPO RETURN

;Ponemos a 0 el flag tmr0 ;W=0x3c --> 60 ;Cargamos TMR0 con 60 ;T01F=1 sino salta ;Incrementa cada ciclo ;Se ha producido el rebosamiento

3) Control del tiempo con INTERRUPCION El calculo para obtener el dato del registro a cargar en el TMR0 es igual al ejemplo anterior as como las primeras pautas del programa, pero el Registro INTCON se debe ajustar para que se produzca interrupciones por lo que los bits 7 y 5 deben de estar a 1 y por ultimo debemos recordar la instruccin RETFIE, con todo ellos mas o menos quedara la rutina as: ;viene de una instruccin CALL CONTROL MOVLW 0x3C MOVWF TMR0 TIEMPO DECFSZ TMR0,1 GOTO TIEMPO RETFIE

;W=0x3c ;TMR0=0x3c ;Controla y decrementa ;control posicion ;vuelta tras interrupcion

EJEMPLO 31: Esta es una rutina muy utilizada en programacin, es de uso general y sirve para hacer temporizaciones de tiempo variable entre 50 mS (49920 nS. ) y 12,8 Sgds. (12,750 segundos.) Esta rutina la vamos a llamar Tiem_po. El programa debe de tener las siguientes caractersticas: Se debe de emplear un preescaler del TMR0 de 256 El Oscilador debe de ser de tipo XT y 4 Mhz. Con estas condiciones LOS CICLOS DE INSTRUCCION tardan 1 uS. , con lo que cada ciclo aumenta el TMR0 hasta llegar al desbordamiento. Cargamos el registro del TMR0 con 60 con lo que tendremos un contador con 195 ciclos. Y estos 195 ciclos con un preescaler de 256 nos dar: Tiempo base = 195 (255-60) Cargado en TMR0 x 256 49920 nS ------ > 49,92 milisegundos. = 49920 nano Sgdos.

Ahora lo que debemos hacer es repetir este ciclo entre 1 vez y 255 veces cargando en un Contador cualquiera de estas cifras entre 1 y 255. Lo que nos dar unas temporizaciones de entre 49,92 milisegundos y 12,729 segundos. Este programa se debe asociar al P16F84.inc de Microchip En el inicio del programa base se debe dejar un registro de memoria para el Contador Ahora pasamos al programa: Tiem_po Bucle bcf INTCON,T0IF movlw b00111100 movwf TMR0 clrwdt btfss INTCON,T0IF goto Bucle ;Pone a 0 el flag de desbordamiento del TMR0 ;00111100=60 en decimal ----> W ;Carga TMR0 con 60 que contara hasta 255 ;Borra el Perro Guardian ;Comprueba si hubo desbordamiento del TMR0 ;no hubo desbordamiento del TMR0

decfsz

Contador,1;Si hubo desbordamiento y decrementa en uno el ;Registro del contador hasta llegar a 0, entonces ;salta

goto Tiem_po ;Repite el ciclo de 50 mS. return ;Al llegar Contador a 0 se produce el ;salto ;y se aplica la orden return. Este subprograma se coloca en cualquier programa teniendo la precaucin de dejar un registro de memoria para el Contador.

EJEMPLO 32: ;La interrupcin del TMR0. ; ;Se trata de comprobar la interrupcin provocada por el TMR0. El programa ;lee el estado de los interruptores conectados a RA0 y RA4 para reflejarlo en ;los leds conectados a RB0 y RB4 respectivamente. Al mismo tiempo el TMR0 ;genera una interrupcin cada 0.05 seg. (50 mS) que se repetir 5 veces con objeto ;de hacer intermitencia de 250 mS sobre el led conectado a RB7.

List p=16F84 include "P16F84.INC" Contador equ org goto org Interrupcion 0x0c 0x00 Inicio 0x04

;Tipo de procesador ;Definiciones de registros internos ;Variable para la temporizacin ;Vector de Reset

;Vector de interrupcin

bcf INTCON,T0IF ;Repone flag del TMR0 decfsz Contador,F ;Decrementa el contador goto Seguir Con_si_0 movlw 5 movwf Contador ;Repone el contador nuevamente btfsc PORTB,7 ;Testea ltimo estado de RB7 goto RB7_ES_1 ;Est a 1 bsf PORTB,7 ;Est a 0, activa RB7 goto Seguir RB7_ES_1 bcf PORTB,7 ;Desactiva RB7

Seguir movlw 0x3c movwf TMR0 retfie Inicio clrf bsf clrf movlw movwf movlw movwf bcf PORTB STATUS,RP0 TRISB b'00011111' TRISA b'00000111' OPTION_REG STATUS,RP0

;Repone el TMR0 con 195 ;Retorno de interrupcin ;Borra los latch de salida ;Selecciona banco 1 ;Puerta B se configura como salida ;Puerta A se configura como entrada ;Preescaler de 256 para el TMR0 ;Selecciona banco 0

;El TMR0 se incrementa cada 1 uS. Si se emplea un preescaler de 256, deber sufrir 195 ;incrementos para provocar una interrupcin cada 50000 uS (50 mS). Si esta se repite 5

;veces, el tiempo total transcurrido es de 250000 uS (250 mS). El complemento del valor ;195 en hex. es 0x3c. movlw movwf movlw movwf movlw movwf Loop clrwdt btfsc goto bcf goto RA0_ES_1 TEST_RB1 0x3c TMR0 0x05 Contador b'10100000' INTCON

;Carga el TMR0 con 195 ;N de veces a repetir la interrupcin ;Activa la interrupcin del TMR0

RA1_ES_1

;Refresca el WDT PORTA,0 ;Testea el estado de RA0 RA0_ES_1 PORTB,0 ;Desactiva RB0 TEST_RB1 bsf PORTB,0 ;Activa RB0 btfsc PORTA,1 ;Testea el estado de RA1 goto RA1_ES_1 bcf PORTB,1 ;Desactiva RB1 goto Loop bsf PORTB,1 ;Activa RB1 goto Loop

end

;Fin del programa fuente

EJEMPLO 33: ;El modo "sleep" y el "despertar mediante el watch-dog Timer (WDT) ; ;Este ejemplo pretende mostrar el empleo de la instruccin SLEEP para poner al PIC en el ;modo stand by de bajo consumo. El despertar del mismo se producir cada vez que el WDT rebase. ;En ese momento se producir un incremento del valor de la puerta B que actuar como contador ;binario y nuevamente se volver a la situacin de stand by. ; ;El preescaler se asociar al WDT y estar comprendido entre 1 y 128, dependiendo del estado ;lgico de los interruptores RA0-RA2. ; ;El valor nominal del WDT es de 18mS. Es decir, con un preescaler de 1, el pic "despertar" ;cada 18mS, con un preescaler de 128, lo har cada 2,3 segundos.

List p=16F84 include "P16F84.INC" org goto org Inicio clrf bsf clrf movlw movwf movlw movwf bcf 0x00 Inicio 0x05 PORTB STATUS,RP0 TRISB b'00011111' TRISA b'00001000' OPTION_REG STATUS,RP0

;Tipo de procesador ;Definiciones de registros internos ;Vector de Reset ;Salva vector de interrupcin ;Borra los latch de salida ;Selecciona banco 1 ;Puerta B se configura como salida ;RA0-RA4 entradas ;Preescaler de 1 para el WDT ;Selecciona banco 0

Loop

sleep incf movf andlw iorlw bsf movwf bcf goto end PORTB,F PORTA,W b'00000111' b'00001000' STATUS,RP0 OPTION_REG STATUS,RP0 Loop

;Modo Standby ;Incrementa el contador binario sobre la puerta B ;Lee el estado de los interruptores RA0-RA2 ;Selecciona el banco 1 ;Ajusta valor del preescaler ;Selecciona el banco 1 ;Volver al modo Stand by ;Fin del programa fuente

EJEMPLO 34: ;despertar del modo SLEEP mediante interrupcin RB0. ; ;La interrupcin se produce con el flanco descendente de RB0. RB0 est conectada, mediante ;la tecla 1, con RB4. A RB4 se le configura como salida a nivel "0". RB0 se configura como ;entrada con carga Pull-UP. Si la tecla est sin pulsar (abierta), RB0 permanecer a "1". ;Cuando se pulsa la tecla RB0 pasar a "0" provocndose la interrupcin que finalizar el ;modo SLEEP de bajo consumo. ; ;El programa de tratamiento de la interrupcin provoca el encendido del led conectado a RB7 ;durante 1 segundo para luego desconectarlo y volver al modo SLEEP. ; ;Se recomienda poner el WDT en OFF para que no sea l quien provoque el Wake-Up y ; desconectar el LCD mediante el jumper J6 para que no interfiera con la lnea RB0. List p=16F84 include "P16F84.INC" Key_var Delay_Cont equ equ org goto org goto 0x0c 0x12 0x00 Inicio 0x04 Interrupcion ;Tipo de procesador ;Definiciones de registros internos ;Inicio de las variables del teclado ;Variable de temporizacin ;Vector de reset ;Vector de interrupcin

include "TECLADO.INC" ;Incluir rutinas de manejo del teclado ;********************************************************************************* ;Delay_var: Esta rutina de propsito general realiza una temporizacin variable ;entre 50 mS y 12.8". Se emplea un preescaler de 256 y al TMR0 se le carga con 195. ;La velocidad de trabajo es de 4Mhz y por tanto el TMR0 se incrementa cada uS. De ;esta forma, el TMR0 debe contar 195 eventos que, con un preescaler de 256 hace una ;intervalo total de 50000 uS/50 mS (195 * 256). El valor 195 hay que expresarlo ;en Hex. (c3) y como el TMR0 es ascendente habr que cargar su complemento (3C hex.) ;Dicho intervalo de 50 mS se repite tantes veces como indique la variable "Delay_cont", ;es por ello que el delay mnimo es de 50 mS ("Delay_cont=1) y el mxima de 12.8" ;(Delay_cont=255). Delay_var: bcf INTCON,T0IF movlw 0x3c ;Desconecta el flag de rebosamiento ;Complemento hex. de 195

Intervalo

movwf clrwdt btfss goto decfsz goto return

TMR0 INTCON,T0IF Intervalo Delay_Cont,F Delay_var

;carga el TMR0 ;Refrescar el WDT ;Rebasamiento del TMR0 ?? ;Todava no ;Decrementa contador de intervalos ;Repite el intervalo de 50 mS

;************************************************************************************ ;Tratamiento de la interrupcin que se provoca cada vez que en RB0 se detecta un flanco ;ascendente como consecuencia de haber pulsado la tecla 1 Interrupcion: bcf bsf movlw movwf call bcf btfss goto retfie INTCON,INTF PORTB,7 .20 Delay_Cont Delay_var PORTB,7 PORTB,0 Es_0 ;Desactiva flag INTF ;Activa la salida RB7

Es_0

;Temporiza 1 segundo ;Desactiva RB7 ;Espera que RB0 pase a "1" (tecla abierta) ;Fin de interrupcin

;************************************************************************************ ;Programa Principal Inicio: clrf bsf movlw movwf movlw movwf bcf movlw movwf sleep nop goto end PORTB STATUS,RP0 b'00000111' OPTION_REG b'00001111' TRISB STATUS,RP0 b'10010000' INTCON ;Borra salidas ;Selecciona pgina 1 de datos ;Cargas Pull-Up activadas,RB0 sensible al descendente ;y el preescaler de 256 asignado al WDT ;RB7-RB4 salidas, RB3-RB0 entradas ;Selecciona pgina 0 de datos ;Activa interrupcin RB0 ;Puesta en stand by de bajo consumo ;Wake-Up Loop ;Fin del programa fuente

Loop

EJEMPLO 35: ;Programa para realizar el apagado y encendido de un LED colocado en ;el Puerto A0 basado en la interrupcin externa INT (RB0) ; list p=16F84 status equ 0x03 porta equ 0x05 portb equ 0x06 intcon equ 0x0B optionr equ 0x81 trisa equ 0x85 trisb equ 0x86 #define LED porta,0 #define BANK1 bsf status,5 #define BANK0 bcf status,5 org 000h ;Indica al ensamblador la direccin de memoria ;de la siguiente instruccin

goto org

Inicio 004h

;Indica al ensamblador la direccin de memoria ; de la siguiente instruccin

Interrupcion btfss intcon,1 ;es interrupcin INT? retfie ;retorna de interrupcin y GIE=1 btfsc porta,0 ;probar estado actual del LED goto Prender ;va a encender el LED Apagar bsf porta,0 ;apaga el LED goto Espera Prender bcf porta,0 ;enciende el LED Espera btfss portb,0 ;espera a que se suelte el pulsador goto Espera bcf intcon,1 ;borra bandera INT retfie ;retorna de interrupcin y GIE=1 ;Programa principal Inicio BANK1 ;seleccin del banco 1 bcf trisa,0 ;selecciona porta,0 como salida BANK0 ;seleccin de banco 0 bsf porta,0 ;apagar LED ;programacin de interrupcin bsf intcon,4 ;activar interrupcin INT BANK1 ;seleccin banco 1 bcf optionr,6 ;seleccin del flanco de bajada en el pin INT BANK0 bsf intcon,7 ;Habilitar interrupciones globales goto $ ;queda a la espera de interrupcin end El smbolo $ significa la direccin de memoria de programa en donde se encuentra ste (ciclo infinito de espera) Debe notarse la ubicacin de la rutina de interrupcin a partir de la posicin de memoria de programa 004h.

EJEMPLO 36: ;Introduccin al manejo del teclado. ; ;Haciendo uso de las rutinas incluidas en el fichero TECLADO.INC, se ;trata de leer el teclado y, visualizar sobre los leds de la puerta B ;el cdigo binario de la tecla pulsada. La visualizacin se mantiene ;estable durante dos segundos hasta una nueva pulsacin. ; ;Se trata de un ejemplo en el que la Puerta B se reconfigura ;dinmicamente. Inicialmente es configurada como salida para ;presentacin del resultado. Posteriormente, la rutina de exploracin ;del teclado reconfigura RB0-RB3 como entradas y RB4-RB7 como salidas. List p=16F84 Include "P16F84.INC" Key_var Delay_Cont equ equ org goto org 0x12 0x00 Inicio 0x05 0x0c ;Tipo de procesador ;Definiciones de registros internos

;Inicio de las variables de manejo ;del teclado ;Variable para la temporizacin ;Vector de Reset ;Salva vector de interrupcin

include "TECLADO.INC"

;Incluye rutinas de manejo del ;teclado

;********************************************************************* ;Delay_var: Esta rutina de propsito general realiza una temporizacin ;variable entre 50 mS y 12.8". Se emplea un preescaler de 256 y al -;TMR0 se le carga con 195. La velocidad de trabajo es de 4Mhz y por -;tanto el TMR0 se incrementa cada uS. De esta forma, el TMR0 debe -;contar 195 eventos que, con un preescaler de 256 hace un intervalo ;total de 50000 uS/50 mS (195 * 256). El valor 195 hay que expresarlo ;en Hex. (c3) y como el TMR0 es ascendente habr que cargar su ;complemento (3C hex.) ;Dicho intervalo de 50 mS se repite tantes veces como indique la ;variable "Delay_cont", es por ello que el delay mnimo es de 50 ;mS("Delay_cont=1) y el mxima de 12.8" (Delay_cont=255). Delay_var: Intervalo bcf INTCON,T0IF ;Desconecta el flag de rebosamiento movlw 0x3c ;Complemento hex. de 195 movwf TMR0 ;carga el TMR0 clrwdt ;Refrescar el WDT btfss INTCON,T0IF ;Rebasamiento del TMR0 ?? goto Intervalo ;Todava no decfsz Delay_Cont,F ;Decrementa contador de intervalos goto Delay_var ;Repite el intervalo de 50 mS return clrf bsf clrf PORTB STATUS,RP0 TRISB ;Borra los latch de salida ;Selecciona banco 1 ;Puerta B se configura como salida

Inicio

movlw b'00000111' movwf OPTION_REG ;Preescaler de 256 para el TMR0 bcf STATUS,RP0 ;Selecciona banco 0 Loop clrwdt call Key_Scan movlw 0x80 subwf Tecla,W btfsc STATUS,Z goto Loop movf movwf movlw movwf call clrf goto end Tecla,W PORTB .40 Delay_Cont Delay_var PORTB Loop ;Refresco del WDT ;Explora el teclado ;Hay alguna pulsada ?? ;No ;Lee el cdigo de la tecla pulsada ;Lo visualiza sobre leds de la Puerta B ;Temporiza 2 segundos ;Desactiva visualizacin ;Fin del programa fuente

EJEMPLO 37: ;El teclado y el LCD. ; ;Haciendo uso de las rutinas incluidas en los ficheros TECLADO.INC y ;LCD_CXX.INC, se trata de leer el teclado y, visualizar sobre el ;mdulo LCD el cdigo hex. de la tecla pulsada. ;

;El ejemplo pretende mostrar cmo es posible gobernar dos perifricos ;distintos conectados a la misma puerta (LCD y teclado). Para ello ;basta reprogramarla dinmicamente en el tiempo segn sea necesario. List p=16F84 include "P16F84.INC" Lcd_var Key_var Temporal_1 Temporal_2 equ equ org goto org equ equ 0x13 0x14 0x00 Inicio 0x05 0x0c 0x0e ;Tipo de procesador ;Definiciones de registros internos ;Inicio de las variables para el LCD ;Inicio de las variables del teclado ;Variable temporal n 1 ;Variable temporal n 2 ;Vector de reset ;Salva vector de interrupcin ;Incluir rutinas de manejo del LCD ;Incluir rutinas de manejo del tec. ;Desplazamiento sobre la tabla

include "LCD_CXX.INC" include "TECLADO.INC" Tabla_Mensajes: Mens_0 dt movwf PCL

equ $ ;Mens_0 apunta al primer carcter "Se ha pulsado: ",0x00

;********************************************************************* ;Mensaje: Esta rutina visualiza en el LCD el mensaje cuyo inicio est ; indicado en el acumulador. El fin de un mensaje se determina ;mediante el cdigo 0x00 Mensaje Mensaje_1 movwf movf call movwf movf btfss goto return No_es_ultimo call incf goto Inicio: Temporal_1 Temporal_1,W Tabla_Mensajes Temporal_2 Temporal_2,F STATUS,Z No_es_ultimo LCD_DATO Temporal_1,F Mensaje_1 ;Salva posicin de la tabla ;Recupera posicin de la tabla ;Busca caracter de salida ;Guarda el caracter ;Mira si es el ltimo ;Visualiza en el LCD ;Siguiente caracter ;Selecciona pgina 1 de datos ;Preescalr de 128 asignado al WDT ;Desconectar interrupciones ;Selecciona pgina 0 de datos ;Refrescar WDT ;Configura Puerta A y B como ;salidas ;Rutina de inicializacin del LCD ;LCD en ON ;Borra LCD y HOME

bsf STATUS,RP0 movlw b'00001111' movwf OPTION_REG bcf INTCON,GIE bcf STATUS,RP0 clrwdt call call movlw call movlw call UP_LCD LCD_INI b'00001100' LCD_REG b'00000001' LCD_REG

;Salida del mensaje "Tecla pulsada:" movlw Mens_0 call Mensaje ;Visualiza el mensaje

;Bucle principal Loop: clrwdt call Key_Scan movlw 0x80 subwf Tecla,W btfsc STATUS,Z goto Loop call movlw call movf sublw btfss goto movf addlw call goto Key_BCD 0x8f LCD_REG Tecla,W .9 STATUS,C Mayor_que_9 Tecla,W 0x30 LCD_DATO Loop ;Refrescar el WDT ;Explora el teclado ;Hay alguna pulsada ? ;No, seguir explorando ;Convierte cdigo de tecla a cdigo BCD ;Posiciona el cursor del LCD ;Es mayor que 9 (A, B,C,D,E,F)? ;Si ;No ;Ajuste ASCII de los caracteres del ;0 al 9 ;Visualizar sobre el LCD

Mayor_que_9 movf Tecla,W addlw 0x37 call goto end EJEMPLO 38: LCD_DATO Loop

;Ajuste ASCII de los caracteres de ;la A a la F ;Visualiza sobre el LCD ;Fin del programa fuente

;visualizar sobre el LCD, las teclas segn se van pulsando. ; ;El ejemplo pretende mostrar cmo es posible gobernar dos perifricos ;distintos conectados a la misma puerta (LCD y teclado). Para ello ;basta reprogramarla dinmicamente en el tiempo segn sea necesario. List p=16F84 Include "P16F84.INC" Lcd_var Key_var Contador_C Contador_L equ equ org goto org equ equ 0x14 0x15 0x00 Inicio 0x05 0x0c 0x0e ;Tipo de procesador ;Definiciones de registros internos ;Inicio de las variables para el LCD ;Inicio de las variables del tec. ;Contador de caracteres ;Contador de lneas ;Vector de reset ;Salva vector de interrupcin

include include Inicio:

"LCD_CXX.INC" ;Incluir rutinas de manejo ;del LCD "TECLADO.INC" ;Incluir rutinas de manejo ;del teclado

bsf STATUS,RP0 ;Selecciona pgina 1 de datos movlw b'00001111' movwf OPTION_REG ;Preescaler de 128 asignado al WDT

bcf INTCON,GIE bcf STATUS,RP0 clrwdt call call movlw call movlw call movlw movwf movlw movwf UP_LCD LCD_INI b'00001110' LCD_REG b'00000001' LCD_REG .2 Contador_L .16 Contador_C

;Desconectar interrupciones ;Selecciona pgina 0 de datos ;Refrescar WDT ;Configura Puerta A y B como salidas ;Rutina de inicializacin del LCD ;LCD en ON, cursor ON ;Borra LCD y HOME ;Inicia contador de lneas ;Inicia contador de caracteres ;Refrescar el WDT ;Explora el teclado ;Hay alguna pulsada ? ;No, seguir explorando ;Convierte cdigo de tecla a cdigo BCD

Borra_LCD Inicia_L Inicia_C Loop:

clrwdt call Key_Scan movlw 0x80 subwf Tecla,W btfsc STATUS,Z goto Loop call movf sublw btfss goto movf addlw goto Key_BCD Tecla,W .9 STATUS,C Mayor_que_9 Tecla,W 0x30 Visualiza

;Es mayor que 9 (A, B, C, D, E, F)? ;Si ;No ;Ajuste ASCII de caracteres del 0 al 9

Mayor_que_9 movf Tecla,W addlw 0x37 Visualiza call LCD_DATO

;Ajuste ASCII de caracteres de A a F ;Visualiza sobre el LCD

;Es necesario esperar que se libere la tecla pulsada, de lo contrario ;la visualizacin de esta se repetira varias veces. Se puede omprobar ;su efecto si se anulan las 5 instrucciones que vienen a continuacin. Tecla_pulsada movlw subwf btfss goto call Key_Scan 0x80 Tecla,F STATUS,Z Tecla_pulsada ;Explora el teclado ;Se ha liberado ?? ;Todava no ;Se han imprimido 16 caracteres ?? ;No

decfsz Contador_C,F goto Loop movlw 0xc0 call LCD_REG

;Si posiciona cursor en la ;siguiente lnea decfsz Contador_L,F ;Se han imprimido 2 lneas ?? goto Inicia_C ;No, se imprimen otros 16 caract. goto Borra_LCD ;Si, se inicia el LCD end ;Fin del programa fuente

EJEMPLO 39: ;Mdulo LCD Serial: este mdulo muestra mensajes en una pantalla de cristal lquido tipo HD44100H o ;similar, enviados desde una computadora a travs del puerto serial RS-232. LIST P=16f84 STATUS RP0 TRISA TRISB PORTA PORTB CARRY DX DR BAUD_3 BAUD_2 BAUD_1 BAUD_X BAUD_4 BAUD_Y W F MSB ADCON1 EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU EQU 3 5 5 6 5 6 0 4 0 .15 .31 .32 .31 .40 .31 0 1 7 8

ORG 0XC contador RES 1 contador2 RES 1 contador3 RES 1 COUNT1 res 1 COUNT2 res 1 ;dato res 1 REG res 1 reg1 RES 1 reg2 RES 1 cont RES 1 cont2 RES 1 TEMP RES 1 RETCUENTA RES 1 RETCUENTA2 RES 1 RETCUENTA4 RES 1 RETCUENTA3 RES 1 cont3 res 1 ORG 0 CLRF CLRF BSF MOVLW MOVWF MOVLW MOVWF BCF PORTA PORTB STATUS,RP0 B'10100' TRISA B'00000000' TRISB STATUS,RP0 ; BANCO 1 ; puerto A como entrada ; puerto B como salida ; BANCO 0

;INICIALIZACION DE LA PANTALLA BCF BCF MOVLW MOVWF CALL CALL MOVLW MOVWF CALL CALL MOVLW MOVWF CALL CALL PORTA,0 PORTA,1 B'00110000' PORTB PULSO DELAY_4 B'00000110' PORTB PULSO DELAY_4 B'00001110' PORTB PULSO DELAY_4 ; RS EN CERO ; E EN CERO ; ESTABLECE QUE LA PANTALLA ES DE DOS LINEAS.

; PARA INCREMENTAR LA DIRECCION DEL CUSOR

; SELECCIONA OPERACION 8 BITS

movlw .17 movwf cont3 INICIO BTFSC PORTA,2 GOTO INICIO CALL RECEP decfsz cont3,1 goto salto1 MOVLW MOVWF CALL CALL salto1 BSF MOVF MOVWF CALL BCF GOTO B'00000111' PORTB PULSO DELAY_4 PORTA,1 REG,0 PORTB PULSO PORTA,1 INICIO ;ENVIA PULSO DE STROBO ; PARA INCREMENTAR LA DIRECCION DEL CUSOR ;LA COMUNICACION SERIAL LLEGA POR PIN RA0

;ENVIA EL DATO

PULSO BSF PORTA,0 CALL DELAY_4 BCF PORTA,0 RETURN

;**********RUTINA DE RECEPCION******* RECEP CLRF CALL MOVLW MOVWF BCF RRF REG DELAY_4 8 COUNT2 STATUS,CARRY REG,F ;COMIENZA LA RECEPCION

R_NEXT

BTFSC BSF CALL DECFSZ GOTO MOVF MOVWF CLRW RETURN

PORTA,2 REG,MSB DELAY_Y COUNT2,F R_NEXT REG,W TEMP

DELAY_Y DELAY_4 SAVE2 REDO_A

MOVLW GOTO MOVLW GOTO MOVWF DECFSZ GOTO RETLW END

BAUD_Y SAVE2 BAUD_4 SAVE2 RETCUENTA2 RETCUENTA2,F REDO_A 0

EJEMPLO 40: ;El manejo de la pantalla LCD ; ;Este ejemplo pretende introducirnos en el manejo de la pantalla LCD, ;para la visualizacin de diferentes mensajes (p.e. Hola). ; ;Debe recordarse que las lneas RA0-RA2 actan ahora como salida de ;seales de control hacia el LCD. Al estar conectadas con sendos ;interruptores, estos deben estar a nivel lgico "1" permanentemente. List p=16F84 Include "P16F84.INC" Lcd_var org goto org equ ;Tipo de procesador ;Definiciones de registros internos

0x0c ;Variables (2) de las rutinas de manejo ;DEL LCD ;Vector de Reset ;Salva vector de interrupcin

0x00 Inicio 0x05

include "LCD_Cxx.inc" ;Incluye las rutinas de manejo d ;del LCD Inicio clrf bsf clrf movlw movwf bcf PORTB STATUS,RP0 TRISB b'00011000' TRISA STATUS,RP0 ;Borra los latch de salida ;Selecciona banco 1 ;Puerta B se configura como salida ;RA0-RA2 salidas, RA3-RA4 entradas ;Selecciona banco 0

call LCD_INI ;Secuencia de inicio del LCD movlw b'00001111' call LCD_REG ;Enva instruccin: LCD ON, Cursor ON y ;blink ON

movlw call movlw call movlw call movlw call movlw call Loop

'H' LCD_DATO 'o' LCD_DATO 'l' LCD_DATO 'a' LCD_DATO ' ' LCD_DATO

;Visualiza H ;Visualiza o ;Visualiza l ;Visualiza a ;Visualiza blanco ;Puesta en Standby ;Vuelta a standby ;Fin del programa fuente

sleep goto Loop end

EJEMPLO 41: ;Este ejemplo pretende introducirnos en el manejo de la pantalla LCD, para la visualizacin de diferentes mensajes. ; ;Debe recordarse que las lneas RA0-RA2 actan ahora como salida de ;seales de control hacia el LCD. Al estar conectadas con sendos ;interruptores, estos deben estar a nivel lgico "1" permanentemente. List p=16F84 include "P16F84.INC" Lcd_var LCD Delay_Cont Temporal_1 Temporal_2 equ equ equ equ org goto org 0x0e 0x0f 0x10 0x00 Inicio 0x05 0x0c ;Tipo de procesador ;Definiciones de registros internos ;Variables (2) de las rutinas de manejo del ;Variable para la temporizacin ;Variable temporal ;Variable temporal ;Vector de Reset ;Salva vector de interrupcin ;Incluye las rutinas de manejo del LCD

include "LCD_Cxx.inc"

;********************************************************************* ;Segn el valor contenido en el registro W, se devuelve el carcter a ;visualizar Tabla_Mensajes Mens_0 equ retlw retlw retlw retlw retlw equ movwf PCL $ 'H' 'o' 'l' 'a' 0x00 $ ;Calcula el desplazamiento sobre la tabla ;Mens_0 apunta al primer carcter del mensaje 0

;Ultimo carcter del mensaje 0 ;Mens_1 apunta al primer carcter del :mensaje 1

Mens_1

retlw 'A' retlw 'd' retlw 'i'

retlw 'o' retlw 's' retlw 0x00

;Ultimo carcter del mensaje 1

;********************************************************************* ;Delay_var: Esta rutina de propsito general realiza una temporizacin ;variable entre 50 mS y 12.8". Se emplea un preescaler de 256 y al ;TMR0 se le carga con 195. La velocidad de trabajo es de 4Mhz y por ;tanto el TMR0 se incrementa cada uS. De esta forma, el TMR0 debe ;contar 195 eventos que, con un preescaler de 256 hace una intervalo ;total de 50000 uS/50 mS (195 * 256). El valor 195 hay que expresarlo ;en Hex. (c3) y como el TMR0 es ascendente habr que cargar su ;complemento (3C hex.) ;Dicho intervalo de 50 mS se repite tantes veces como indique la ;variable "Delay_cont", es por ello que el delay mnimo es de 50 ;mS("Delay_cont=1) y el mxima de 12.8" (Delay_cont=255). Delay_var: Intervalo bcf INTCON,T0IF ;Desconecta el flag de rebosamiento movlw 0x3c ;Complemento hex. de 195 movwf TMR0 ;carga el TMR0 clrwdt ;Refrescar el WDT btfss INTCON,T0IF ;Rebasamiento del TMR0 ?? goto Intervalo ;Todava no decfsz Delay_Cont,F ;Decrementa contador de intervalos goto Delay_var ;Repite el intervalo de 50 mS return

;********************************************************************* ;Mensaje: Esta rutina visualiza en el LCD el mensaje cuyo inicio est ;indicado en el acumulador. El fin de un mensaje se determina mediante ;el cdigo 0x00 Mensaje Mensaje_1 movwf movf call movwf movf btfss goto return call incf goto Temporal_1 Temporal_1,W Tabla_Mensajes Temporal_2 Temporal_2,F STATUS,Z No_es_ultimo LCD_DATO Temporal_1,F Mensaje_1 ;Salva posicin de la tabla ;Recupera posicin de la tabla ;Busca carcter de salida ;Guarda el carcter ;Mira si es el ltimo ;Visualiza en el LCD ;Siguiente carcter

No_es_ultimo

;********************************************************************* ; Inicio clrf PORTB ;Borra los latch de salida bsf STATUS,RP0 ;Selecciona banco 1 clrf TRISB ;Puerta B se configura como salida movlw b'00011000' movwf TRISA ;RA0-RA2 salidas, RA3-RA4 entradas movlw b'00000111' movwf OPTION_REG ;Preescaler de 256 para el TMR0 bcf STATUS,RP0 ;Selecciona banco 0 call LCD_INI ;Secuencia de inicio del LCD movlw b'00001100' call LCD_REG ;Enva instruccin: LCD ON, Cursor OFF y ;blink OFF Loop movlw b'00000001'

call movlw call movlw movwf call movlw call movlw call movlw movwf call goto end

LCD_REG ;Borra LCD ;posicin). Mens_0 Mensaje ;Visualiza .20 Delay_Cont Delay_var ;Temporiza b'00000001' LCD_REG ;Borra LCD ;posicin). Mens_1 Mensaje ;Visualiza .20 Delay_Cont Delay_var ;Temporiza Loop

y Home (colocar cursor en 1 el mensaje 0 2 segundos y Home (colocar cursor en 1 el mensaje 1 2 segundos

;Fin del programa fuente

EJEMPLO 42: ;visualizacin de diferentes mensajes. ; ;Debe recordarse que las lneas RA0-RA2 actan ahora como salida de ;seales de control hacia el LCD. Al estar conectadas con sendos ;interruptores, estos deben estar a nivel lgico "1" permanentemente. List p=16F84 Include "P16F84.INC" Lcd_var Delay_Cont Temporal_1 Temporal_2 equ equ equ equ org goto org 0x0c 0x0e 0x0f 0x10 0x00 Inicio 0x05 ;Tipo de procesador ;Definiciones de registros internos

;Variables (2) de las rutinas de ;manejo del LCD ;Variable para la temporizacin ;Variable temporal ;Variable temporal ;Vector de Reset ;Salva vector de interrupcin ;Incluye rutinas de manejo del LCD

include "LCD_Cxx.inc"

;************************************************************************ ;Segn el valor contenido en el registro W, se devuelve el carcter a ;visualizar Tabla_Mensajes ;Calcula el desplazamiento sobre la ;tabla ;********************************************************************* ;La directiva dt genera tantas intsrucciones retlw como bytes o ;caracteres contenga Mens_0 dt Mens_1 dt equ ;Mens_0 apunta al primer carcter ;del mensaje 0 "CursoPIC16F84",0x00 ;Mens_1 apunta al primer carcter ;del mensaje 1 "ForoLaResistencia",0x00 $ $ movwf PCL

equ

Mens_2 dt Mens_3 dt

equ

;Mens_2 apunta al primer carcter ;del mensaje 2 "enEzboard",0x00 $

equ

;Mens_3 apunta al primer carcter del ;mensaje 3 "Internet",0x00

;********************************************************************* ;Delay_var: Esta rutina de propsito general realiza una temporizacin ;variable entre 50 mS y 12.8". Se emplea un preescaler de 256 y al ;TMR0 se le carga con 195. La velocidad de trabajo es de 4Mhz y por ;tanto el TMR0 se incrementa cada uS. De esta forma, el TMR0 debe ;contar 195 eventos que, con un preescaler de 256 hace una intervalo ;total de 50000 uS/50 mS (195 * 256). El valor 195 hay que expresarlo ;en Hex. (c3) y como el TMR0 es ascendente habr que cargar su ;complemento (3C hex.) ;Dicho intervalo de 50 mS se repite tantes veces como indique la ;variable "Delay_cont", es por ello que el delay mnimo es de 50 ;mS("Delay_cont=1) y el mxima de 12.8" (Delay_cont=255). Delay_var: Intervalo bcf INTCON,T0IF ;Desconecta el flag de rebosamiento movlw 0x3c ;Complemento hex. de 195 movwf TMR0 ;carga el TMR0 clrwdt ;Refrescar el WDT btfss INTCON,T0IF ;Rebasamiento del TMR0 ?? goto Intervalo ;Todava no decfsz Delay_Cont,F ;Decrementa contador de intervalos goto Delay_var ;Repite el intervalo de 50 mS return

;********************************************************************* ;Mensaje: Esta rutina visualiza en el LCD el mensaje cuyo inicio est ;indicado en el acumulador. El fin de un mensaje se determina mediante ;el cdigo 0x00 Mensaje Mensaje_1 movwf movf call movwf movf btfss goto return call incf goto Temporal_1 Temporal_1,W Tabla_Mensajes Temporal_2 Temporal_2,F STATUS,Z No_es_ultimo LCD_DATO Temporal_1,F Mensaje_1 ;Salva posicin de la tabla ;Recupera posicin de la tabla ;Busca caracter de salida ;Guarda el caracter ;Mira si es el ltimo ;Visualiza en el LCD ;Siguiente caracter

No_es_ultimo

;********************************************************************* Inicio clrf bsf clrf movlw movwf PORTB STATUS,RP0 TRISB b'00011000' TRISA ;Borra los latch de salida ;Selecciona banco 1 ;Puerta B se configura como salida ;RA0-RA2 salidas, RA3-RA4 entradas

movlw b'00000111' movwf OPTION_REG ;Preescaler de 256 para el TMR0 bcf STATUS,RP0 ;Selecciona banco 0 call LCD_INI ;Secuencia de inicio del LCD movlw b'00001100'

call Loop

LCD_REG ;Enva instruccin: LCD ON, Cursor OFF y ;blink OFF

movlw b'00000001' call LCD_REG ;Borra LCD y Home (colocar cursor en 1 ;posicin) movlw Mens_0 call Mensaje ;Visualiza el mensaje 0 movlw b'11000101' call LCD_REG ;Coloca cursor en 2 fila del LCD movlw Mens_1 call Mensaje ;Visualiza mensaje 1 movlw .40 movwf Delay_Cont call Delay_var ;Temporiza 4 segundos movlw b'00000001' call LCD_REG ;Borra LCD y Home (colocar cursor en 1 ;posicin) movlw Mens_2 call Mensaje ;Visualiza el mensaje 2 movlw b'11000010' call LCD_REG ;Coloca cursor en 2 fila del LCD movlw Mens_3 call Mensaje ;Visualiza el mensaje 3 movlw .40 movwf Delay_Cont call Delay_var ;Temporiza 4 segundos goto Loop end ;Fin del programa fuente

EJEMPLO 43: ;Generador de mensajes. ; ;Este ejemplo pretende realizar un generador de mensajes para el LCD. ;Con RA4 a "1", el sistema est en el modo de programacin. En este ;modo el mensaje se graba en la EEPROM de datos. Con RA4 a "0" ;entramos en el modo de reproduccin. El mensaje grabado en la EEPROM ;se visualiza sobre el LCD. ; ;Cuando el interruptor RA3 est a nivel "1", en la posicin actual del ;cursor van apareciendo secuencialmente los distintos caracteres ;disponibles. Al ponerlo a "0" se selecciona el actual y se graba en ;la EEPROM. Al pasar nuevamente a "1" se selecciona el siguiente ;carcter. ; ;Debe recordarse que las lneas RA0-RA2 actan ahora como salida de ;seales de control hacia el LCD. Al estar conectadas con sendos ;interruptores, estos deben estar a nivel lgico "1" permanentemente. List p=16F84 Include "P16F84.INC" Lcd_var Delay_Cont Temporal_1 Temporal_2 Cur_Pos equ equ equ equ org 0x0c 0x0e 0x0f 0x10 equ 0x00 ;Tipo de procesador ;Definiciones de registros internos

;Variables (2) de las rutinas de ;manejo del LCD ;Variable para la temporizacin ;Variable temporal ;Variable temporal 0x11 ;Posicin del cursor ;Vector de Reset

goto org

Inicio 0x05

;Salva vector de interrupcin ;Incluye las rutinas de manejo LCD

include "LCD_Cxx.inc"

;********************************************************************* ;Delay_20_ms: Esta rutina de temporizacin tiene por objeto eliminar ;el "efecto rebote" de los perifricos electromecnicos. Realiza un ;delay de 20 mS. Si el PIC trabaja a una frecuencia de 4MHz, el TMR0 ;evoluciona cada uS. Si queremos temporizar 20000 uS (20 mS) con un ;preescaler de 128, el TMR0 deber contar 156 eventos (156 * 128). El ;valor 156 equivale a 9c hex. y como el TMR0 es ascedente habr que ;cargar su complemento a 1 (63 hex.). Delay_20_ms bcf INTCON,T0IF ;Desconecta el flag de rebosamiento movlw 0x63 ;Complemento hex. de 156 movwf TMR0 ;carga el TMR0 Delay_20_ms_1 clrwdt ;Refrescar el WDT btfss INTCON,T0IF ;Rebasamiento del TMR0 ?? goto Delay_20_ms_1 ;Todava no bcf INTCON,T0IF ;Ahora si, reponer el flag return ;********************************************************************* ;Delay_var: Esta rutina de propsito general realiza una temporizacin ;variable entre 50 mS y 12.8". Se emplea un preescaler de 256 y al ;TMR0 se le carga con 195. La velocidad de trabajo es de 4Mhz y por ;tanto el TMR0 se incrementa cada uS. De esta forma, el TMR0 debe ;contar 195 eventos que, con un preescaler de 256 hace un intervalo ;total de 50000 uS/50 mS (195 * 256). El valor 195 hay que expresarlo ;en Hex. (c3) y como el TMR0 es ascendente habr que cargar su ;complemento (3C hex.) ;Dicho intervalo de 50 mS se repite tantas veces como indique la ;variable "Delay_cont", es por ello que el delay mnimo es de 50 ;mS("Delay_cont=1) y el mxima de 12.8" (Delay_cont=255). Delay_var: Intervalo bcf INTCON,T0IF ;Desconecta el flag de rebosamiento movlw 0x3c ;Complemento hex. de 195 movwf TMR0 ;carga el TMR0 clrwdt ;Refrescar el WDT btfss INTCON,T0IF ;Rebasamiento del TMR0 ?? goto Intervalo ;Todava no decfsz Delay_Cont,F ;Decrementa contador de intervalos goto Delay_var ;Repite el intervalo de 50 mS return

;********************************************************************* ;EE_Write: Graba un byte en la EEPROM de datos. La direccin ser la ;contenida en EEADR y el dato se le supone previamente metido en ;EEDATA EE_Write bsf bsf movlw movwf movlw movwf bsf bcf btfss goto bcf bcf return STATUS,RP0 ;Selecciona banco 1 EECON1,WREN ;Permiso de escritura b'01010101' EECON2 b'10101010' EECON2 ;Secuencia establecida por Microchip EECON1,WR ;Orden de escritura EECON1,WREN ;Desconecta permiso de escritura EECON1,EEIF ;Testear flag de fin de escritura Wait EECON1,EEIF ;Reponer flag de fin de escritura STATUS,RP0 ;Seleccin banco 0

Wait

;********************************************************************* ;EE_Read: Leer un byte de la EEPROM. Se supone al registro EEADR ;cargado con la direccin a leer. En EEDATA aparecer el dato ledo. EE_Read bsf bsf bcf return STATUS,RP0 ;Seleccin de banco 1 EECON1,RD ;Orden de lectura STATUS,RP0 ;Seleccin de banco 0

;********************************************************************* Inicio clrf PORTB ;Borra los latch de salida bsf STATUS,RP0 ;Selecciona banco 1 clrf TRISB ;Puerta B se configura como salida movlw b'00011000' movwf TRISA ;RA0-RA2 salidas, RA3-RA4 entradas movlw movwf bcf movlw movwf call movlw call movlw call clrf Loop Programar b'00000111' OPTION_REG ;Preescaler de 256 para el TMR0 STATUS,RP0 ;Selecciona banco 0 0x80 Cur_Pos ;Posicin inicial del cursor LCD_INI ;Secuencia de inicio del LCD b'00000001' LCD_REG ;Borra LCD y Home b'00001110' LCD_REG ;Enva instruccin: LCD ON, Cursor ON y ;blink OFF EEADR ;Direccin inicial de la EEPROM ;Modo programacin ?? ;No, modo de reproduccin

btfss PORTA,4 goto Reproducir

movlw movwf Programar_1 btfss goto movf call movf call movlw movwf call incf btfss goto goto Grabar

0x20 Temporal_1 ;Primer carcter ASCII PORTA,3 ;Grabar el byte en EEPROM ?? Grabar ;Si Cur_Pos,W LCD_REG ;Coloca el cursor Temporal_1,W LCD_DATO ;Visualiza el carcter .10 Delay_Cont Delay_var ;Temporiza 0.5 segundos Temporal_1,F;Siguiente carcter ASCII Temporal_1,7;Es el ltimo carcter ASCII ?? Programar_1 ;No Programar ;Si, empezar desde el primero

Grabar_1

call Delay_20_ms ;Elimina rebotes decf Temporal_1,W movwf EEDATA ;Dato a grabar en la EEPROM call EE_Write ;Graba el carcter incf EEADR,F ;Siguiente direccin EEPROM clrf EEDATA call EE_Write ;Graba 0x00 incf Cur_Pos,F ;Siguiente posicin del cursor clrwdt ;Refrescar el WDT btfss PORTA,3 ;Esperar a que RA3 vuelva a "1" goto Grabar_1 call Delay_20_ms ;Eliminar rebotes

goto Reproducir movlw call movlw call clrf

Loop

;Siguiente carcter del mensaje

b'00000001' LCD_REG ;Borra LCD y Home b'00001100' LCD_REG ;LCD = ON, cursor = OFF EEADR ;Direccin inicial EEPROM

Reproducir_0 clrwdt ;Refresco del WDT call EE_Read ;Lee carcter de la EEPROM movf EEDATA,F btfsc STATUS,Z ;Es el ltimo del mensaje ?? (0x00) goto Reproducir_1;Si movf EEDATA,W call LCD_DATO ;Visualiza el carcter incf EEADR,F ;Siguiente carcter goto Reproducir_0 Reproducir_1 movlw .40 movwf Delay_Cont call Delay_var

;Mantiene el mensaje 2 segundos

;**************************** SECUENCIA DE PARPADEO******************* Blink movlw .6 movwf Temporal_2 ;Inicia contador de parpadeos Blink_1 movlw b'00001100' call LCD_REG ;LCD en ON movlw .5 movwf Delay_Cont call Delay_var ;Temporiza 0.25 segundos movlw b'00001000' call LCD_REG ;LCD en OFF movlw .5 movwf Delay_Cont call Delay_var ;Temporiza 0.25 segundos decfsz Temporal_2,F goto Blink_1 ;Repite el parpadeo movlw .20 movwf Delay_Cont call Delay_var ;Temporiza 1 segundo goto Loop end ;Fin del programa fuente

EJEMPLO 44: ;Ejemplo para usar un LCD de 2X40 sin retroiluminacin ; ;Este programa solo pretende una introduccin sencilla para el uso de las Pantallas de LCD ;apareciendo un sencillo texto List p=16F84 include "P16F84.INC" Lcd_var equ 0x0c ;Tipo de uPIC ;Programa base de Microchip ;Posiciones para las rutinas de LCD, ojo con ocupar estas ;posiciones 0x00 Inicio 0x05 ;Vector de Reset ;Salva vector de interrupcin

org goto org

include "lcd_amr.inc" Inicio clrf bsf clrf movlw movwf bcf PORTB STATUS,RP0 TRISB b'00011000' TRISA STATUS,RP0

;Incluye las rutinas de manejo del LCD ;Borra los latch de PORTB ;Selecciona banco 1 ;Puerta B se configura como salida ;RA0-RA2 salidas, RA3-RA4 entradas ;Selecciona banco 0 ;Inicializacin del LCD ;Esta orden prepara al LCD para determinar la forma de ;la presentacin de los datos en la pantalla segn los ;datos que introduzcamos se veran los datos de una u ;otra forma. Estos datos en W ;Enva instruccin para comandos en LCD ;Dato a W ;Visualiza S ;Dato a W ;Visualiza o ;Dato a W ;Visualiza y ;Dato a W ;Visualiza " " (nada) ;Dato a W ;Visualiza y ;Dato a W ;Visualiza o ;Rutina de espera

call LCD_INI movlw b'00001111'

call movlw call movlw call movlw call movlw call movlw call movlw call Loop sleep goto end

LCD_REG 'S' LCD_DATO 'o' LCD_DATO 'y' LCD_DATO '' LCD_DATO 'y' LCD_DATO 'o' LCD_DATO

Loop

EJEMPLO 45: ;Programa para manejar la pantalla del LCD. Pone en la misma en peridos de 2 Sgd. ;las palabras Blanco/Negro ; ;Vamos a utilizar la instruccion de ensamblador "dt" (define table). Con esta orden ;se facilita la realizacion de tablas ; List p=16F84 include "P16F84.INC" Lcd_var equ Contador Temp_1 equ Temp_2 equ 0x0c equ 0x0f 0x10 org goto org ;Tipo de procesador ;Programa de Microchip

0x0e

;Variables (2) de las rutinas de manejo del LCD ;Variable para la temporizacin ;Variable temporal ;Variable temporal ;Vector de Reset ;Salva vector de interrupcin ;Incluye las rutinas del LCD

0x00 Inicio 0x05

include "lcd_amr.inc" ;-------------------------;Mensajes a visualizar

;-------------------------Mensa_jes Mensa_1 dt Mensa_2 dt movwf PCL ;Control de desplazamiento sobre la tabla

equ $ "BLANCO",0X00 equ $ "NEGRO",0X00

;El codigo 0x00 determina que es el ultimo dato ;de mensa_1

;-------------------------;Control de tiempo. Periodos de 50 mS por valor en Segun_dos ;-------------------------Tiem_po bcf INTCON,T0IF movlw b'00111100' movwf TMR0 clrwdt btfss INTCON,T0IF goto Bucle decfsz Contador,1 goto Tiem_po return ;Desconecta el flag de rebosamiento ;60 = W ;TMR0=255-60=195 ;limpia WDT ;Comprueba si flag de rebosamiento cambia ;Va reduciendo la variable por cada paso ;Vuelve a la rutina de Tiem_po

Bucle

;-------------------------;Rutina de visualizacin en el LCD ;-------------------------Mensaje movwf Temp_1 Mensaje_1 movf Temp_1,W call Mensa_jes movwf Temp_2 movf Temp_2,F btfss STATUS,Z goto No_es_ultimo return No_es_ultimo call LCD_DATO incf Temp_1,F goto Mensaje_1 ;-------------------------;Inicio general del programa ;-------------------------Inicio clrf bsf clrf movlw movwf movlw movwf bcf PORTB STATUS,RP0 TRISB b'00011000' TRISA b'00000111' OPTION_REG STATUS,RP0 ;Borra los latch de salida ;Selecciona banco 1 ;Puerta B se configura como salida ;RA0-RA2 salidas, RA3-RA4 entradas ;Preescaler de 256 para el TMR0 ;Selecciona banco 0 ;Secuencia de inicio del LCD ;Enva instruccin a modo LCD ;Salva posicin de la tabla ;Recupera posicin de la tabla ;Busca carcter de salida ;Guarda el carcter ;Mira si es el ultimo

;Visualiza en el LCD ;Siguiente carcter

call LCD_INI movlw b'00001100' call LCD_REG Loop movlw b'00000001' call LCD_REG movlw Mensa_1

;Borra LCD y Cursor a Inicio

call movlw movwf call movlw call movlw call movlw movwf call goto end

Mensaje .20 Contador Tiem_po b'00000001' LCD_REG Mensa_2 Mensaje .20 Contador Tiem_po Loop

;Visualiza el mensaje 0 ;Carga registro bucles con 20 ;Temporiza 2 segundos ;Borra LCD y Cursor a Inicio ;Visualiza el mensaje 1

;Temporiza 2 segundos

;Fin del programa fuente

EJEMPLO 46: CONVERSION DE VALORES BINARIOS A BCD Los programas por causa de los PIC de 8 bytes deben de usar valores en binario de hasta 11111111 (0xFF=255) por registro. Este programa modifica el valor obtenido y lo carga en registros que acumulan la informacion en valores limite de 11111111 (0xFF) que es el tope por registro en estos modulos de 8 bits PIC 16F84 4 Mhz El valor a convertir se encuentra en el Registro W registros previamente reservados como : REG_L EQU 0X10 REG_H EQU 0X11 TEMP1 EQU 0x14 NUM_BCD NUM_BCDA clrf clrf REG_L REG_H ;Pone el registro 0x10 a 0 ;Pone el registro 0x11 a 0

addlw 0xf6

btfss goto movwf incf movf xorlw btfss goto clrf incf NUM_BCDB movf goto

;Dado que 0xf6 es 246 en decimal el dato ;que sumes de W con 0xf6 da un registro ;de resta con 10 por suma de complemento ;a 2 en W, con Carry en ESTADO, C ESTADO,0 ;Hay Acarreo?, es decir la suma anterior ;dio un resultado superior a 255 NUM_BCDC ;No TEMP1 ;Si, mueve el valor de W a TEMP1 REG_L,1 ;Incrementa en 1 el valor de REG_L REG_H, ;Mueve el valor de REG_H a W b'00001010' ;Pasa el registro W por la mscara ; 00001010 ESTADO,2 ;Es 0 el resultado de la operacin ;control de ESTADO, Z NUM_BCDB ;No REG_L ;Si poner a cero el registro REG_H,1 ;Incrementa el valor y lo pone en REG_H ;Mueve el valor de REG_L A W ;Repite la operacin

REG_L,0 NUM_BCDA

NUM_BCDC

addlw 0x0a swapf REG_L,1 iorwf REG_L,1 return

;suma 10 al valor de W ;Intercambio de los 4 bits de menospor los ;4 de mas peso ;Se realiza la operacin lgica OR y se carga ;en W

El resultado queda en los registros REG_L Y REG_H

EJEMPLO 47: CONVERSION DE REGISTROS EN CARACTERES ASCII Los datos se suelen encontrar en uno o ms registros de 8 bits. El primero almacena una cantidad entre 0 y 255 siendo el resto de registros el indicador de medidas completas de 255 unidades que se hayan contado en el registro anterior. Segn se van contando registros con 255 unidades se suma 1 al registro siguiente. Esto es lo que se conoce como un numero BCD. Este lote de registros es el que se va a convertir en caracteres ASCII para poder ser visualizados en pantallas LCD. Esta ser la rutina: Cargar los registros de la pantalla LCD LCD_CXX.ASM

Supongamos que tenemos un numero BCD en dos registros REG_L equ REG_H equ CONVERSOR movf andlw iorlw call swapf 0x11 0x12

;Mueve el valor de REG_H a W ;Filtra el valor con esta mscara ;Nuevo filtrado ;Visualiza el dato en la pantalla LCD ;Cambia los 4 bits de mas peso por los de ;menos peso y viceversa y lo guarda en W andlw b00001111 ;Filtra el valor con esta mascara iorlw b00110000 ;Nuevo filtrado call LCD_DATO ;Visualiza el dato en la pantalla LCD movf REG_L,0 amdlw b00001111 ;Filtra el valor con esta mscara iorlw b00110000 ;Nuevo filtrado call LCD_DATO ;Visualiza el dato en la pantalla LCD return

REG_H,0 b00001111 b00110000 LCD_DATO REG_L,0

En el caso de que el dato a visualizar este en un solo registro el programa empezara en la instrucccin SWAPF REG_L,

EJEMPLO 48: ;Convierte el valor binario presente en posicin 0x10 en BCD. El ;resultado se deposita en las variables Buffer_H y Buffer_L. List p=16F84 Include "P16F84.INC" ;Tipo de procesador ;Definiciones de registros internos

Binario Buffer_H Buffer_L Temp_1

equ equ equ org

equ 0x11 0x12 0x13 0x00

0x10

;Valor binario inicial ;Parte alta del resultado ;Parte baja del resultado ;Registro temporal ;Vector de Reset ;Carga el valor binario inicial ;Inicia registros de trabajo

Inicio

movf clrf clrf addlw btfss goto movwf incf

Binario,W Buffer_L Buffer_H

BIN_BCD_1

BIN_BCD_2 BIN_BCD_3

0xf6 ;Resta 10 con suma de complemento a 2. STATUS,C ;Hay Carry? BIN_BCD_3 ;NO. Temp_1 ;SI.Guardar en registro temporal. Buffer_L,F ;Incrementar byte bajo, guardarlo y ;enviar ... movf Buffer_L,W ;..copia a acumulador= W... xorlw b'00001010';..0Ah xor W. btfss STATUS,Z ;Buffer_L es igual a 10 ?? goto BIN_BCD_2 ;NO. clrf Buffer_L ;SI. Poner Buffer_L a 0 incf Buffer_H,F ;Incrementar Buffer_H movf Temp_1,W ;Recuperar el dato. goto BIN_BCD_1 ;Continuar la operacin. addlw H'0A' ;TEMPO + 0Ah swapf Buffer_L,F ;<3:0> == <7:4> y == Buffer_L iorwf Buffer_L,F ;W OR Buffer_L == Buffer_L end ;Fin del programa fuente

EJEMPLO 49: ;realiza el producto de dos nmeros de 8 bits generando un resultado de ;16 bits. ;El programa emplea la misma mecnica que al hacer un producto sobre el ;papel. List p=16F84 Include "P16F84.INC" cblock 0x10 Multiplicando Multiplicador Resultado_H Resultado_L Estatus_Temp Contador endc org Inicio clrf clrf movlw movwf bcf 0x00 Resultado_H Resultado_L 0x08 Contador STATUS,C ;Tipo de procesador ;Definiciones de registros internos ;Inicio de definicin de variables ;Variable para el multiplicando ;Variable para el multiplicador ;Parte alta del resultado ;Parte baja del resultado ;Registro de estado temporal ;Variable con nmero de veces a operar ;Fin de definiciones ;Vector de Reset

;Pone a 0000 el resultado inicial ;Inicia el contador con 8 ;Borra el carry

Bucle

movf Multiplicando,W ;Carga el multiplicando btfsc Multiplicador,0 ;Es 1 el bit de menos peso del ;multiplicador ?? addwf Resultado_H,F ;Si, se suma el multiplicando rrf Resultado_H,F rrf Resultado_L,F ;Desplaza a la derecha el resultado

;Rota a la derecha el multiplicador sin que se modifique el flag Carry Rota_sin_Carry movf STATUS,W movwf Estatus_Temp ;Salva temporalmente el carry rrf Multiplicador,F ;Desplaza a la derecha el ;multiplicador movf Estatus_Temp,W movwf STATUS ;Recupera el carry original decfsz Contador,F ;Repite el bucle 8 veces goto Bucle end ;Fin del programa fuente

EJEMPLO 50: ;Convierte el valor binario presente en posicin 0x10, comprendido ;entre 0 y 9, en su equivalente en cdigo GRAY. ;Este ejemplo pretende familiarizar al usuario con el manejo de tablas List p=16F84 Include "P16F84.INC" Bcd Gray equ equ org Tabla addwf retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw 0x10 0x11 0x00 PCL,F b'00000000' b'00000001' b'00000011' b'00000010' b'00000110' b'00000111' b'00000101' b'00000100' b'00001100' b'00001101' ;Tipo de procesador ;Definiciones de registros internos

;Valor BCD inicial ;Valor obtenido en cdigo GRAY ;Vector de Reset ;Calcula desplazamiento ;Cdigo GRAY del dgito ;Cdigo GRAY del dgito ;Cdigo GRAY del dgito ;Cdigo GRAY del dgito ;Cdigo GRAY del dgito ;Cdigo GRAY del dgito ;Cdigo GRAY del dgito ;Cdigo GRAY del dgito ;Cdigo GRAY del dgito ;Cdigo GRAY del dgito sobre la tabla 0 1 2 3 4 5 6 7 8 9

Inicio

movf Bcd,W call Tabla movwf Gray end

;Carga el valor BCD original ;Convierte a GRAY ;Guarda el resultado ;Fin del programa fuente

TEMA 3: ESCRITURA DE PROGRAMAS EN ASM.

El ensamblado de un programa traduce las instrucciones que se han escrito utilizando los mnemnicos del lenguaje maquina (CALL, etc.), a cdigo binario ejecutable por el microcontrolador. La secuencia de mnemnicos se llama listado o cdigo fuente del programa, mientras que el cdigo binario se llama objeto o ejecutable. Una vez que el programa se ha escrito y ensamblado (compilado no existe para el lenguaje ensamblador, solo se compilan los lenguajes de alto nivel como el C) ya tenemos un binario ejecutable.

Estructura de un programa tpico: Los programas desarrollados para el microprocesador PIC constan bsicamente de esta estructura:

Definir el Microcontrolador a usar: En esta directiva se especifica el tipo de microcontrolador que ser utilizado; esto se logra utilizando LIST = PIC16F84. Establecer las constantes a utilizar: Las constantes son tiles para referenciar direcciones de memoria, posiciones de los bits y valores que no cambiarn a lo largo de todo el programa. Esto se logra utilizando la directiva "EQU". Si se desea por ejemplo establecer un valor a una constante, sera CONST EQU 1, con lo cual le asigna el valor de "1" al registro CONST. Reservar los espacios en memoria de las variables: Se utiliza para reservar espacios en memorias para las variables utilizadas en el programa. Se logra utilizando la directiva denominada "RES". Muy til cuando un registro cambia su valor durante la ejecucin del programa. Configurar los puertos: Es necesario establecer si los bits de cada puerto sern utilizados como entrada o como salida. Para ello utilizamos los registros especiales TRISA y TRISB. Desarrollar el Programa: Es el verdadero corazn del trabajo que se realiza, puesto que aqu se desarrollan las rutinas que sern ejecutadas por el microcontrolador.

En la imagen anterior, tenemos un pequeo programa como ejemplo, para el microcontrolador PIC16F84 en la cual vemos las zonas en diferentes colores. El color amarillo representa la definicin del microcontrolador, el color verde representa el establecimiento de las constantes, el color celeste representa la reserva de Memoria, el color rojo es donde realmente comienza el programa en s y representa la configuracin de los puertos y el cuerpo del programa.

3.1. USO DEL BLOCK DE NOTAS CON WINDOWS

Los programas para el microcontrolador PIC16F84 pueden escribirse tambin en el BLOCK DE NOTAS de Windows, e incluso con el editor de textos del MS-DOS. Dentro del Block de notas o el editor de textos el programa deber escribirse en cuatro columnas, las cuales estarn destinadas cada una de ellas para una tarea especfica. Cada una de estas columnas tienen los siguientes nombres asignados:
No. De la Columna Columna 1 Columna 2 Columna 3 Columna 4 Nombre de la Columna Etiqueta Operacin Operandos Comentario.

La idea es organizar cuatro columnas independientes con una separacin mnima de un carcter entre una columna y otra.

Los programadores utilizan la tecla de tabulacin para desplazarse a travs de las cuatro columnas. Lo ms prctico es utilizar el tabulador para establecer las posiciones de las columnas. Si nos colocamos a la izquierda, nos encontraremos en la columna n 1 del editor, la cual representa la columna de las etiquetas, pulsando la tecla de tabulador dos veces nos situaremos en la columna de operacin. El ensamblador de programa que ser el encargado de interpretar los comandos escritos en el block de notas, sabr reconocer fcilmente la columnas definidas. Cada una de las columnas tienen sus reglas generales, a continuacin mencionamos y explicamos cada una de ellas.

LAS ETIQUETAS: Las etiquetas tienen algunas reglas obligatorias que debern cumplirse:

Debe comenzar exactamente en la columna 1 del editor de textos. La etiqueta no podr tener mas de 31 caracteres. La etiqueta podr estar formada por caracteres alfa-numricos.

OPERACION: En esta columna se escriben cualquiera de las 37 instrucciones del microcontrolador PIC16F84.

OPERANDOS: Los operandos son los registros en donde se realizan las operaciones y los registros son los espacios de memoria donde se almacenarn los resultados de las operaciones. Este registro puede ser una memoria de datos o un registro constante que hemos denominado anteriormente como un literal.

COMENTARIOS: En esta columna se escriben los comentarios que explican la idea de lo que est haciendo el programa. El ensamblador ignora esta lnea en el momento de generar los cdigos necesarios para el microcontrolador PIC16F84. Es la parte del cdigo que resulta fundamental para poder saber que hace un fichero sin tener que estudiar una por una todas las instrucciones del listado ASM del programa a investigar! Si partimos de un fichero en hexadecimal y lo convertimos a ASM con alguno de los programas que hay para ello (entre ellos el IC-Prog) conseguiremos un listado sin la columna de comentarios. Esto no es algo grave si es un programa de unas pocas lneas de cdigo. El problema es cuando el programa ocupa ms de 1 hoja. Para haceros una idea un poco ms aproximada, deciros que el cdigo ASM de uno de tantos ficheros que hay en internet para las tarjetas piccard1 ocupa unas 17 pginas. Pero tampoco es para

tanto si tenemos en cuenta que la tabla seca ocupa 4 pginas y media. Tan slo nos quedaran para intentar descifrar el cdigo de poco ms de 12 pginas. Tambin se podrn agregar comentarios al programa desde la columna n 1 del editor de textos; pero debern comenzar con el smbolo " ; " (punto y coma).

3.2. PROGRAMA MPLAB.

EL MPLAB es un Entorno de Desarrollo Integrado (Integrated Development Environment, IDE) que funciona bajo Windows, mediante el cual podemos desarrollar aplicaciones para los microcontroladores de las familias PIC 16/17. EL MPLAB nos permite escribir, depurar y optimizar los programas diseados para utilizar con dichos microprocesadores. De nada nos servira saber programar si finalmente no podemos hacerlo por carecer de las herramientas necesarias para ello. Por eso es importante conocer el funcionamiento del MPLAB. Con el MPLAB podemos:
Depurar programas fuente. Detectar errores automticamente en programas fuente para editarlos. Depurar programas utilizando puntos de corte (breakpoints) mediante valores de los registros internos. Observar el flujo del programa con el simulador MPLAB -SIM, seguirlo en tiempo real utilizando el emulador PICMASTER. Realizar medidas de tiempo utilizando un cronmetro. Ver variables en las ventanas de observacin. Encontrar respuestas, utilizando la ayuda en lnea del MPLAB.

Este entorno funciona como un contenedor, es decir, las diferentes opciones que contiene estn asociadas a programas independientes que se ejecutarn cuando sean seleccionados los diferentes modos dentro del MPLAB. Podemos definir un ensamblador (por ejemplo en C), un emulador o un grabador diferente a los que tiene por defecto, quedando de esta forma integrado al entorno. En el organigrama que veremos a continuacin tenemos las distintas fases de implementacin que deberemos seguir para completar con xito la programacin del microprocesador.
INICIO

ESCRITURA DEL CDIGO FUENTE

Se har en formato de texto DOS o ASCII con cualquier

editor, como, por ejemplo, el EDIT. Tambin es posible usar el entorno WIN95-98 respetando este formato de grabacin. Nosotros emplearemos el MPLAB como editor. Para el lenguaje ensamblador emplearemos el MPASM, habiendo tambin herramientas para trabajar en C. Nosotros lo elegiremos por defecto como ensamblador en el MPLAB. La herramienta de simulacin en DOS es MPSIM, pero el entorno grfico MPLAB tiene su propio sistema, que utilizaremos.

ENSAMBLADO

SIMULACIN

ERRORES?

GRABACIN DEL CONTROLADOR

Cada grabador tiene su software especfico, y es posible encontrar mltiples circuitos y programas en Internet. Microchip vende sus propios equipos, as como micros programados de fbrica.

FIN

3.2.1. HERRAMIENTAS DEL MPLAB.


MPLAB es un conjunto de herramientas para el desarrollo y depuracin de aplicaciones en un proyecto. MPLAB incluye un organizador de proyectos para mantener tu cdigo ordenado, un editor de texto, un simulador para depurar el software que desarrollemos y soporta otras herramientas de Microchip tales como el emulador PICMASTER y el programador de dispositivos PICSTART Plus. Organizador de Proyectos El organizador de proyectos es la parte central del MPLAB. Sin la creacin de un proyecto no se puede hacer depuracin alguna. A travs de l podremos: Crear un proyecto. Aadir un archivo de cdigo fuente a un proyecto. Ensamblar o compilar cdigo fuente. Editar cdigo fuente.. Reconstruir todo el cdigo fuente, o compilar un archivo solo. Depurar el cdigo fuente. El Editor MPLAB El Editor de MPLAB permite a los programadores escribir y editar cdigo fuente para las familias de microcontroladores PIC16/17, as como otros archivos de texto. El Ensamblador MPASM El MPASM permite el ensamblado condicional, de diferentes fuentes y lista de formatos. MPASM permite generar varios formatos de cdigo objeto que soportan las herramientas de desarrollo de Microchip as como los programadores relacionados con ellas sin salir de MPLAB. El Simulador MPSIM El simulador MPSIM permite aislar problemas de cdigo y depurar diseos. Simula las funciones principales as como la mayora de los perifricos de las familias de microcontroladores PIC16/17. Otras Herramientas El MPLAB soporta herramientas de desarrollo tales como programadores, compiladores y emuladores ya sea de Microchip o de otros diseadores. Como herramientas de Microchip tenemos el emulador PICMASTER y el programador de dispositivos PICSTART PLUS entre otras.

3.2.2. FUNCIONES DEL MPLAB (MENS).


Con el MPLAB tenemos todas las herramientas que necesitamos para trabajar con el PIC.
En este captulo veremos y describiremos los mens que nos encontraremos en la barra del programa.

Adems disponemos de la barra de herramientas con cuatro opciones de serie, adaptadas a lo que estemos realizando en cada fase. Estas son: La barra User. La barra Project. La barra Edit. La barra Debug.

Sea cual sea la barra que tengamos activa, podemos acceder directamente a la barra de mens donde encontraremos todas las funciones del MPLAB:

MENU FILE:

Aqu tenemos todos los comandos comunes del men FILE tpico de Windows.

NEW es para crear un nuevo archivo con extensin *.asm.

OPEN es para abrir un archivo que puede tener la extensin *.asm, *.obj, *.c, *.err, *.h, *.lkr, *.map, *.hex o *.lst.

VIEW es para abrir un archivo para verlo pero en modo de slo lectura, no se puede modificar.

SAVE es para guardar el archivo que tenemos abierto. Si ste ya lo habamos guardado antes con algn nombre se archivar con el mismo. Si es la primera vez que lo vamos a guardar, automticamente se nos abrir la opcin SAVE AS (guardar como) y tendremos que asignarle nombre antes de archivarlo.

SAVE ALL es para guardar todos los archivos que tengamos abiertos.

CLOSE es para cerrar un proyecto. CLOSE ALL es para cerrar todos los proyectos abiertos. En IMPORT tenemos dos opciones. La primera es IMPORT TO MEMORY, y con ella podemos cargar la memoria del MPLAB con algn archivo ya compilado *.hex, y podremos debuguearlo, o grabarlo en el PIC, o incluso emularlo si es que tenemos el emulador. IMPORT TO TARGET MEMORY, hace lo mismo que la opcin anterior pero se carga en la memoria del emulador.

En EXPORT tenemos dos opciones. La funcin EXPORT TRACE BUFFER nos permite guardar el buffer de 8K de traceado en *.hex para futuros usos. EXPORT MEMORY nos permite guardar el programa ya compilado en formato INTEL de 8 o 32 bits, adems de guardar conjuntamente los bits de configuracin, etc.

PRINT sirve para imprimir, y PRINT SETUP abre una ventana de configuracin de la impresin, donde elegir tipo y tamao de fuente, numerar las paginas, etc.

EXIT es para cerrar el MPLAB. Debajo de EXIT tendramos los accesos directos a los ltimos 5 documentos que hubisemos abierto.

MENU PROJECT:

Con el men PROJECT tenemos todas las funciones necesarias para trabajar con proyectos. Supongamos que tenemos que hacer un programa. Podemos sencillamente ir al men FILE, luego pulsar NEW y se abrir una ventana tipo notepad, en donde introducimos el cdigo, despus lo ensamblamos y listo. Ya tenemos el fichero listo para grabar el PIC o debuguearlo. Sera preferible que todo lo que queremos hacer con un programa pudisemos abrir o cerrar todo al mismo tiempo. Pues para ello tenemos el PROYECTO. Con un proyecto podemos agregar ventanas de registros personales que slo ese programa necesita o utiliza. Podemos simular algunas condiciones que nicamente ese programa usa, y que sera completamente intil para otro programa. Dentro de un proyecto podemos realizar, guardar y personalizar todo a nuestro gusto y bajo un mismo nombre. Luego, al abrirlo de nuevo, lo har con toda la personalizacin y valores previamente guardados. Es algo as como la personalizacin de Windows con varios usuarios, en el que cada uno tiene un tipo diferente de desktop, etc.

NEW PROJECT crea un nuevo proyecto con un nombre, en el que dentro estar el programa en si, las ventanas de debugueo exclusivos de ese programa, etc.

OPEN PROJECT abre un proyecto. CLOSE PROJECT cierra un proyecto. SAVE PROYECT guarda un proyecto. EDIT PROJECT es muy importante, como veremos mas adelante nos sirve para seleccionar la herramienta de desarrollo, los path, los nodos, el target name, el linker, las libreras, etc. MAKE PROJECT ensambla el proyecto. Y decimos proyecto y no programa, dado que el programa puede estar conformado por partes de libreras de rutinas aparte de las lneas de cdigo propias. Cuando se ensambla, se genera un archivo con extensin *.HEX, y es el que se usa para grabar el PIC. Tambin se pueden generar libreras con extensin *.LIB, o cdigo objeto (usado para enlazarse con el proyecto) con extensin *.OBJ. Entonces si hacemos MAKE PROJECT o pulsamos F10 se ensamblar todo, pero tenemos que considerar un detalle; y es que MAKE PROJECT tiene en cuenta la fecha de creacin del archivo .HEX, la cual compara con el archivo del que ensambl *.ASM. Si ste tiene una fecha ms reciente que el archivo *.HEX asociado, debido digamos a una actualizacin del cdigo, entonces al pulsar F10 ensamblar nuevamente el proyecto. En caso de que la fecha sea anterior al archivo *.HEX generado (como es el caso posterior al ensamblado, donde el *.ASM es ms antiguo que el *.HEX) al pulsar F10 no har nada. BUILD ALL no tiene en cuenta ninguna fecha al pasar a ensamblador. BUIL NODE convierte a ensamblador algn nodo que hayamos asociado al proyecto. nicamente ensamblar el nodo.

INSTALL LANGUAGE TOOL nos permite configurar el lenguaje que vamos a utilizar, que en nuestro caso es el ASM de Microchip. Obviamente, tenemos muchas funciones, incluso el C. Y por ltimo tenemos el acceso directo a los ltimos proyecto abiertos (en el caso de haber abierto alguno anteriormente).

MENU EDIT:

En el men EDIT podemos hacer todo lo referente a las acciones de tipo texto. UNDO deshace la ltima accin. CUT corta lo que tengamos seleccionado. COPY copia lo que tengamos seleccionado. PASTE pega lo que habamos cortado o copiado anteriormente.

SELECT ALL selecciona todo. SELECT WORD selecciona la palabra sobre la que esta el cursor. DELETE LINE borra la lnea sobre la que esta el cursor. DELETE EOL borra desde donde esta el cursor hasta el final de la lnea. Si est al principio de la lnea, la borrara toda, haciendo subir una posicin la siguiente lnea. GOTO LINE desplaza el cursor a una lnea determinada. FIND busca algn texto que tengamos dentro del programa. REPLACE reemplaza el texto que anteriormente buscamos. REPEAT FIND repite la bsqueda si es que hay otra palabra igual. REPEAT REPLACE repite el reemplazo del texto. MATCH BRACE localiza y coloca el cursor al principio o final de un emparejamiento de cdigo.

El submen TEMPLATE sirve para crear secciones de texto que sirven para incluir en el programa varias veces sin necesidad de teclear de nuevo lo mismo. Vienen siendo plantillas con cdigo.

Dentro del submen TEXT tenemos TRANSPOSE que sirve para intercambiar entre si dos letras, las cuales estn una a cada lado del cursor. Por ejemplo: si el cursor lo tengo entre las letras A y F de la palabra AFTER, al hacer TRANSPOSE quedar FATER.

UPPER CASE har maysculas todas las letras seleccionadas. LOWER CASE har minsculas todas las letras seleccionadas. INDENT mantiene el sangrado de mrgenes de la lnea anterior. UN-INDENT no mantiene el sangrado de mrgenes de la lnea anterior.

MENU DEBUG:

El men DEBUG es el que vamos a utilizar para simular nuestro programa, depurarlo, colocar breal points, correr el programa paso a paso, hacer un reset, etc. En el submen RUN tenemos varias opciones:

RUN que nos hecha a andar nuestro programa a toda velocidad, o sea que es solo para cuando tenemos algunos breakpoints colocaditos y poder detenerlo. RESET nos resetea el programa y comienza nuevamente desde ell principio. HALT detiene el programa. HALT TRACE detiene un traceo que se est haciendo.

ANIMATE es igual a la ejecucin paso a paso pero en forma automtica, algo as como autostep de cualquier debuger. STEP ejecuta un paso slo. STEP OVER ejecuta un paso slo, pero que no salta dentro de ningn CALL, nicamente lo ejecuta todo de golpe. UPDATE ALL REGISTER actualiza el valor de todos los registros. CHANGE PROGRAM COUNTER cambia el valor del ProgramCounter y adems nos cambiar la posicin de nuestro programa.

EXECUTE nos permite ejecutar un OpCode o cdigo de operacin, en forma totalmente independiente a la secuencia del programa. Aqu debajo puedes ver la ventana de ejecucin. Puedes hacer digamos un GOTO cualquier lado y ejecutarlo y listo. En la ventana desplegable se guardan los ultimo cdigos ejecutados para no tener que escribirlos de nuevo.

CONDITIONAL BREAK ejecuta un breakpoint en forma condicional. Hay muchas formas de ejecutar un breakpoint. Por ejemplo: parar cuando una lnea a sido ejecutada un nmero de veces determinado, o slo porque se llego hasta all, o cuando un registro adquiere determinado valor, etc.

SIMULATOR STIMULUS permite que instalemos seales del estmulo del reloj y que el simulador responda a los acontecimientos de ficheros en el PC. Los ficheros se pueden escribir con el editor de MPLAB, o cualquier otro editor o procesador de textos conveniente, y se deben guardar en el mismo directorio que el proyecto actual. El simulador de estmulos genera las seales para el simulador. Podemos fijar los contactos altos o bajos, e inyecta valores directamente en los registros. Hay cuatro tipos del estmulos: Dilogo asncrono del estmulo (un dilogo interactivo con las seales de control en los contactos de la entrada de informacin). El estmulo del Pin (el contenido de un fichero del texto describe seales de entrada en los contactos). Tambin llamados Synchronous Stimulus. El estmulo de los registros (el contenido de un fichero del texto se utiliza para fijar valores 8-bit directamente en un registro).

Estmulo del reloj (una fuente regular, programable y peridica de los impulsos).

ASYNC STIMULUS permite simular las entradas de determinados pines o puertos de distintas formas.

En esta pantalla vemos que el primer botn lo hemos asignado a la pata 1 del puerto A (RA1) y la T significa que el tipo de estmulo es un alto o un alto cada vez que lo oprima. Esto lo hacemos con el botn derecho del mouse encima de cualquiera de los cuadrados que tenemos en esta pantalla. PIN STIMULUS nos permite en forma automtica simular el estado de los pines de los puertos. Consiste en crear un archivo de texto con la extensin *.STI en el cual en la primer columna van las posiciones del programa donde queremos simular esas entradas a los pines, y en la primer fila los pines a los cuales vamos a "estimular". Todo esto es para poder simular un puerto como si fuese en la vida real. CLOCK STIMULUS hace que para un determinado rango del reloj, un pin tome un valor determinado, etc. REGISTER STIMULUS es exactamente lo mismo que con los pines, solo que lleva la extensin *.REG y sirve que para una determinada posicin del programa se cargue un registro con el valor que nos interese. CENTER DEBUG LOCATION sirve para posicionarnos en el lugar donde est la ejecucin del programa por si nos hemos perdido y no sabemos donde est la lnea en ejecucin. BREAK SETTINGS nos abre una ventana en donde guardamos una serie de breakpoints a los que asignamos nombre. Es lo mismo que TRACE SETTINGS en el cual guardamos las caractersticas de traceo que queremos. TRIGGER IN/OUT SETTINGS son opciones para los emuladores MPLAB-ICE y PICMASTER que no utilizaremos en este curso. Las pruebas de lgica proporcionan la entradas de informacin externas del rastro, a la seal de salida del disparador a +5V y a una toma de tierra comn. TRIGGER OUTPUT POINTS sirve para definir hasta 16 disparadores fuera de rango para los emuladores MPLAB-ICE y PICMASTER. CLEAR ALL POINTS limpia todos los break/trace points. COMPLEX TRIGGER SETTINGS es para configurar las funciones complejas del emulador.

CODE COVERAGE (cobertura del cdigo). Nos permite ver qu porciones del cdigo estn siendo utilizadas. Este cdigo se destaca en la ventana de la memoria del programa en un color definido en configuraciones de Options Environment: tabulacin del color. CLEAR PROGRAM MEMORY borra la memoria de programa. Vamos a explicar que es la memoria de programa, la cual podemos acceder desde el men WINDOW-PROGRAM MEMORY para verla. La memoria de programa es el buffer que tenemos en la maquina para poder almacenar l programa propiamente dicho para ser simulado o programado. Si estamos simulando un proyecto, e intentamos leer el contenido de la memoria de un PIC por medio del programador, esta ultima lectura sobreescribir el contenido del buffer o memoria de programa. Por lo cual, es aconsejable primero cerrar algn proyecto que tengamos abierto, y luego leer al PIC. Cuando simulamos un programa, lo que la maquina en realidad hace, es seguir a travs de la memoria de programa. Luego desde all mismo y sin ningn previo paso, podemos grabar el PIC, obviamente si tenemos el programador PICSTART PLUS. Si no es as, no hay problema, ya veremos que fcil es hacer uno. La nica diferencia es que este programador no lo podremos utilizar por medio del MPLAB sino a travs de su propio software de control. Pero el MPLAB lo usamos absolutamente para todo, menos grabar. SYSTEM RESET para hacer un reset del sistema como si comenzramos el programa. POWER ON RESET es para meter datos aleatorios como los que podran ser en la realidad cuando se produce un PowerOnReset, y ver de esta forma el comportamiento del programa. MENU PICSTART PLUS:

No tiene sentido alguno explicarlo si no se tiene el programador PICSTAR PLUS (como es mi caso).

MENU OPTIONS:

DEVELOPMENT MODE significa modo de desarrollo. Aqu es donde seteamos nuestras primeras configuraciones del proyecto, como ser si vamos a utilizar el simulador, sobre cul PIC, memoria, reloj, accesos, herramientas, etc.

WINDOW SETUP permite utilizar la configuracin por defecto, guardar la actual o cargar alguna de las anteriores que tengamos guardadas.

CURRENT EDITOR MODES nos permite seleccionar y configurar los modos del editor que se aplican a la ventana actual. RESET EDITOR MODES nos permite seleccionar los modos del editor para reajustar los aplicados a la ventana actual a los valores por defecto.

ENVIRONMENT SETUP nos abre una pantalla de dilogo que permite cambiar configuraciones en las reas siguientes: ficheros, opciones generales, modos del editor, colores, mapas de memoria, opciones del proyecto, etc. PROGRAMMER OPTIONS (opciones del programador) permiten seleccionar el programador y el inicio del puerto de comunicaciones.

MENU TOOLS:

Las opciones del men de herramientas nos permiten ejecutarprogramas en MS-DOS, configurar un emulador, y verificar que el emulador est funcionando correctamente.

DOS COMMAND TO WINDOW nos permite ejecutar un programa de MS-DOS tal como un compilador, o ejecutar un comando interno como DIR y capture la salida en una ventana del editor. REPEAT DOS COMMAND TO WINDOW ejecuta de nuevo el ltimo comando realizado con la opcin anterior. Nos muestra el comando realizado en una ventana cuando termina. Si no hemos ejecutado previamente un comando, el editor actuar como si seleccionramos ejecutar comando del DOS en pantalla y mostrar el dilogo correspondiente. VERIFY PICMASTER nos indicar si el emulador PICMASTER est funcionando correctamente. VERIFY MPLAB-ICE nos indicar si el MPLAB-ICE est funcionando correctamente. MENU WINDOW:

En este men podemos abrir la memoria de programa, la memoria eeprom, nuestro reloj del PIC, una ventana de observacin de los registros que a nosotros nos interesan, el WATCH WINDOW, etc.

PROGRAM MEMORY la ventana de la memoria del programa puede visualizar localizaciones en el rango de la memoria del programa para el procesador actualmente seleccionado. Podemos dejar esta ventana abierta siempre y mover y volver a clasificar segn el tamao dicha ventana. La memoria del programa se puede visualizar de tres formas diferentes. El formato deseado se elige a travs del men del sistema. Hex Code Display: visualiza la memoria del programa como datos en hexadecimal. Esta opcin es la ms til al usar un programador del dispositivo (es el cdigo que utilizamos para grabar los PIC). Machine Code Display: visualiza el cdigo desensamblado sin la informacin simblica. Disassembly Display: visualiza el cdigo desensamblado con smbolos. La ventana de la memoria del programa est solamente disponible en modo emulador y en modo simulador. Cuando tenemos funcionando un programador la ventana de la memoria del programa se abrir en formato de cdigo hexadecimal, si no est ya abierto como tal.

TRACE MEMORY nos permite ver una foto de la ejecucin del programa. Para los emuladores que tienen un almacn intermedio, sto muestra cmo el programa se ejecuta en su mxima velocidad. EEPROM MEMORY visualiza la ventana de la memoria de los datos de EEPROM para un dispositivo del microcontrolador que tenga dicha memoria. El PIC16F84 es un ejemplo de un dispositivo que utilice memoria EEPROM. La ventana puede estar abierta siempre, mover por la

pantalla y recolocar segn el tamao. Est nica y exclusivamente para informacin y no podremos cambiar los valores visualizados.

ABSOLUTE LISTIN visualiza la lista (*.LST) y la progresin del *.LST generado por MPASM o un compilador compatible de C. El listado absoluto visualiza cdigo fuente con el cdigo objeto generado. Podemos utilizar esta funcin para visualizar cdigo en C y el cdigo del ensamblado que corresponde al cdigo en C. El listado absoluto nos da una idea mejor de cmo el compilador de C ejecuta el cdigo. Si no utilizamos C, MPASM generar un listado similar. MAP FILE nos muestra las localizaciones de memoria usadas y sin usar despus de conectar. STACK abre una ventana que visualiza el contenido de la pila. El nmero de niveles disponibles depende del tipo del procesador que emulemos. La ventana de la pila puede estar abierta siempre, moverla y colocada de nuevo segn su tamao. El contenido de la pila se puede visualizar con o sin nmeros de lnea. El formato deseado se elige a travs del men del sistema. FILE REGISTERS visualiza una ventana de todos los registros del fichero del procesador que emulamos. Cuando un valor del registro del fichero cambia, o se interroga el procesador, los datos en la ventana se actualizan. La ventana puede estar abierto siempre, moverla y colocar de nuevo segn su tamao. SPECIAL FUNCTION REGISTERS nos permite visualizar el contenido de los registros especiales de la funcin (SFRs) para el procesador que emulamos. SHOW SYMBOL LIST visualiza los smbolos del cdigo fuente. Estos smbolos son *.COD en el proyecto e incluyen todos los smbolos conocidos en MPLAB. Los smbolos incluyen constantes y escrituras de la etiqueta. La lista del smbolo de la demostracin es un rectngulo de dilogo de la informacin nicamente. STOPWATCH visualiza el valor actual del contador de ciclo. El cronmetro del sistema cuenta el nmero de los ciclos de reloj que el procesador ejecuta. El cronmetro nos permite medir el tiempo de ejecucin del cdigo. Este se calcula basadose en la frecuencia de reloj del PIC. PROJECT WINDOW visualiza la ventana del proyecto si ste est abierto. Visualiza la lista de ficheros actualmente en el proyecto. Si se ha compilado el proyecto, ensea una lista de todos los ficheros incluidos en el proyecto. Si no, la ventana muestra solamente el fichero del proyecto principal.

WATCH WINDOWS nos permiten vigilar smbolos del programa mientras se ejecuta. Y esta opcin nos d acceso a los comandos para crear, cargar, modificar y grabar nuestras propias WATCH WINDOWS personalizadas para as comprobar las variables que nosotros queramos mientras que ejecuta un programa.

MODIFY MEMORY nos permite hacer lo siguiente en la memoria de datos, memoria del programa, la pila, o la memoria de la Eeprom: Leer/Escribir en un direccionamiento especfico. Leer/Escribir mientras que incrementa al siguiente direccionamiento. Rellenar un bloque del direccionamiento. Leer un rango de la RAM externa. TILE HORIZONTAL abre las pantallas en formato horizontal haciendo posible ver cada lnea en tantas ventanas como sea posible. Este comando arregla las ventanas abiertas, colocando las ventanas unas sobre otras. El exceso de pantallas se juntan en un modelo horizontal en la parte de la pantalla. TILE VERTICAL abre las pantallas verticalmente en columnas para permitir ver tantas lneas como sea posible en cada una de ellas. Este comando arregla las ventanas abiertas, colocndolas lado sobre lado de modo que cada ventana tenga tanta profuncidad como sea posible. CASCADE coloca todas las ventanas abiertas en forma de cascada. ICONIZE ALL transforma todas las ventanas en iconos. ARRANGE ICONS coloca los iconos de modo que sean visibles en filas en el fondo del escritorio. Este comando no afecta a las ventanas abiertas.

MENU HELP:

En este men tenemos toda la ayuda referente a este programa y todas las partes que lo forman, pero para los que no dominan el ingls escrito no les servir de mucha ayuda.

Y hasta aqu, el repaso de los mens que tenemos en el MPLAB. Unicamente me queda recordar que esta parte es solo para tener una idea de como es el IDE de Microchip. En el prximo tema (tutorial) veremos los pasos a seguir para realizar un programa sencillo utilizando como base lo aprendido en ste.

3.2.3 GUIA DE USO DEL ENSAMBLADOR MPASM (TUTORIAL):

Este tutorial esta basado en el propio tutorial de Microchip que est en su pgina web en formato PDF.

CONFIGURANDO EL MPLAB:

Si ya tenemos instalado el MPLAB, lo primero que tenemos que hacer es configurarlo para el uso que vamos a hacer de l, si es editor solamente o simulador. Al poner simulador se entiende que es para programar, depurar, etc. As que nos vamos al men OPTION y abrimos DEVELOPMENT MODE, y nos aparece la siguiente ventana, lo cual configuraremos solamente la solapa TOOLS dejando el resto por defecto. En la ventana hemos seleccionado el PIC16F84,y en el modo SIMULATOR.

Pulsamos en el botn OK o APPLY, y vemos que en la barra de estado o STATUS BAR (en la parte baja de la ventana del MPLAB) cambia el chip para el PIC16F84 y en modo simulador (SIM).

CREAR UN PROYECTO NUEVO:

El simulador o debuger para poder funcionar, utiliza el archivo *.HEX generado a partir de una compilacin o ensamblado del cdigo fuente. Adems este mismo archivo generado (*.HEX) es el que se usa para grabar el PIC. El ensamblador produce otros ficheros aparte del *.HEX para otros usos que veremos luego. En este tutorial (basado en el de Microchip) el fichero generado se llamar tutor84.hex. Seleccionamos FILE - NEW del men FILE y nos saldr la siguiente pantalla de dialogo:

Veremos que tambin se abre una ventana en blanco, que es donde introduciremos nuestro cdigo. En la ventana anterior pinchamos en YES y as comenzaremos a crear nuestro proyecto nuevo. Nos abrir la siguiente ventana para que escribamos el nombre del proyecto, y el directorio donde lo guardaremos. Lo llamaremos TUTOR84 y lo guardaremos en alguna carpeta que tengamos dentro del MPLAB, por ejemplo una que llamaremos "propios", o en otro directorio diferente si as lo queremos nosotros.

Como vemos, la extensin *.PJT corresponde a proyectos. Guardamos entonces nuestro proyecto asignndole antes un nombre, y automticamente se abre el siguiente cuadro de EDICION DE PROYECTO.

Tanto el simulador como el programador o el emulador trabajan a partir del archivo *.HEX generado por el IDE del MPLAB, por el ensamblado, compilado y/o encadenado (linkeado) del cdigo fuente. Diferentes tips de herramientas generan el archivo *.HEX, y estas herramientas son parte de cada proyecto. El proyecto nos da la flexibilidad de poder utilizar diversas herramientas para crear el ejecutable *.HEX. En la pantalla de EDICION DEL PROYECTO vemos que por defecto, el proyecto nos asign el mismo nombre para el fichero ejecutable tutor84.hex. As mismo, tambin tenemos el MPLAB SIM 16F84 que es lo que habamos seteado anteriormente en el men OPTION, al igual que la suite de lenguajes (en este caso Microchip). Si seleccionamos dentro de la ventana Projects Files tutor84.hex nos habilitara el botn NODE PROPERTIES. Este botn nos sirve para configurar y decirle al MPLAB IDE cmo crear el fichero *.HEX. Lo pulsamos y nos abre el siguiente cuadro:

Como vemos, aparece en la esquina superior derecha el lenguaje utilizado; a la izquierda el nombre del fichero a crear, que por defecto nos sale tutor84.hex. Todas las filas y columnas dentro del cuadro, son switchs o llaves en las cuales marcamos nuestras preferencias. Por ejemplo la numeracin utilizada (HEX) si queremos utilizar macros, etc. Esto se traduce en una lnea de comandos que podemos visualizar en la parte inferior de la pantalla, en Command Line. Por ahora, hay que marcarlo como vemos en la ventana de muestra. Pinchamos en el botn OK y volvemos a la ventana anterior.

Hacemos click en ADD NODE y nos aparece la siguiente ventana:

En la misma debemos guardar dentro del mismo directorio del proyecto nuestro archivo fuente que se llamar tutor84.asm. Le damos ACEPTAR y volvemos otra vez al cuadro anterior:

Como vemos, se ha aadido el nodo tutor84.asm en forma dependiente de tutor84.hex. Apretamos OK y volvemos al escritorio en donde tendremos abierta una ventana en donde introduciremos nuestro cdigo, pero an sin titulo. Para ello seleccionaremos en el men EDIT SAVE AS y le daremos el nombre del nodo que hemos configurado tutor84.asm.

Como podemos apreciar ahora la barra de titulo de la ventana de cdigo a cambiado de nombre de untitled a tutor84.asm. Podemos ver que siempre colocaremos el mismo nombre en el proyecto y

en el cdigo fuente. Esto es porque no estamos trabajando con un linker que nos permite incorporar o linkear distintos archivos con distintos nombres. Entonces al trabajar con un archivo nico debemos nombrarlo igual que el proyecto al cual pertenece, adems de guardarlo en el mismo directorio.

INTRODUCIR CODIGO ASM:

En la ventana que tenemos abierta empezaremos a introducir el cdigo de nuestro programa. Escribimos lo siguiente:

Algunas consideraciones: Este es el programa que utilizaremos en este tutorial, y como se puede ver consta de varias columnas, las cuales significan lo mismo que en otros lenguajes de programacin (ya hemos explicado esto en un tema anterior). La primera de la izquierda son las famosas etiquetas que pueden tener cualquier nombre y sirven para referenciar direcciones a llamar o bifurcar/saltar. El programa cuenta con 4 etiquetas c1, reset, start y loop. Podemos cambiarles los nombres por cualquier otro que se nos ocurra, siempre que tambin lo hagamos en la instruccin que llama a dichas etiquetas. En la segunda columna tenemos las instrucciones: goto, movlw, etc. En la tercera el operando, registro o llamada: c1, f, start, etc. Y por ltimo en la cuarta, siempre despus de un PUNTO Y COMA, los comentarios, que sirven nada ms (y nada menos) que para ayudar a la memoria del programador o facilitar la comprensin del cdigo por otra persona ajena al propio programador. No tienen utilidad alguna en el ensamblado, pero si mucha para los programadores. Para escribir el cdigo utilizamos la tecla TAB para desplazarse entre columnas. Por ejemplo: la primera lnea la escribiremos =c1 TAB equ TAB0 0x0c TAB ; Set temp ... Ntese que la etiqueta c1 est en la misma lnea y por ejemplo reset no. Esto no importa,

slo que la etiqueta apunte a la lnea en cuestin o por encima, siempre y cuando la primera lnea a ejecutarse despus de la etique sea a la que hace referencia. Por descontado, en el cdigo que tecleamos para practicar con este ejemplo no hace falta escribir el campo de comentarios. Este programa lo que hace es cargar un registro cualquiera de uso general, el cual se denomin c1, con un valor X que en el ejemplo es 9. Luego lo incrementamos de 1 en 1 hasta que se desborde (recordemos que son registros de 8 bits, y se desbordar cuando llegue a FF o 255 y volver a 00) y vuelva a 0. Cuando esto ocurra, el programa cargar nuevamente el registro con el valor 9 y repetir lo mismo. Por ltimo, recordar que en los cuadros seleccionables del nodo tenamos marcado CASE SENSITIVE lo cual quiere decir que escribiremos el cdigo de una nica forma; o maysculas o minsculas, o haremos referencia a etiquetas iguales. Lo que significa que start no es lo mismo que Start. Y guardamos los cambios en el men EDIT SAVE.

ENSAMBLADO (COMPILAR):

Nuevamente haremos mencin a que no vamos a compilar sino ensamblar, porque recordaremos que solamente se compila desde lenguajes de alto nivel. Accedemos al men PROJECT - BUILD ALL. Hacemos build all y nos sale la ventana de compilacin dicindonos que hemos tenido un error. Cmo puede ser que nos hayamos equivocado? Veamos que nos dice la ventana:

Pero no hay problema. El fallo es debido a que hemos introducido a propsito un error en el cdigo: es en el ltimo goto, donde pone "goto bug". Hemos hecho referencia a una etiqueta (bug) que no existe. Para corregir dicho error, hacemos doble click con el puntero del ratn sobre el error dentro de esta ltima ventana llamada "Build Results" y nos lleva a la ventana de cdigo colocndose el cursor sobre el error. Cambiamos la etiqueta "bug" por "start", y ensamblamos nuevamente (build all).

Nos aparecer nuevamente la ventana de resultados dicindonos que ahora tenemos todo correcto (lo que no quiere decir que funcione correctamente, que no es lo mismo). Recordemos que no hace falta salvar los cambios en el cdigo cuando cambiamos "bug" por "start" ya que cuando ensamblamos se guardan automticamente los cambios. Veremos la siguiente ventana:

Ya se ha creado el archivo *.HEX que es el que se graba en el PIC. Si nos fijamos en el directorio donde hemos guardado el proyecto, veremos el archivo. En estos momentos ya podramos utilizar este archivo para grabarlo en el PIC, pero antes necesitamos saber si funciona bien el programa, as que tendremos que simular antes para comprobarlo. Como dato respecto al ensamblado o compilado, cada vez que nos aparezca la ventana en la que nos indique que hemos tenido algn error (uno o ms), siempre hay que comprobar el primero, porque el resto de los errores pueden producirse por culpa del primero, as que solucionando ste podran desaparecer el resto o al menos alguno de ellos.

SIMULACIN: Ahora lleg el momento de simular, depurar o debuguear . Si tenemos el proyecto cerrado, nos vamos al men project y seleccionamos open project, y elegimos tutor84. Recordar que si queremos guardar el proyecto, nos vamos al men project y despus close project. Es la nica forma de cerrarlo. No es suficiente con cerrar la ventana de cdigo para cerrar el proyecto, eso lo podremos observar cuando la cerremos y se siga viendo en la barra de ttulo el proyecto. La primera vez que guardamos o cerramos el proyecto, nos preguntar si queremos guardar los cambios hechos, y estos cambios incluyen hasta las posiciones de las ventanas de cdigo, etc. en el rea de trabajo. Y as cuando lo abramos la prxima vez, nos aparecern las ventanas y dems partes integrantes del mismo, en las mismas posiciones donde estaban antes de guardarlo. Una vez abierto el proyecto, y viendo la ventana de cdigo, nos vamos al men DEBUG RUN RESET para inicializar el sistema. Una vez inicializado, vemos que estamos parados en la primera instruccin que va a ejecutar el PIC. La lnea que aparece resaltada es la que se va a ejecutar, NO que ya est ejecutada. Para volver a simular o regresar al punto de partida, de nuevo pulsaremos RESET. Una vez parados sobre la primera instruccin a ejecutar (lo que tenemos arriba son directivas para el ensamblador y no forman parte del cdigo asm) nos vamos al men DEBUG RUN - STEP o

desde el acceso directo que tenemos en el botn que tiene el dibujo de dos pies. Este es el botn para ejecutar paso a paso. A la derecha hay otro igual pero con una lnea entre los dos pies. Esta funcin se llama STEP OVER y sirve para ejecutar paso a paso igual que el anterior, pero si encuentra algn CALL lo ejecuta todo de golpe como si de una sola lnea se tratara. Tambin puedes acceder a STEP a travs de la tecla F7. Vemos que hemos ido a START dado que la primer instruccin es GOTO START. En este comando no veremos programacin, sino en forma bsica la simulacin o depuracin. Si observamos la barra de status, veremos como ha cambiado el valor del Program Counter (PC) a 0x04. Si seguimos presionando F7 repetidamente, podremos observar como se ejecuta el proceso paso a paso. Para hacer que funcione a tiempo real (tiempo real para el programa de simulacin, no la velocidad real del pic durante la simulacin). Nos vamos nuevamente al men DEBUG RUN - RUN o pulsamos el botn del semforo verde o F9, y veremos como la barra de estado cambia su color a amarillo. Esto nos indica que el programa esta funcionando en tiempo real (lgicamente no veremos la lnea negra de simulacin cambiar de posicin por cada instruccin que ejecuta ya que no nos dara tiempo a verlo). Para detener el proceso apretamos el semforo rojo, o F5. Se detendr donde estaba ejecutndose en el momento de pulsar el semforo o la tecla F5. Tambin tenemos la funcin ANIMATE que no es nada ms que un AUTO STEP. La podemos seleccionar en el men DEBUG RUN - ANIMATE o control F9, y veremos en forma automtica como se ejecutan las lneas. Lo detenemos tambin con F5.

OTRAS VENTANAS DE LA SIMULACIN: Realmente de poco nos sirve ver esa lnea subir y bajar, si no nos muestra ninguna informacin sobre los registros, etc. Para eso tendremos que ir al men WINDOWS SPECIAL FUNCTION REGISTER y nos abrir la ventana de registros especiales o especficos del PIC16F84 que ya est configurado en DEVELOPMENT MODE.

En esta ventana veremos todos los registros especiales del micro. Tambin veremos que cuando cambian de valor, cambian de color azul a rojo. Y donde esta el registro de uso general que lo hemos denominado c1 en el programa? Si queremos ver absolutamente todos los registros tenemos que ir al men WINDOWS FILE REGISTER. As se abrir una ventana en hexadecimal que no entendemos. Sobre la barra de titulo de esta nueva ventana, vemos que a la izquierda del titulo hay un icono que son tres hojas superpuestas. Si pinchamos con el puntero del ratn encima, nos desplegar un men, en donde elegiremos "Symbolic Display" y veremos la ventana siguiente:

Aqu vemos todos los registros del micro, tanto los especiales como los de uso general, incluso los que hemos renombrado como el caso de "c1". Hasta aqu todo correcto. Pero Qu pasa si tenemos un programa ms grande que el actual y con ms registros? El poder ver esta ventana se nos hara muy complicado. Para buscar una solucion a esto, tenemos otra ventana especial llamada "Watch Window" y que se guardar con nuestro proyecto.

WATCH WINDOW: Cerramos todas las ventanas que hemos abierto escepto la de cdigo y seleccionamos en men window - watch window - new watch window. Nos aparecer una ventana en blanco y al mismo tiempo sobre esta ltima, la ventana Add Watch Symbol, ya que no tenemos todava ningn smbolo cargado. Escribimos en el cuadro de dilogo el registro que queremos ver (en este caso sera c1):

Pinchamos en el botn Add. Tal y como est ahora lo veremos por defecto en hexadecimal. Si queremos verlo en otro formato (decimal, binario, ...), antes de presionar Add pulsamos en Properties y seleccionamos el que nosotros queramos. Y para finalizar con la pantalla de aadir smbolos pinchamos en Close. Ahora ya tenemos nuestra ventana con los registros que realmente nos interesa ver. Podemos agregar ms registros presionando la barra de titulo, sobre el icono y despus Add, o Edit si queremos editarla, etc.

De esta forma nos ser ms fcil seguir a un registro en particular. Con el programa tecleado antes, veremos como se incrementa y luego se desborda c1 volviendo nuevamente a 00000000. Para agregar o editar registros accedemos a travs del icono de la barra de ttulo de la ventana watch window o a travs del men window - watch window - xxx en donde nos mostrar add active watch, edit active...etc, haciendo referencia a active porque podemos tener ms de una ventana watch window. Si queremos guardar la ventana de watch window para no tener que construirla nuevamente cada vez que queramos utilizarla, lo haremos con save watch window. Pero si cerramos el proyecto, nos preguntar si queremos guardar los cambios. Le respondemos que si y entonces se guardar automticamente la ventana con el nombre por defecto watch_1.wdt.

BREAK POINTS O PUNTOS DE PARADA: Los breakpoints sirven para detener el procesador en el punto del programa donde le indiquemos. Para ello nos situamos en la ventana de cdigo, y colocamos el cursor sobre la instruccin MOVLW 0x09 y una vez all pinchamos con el botn derecho del ratn y se nos abre el men

contextual, donde elegimos Break Point(s). Veremos que la lnea cambia de color (a rojo), indicndonos que tenemos un break point en dicha lnea.

Tendremos que asegurarnos que en la barra de estado (la que tenemos en la parte de abajo) en donde dice Bk est en ON. Si est en OFF nunca se detendr en ningn break point. Para cambiarlo hacemos doble click ah mismo y se cambiar de un estado a otro. Tambin podremos hacerlo en el men option - development mode y pinchamos en la solapa Break Point y marcamos la casilla Global Break Enable. Hacemos de nuevo un reset del sistema, presionamos F9 y veremos como se detiene cada vez que llegue al break point. Tambin tenemos muchas otras opciones, como por ejemplo RUN TO HERE, que hace que se ejecute el cdigo hasta all sin necesidad de colocar un break point. Los Break Points se pueden colocar en la ventana de cdigo, en window - Program Memory (es el buffer que habamos mencionado antes) o en window - Absolute Listing. Source Files: si vamos al men window - Project Window se nos abrir una ventana en donde nos muestra todos los archivos que forman parte del proyecto. Haciendo click en ellos nos abrir el editor del mismo.

MPASM, EL ENSAMBLADOR DE MICROCHIP:

El ensamblador de Microchip es el MPASM, el cual forma parte constituyente del IDE. Veremos las directivas del mismo, los controles, etc. Con el MPASM procederemos a ensamblar un programa que hayamos creado o editado con el MPLAB. Este nos permite escribir el cdigo y ensamblarlo para producir como salida un fichero *.HEX que nos servir para grabarlo en el PIC o utilizarlo por el simulador o emulador. Pero tenemos distintas configuraciones del MPASM para producir diferentes resultados: Podemos utilizarlo, como el caso del tutorial, para generar un fichero "ejecutable" *.HEX a partir de un solo cdigo "ABSOLUTO" como lo era el pequeo programa del tutorial. Podemos generar un archivo ejecutable *.HEX a partir de la unin de distintos cdigos objeto y otros mdulos separados, ensamblados y/o precompilados. En este caso la herramienta que dispone el MPASM para unir esos mdulos se llama MPLINK o linker. Genera mdulos objeto para ser ensamblados con otros mdulos y as producir un nico archivo ejecutable.

Crear libreras con el MPLIB (una coleccin de cdigos objeto listos para ser usados y que se almacenan todos juntos en un nico archivo con extensin *.LIB).

Es conveniente aprender a utilizar el linkeador, dado que hay mucho cdigo objeto en Internet para bajar e incluir en nuestros proyectos. Configuracin y uso:

En la pantalla anterior vemos el botn Browse que utilizaremos para localizar e indicar al MPASM el archivo que queremos ensamblar, y con las opciones que podemos seleccionar en ella: Formato de salida del archivo *.HEX. Si queremos que nos muestre todos los mensajes, o slo los de error. El formato de salida del archivo *.HEX. Archivos y listados que generar. Tipo de procesador, etc...

Una vez tengamos todas las opciones seleccionadas, pulsamos el botn de Assemble y nos aparecer la siguiente pantalla:

Aqu nos muestra los errores, advertencias (warnings), mensajes y lneas ensambladas. Si no hemos tenido ninguno, podemos proceder a grabar el pic o simular el programa. Si hemos tenido errores, vamos a editar el archivo *.ERR generado por el MPASM con el propio editor del MPLAB o con cualquier otro editor de texto, y que nos mostrar las lneas en donde tenemos los errores. Lenguaje de DIRECTIVAS: Insisto en que las instrucciones de los PIC's son nicas y no hay ms que las que hemos visto anteriormente. No confundir las propias instrucciones de los PIC's con las directivas del ensamblador. Las famosas directivas son solo eso, directivas para el ensamblador, le dicen cmo hacer tal cosa o tal otra, y solo nos sirve para realizar las cosas ms rpido, y as ayudarnos en la tarea de programacin. Tenemos muchos tipos de directivas, las cuales se escriben dentro del cdigo fuente. Por eso no hay que confundir las directivas con las instrucciones del PIC. Los tipos de directivas son: Directivas de control. Directivas de datos. Directivas de listado. Directivas de macros. Directivas de ficheros objeto.

Las directivas de control, permiten un ensamblado CONDICIONAL. Las directivas de datos, son todas aquellas que permiten la manipulacin simblica y posicionamiento en memoria. Las directivas de listado permiten todo el control sobre la paginacin o listado del programa, as como su formato.

La directivas de macros, permiten todas las gestiones de las macros. Las directivas de fichero objeto, slo se utilizan para la creacin de ficheros objeto o reubicables/reusables para luego enlazar con el MPLINK.

Aunque hay muchas directivas, vale la pena conocerlas para as ahorrarnos tiempo al programar. Veamos las que tienen mayor uso: ORG: Le indica al ensamblador dnde comienza el programa, y as lo graba a partir de la posicin que especificamos aqu. #DEFINE: Muy til. Define un nombre para algn registro, pin, etc. Por ejemplo, #DEFINE SALIDA PORTA,3 sirve para no tener necesidad de recordar cual era el pin de salida, sino que slo lo mencionaremos como SALIDA. Podemos ponerlo a 0 con la instruccin BCF SALIDA en vez de hacer BCF PORTA,3 o BCF RA3. END: Indica al MPASM que ha terminado el programa. EQU: Define una constante con una etiqueta. La constante puede ser un registro o un valor numrico. #INCLUDE: Con esta directiva empezamos casi todos los programas. Como el ensamblador no sabe que microprocesador estamos utilizando en nuestro cdigo, Microchip ha creado una serie de archivos con extensin *.INC donde se definen todos los registros y datos respecto del procesador que estemos utilizando. En dicho archivo se define que la direccin 0x05 se llama PORTA, y por eso no tendremos que recordar la direccin, simplemente escribir en nuestro cdigo CLRF PORTA directamente. Lgicamente, si en nuestro cdigo definimos que PORTA ahora se llama R2D2, lo tendremos que llamar R2D2. Por eso al principio del cdigo ponemos #INCLUDE P16F84.INC si es que estamos trabajando con el PIC16F84. Todos los archivos *.INC se encuentran en el directorio de instalacin del MPLAB. Tambin sirve esta directiva para incluir libreras de rutinas, algo as como las DLL's del x86. MACRO: Para crear una macro. Por ejemplo: NUEVO CLRF BSF ENDM Hemos creado una macro llamada NUEVO. Ahora cada vez que pongamos la palabra NUEVO (en la segunda columna cuando queramos llamar a la macro), en realidad lo que har el MPASM es reemplazar la palabra NUEVO por CLRF PORTA.......etc. hasta el final de la macro que termina con la directiva ENDMacro (ENDM). Muy til tambin! MACRO PORTA PORTB,2

Vous aimerez peut-être aussi