CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
CURSO I NTEGRAL PIC
Las mejores cosas de la vida son gratis!!! Este curso es un obsequio de electrónica para todas las interesadas en esta tecnología.
WELGOS personas
En uno de los capítulos se describe la construcción de una tarjeta programadora “in circuit”. Si le interesa sonstruirla, el software del PIC y de la computadora puede solicitarlos por medio de correo electrónico.
Disfrútenlo!!!!!
1
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
CURSO I NTEGRAL PIC
Capítulo 1 Introducción a los microcontroladores PIC Los microcontroladores PIC son circuitos integrados producidos por la empresa Microchip Technology Inc., que pertenecen a la categoría de microcontroladores, debido a que en este componente se han integrado todos los circuitos necesarios para realizar un completo sistema digital programable. Como se puede ver en la figura,
el PIC (en este caso un PIC16F84A) posee una apariencia externa que no lo diferencia de otro integrado TTL o CMOS, pero internamente dispone de todo lo correspondiente a un sistema de microprocesadores: * Una CPU (Central Processor Unit) la cual es la unidad central que esta en capacidad de interpretar las instrucciones del programa. * Una memoria FLASH en donde se memoriza de manera permanente las instrucciones del programa a seguir. * Una memoria RAM (Random Access Memory) utilizada para memorizar las variables utilizadas en el programa. * Una serie de líneas de I/O (Input/Output) que permite el ingreso y la lectura de dispositivos externos o para recibir señales de sensores, pulsadores, etc. * Una serie de dispositivos auxiliaries al funcionamiento como la generación de reloj, buses, contadores, etc. La presencia de todos estos dispositivos en un espacio tan supremamente reducido, nos proporciona una gran ventaja frente a sistemas basados en microprocesadores. Los microcontroladores PIC se encuentran disponibles en una amplia gama de modelos, que se diferencian por el número de líneas I/O y los periféricos internos del dispositivo. Cada modelo posee su referencia, los más básicos se identifican por las siglas PIC12C5xx y solo poseen 8 pines, y los más avanzados se identifican por la sigla PIC18Cxx y está dotados de hasta 40 pines. En la página web de la Microchip se encuentra una descripción completa de todos los tipos de microcontroladores PIC, además de notas de aplicación y soporte.
2
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Parta este curso vamos a trabajar con los PIC16F84A, los cuales están dotados de 18 pines.
Estos microcontroladores disponen de una memoria interna para almacenar el programa que es de tipo FLASH, la cual puede reescribirse muchísimas veces, lo cual los hace ideales para experimentos. En la siguiente figura se muestra el diagrama de pines del PIC16F84A.
Los pines mostrados en azul corresponden a pines I/O diponibles para nuestra aplicación, los pines en rojo y negro corresponden a los de alimentación y los verdes son reservados para el funcionamiento del microcontrolador (MCLR para el reset, y los OSC1-2 son para el reloj).
1.1 Realizando una sencilla activación de un led Pasemos de una vez a desarrollar una sencilla aplicación práctica con microcontroladores PIC. Se trata de un circuito muy simple para activar un diodo LED. Veremos paso a paso, como se escribe un programa en assembler, como se compila y como se transfiere a la memoria FLASH interna del microcontrolador PIC para ponerlo a trabajar. Monte en el entrenador el circuito que se muestra en la siguiente figura:
3
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Para alimentar el circuito es necesario disponer de un voltaje DC constante de 5 voltios, la cual se aplica a el pin Vdd (pin 14) y la tierra se aplica al pin Vss (pin 5). El pin MCLR (pin 4) sirve para efectuar el reset al PIC microcontrolador. Normalmente viene mantenido a 5 voltios a través de una resistencia de pull up (R1) y se lleva a cero voltios cuando se require aplicar un reset. ATENCION Gracias a la circuitería interna del reset interna del microcontrolador, no es necesario colocar un pulsador para el reset o un circuito RC, pero nunca está demás. El pin OSC1/CLKIN (pin 16) y el pin OSC2/CLKOUT (pin 15) se conectan con un circuito interno que genera la frecuencia de reloj utilizada para temporizar todo el ciclo de funcionamiento interno en el chip. De esta frecuencia depende casi todas las operaciones internas del microcontrolador, especialmente la velocidad con que el PIC ejecuta las instrucciones del programa. En lo personal, cuando doy mis clases de microcontroladores, les digo a mis estudiantes que hagan la analogía con una escalera eléctrica en la cual viajamos, donde en cada peldaño que viajamos ejecutamos una instrucción. Cada microcontrolador posee una capacidad maxima del cristal, si la escalera se mueve demasiado rápido podríamos caernos. Pero también es possible que puede llegar otro tipo con mayor fortaleza que puede permanecer allí. Es decir, cada microcontrolador posee una cierta capacidad para manejar determinada frecuencia.
4
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
En el caso del PIC16F84A-04/P teóricamente puede llegar a un máximo de 4Mhz, aunque en realidad en la práctica es común superar apliamente esta frecuencia, lo que recibe el nombre de overclocking, en lo personal le he aplicado un cristal de 10 MHz (ver convertidor RS-232/ RS-485 half-duplex, en www.wellgos.com) sin tener ningún problema. Como en el circuito se tiene un cristal de 4 Mhz y dos condensadores de 22 pF, se obtiene una velocidad de ejecución de las instrucciones de 1 millón de instrucciones por segundo. El pin RB0 (pin 6) es la línea I/O que vamos a utilizar para este primer ejercicio. Allí se encuentra conectada una resistencia para limitar la corriente y un LED.
1.2 Escritura y compilación de un programa en ensamblador Todo sistema microcontrolador necesita de un programa para hacerlo funcionar. Un programa se constituye de una secuencia de instrucciones, cada una de las cuales identifica unívocamente una function que el microcontrolador debe ejecutar. Cada instrucción se representa por un código operative (en ingles operation code o abreviadamente opcode) compuesto de 14 bits y que se memoriza en una posición de la memoria donde se almacena el programa. En el PIC16F84A posee 1024 posiciones de memoria y el PIC16f877 posee 8K, cada una de las cuales puede contener una sola instrucción o un dato. Un ejemplo de un opcode en notació binaria, puede ser la siguiente: 00 0001 0000 0000
sin embargo es muy probable que el opcode lo vea en su representación hexadecimal, así: 0x100
que es exactamente el mismo valor pero en una forma más breve. El 0x delante de cualquier valor indica que se trata de una notación hexadecimal, aunque también se puede representar con la notación: H'0100'. Este opcode, es completamente privado para el entendimiento del ser humano, solo el PIC lo puede entender. Afortunadamente existen algunas herramientas que facilitan trabajar con las instruciones para su comprensibilidad. Por convención, se asocia a cada opcode, una breve sigla. Denominada mnemonica, con la cual se puede recordar la función de cada instrucción. El opcode 0x100 del ejemplo anterior, efectúa el borrado del registro W (enseguida veremos que significa esto) que en ingles viene indicado con la frase CLEAR W REGISTER, o sea, borrar el registro W, o en su forma abreviada CLRW. Una secuencia de estas siglas de acuerdo a ciertas reglas, forman un programa completo en LENGUAJE ENSAMBLADOR.
5
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Para escribir un programa en lenguaje ensamblador se debe conocer el conjunto de instrucciones disponibles por el microcontrolador que va a usar (en este caso los PIC), las reglas sintácticas para definer variables, parámetros, etc., y disponer de un editor de texto en donde se digita el programa. El archivo de texto con el programa se denomina fuente. El paso siguiente consiste en traducer nuestro archive fuente en la secuencia de instrucciones en formato binario que el PIC puede captar. Este programa se denomina ensamblador compilado. En la figura siguiente viene esquematizado el flujo de operaciones y los archivos generados necesarios para obtener un PIC programado.
6
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Como se dijo, la primera operación es la de efectuar la escritura de el programa fuente en ensamblador y su grabado en un archivo de texto. La extension de este archivo es .ASM. Se puede usar un sencillo editor ASCII, como el NOTEPAD de Windows o el Ultraedit32. Es posible generar este archivo desde un programa sofisticado como WORD o Star Office, pero no lo recomiendo mucho, debido a que el formato nativo de estos programas es .DOC, lo cual puede traer algunos problemas en el formato de los programas que el compilador puede entender.
7
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
En nuestro primer experimento práctico, utilizaremos el archivo LED.ASM. El paso siguiente es la compilación del programa fuente, esto es, la trnasformación en opcode del código mnemónico o instrucciones en ensamblador. El compilador de ensamblador que utilizaremos el programa MPASM.EXE de la Microchip. Como se muestra en la figura anterior, además del archive .ASM, es necesario otro archivo .INC, el cual es proporcionado por la Microchip. En el caso del PIC84 se denomina P16F84.INC. Este archivo contiene las definiciones del chip utilizado. Durante la compilación, el ensamblador genera una serie de archivos con el mismo nombre al del archivo fuente pero con distitnas extensiones. Veamos cuales son y que contiene cada uno de ellos: .HEX es el archivo que contiene el opcode que se debe grabar en la memoria de programa del microcontrolador PIC. .LST es un archive de texto en donde viene reportado el archivo fuente complete y la correspondiente traducción en opcode. Este no se utilize para programar el microcontrolador, pero es extremadamente útil para verificar el proceso de compilación que ha llevado a cabo el ensamblador. .ERR contiene la lista errores de compilación encontrados y el número de línea del archivo fuente donde se encontró. Los archivos .LST y .ERR sirven para controlar lo hecho en la compilación. Solo el .HEX se utilize para programar el microcontrolador. El archivo .HEX no viene en formato binario, es un archivo codificado en un formato inventado por la empresa norteamericana Intel para la descripción del archivo en formato ASCII, con el cual se facilita la transferencia a la memoria del microcontrolador PIC.
1.3 Analizando un archivo fuente Analicemos línea por línea el contenido de nuestro archivo fuente LED.ASM. Procedamos ahora a analizar el programa línea por línea. Partamod de la primera línea del código: PROCESSOR 16F84
PROCESSOR es una directiva del compilador que permite definir para que tipo de microprocesador vamos a escribir nuestro programa. Las directives no forman parte del conjunto de instrucciones del microcontrolador que el compilador convierte en un OPCODE, simplemente son indicaciones de las cuales se sirve el compilador para determiner el funcionamiento que va a seguir durante la compilación. En este caso le estamos diciendo al compilador que estamos escribiendo un programa para el PIC16f84. RADIX DEC
8
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
La directiva RADIX sirve para informar al compilador cual es la notación por defecto que van a tener los diferentes números que se escriban dentro del programa. En este caso, debido a la palabra DEC, establecemos que los valores numéricos se deben entender como decimales. Si vamos a especificar, por ejemplo, el número hexadecimal 10 (16 en decimal) no podemos escribir simplemente 10 porque el compilador lo entendería como 10 en decimal; debemos escribir 0x10 o H’10’. ERRORLEVEL -302
Esta directiva sirve para excluir algunos mensajes de error resultantes de la compilación. En este caso sirve para evitar que el compilador arroje estos dos tipos de errores: Message[302] C:\EPIC\LED.ASM 37 : Register in operand not in bank 0. Ensure that bank bits are correct. Message[302] C:\EPIC\LED.ASM 40 : Register in operand not in bank 0. Ensure that bank bits are correct.
Los cuales se detectaron en las líneas 37 y 40 de nuestro código fuente, en donde no estamos trabajando en el banco de memoria correcto. Más adelante veremos el significado real de este error, por ahora sigamos adelante.
INCLUDE "P16F84.INC"
Esta es una directiva muy importante y que vamos a utilizar mucho en nuestros programas. Con esta directiva le manifestamos al compilador nuestra intención de incluir un segundo archivo a nuestro código fuente denomiando P16F84.INC. El compilaador se limitará a sustituir la línea que contiene la directiva INCLUDe con el contenido del archivo especificado. LED EQU 0
Otra directiva ! Cuando entraremos a las instrucciones ? Paciencia mi amigo, paciencia.... ☺ La directiva EQU es muy importante, pues nos permite constantes simbólicas dentro de nuestro programa. En este caso la palabra LED en cualquier punto del programa será equivalente al valor 0. El objetivo principal de la directiva EQU es facilitar la lectura y entendimiento de los programas a un lector desprevenido. Es muy utilizada cuando manejemos banderas, más adelante explicaremos este concepto. Es importante resaltar que la palabra LED no es una variable más, simplemente es un nombre simbólico válido durante la compilación. No es posible escribir una instrucción donde se asigna a LED el número 3.
9
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Cuando el PIC trabaja dentro de su aplicación final, solo puede manipular la información suministrada por las instrucciones, no por las directivas. Veamos ahora la siguiente línea: ORG 0x0C
La directiva ORG permite definir una dirección donde el compilador va a ubicar los datos o las instrucciones siguientes. En este caso vamos a definir un área de datos dentro del PIC sobre la cual memorizar diversos datos dirante la ejecución de nuestro programa. Esta área coincide con la RAM del PIC, definida por la Microchip como el área de FILE REGISTER. Esta área no es otra cosa que la localización de la RAM disponible para el usuario y se encuentra a partir de la dirección 0x0C. Las direcciones de memoria anterioras a esta no pueden ser utilizadas como casillas de memoria de propósito generalm pues allí se han asignado previamente otros registros especializados para uso interno del microcontrolador. Count RES 2
En esta línea encontramos una etiqueta: Count y una directiva: RES. La directiva RES le indica al compilador que queremos reservar un cierto número de bytes en el interior del área de datos; en este caso 2 bytes. La etiqueta Count, donde Count es un nombre, es una marcación que en el resto del código fuente asumirá el valor de la dirección donde se ha insertado. Dado que previamente habíamos definido como dirección de inicio la 0x0C (con la directiva ORG), Count partirá desde 0x0C. Si por ejemplo, insertamos una etiqueta en la línea inmediatamente sucesiva, esa variable se ubicará en 0x0C + 2, es decir 0x0E. Una etiqueta se distingue de una constante simbólica porque su valor viene calculado en la fase de compilación. ORG 0x00
Esta segunda directiva nos permite señalar una dirección en el área de la memoria de programa (FLASH). Desde allí se alamacenarán las instrucciones mnemonicas que el compilador deberá convertir em opcodes para el PIC. El primer opcode que el microcontrolador va a seguir después de un RESET se memoriza en la posición 0, por eso es el valor 0x00 escrito en la ORG. bsf STATUS,RP0
Al fin la primera instrucción mnemónica completa. El microcontrolador PIC posee una CPU interna de tipo RISC, donde cada una de sus instrucciones ocupa una sola posición de memoria, opcode e incluso parámetros. En este caso la instrucción bsf (BIT SET FILE REGISTER) pone un uno (estado lógico alto) el bit contenido en la posición de RAM especificada. El parámetro STATUS viene definido en el archivo P16F84.INC a través de una directiva EQU. En este archivo se a asignado la dirección 0x03, la cual corresponde a una casilla reservada en la memoria ram del área de datos. El parámetro RP0 viene definido en el archivo P16F84.INC con el valor 0x05h y corresponde al quinto bit del registro
10
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
STATUS. Si se pone un 1 en este bit para cambiar el banco de trabajo y poder trbajar con los registros TRISA y TRISB, esto lo veremos más adelante. movlw B'00011111'
Esta instrucción significa: MOVE LITERAL TO W REGISTER, es decir, mueva un valor constante hacia el acumulador. El acumulador es un registro particular utilizado por la CPU en todas las situaciones donde se efectuen operaciones donde se necesite movimiento de valores de alguna posición de memoria. En la práctica es un registro de apoyo utilizado por la CPU para memorizar temporalmente un byte. El valor constante que vamos a memorizar en el acumulador es el 00011111 en binario. El bit ubicado más a la derecha es el bit 0 o menos significativo. En la instrucción siguiente: movwf TRISA
el valor 00011111 se memoriza en el registro TRISA (al igual que el registro STATUS, TRISA esta definido en el mismo archivo inc mediante otra directiva EQU) el cual define el funcionamiento de cada una de las líneas I/O del puerto A. En particular, cada bit en uno del registro TRISA configura como entrada la respectiva línea del puerto A, mientras un 0 lo configura como salida. En la siguiente tabla se muestra la configuración realizada en el PIC después de ejecutada esta instrucción:
Como podemos ver, los bits 5, 6 y 7 no corresponde a ninguna línea I/O por lo tanto el valor con que se configuren no importa.
11
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Las dos instrucciones que siguen determinan el funcionamiento del puerto B del microcontrolador: movlw B'11111110' movwf TRISB
En este caso la definición de las líneas será la siguiente:
Note como el valor 0 en el bit 0 del registro TRISB determina la configuración como salida de la respectiva línea del PIC. En nuestra aplicación esta línea se utiliza para manejar el LED. Ya dijimos que la instrucción movwf TRISB trnasfiere el valor contenido en el acumulador (inicializado previamente con la instrucción movlw B’11111110’) al registro TRISB. El significado de movwf es (en inglés) MOVE W TO FILE REGISTER. bcf STATUS,RP0
Esta instrucción es muy similar a la bsf vista en uno de los párrafos anteriores. La diferencia es que en este caso el bit respectivo se pone en uno. La sigla en este caso quiere decir (en inglés) BIT CLEAR FILE REGISTER. Desde el punto de vista funcional de este programa, esta instrucción nos permite el acceso a los registros internos del banco 0. Una descripción más detallada de este proceso lo veremos más adelante. bsf PORTB,LED
Con esta instrucción llevamos a cabo la primera operación en el entorno externo del PIC, especificamente en la línea RB0 del integrado. PORTB es una constante definida en el archivo P16F84.INC que nos permite referenciar el registros correspondiente a las líneas I/O del puerto B. En cuanto a la palabra LED, recordemos que al inicio del programa la definimos como 0, por lo que en esta línea nos estamos refiriendo a la línea RB0.
12
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
MainLoop
Esta línea contiene una etiqueta esto es, una referencia simbólica hacia una posición de memoria. EL valor de la etiqueta se calcula en la fase de compilación en base al número de instrucción, a la directiva ORG y a la instrucción que hace reservar espacio en la memoria del micro. En este caso, si contamos las instrucciones insertadas a partir de la última directiva ORG podriamos calcular que el valor que se asignará a MainLopp será 0x07. El valor que asume la etiqueta es importante pues su objetivo real es el de conocer la posición precisa su opcode en la memoria del PIC permitiendo referenciarla en una determinada posición de memoria. En este caso la etiqueta MainLoop se utiliza como punto de ingreso a un ciclo ( del inglés loop) de encendido y apagado de un LED, es decir, una porción de código que se repetirá cíclica e idefinidamente. call Delay
Esta instrucción determina una llamada (de ingles call) a una subrutina que inicia en correspondencia con la etiqueta Delay. La subrutina es una parte del programa especializada en una función muy específica que pueda necesitarse repetidamente dentro de un programa. Cada vez que necesitemos ejecutar esta función basta invocar la función. En este caso la subrutina inserta un retardo para darle tiempo al LED de prendido y apagado. Las instrucciones que componen la subrutina Delay se encuentran más adelante en el código fuente. btfsc PORTB,LED
El significado de esta instrucción es BIT TEST FLAG, SKIP IF CLEAR, es decir, controla el estado de un bit interno de un registro y se salta la instrucción sucesiva si el valor de dicho bit es cero. El bit que estamos controlando corresponde a la salida en donde se encuentra conectado el LED. A través de este test podemos determinar el estado del led para poder invertirlo, es decir, si se encuentra apagado se prende y si se encuentra prendido se apaga. goto SetToZero
Esta instrucción es un salto incondicional (del inglés GO TO, ir a) a la etiqueta SetToZero donde tenemos las instrucciones para prender el led. Esta instrucción se saltará las instrucciones sucesivas que sirven para apagar el led. bsf PORTB,LED goto MainLoop
Esta dos instrucciones activan el led y retorna el programa al ciclo de parpadeo. SetToZero bcf PORTB,LED goto MainLoop
Esta dos instrucciones apagan el led y retorna el programa al ciclo de parpadeo. La subrutina Delay Como se dijo anteriormente, esta subrutina inserta un retardo de casi un segundo y puede ser llamada desde nuestro código fuente mediante la instrucción call Delay. Veamos como funciona:
13
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Delay clrf Count clrf Count+1 DelayLoop decfsz Count,1 goto DelayLoop decfsz Count+1,1 goto DelayLoop retlw 0
Delay y DelayLoop son dos etiquetas. Delay identifica la dirección de inicio de la subrutina y se utiliza dentro para llamar cuerpo principal del programa. DelayLoop se ( invoca internamente de la el subrutina y sirve como punto de entrada al ciclo del inglés loop) de retardo. En la práctica el retardo se obtiene ejecutando una serie de instrucciones que no hacen absolutamente nada! Este tipo de retardo se denomina retardo por software o retardo por programa. Es el tipo de retardo mas sencillo de implementar y puede ser utilizado cuando podemos darnos el lujo de que el PIC no tenga que ejecutar otras tareas mientras se encuentra desarrollando el retardo. Las instrucciones: clrf Count clrf Count+1
CLEAR FILE REGISTER, borran las dos posiciones de RAM que se han reservado previamente mediante la instrucción: Count RES 2
Estas dos posiciones son consecutivas y se ubican paratir de la dirección referenciada por la etiqueta Count. decfsz Count,1
Esta instrucción significa DECREMENT FILE REGISTER, SKIP IF ZERO , es decir, decrementa el contenido de un registro (en este caso Count) y se salta la siguiente instrucción si el valor obtenido es cero. Si el valor obtenido no es cero, se ejecuta la instrucción consecutiva: goto DelayLoop
Nos dirige hacia la ejecución de un ciclo de retardo. Una vez el contador Count ha llegado a cero, se tienen las instrucciones: decfsz Count+1,1 goto DelayLoop
que decremetan el registro siguiente hasta que este llegue a cero. El registro Count+1 en particular se decrementerá en una unidad por cada 256 decrementos de Count. Cuando Count+1 llegue a cero se ejecuta la instrucción: return
el significado de esta instrucción es RETURN FROM SUBROUTINE, es decir, nos dará la salida de la rutina de retardo y la posibilidad de continuar con la ejecución de la instrucción consecutiva a la instrucción call Delay. Para finalizar END es una directiva que indica al compilador el fin del código en asembler.
1.4 Compilando un código en ensamblador
Veamos ahora como es posible efectuar en la práctica la compilación de un código en lenguaje ensamblador. El primer paso es crear en el disco duro una carpeta donde vamos a guardar todos los programas de este curso. Por ejemplo: C:\WEL
14
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
(Auqnue cualquier otro nombre es válido). Parsa trabajar adecuadamente es necesario descargar de internet el compilador MPASM disponible gratuitamente en el sitio de Microchip en la siguiente dirección: http://www.microchip.com/1010/pline/tools/archive/other/61/index.htm El archivo que se debe descargar se llama asm21500.zip (579K) y contiene el ensamblador MPASM en su versión para Windows (MPASMWIN.EXE) o para MS/DOS (MPASM.EXE) además de una serie de utilidades como todos los archivos .INC los cuales necesitaremos para trabajar con los microcontroladores de Microchip. Una vez expandido el contenido del archivo asm21500.zip en nuestro directorio de trabajo podemos abrir el archivo MPASMWIN.EXE cuya presentación es la siguiente:
Oprimiendo el boton de “Browse..." podemos seleccionar de nuestra carpeta de trabajo el archivo LED.ASM. Luego podemos oprimir el boton "Assemble". El ensamblador iniciará la compilación. Al terminar la compilación obtendremos el siguiente esquema:
15
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Si vamos al directorio C:\WEL podremos observar un nuevo archivo llamado LED.HEX, el cual contiene el código objeto que utilizaremos para programar el PIC, además de una serie de archivos auxiliares como LED.ERR y LED.LST. Ahora podemos programar el PIC16F84A con el programa compilado.
1.5 Que programador utilizar? Para programar los ejemplos presentados en este curso, hay dos opciones ha seguir. Existen dos modalides para programar los microcontroladores: la serial y la paralela. La empresa microEngineering Labs Inc. ha desarrollado un programa denominado EPIC para la programación paralela y la segunda opción es utilizando el puerto serial mediante nuestro programador WELPROG. Recomendamos el uso de un programador serial (ya sea el WELPROG o el PICStart PLUs de Microchip). Los usuarios del programador por el puerto paralelo han manifestado daños en la estructura del puerto, lo que puede implicar no poder utilizar el puerto paralelo para la impresora.
Las banderas de configuración del microcontrolador PIC El microcontrolador PIC dispone de una serie de banderas de configuración contenidos en la denominada configuration word. Estas bandera determinan algunos aspectos del funcionamiento del microcontrolador cuando este sigue un programa. La configuración las banderas se puede en establecer dentro fuente mediante la directiva de _CONFIG o establecerce el momento de del la código programación del microcontrolador. Todos los ejercicios analizados en este curso a exepción del manejo del tiempo real, utilizan la siguiente configuración:
16
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
* Oscilador en modalidad XT. En esta modalidad, el PIC funciona correctamente con un cristal de cuarzo conectado a los pines OSC1 y OSC2 como se muestra en el esquema del primer ejemplo. * Watch Dog Timer Deshabilitado. La función del WATCH DOG se explica más adelante en este curso. Cuando en alguno de los ejemplos de este curso se vaya a habilitar, se especificará claramente esta acción.
1.6 Programando el PIC con EPICWIN Una vez instalado correctamente la tarjeta de programación abrimos el programa EPICWIN.EXE, seleccionamos el tipo de microcontrolador que vamos a programar (PIC16F84A).
Insertamos el PIC en la base del programador teniendo cuidado en la orientación como se instale, para lo cual puede guiarse por el screen de la tarjeta. Se carga el archivo LED.HEX del directorio de trabajo C:\WEL (En el EPICWin se selecciona "Menu File" y luego "Open"). Por último nos aseguramos que los fusibles de programación esten bien configurados.
17
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Es importante seleccionar bien el tipo de oscilador con que vamos a trbaajr. Si vamos a hacerlo con cristal se debe elegir XT y deshabilitar el watch dog timer. Si metemos mal estos parámetros, los programas no nos funcionarán. Más adelante en este curso veremos ejemplos de cual es la función de estos parámetros y cuando modificarlos. Finalmente podemos hacer la programación (Menu "Run" --> "Program"). Si no se señalan errores en el sistema de programación tendremos el PIC listo para ser insertado en el circuito de ejemplo. Si alimentamos el circuito, podremos ver el LED parpadeando.
1.7 Programando el PIC con WELPROG PROGRAMADOR “In – circuit” DE MICROCONTROLADORES PIC
El software del programador está escrito en C para DOS, y puede ejecutarse desde un prompt o línea de comandos DOS en el ambiente Windows 3.1/95/98 y en máquinas que poseen procesadores Intel de 286 en adelante. Características del programador • • • •
Interfaz interactiva Acepta la variedad de familias de microcontroladores PIC 16xxx Lectura y escritura de archivos en formato IN8HEX Chequeo de memoria vacía
18
www.welgos.net
CURSO
• •
INTEGRAL
SOBRE
MICROCONTROLADORES
Lectura de la memoria de programa y de la palabra de configuración Programación “in circuit” o dentro de la aplicación.
TIPOS DE PIC SOPORTADOS POR LA TARJETA 12C508 16C620 16C64A 16C72
12C509 16C620A 16C65 16C72A
16C554 16C621 16C65A 16C73
16C556 16C621A 16C65B 16C73A
16C558 16C622 16C66 16C73B
16C61 16C622A 16C67 16C74
16C62 16C63 16C71 16C74A
16C62A 16C63A 16C710 16C74B
16C62B 16C64 16C711 16C76
16C77
16C84
16F83
16F84
16F84A
16C923
16C924
16CE623
16CE624
Instalación de la tarjeta Un programador “in circuit” se caracteriza por enviar el programa directamente a la memoria del PIC en cualquier sitio que este se encuentre ubicado. Esa es la principal diferencia con respecto a los programadores “STAND ALONE” o independientes, ellos cuentan con una base tipo ZIF en la cual se inserta el PIC en el momento de programarlo, luego deben retirarlo del programador e insertarlo dentro de la aplicación. Para utilizar este programador se debe tener a disposición el prototipo montado, en el cual se conecta la tarjeta programadora, tal como se muestra en la figura:
PC
Programador
prototipo
Para la conexión con el prototipo, la tarjeta cuenta con un conector de seis pines, cada uno de los cuales deben ser conectados con el PIC objetivo así: 1. MCLR. 2. DATA. Por este pin van los datos de programación y debe conectarse al pin RB7 del PIC objetivo. 3. CLOCK. Es la señal de reloj, debe conectarse al pin RB6 del PIC a programar. 4. GND. Es la tierra del programador, debe conectarse a la tierra del prototipo. 5. KEY. 6. VCC. En este pin van los voltajes de programación. Debe conectarse a los pines 12,6 o 14,6 del PIC.
19
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Instalación del software y guía rápida de programación Para instalar el programa debe crear una carpeta en el disco duro del computador llamada WELGOS y copiar los archivos en esta carpeta, no altera ningún registro de Windows y de la misma manera, para desinstalarlo solo basta borrar el archivo. Para ejectar el programa debe ejecutar un prompt de DOS y abrir la carpeta WELGOS: Cd welgos Luego ejecutar la siguiente sintaxis: WELGOS> progra / com1 (o com2 según donde lo tenga conectado). Si la tarjeta no se encuentra conectada al puerto serial, el software no establecerá comunicación y el programa no se ejecutará. Si la conexión con la tarjeta y el cable serial está bien instalado, se podrá entrar al pantallazo inicial del programa: En este pantallazo se indica el PIC actualmente seleccionado, el contenido del buffer de memoria ( si este aún no se ha cargado aparecerá el aviso de no definido) , la palabra de configuración y un menú de opciones. Para seleccionar cada una de las posibilidades de este menú, basta con teclear la letra que se encuentra a la izquierda de cada opción entre paréntesis, a continuación analicemos cada uno de los items de este menú.
Seleccionar tipo de PIC Este programador puede trabajar con toda la familia de microcontroladores PIC 16XXX. Con esta opción se selecciona el Pic en específico que se va a trabajar. Al presionar la tecla T, sale un listado de todos los PICs que se pueden trabajar, para esa selección se debe buscar el dispositivo correcot con las teclas de flecha hacia arriba y flecha hacia abajo o las teclas Repág. y Avpág. En este pantallazo aparece a la izquierda el tipo de PIC y a la derecha el tamnaño de la memoria de programa de cada uno de ellos
Leer PIC Al oprimir la tecla R, se puede leer el contenido de la memoria del micro. Este proceso se demora unos cuantos segundos. Al cabo de ls cuales aparece un nuevo menú, en el cual aparecen nuevas opciones. La lectura del programa del chip a quedado almacenado en un espacio de memoria llamado la imagen de entrada. Entre las nuevas opciones que aparecen se encuentran la de abrir un archivo de disco, la de escribir en el PIC, establecer palabra de configuración. 40
20
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Mostrar Buffer En el buffer se encuentra almacenado un programa en hexadecimal, el cual puede provenir de la lectura del PIC o de un archivo grabado en disco. Este buffer se puede visualizar con esta opción, con la cual se muestran todas las direcciones de memoria y su contenido.
Contenido del Buffer...........:IMAGEN DE LA MEMORIA DEL PIC [1] [2] [3] [4]
MODO DEL OSCILADOR : XT WATCH DOG TIMER.: DESHABILITADO PROTECCION DEL CODIGO: DESHABILITADO POWER UP TIMER: DESHABILITADO
[D] Buffer dump [R] LEER PIC [W] ESCRIBIR EN EL PIC [F] ESCRIBIR SOLO FUSIBLES [L] CARGAR ARCHIVO IN8HEX [V] VERIFICAR PIC [T] SELECCIONAR TIPO DE PIC [V] VERIFICAR PIC [H] PANEL DE PRUEBAS DEL HARDWARE [K] DESHABILITAR PROTECCION DEL CODIGO
Panel de pruebas del hardware Con esta opción se realizan una serie de pruebas para comprobar que la tarjeta está funcionando correctamente. Aquí se entra a un nuevo menú en el cual se permite variar los voltajes del conector que va hasta el pic objetivo.
Se muestran cinco tipos de pruebas distintas las cuales modifican los voltajes en cada uno de los pines del conector, de manera que si el aparato presenta alguna falla en la programación, el usuario puede llevar a cabo estas pruebas con un multímetro.
Programación del microcontrolador El primer paso para programar un microcontrolador es cargar el archivo hexadecimal resultante ensamblar código fuente. Este archivo debe estar en una de las de unidades de la el computadora; si pulsa la tecla hexadecimal L, el programa lle permitirá cargar el archivo hexadecimal que desea programar, para lo cual le pide la ubicación y el nombre del archivo.
21
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
DIGITE EL NOMBRE DEL ARCHIVO: c:\wel\led.asm
Cuando el archivo ha sido leído, queda almacenado en un buffer de memoria, por lo tanto podemos visualizarlo pulsando la letra D. Después de que se ha cargado el archivo hexadecimal, se deben establecer los fusibles de programación; ellos corresponden a las condiciones bajo las cuales va a funcionar el sistema. Esos parámetros son: el tipo de oscilador que se va a instalar, el estado del temporizador watchdog, la habilitación de la protección del código y el PWRT. En el menú aparecen estas opciones para que las modifique de acuerdo a sus necesidades; como se puede observar, a la izquierda de cada fusible aparece un número ([1], [2], [3] y [4]), oprimiendo cada número se modificarán cada uno de los fusibles. Por ejemplo, si el oscilador se encuentra en RC y oprime la tecla 1 este fusible cambiará a XT, si lo oprime nuevamente cambiará a INTRC y así sucesivamente para cada una de las opciones. Una vez se ha seleccionado el microcontrolador, cargado el archivo hexadecimal y configurado adecuadamente los fusibles, puede proceder a programar. Para llevar a cabo este proceso hay que oprimir la tecla W, con la cual se inicia el almacenamiento del programa en la memoria del PIC. En este momento podrá apreciar en la pantalla como van apareciendo poco a poco las distintas posiciones de memoria llenándose con los distitnos datos del archivo hexadecimal. 0000: 0008: 0010: 0018: 0020:
2813 ....... ....... ..... 306E 0080 306E 0000 0000 0000 0000 088E 2080 4321 0B8D 2806 3400 2134 OE40 3456 5639 304F 34E0 1200 00A0 0789 2234 00B1
008E 0000 0050 0090
El programa realiza un procedimiento de verificación para comprobar que en cada posición se ha almacenado el dato correcto, para ello compara el dato actual programado con el dato leído en el buffer. Al final de la programación se brinda un pequeño reporte donde se especifica si han ocurrido errores o si la programación se desarrolló correctamente. Si ha ocurrido un error en la programación de alguna de las posiciones de memoria, aparecerá un asterisco (*) enseguida de la posición donde se ha presentado la falla. Finalmente es posible realizar una verificación total del programa grabado en el microcontrolador, comparándo este último con el buffer de memoria que permanece en el buffer de la PC.
22
www.welgos.net
CURSO
INTEGRAL
SOBRE
;************************************************** ; Programa ; LED.ASM ; ; ; http://www.wellgos.com ;************************************************** PROCESSOR 16F84 RADIX DEC INCLUDE "P16F84.INC" ERRORLEVEL -302 ;Setup of PIC configuration flags ;XT oscillator ;Disable watch dog timer ;Enable power up timer ;Disable code protect __CONFIG 0x3FF1 LED EQU 0 ORG 0x0C Count RES 2 ;Reset Vector ;Start point at CPU reset ORG 0x00 bsf STATUS,RP0 movlw B'00011111' movwf TRISA movlw B'11111110' movwf TRISB bcf STATUS,RP0 bsf PORTB,LED MainLoop call Delay btfsc PORTB,LED goto SetToZero bsf PORTB,LED goto MainLoop SetToZero bcf PORTB,LED goto MainLoop ;Subroutines ;Software delay Delay clrf Count clrf Count+1 DelayLoop decfsz Count,1 goto DelayLoop decfsz Count+1,1 goto DelayLoop return END
23
www.welgos.net
MICROCONTROLADORES
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
LIST ; P16F84.INC Standard Header File, Version 2.00 Microchip Technology, Inc. NOLIST ; This header file defines configurations, registers, and other useful bits of ; information for the PIC16F84 microcontroller. These names are taken to match ; the data sheets as closely as possible. ; Note that the processor must be selected before this file is ; included. The processor may be selected the following ways: ; 1. Command line switch: ; C:\ MPASM MYFILE.ASM /PIC16F84 ; 2. LIST directive in the source file ; LIST P=PIC16F84 ; 3. Processor Type entry in the MPASM full-screen interface ;======================================================================= === ; ; Revision History ; ;======================================================================= === ;Rev: Date: Reason: ;2.00 07/24/96 Renamed to reflect the name change to PIC16F84. ;1.01 05/17/96 Corrected BADRAM map ;1.00 10/31/95 Initial Release ;======================================================================= === ; ; Verify Processor ; ;======================================================================= === IFNDEF __16F84 MESSG "Processor-header file mismatch. Verify selected processor." ENDIF ;======================================================================= === ; ; Register Definitions ; ;======================================================================= === W EQU H'0000' F EQU H'0001' ;----- Register Files----------------------------------------------------INDF EQU H'0000' TMR0 EQU H'0001' PCL EQU H'0002' STATUS EQU H'0003' FSR EQU H'0004' PORTA EQU H'0005' PORTB EQU H'0006' EEDATA EQU H'0008' EEADR EQU H'0009' PCLATH EQU H'000A' INTCON EQU H'000B' OPTION_REG EQU H'0081'
24
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
TRISA EQU H'0085' TRISB EQU H'0086' EECON1 EQU H'0088' EECON2 EQU H'0089' ;----- STATUS Bits ------------------------------------------------------IRP EQU H'0007' RP1 EQU H'0006' RP0 EQU H'0005' NOT_TO EQU H'0004' NOT_PD EQU H'0003' Z EQU H'0002' DC EQU H'0001' C EQU H'0000' ;----- INTCON Bits ------------------------------------------------------GIE EQU H'0007' EEIE EQU H'0006' T0IE EQU H'0005' INTE EQU H'0004' RBIE EQU H'0003' T0IF EQU H'0002' INTF EQU H'0001' RBIF EQU H'0000' ;----- OPTION Bits ------------------------------------------------------NOT_RBPU EQU H'0007' INTEDG EQU H'0006' T0CS EQU H'0005' T0SE EQU H'0004' PSA EQU H'0003' PS2 EQU H'0002' PS1 EQU H'0001' PS0 EQU H'0000' ;----- EECON1 Bits ------------------------------------------------------EEIF EQU H'0004' WRERR EQU H'0003' WREN EQU H'0002' WR EQU H'0001' RD EQU H'0000' ;======================================================================= === ; ; RAM Definition ; ;======================================================================= === __MAXRAM H'CF' __BADRAM H'07', H'50'-H'7F', H'87' ;======================================================================= === ; ; Configuration Bits ; ;======================================================================= === _CP_ON EQU H'000F' _CP_OFF EQU H'3FFF' _PWRTE_ON EQU H'3FF7' _PWRTE_OFF EQU H'3FFF' _WDT_ON EQU H'3FFF'
25
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
_WDT_OFF EQU H'3FFB' _LP_OSC EQU H'3FFC' _XT_OSC EQU H'3FFD' _HS_OSC EQU H'3FFE' _RC_OSC EQU H'3FFF' LIST
CURSO INTEGRAL PIC
Capítulo 2 Arquitectura interna del PIC16F84A 26
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
En la lección anterior vimos un poco de práctica, ahora pasemos a la teoría. Empezemos estudiando como se estructura internamente un microcontrolador PIC. En la figura siguiente se muestra un diagrama en bloques simplificado de la arquitectura interna del PIC16F84A en el cual nos basaremos para las explicaciones que siguen a continuación. Los bloques resaltados en amarillo son los que nos referiremos en la explicación. Iniciamos con la memoria de programa (PROGRAM MEMORY) y con la memoria de datos (REGISTER FILE).
La PROGRAM MEMORY es una especial de tipo FLASH, borrable 2.1 La Memoria dememoria Programa eléctricamente y se utiliza para almacenar el programa que el microcontrolador debe seguir.
27
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
La capacidad de memoria en este caso es de 1024 posiciones, cada una de las cuales puede contener un código operativo (opcode) de 14 bits, es decir, una instrucción del microcontrolador, por lo tanto el microcontrolador puede almacenar un programa de 1024 instrucciones. Las direcciones reservadas para la memoria de programa van desde la 0x000 hasta la 0x3FF (0x3FF en hexadecimal equivale a 1023 en decimal). El microcontrolador PIC solo puede seguir instrucciones memorizadas en estas posiciones. No puede leer, escribir o cancelar posiciones que sobrepasen este rango. Para escribir, leer o cancelar estas posiciones es necesario un dispositivo externo denominado programador. Un ejemplo de este tipo de dispositivos es el EPIC Plus, el PICSTART de la Microchip o el WELPROG (incluido en este curso). La primera posición de memoria, debe contener la primera instrucción que el microcontrolador debe seguir después del reset (reinicIo) y por esto se denomina vector de reset. Como podemos recordar, en el archivo LED.ASM presentado en la lección anterior, se había insertado la directiva: ORG 0x00
Para señalizar el inicio del programa. Esta directiva establece el hecho de que la ejecución del programa después de un reset parte desde la dirección 0x000 del área de memoria de programa. Después de la directiva ORG 0x00 se tiene: bsf STATUS,RP0
que será la primera instrucción que se ejecuta enseguida.
2.2 Los registros (Register File) El archivo de registros (REGISTER FILE) es un conjunto de posiciones de memoria RAM sobre los cuales es posible modificar el contenido sin el auxilio de un programador externo, simplemente se hace directamente desde el programa que se está ejecutando en el microcontrolador. Debido a que el archivo de registros se utiliza normalemente para almacenar las variables del programa, su contenido es variables durante la ejecución del programa. Contrariamente a lo que ocurre con la memoria de programa, el archivo de registros pierden su contenido cuando el microcontrolador es reiniciado, por lo que es recomendable inicializar las variables en el inicio del programa. Alguna posiciones determinadas del archivo de registros vienen con funciones predeterminadas para el control del hardware del microcontrolador como se muestra en la siguiente figura.
28
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Las posiciones de memoria del archivo de registros se pueden direccionar directamente en un espacio de memoria que va desde 0x00 hasta 0x2F para un total de 48 bytes, denominado página 0. Un segundo espacio de direccionamiento denominado página 1 va desde la 0x80 hasta la 0xAF. Para acceder a este segundo espacio es necesario recurrir a dos bits auxiliares denominados RP0 y RP1 pertenecientes a un registro especial denominado estado. Las primera 12 posiciones de la página 0 (0x00 hasta 0x0B) y de la página 1 (desde la 0x80 hasta la 0x8B) son los reservados para funciones especiales para el funcionamiento del microcontrolador y no se pueden utilizar para otras funciones. Las 36 posiciones en la página 0, direccionadas desde la 0c0C hasta la 0x2F puede utilizarse libremente en nuestro programa para memorizar variables, contadores, etc. En nuestro ejemplo LED.ASM, la directiva: ORG 0x0C
Indica la dirección de inicio del área de datos de nuestro programa. La directiva siguiente: Count RES 2
Reserva un espacio de dos posiciones, que el programa utilizará oara memoriza el contador de retardo de la subrutina Delay. Los registros especializados del PIC se utilizan de un modo diferente dentro del programa. Por ejemplo, se recurre a la copia del registro especializado TRISA (0x85) y TRISB (0x86) para definir cuales de las líneas I/O son entradas y cuales serán salidas. El estado lógico deAlgunos las líneas I/O dependen del valor de los registros (0x05) y PORTB (0x06). registros sirven para reportar el estado delPORTA funcionamiento de los dispositivos internos del microcontrolador o el resultado de operaciones aritméticas y lógicas. Es necesario conocer exactamente cual es la función de cada uno de los registros especializados y cual es el efecto que se obtiene de manipular sus contenidos. Para facilitar la manipulación de los registros especializados,
29
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Microchip proporciona un listado de nombres que identifican cada uno de los registros mediante un nombre único relacionados con la dirección correspondiente en el archivo de registros, dicho listado se guarda en un archivo llamado P16F84.INC. En nuestro programa LED.ASM el archivo de definiciones se ha insertado mediante la directiva INCLUDE. Si por ejemplo, vamos a definir la configuración de las líneas del puerto B del PIC como salidas, debemos utilizar el registro TRISB. Para ello debemos referenciar directamente el registro mediante su dirección: movlw B'00000000' movwf 0x86
o podemos referenciarlo son su nombre simbólico: movlw B'00000000' movwf TRISB
lo que podemos hacer gracias a que insertamos la directiva INCLUDE "P16F84.INC" en nuestro código fuente.
2.3 La ALU
La ALU (acrónimo de Arithmetic and Logic Unit: unidad lógico artimética) es el componente más complejo del microcontrolador em cuanto contiene toda la
30
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
circuitería necesaria para llevar a cabo las funciones de calculo y manipulación de los datos durante la ejecución del programa. La ALU es un componente presente en todos los microprocesadores y de ella depende directamente la potencia de calculo del microcontrolador. La ALU del PIC16F84A puede operar con valores de 8 bit, es decir valores numéricos hasta 255. Existen microprocesadores con una ALU de 16, 32, 64, y más. La familia Intel© 80386©, 486© y Pentium© por ejemplo, disponen de una ALU de 32 bits. Naturalmente estos microprocesadores poseen una capacidad de cálculo muy superior a los PIC.
2.4 El Acumulador o registro W Directamente conectado a la ALU se encuentra el registro W denominado acumulador. Este registro consiste de una simple posición de memoria que puede contener un valor de 8 bits. La diferencia sustancial que tiene el registro W con otras posiciones de memoria consiste en que para referenciar al registro W, la ALU no debe hacer un direccionamiento a la memoria, lo puede hacer directamente. El registro W se utiliza muy frecuentemente en los programa de microcontroladores. Observemos un ejemplo práctico. Supongamos que debemos poner en la posición de memoria 0xC del una archivo de registros el valor de 0x01. No existe en el microcontrolador instrucción que nos permita efectuar esta operación por sí sola; debemos recurrir necesariamente al acumulador y usar una pequeña secuencia de instrucciones. Veamos por qué: Como habíamos mencionado anteriormente, el opcode de una instrucción no puede ser mayor de 14 bits, mientras que para llevar a cabo la operación que deseamos necesitamos: 8 bits para especificar el valor qie queremos almacenar en la posición de memoria, 7 bits para especificar en cual posición de memoria vamos a insertar nuestro valor, 6 bits para especificar cual instrucción vamos a utilizar. Todo esto nos da un total de 8 + 7 + 6 = 21 bits. Debemos escribir las siguientes dos instrucciones: movlw 0x01 movwf 0x0C
la primera instrucción carga el registro W con el valor 0x01H con la instrucción MOVe Literal to W. Luego podemos mover el contenido de la posición 0x0C con la instrucción MOVe W to F.
31
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
2.5 El Contador de Programa (PC)
Como habíamos mencionado anteriormente, el PIC16F84A inicia la ejecución del programa a partir del vector de reset empezando por la instrucción memorizada en la primera posición de memoria (dirección 0x000). Después de ejecutada esta primera instrucción, pasa a la instrucción siguiente, memorizada en la posición 0x001 y así sucesivamente. Si no existiera ninguna instrucción que pueda influenciar o estar en capacidad este orden de ejecución, el PIC seguiría ejecutando todas las instrucciones sucesivas hasta llegar a la última posición de memoria disponible. Casi todoinstrucciones microprocesador o lenguaje brinda el la flujo posibilidad ejecutar de salto, con lo de queprogramación podemos modificar normalde de la ejecución del programa en base a las exigencias del programador.
32
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Una de estas instrucciones es la GOTO (del inglés GO TO, ir a), la cual nos permite cambiar la secuencia de la ejecución y “saltar” directamente a otro punto de la memoria de programa y continuar la ejecución desde ese punto.
Miremos un ejemplo: ORG 0x00 Point1
movlw 10 goto Point1 Una vez se reinicia el microcontrolador, se ejecutará la instrucción MOVLW 10, memorizada en la posición de memoria 0x000, la cual cargará en el acumulador el valor decimal 10, luego se pasa a la instrucción GOTO Point1. Esta instrucción determina un salto incondicional a la posición de memoria apuntada por la etiqueta Point1, la cual es de nuevo la 0x000. Este programa no hará otra cosa más que ejecutar infinitamente estas dos intrucciones. Durante este ciclo o lazo (loop) para determinar cual es la instrucción siguiente que se debe ejcutar, el PIC utiliza un registro especial denominado el Contador de Programa (PROGRAM COUNTER, PC) el cual posee la dirección de la próxima instrucción que se debe ejecutar. Este registro se incrementa automáticamente con cada instrucción, de esta manera actualiza la dirección de la siguiente instrucción que se debe ejecutar. En el momento de un reset, el contador de programa se borra, poniendose de nuevo en 0x000. La instrucción GOTO permite modificar el contenido del contador de programa para de esa manera ejecutar el salto hacia un punto en cualquier parte de la memoria de programa.
2.6 El puntero a la pil a (Stack Pointer) Otra instrucción muy utilizada y que también puede modificar el valor del contador de programa es la instrucción CALL (del inglés l lamar) con la cual podemos hacer el llamado a subrutinas. Esta instrucción funciona de manera muy similar al GOTO. La diferencia consiste en el hecho de que después del salto, el PIC memoriza en un registro especial denominado la pila (stack) la dirección de la siguiente instrucción que se iba a ejecutar antes de hacer el salto.
Veamos esto con un ejemplo: ORG 0x00 Point1 movlw 10 call Point2
33
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
goto Point1 Point2 movlw 11
return
En este caso el PIC después de ejecutar MOVLW 10, pasa a la instrucción CALL Point2. Antes de saltar memoriza en la pila la dirección 0x002, que es la dirección que le sigue a la dirección donde se encuentra CALL. Luego se ejecuta la instrucción MOVLW 11 y la instrucción RETURN (del inglés retorno). Esta instrucción, como su nombre lo indica, permite “retornar” a la instrucción siguiente desde donde se invocó a CALL, es decir, al punto exacto donde se abondó el flujo normal del programa, acudiendo a la información almacenada en la pila. Lo que acabamos de hace es lo que se denomina una llamada a subrutina. Es decir, la interrupción momentanea del flujo normal del programa para invocar la ejecución de otro conjunto de instrucciones agrupadas dentro de una unidad denominada subrutina, y luego retornar al flujo normal de la ejecución. La pila recibe ese nombre debido a que en realidad lo podemos asemejar a una canasta donde apilamos, una sobre otra, distintas direcciones de retorno que se deben recuperar en un programa, debido al uso de una o varias instrucciones CALL. Este tipo de memorización se denomina LIFO (Last In First Out), en donde el último elemento almacenado (last in) es necesariamente el primero en salir ( First Out). Gracias a esta característica, es posible efectuar una serie de instrucciones CALL anidadas sin perder el flujo normal en el momento en que se encuentre una instrucción RETURN. Veamos otro ejemplo: ORG 0x00 Point1 movlw 10 call Point2 goto Point1 Point2 movlw 11 call Point3
return Point3 movlw 12
return En este caso, al efectuar la subrutina Point2, se encuentra otro CALL a la subrutina Point3. En esta última sección del programa se encuentra un RETURN se entra a la subrutina Point2 donde se ejecuta el segundo RETURN y de allí se retoma el flujo normal del programa principal. En este caso se han memorizado dos posiciones en la pila, ya que se ejecutan dos CALL antes de encontrar un RETURN. El PIC 16F84A dispone de una pila de 8 niveles, lo que permite 8 llamados anidados.
34
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Es muy importante que en la escritura de un programa, que siempre haya una instrucción RETURN por cada instrucción CALL. Esto evitará desalineamientos en la pila que pueden traernos errores de compilación que pueden ser difíciles de detectar.
2.7 Realizando un secuenciador de luces En este segundo ejercicio vamos a ampliar el primer ejercicio para hacer un secuenciador de luces con cuatro diodos led. El nuevo programa se ha denominado SEQ.ASM. En la siguiente figura se muestra el diagrama esquemático del nuevo circuito, el cual como se puede ver, es muy parecido al montaje anterior, con la diferencia que hay cuatro LED en lugar de uno.
Las líneas utilizadas son RB0 para el primer LED, RB1 para el segundo, RB2 para el tercero y RB3 para el cuarto. Estos pines debe ser configurados como salidas en el inicio del programa cambiando las siguientes instrucciones: movlw B'11111110' movwf TRISB por movlw B'11110000' movwf TRISB
35
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
en donde los cuatro bits menos significativos, corresponden a las líneas RB0, RB1, RB2 y RB3. las cuales se configuran como salidas. En el área de memoria del archivo de registros (en el código fuente inicia con la directiva ORG 0x0C) de nuevo se tienen dos bytes reservados para la variable Count y se reservan otros dos para la etiqueta Shift, la cual utioizaremos para determinar la secuencia del movimiento del LED. La directiva adicionada es: Shift RES 1
Antes de emnpezar el ciclo principal (etiqueta MainLoop) inicilizamos el nuevo registro (Shift) con el valor 00000001B así: movlw B'00000001' movwf Shift En este punto, dentro del ciclo principal de nuestro programa, nos ocuparemos de transferir el contenido memorizado en el registro Shift sobre el puerto B, obteniendo la iluminación del primer LED, así: movf Shift,W movwf PORTB para efectuar el secuenciamiento de la iluminación de los LED necesitamos rotar el contenido del registro Shift, con las siguientes instrucciones : bcf STATUS,C rlf Shift,F la primera instrucción borra el bit CARRY del registro de estado, esto se analizará en la siguiente lección. La instrucción RLF (Rotate Left F through Carry: rota el registro a través del carry) se encarga de rotar hacia la izquierda el contenido del registro. Es decir, el bit de la posición pasaaaocupar la posición de la (acarreo) posición 6que pasa la bit cinco y así sucesivamente. El bit 07pasa el bit6,deelcarry es aun pertenciente a un registro de la CPU denominado STATUS (estado) y el contenido del carry pasa al bit 7. Es por esta razón que inicialmente borramos el contenido del carry mediante la instrucción BCF STATUS,C. En este punto el registro Shift tendrá el valor 00000010 y en la siguiente transferencia al puerto B se activaráel LED 2 y se desactivará el LED 1. Cuando el bit 4 de Shift valga 1, podemos deducir que ya se han activado los cuatro LED, por lo tanto debemos repetir el ciclo para que se vuelva a ctivar el LED 1. Miremos las siguientes instrucciones: btfsc Shift,4 swapf Shift,F La instrucción BTFSC Shift,4 detecta el momento en que el bit 4 del registro Shift vale 1. Si detecta un cero se salta la instrucción siguiente que en este caso es SWAPF Shift,F. La instrucción SWAP (del inglés intercambiar) sirve para intercambiar el contenido de los cuatro bits menos significativos con los cuatro bits más siginificativos. Cuando el registro Shift toma el valor 00010000 debido a las rotaciones, la instrucción SWAP convierte este valor en 00000001, para reiniciar la secuencia de encencido de los diodos LED.
36
www.welgos.net
CURSO
INTEGRAL
SOBRE
;************************************************** ; Curso integral de microcontroladores Pic ; SEQ.ASM ; ; (c) 2003, WELGOS electronica ; http://www.wellgos.com ;************************************************** PROCESSOR 16F84 RADIX DEC INCLUDE "P16F84.INC" ERRORLEVEL -302 ;Setup of PIC configuration flags ;XT oscillator ;Disable watch dog timer ;Enable power up timer ;Disable code protect __CONFIG 0x3FF1 ORG 0x0C Count RES 2 Shift RES 1 ;Reset Vector ;Program start point at CPU reset ORG 0x00 bsf STATUS,RP0 movlw B'00011111' movwf TRISA movlw B'11110000' movwf TRISB bcf STATUS,RP0 movlw B'00000001' movwf Shift MainLoop movf Shift,W movwf PORTB bcf STATUS,C rlf Shift,F btfsc Shift,4 swapf Shift,F call Delay goto MainLoop ; Subroutines Delay clrf Count clrf Count+1 DelayLoop decfsz Count,1 goto DelayLoop decfsz Count+1,1 goto DelayLoop return END
CURSO
INTEGRAL PIC
Capítulo 3 37
www.welgos.net
MICROCONTROLADORES
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Introducción a los periféricos 3.1 Los puertos A y B El PIC16F84A dispone de un total de 13 líneas I/O organizadas en dos puertos denominados Puerto A y puerto B. El puerto A dispone de 5 líneas configurables como entradas o como salidas, identificadas como RA0, RA1, RA2, RA3 y RA4. El puerto B dispone de 8 líneas también configurables como entradas o como salidas, ellas son RB0, RB1, RB2, RB3, RB4, RB5, RB6 y RB7.
Las líneas de cada uno de los puertos poseen una arquitectura interna determinada dentro del microcontrolador. Para la gestión de la líneas I/O, el PIC dispone de dos registros internos, uno para cada puerto. Ellos se denominan TRISA para determinar el funcionamiento del puerto A y el registro TRISB para configurar el puerto B.
38
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Cada uno de los bits contenidos en los registros anteriores tienen una correspondencia unívoca con una de las líneas I/O. Por ejemplo, el bit 0 del registro PORTA y del regsitro TRISA corresponde a la línea RA0, el bit 1 a la línea RA1 y así sucesivamente. Si el bit 0 del regsitro TRISA se pone en cero, la línea RA0 se configura como salida y el valor que se ponga en el bit 0 de PORTA se verá reflejado en el estado lógico de dicha línea (0= 0 voltios, 1 = 5 voltios). Si en el bit 0 del registro TRISA se pone un uno, la línea RA0 se configurará como entrada, en este caso, el estado lógico dependerá de la circuitería externa conectada a la línea RA0 y dicha entrada externa se verá reflejasa en el estado del bit 0 del registro PORTA. Miremos un ejemplo práctico, instalemos un LED sobre la línea RB0 y un interruptor en la línea RB4. Miremos el código siguiente: movlw 00010000B tris B estamos poniendo un 0 en el bit 0 (RB0 como entrada) y un 1 en el bit 4 (línea RB4) para que sea una entrada. Si recordamos la notación binaria del lenguaje ensamblador, podremos recordar que el bit menos significativo corresponde al bit 0 (el que se encuentra en la primera posición de derecha a izquierda). Para encender el LED podemos escribir lo siguiente: bsf PORTB,0 y para apagarlo: bcf PORTB,0 Para leer el estado del interruptor conectado a la línea RB4: btfss PORTB,4 goto SwitchAMassa goto SwitchAlPositivo
3.2 Estado de entrada de las líneas de I/O Para entender la adaptabilidad del microcontrolador PIC para las diversas configuraciones, la Microchip a implementado diversas topologías para las líneas I/O. Cada grupo de pines posee un comportamiento distinto a los otros grupos. Conociendo bien el funcionamieno de los diversos estados de las entradas podemos disfrutar mejor de las características y optimizar su uso en nuestros proyectos. Estado de las entradas de las líneas RA0, RA1, RA2 e RA3 Iniciemos con elgrupo de las líneas RA0, RA1, RA2 y RA3 el cual reproducimos en la siguiente figura, el esquema del estado de las entradas se encuentra en las hojas de datos de la Microchip:
39
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Como se habiamos mencionado anteriormente, la configuración de una línea como entrada o salida depende del estado del bit correspondiente en el registro TRIS (TRISA para el puerto A y TRISB para el puerto B).Pongamos como ejemplo la línea RA0 y analizemos su funcionamiento cuando actúa como entrada. Funcionamiento como entrada Para configurar la línea RA0 como entrada, debemos poner un 1 en el bit 0 del registro TRISA, así: bsf TRISA,0 Esto determina una conmutación a 1 del estado lógico del flip-flop tipo D indicado con el bloque TRIS latch. Por cada línea de I/O existe un flip-flop de este tipo y su estado lógico está ligado al estado lógico del bit correspondiente en el registro TRIS (esto quiere decir que un bit en el registro TRIS se implementa físicamente con un TRIS latch). La salidaque, Q delindependientemente TRIS latch se conecta la entrada de una lógica OR. Esto significa delavalor presente en lacompuerta otra entrada, la salida de la compuerta OR siempre será 1. En esta condición el transistor P se activa y mantiene la línea RA0 conectada al positivo de la alimentación.
40
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
La salida negada del TRIS latch se conecta a la entrada de una compuerta AND, cuya salida siempre valdrá cero debido a que una de sus entradas esta en cero. En esta condición el transistor N no se activará y mantendrá la línea RA0 desconectada de la tierra. El estado lógico de la línea RA0 dependerá exclusivamente de la circuitería externa que se le conecte. Ahora es posible leer el estado mediante la circuitería de entrada de los bloques representados por el buffer de entrada TTL y el latch de entrada. Funcionamento como salida Para configurar la línea RA0 como salida, debemos poner en 0 el bit 0 del registro TRISA mediante la instrucción: bcf TRISA,0 Esto determina la conmutación a 0 de la salida Q del latch TRIS (y a 1 de la salida Q negada). En este estado el valor en la salida de la compuerta OR y AND depende exclusivamente del estado de la salida Q negada del latch de datos. Así como en el latch TRIS, el latch de datos depende del estado de un bit de un regsitro, en particular del registro PORTA. La salida negada viene enviada a la entrada de las dos compuertas lógicas OR y AND y de estas a la base de los transistores P y N. Si ponemos un 0 en el bit 0 del registro PORTA con la instrucción: bcf PORTA,0 obtenemos la conducción del transistor N con la consiguiente conexión a tierra de la línea RA0. Si por el contrario ponemos un 1 en el bit 0 con la instrucción: bsf PORTA,0 obtenemos la conducción del transistor P y la conexión de RA0 con los +5 voltios. En esta condición siempre es posible leer nuevamente el valor enviado sobre la línea a través de la circuitería de entrada.
Estado de salida de la línea RA4 Analicemos ahora el funcionamiento como salida de la línea RA4, la cual se diferencia de las demás líneas de I/O en que comparte su función con la del contador interno del microcontrolador (este tema lo abordaremos más adelante), por eso es común encontrar diagramas donde este pin se encuentra con el nombre RA4/TOCKI. En la siguiente figura se muestra el esquema en bloques del estado de salida RA4:
41
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
La lógica de conmutación es idéntica a la del grupo de líneas RA0-3 a excepción de La carencia de la compuerta OR y del transistor P. Esto significa, en términos prácticos, que cuando la línea RA4 viene programada como salida y tiene un 1, no viene conectada al positivo. Tal tipo de circuitería de salida se denomina en "colector abierto". Si necesitamos sacar uu 1 por RA4 necesitamos poner externamente una resistencia de pull-up conectada al positivo de la alimentación. En cuanto a la utilización de la línea indicada en el esquema como entrada de TMR0, ese tema lo veremos más adelante.
Estado de salida de las líneas RB0, RB1, RB2 y RB3 En este la grupo dese líneas disponemos de unaentradas. circuitería de weak up que se activan cuando líneas han programado como El estado de la línea depende exclusivamente de la circuitería externa.
42
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Si tal circuitería es de colector abierto puede constituirse simplemente con un sencillo pulsador con una resistencia de pull-up conectada a 5 voltios, el cual en el momento de pulsarse conecte a tierra la línea I/O. La circuiteria de weak pull-up permite evitar el uso de resistencias de pull-up, para activar o desactivar esta función se activa o desactiva el bit RBPU de un registro interno del microcontrolador denominado OPTION. En esta figura se muestra el esquema de bloques del estado de entrada de este grupo de pines:
La línea RB0 presenta una característica muy particular. Cuando viene configurada como entrada, puede generar, en correspondencia con un cambio de estado lógico, una interrupción, esto es, como su nombre lo indica, una interrupción inmediata del programa que se está ejecutando y una llamada a una subrutina especial denominada servicio de interrupción. Hablaremos de este importante tema más adelante.
Estado de salida de las líneas RB4, RB5, RB6 y RB7 La circuitería interna de conmutación de este grupo de líneas es idéntica a la del grupo RB0-3. Estas líneas disponen de la circuitería de weak pull-up. En la siguiente
43
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
figura se reproduce el diagrama de bloques de las salidas tomada de las hojas de datos de Microchip:
En la lección anterior, mostramos una secuenciador de luces utilizando las líneas RB0-3 como líneas de salida, veamos ahora como realizar en entrada a tierra configurando las líneas de RB4 a RB7 como entradas. Ampliemos el circuito presentado en la lección 2 con cuatro pulsadores denominados SW1, SW2, SW3 y SW4.
Esquema Cada uno eléctrico de los pulsadores conecta a tierra las líneas de entrada, las cuales normalmente se mantienen a +5 voltios mediante una resistencia (de R6 a R9). Por ejemplo, el pin 10 del PIC16F84A se mantendrá en +5 voltios hasta que el pulsadro SW1 no se active. Cuando esto ocurra el pin verá 0 voltios. Realizemos un programa
44
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
de ejemplo en donde se van iluminando los led D1, D2, D3 y D4 en correspondencia a cuatro pulsadores SW1, SW2, SW3 y SW4. El código fuente del ejemplo se muestra en el archivo INPUT.ASM . En la parte inicial del programa se pueden apreciar las siguientes instrucciones: movlw 11110000B movwf TRISB con las cuales se configuran las líneas de RB0 a RB3 como salidas para conectar allí los LED y las líneas de RB4 a RB7 como entrada para conectar en ellas los cuatro pulsadores. La instrucción: bcf STATUS,RP0 Efectúa una conmutación del banco al registro 0 de manera que podemas acceder directamente al estado de las líneas de I/O. MainLoop clrf PORT Esta instrucción apaga todos los diodos led conectados al puerto B. btfss PORTB,SW1 bsf PORTB,LED1 Este par de instrucciones se coloca por cada línea de entrada que posee un pulsador, y con ella se verificar la activación de estos para activar el led correspondiente. Si detecta un uno en SW1: btfss PORTB,SW1 se salta la siguiente instrucción: bsf PORTB,LED1 sólo si el pusador SW1 está oprimido se ejecuta la enterior instrucción. El mismo proceso se repite para todos los pulsadores y al final se ejecuta todo el ciclo neuvamente gracias a la instrucción: goto MainLoop
45
www.welgos.net
CURSO
INTEGRAL
SOBRE
;************************************************** ; Curso integral de microcontroladores Pic ; INPUT.ASM ; ; (c) 2003, WELGOS electrónica ; http://www.wellgos.com ;************************************************** PROCESSOR 16F84 RADIX DEC INCLUDE "P16F84.INC" ;Setup of PIC configuration flags ;XT oscillator ;Disable watch dog timer ;Enable power up timer ;Disable code protect __CONFIG 3FF1H LED1 EQU 0 LED2 EQU 1 LED3 EQU 3 2 LED4 SW1 EQU 4 SW2 EQU 5 SW3 EQU 6 SW4 EQU 7 ORG 0CH
46
www.welgos.net
MICROCONTROLADORES
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
;Reset Vector ;Punto di inizio del programma al reset della CPU ORG 00H ;Commuta al segundo banco de registros para acceder al registro TRISA y TRISB bsf STATUS,RP0 ;Definicion del las lineas de I/O (0=salida, 1=Entrada) ;Definicion del puerto A movlw 00011111B movwf TRISA & 7FH ;Definicion del puerto B ;Las lineas de RB0 a RB3 vienen programadas como salida para conectar los cuatro led ;Las lineas de RB4 a RB7 viene programadas como entradas para conectar los cuatro pulsadores movlw 11110000B movwf TRISB & 7FH ;Commuta el primer banco de registros bcf STATUS,RP0 MainLoop ;apaga las led clrf PORTB ;se se oprime SW1 se enciende el LED1 btfss PORTB,SW1 bsf PORTB,LED1 ;se se oprime SW2 se enciende el LED2 btfss PORTB,SW2 bsf PORTB,LED2 ;se se oprime SW3 se enciende el LED3 btfss PORTB,SW3 bsf PORTB,LED3 ;se se oprime SW4 se enciende el LED4 btfss PORTB,SW4 bsf PORTB,LED4 goto MainLoop END
CURSO
INTEGRAL PIC
Capítulo 4 47
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
El contador TMR0 y el PRESCALER 4.1 El registro contador TMR0 Veamos ahora como funciona el registro TMR0.
El registro TMR0 es un contador. Se trata de un tipo especial de registro cuyo contenido se incrementa mediante los ciclos internos del reloj o mediante pulsos externos PIC. diferenciainicialmente. de otros registros, el TRM0 puede alterar si solo el valor con al que se Amemoriza Por ejemplo, escribamos en elpor TMR0 el valor 10: movlw 10 movwf TMR0
48
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
a medida que las instrucciones del programa se van ejecutando, el contenido del registro comienza a incrementarse 11, 12, 13 en pasos de a uno en directa correspondencia con los ciclos de máquina empleados. Si por ejemplo, después de haber cargado el TMR0 con algún valor, se plantea un ciclo infinito: movlw 10 movwf TMR0 loop goto loop el registro TMR0 se incrementa de manera infinita a la para con el loop. Como el TMR0 es un registro de 8 bits, solo puede incrementarse hasta 255. Cuando esto ocurre y los ciclos de máquina siguen andando, el registro se reinicia y toma el valor de 0. La frecuencia con la cual se incrementa el TMR0 es directamente proporcional a la frecuencia de reloj aplicada al circuito integrado, pero esta frecuencia puede modificarse mediante unos bits de configuración. En la siguiente figura se muestra el diagrama de bloques del funcionamiento interno del registro TMR0.
Los bloques Fosc/4 y TOCKI (en azul) representan las dos posibilidades que se tienen para incrementar el valor del TMR0. Fosc/4 es una seal generada internamente en el PIC a partir del circuito de reloj y equivale a la frecuencia del reloj dividio por cuatro (esto recibe el nombre de ciclo de máquina). TOCKI es una señal generada desde un eventual circuito externo que se aplica sobre el pin TOCKI, que en el caso del PIC16F84A corresponde al pin 3. Los bloques TOCS y PSA (resaltados en verde) son dos conmutadores que determinan las características de la señal que entra el TMR0. Estos conmutadores se configuran en base a los valores de los bits TOCS y PSA del registro OPTION. El bloque PRESCALER es un divisor programable cuyo funcionamiento se explicará en la siguiente sección. Veamos como funcionan estos bloques para obtener las distintas modalidades de conteo por parte del TMR0.
49
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Iniciamos programando los bits TOCS en 0 y el PSA en 1. La configuración de funcionamineto que se obtiene se muestra en la siguiente figura:
En rojo se muestra la ruta que sigue la señal hasta llegar al TMR0. Como se habia mencionado, la frecuencia Fosc/4 equivale a un cuarto de la frecuencia del reloj. Si utilizamos un cristal de 4 Mhz obtendremos una frecuencia interna de 1 MHz. Tal frecuencia se envia directamente al registro TMR0 sin ninguna modificación. El incremento que se obtiene equivale a 1 millón de incrementos por segundo a partir del valor presente en el TRM0. Ahora comabiemos el estado del bit TOCS de 0 a 1, la configuración que obtenemos es la siguiente:
En este caso la señal de entrada es la que se aplica externamente al pin TOCKI y esa frecuencia es la que le entra al TMR0. Esta configuración nos brinda la posibilidad de efectuar el conteo automátcio de un evento externo. Si por ejemplo aplicamos al pin TOCKI una frecuencia de 100 Hz, obtendremos una frecuencia de conteo de 100 por segundo. La presencia de la compuerta lógica XOR (OR exclusiva) en la entrada TOCKI del PIC tiene como función permitir que el bit TOSE del registro OPTION regule el funcionamiento del TMR0 para determinar cual de las dos posibles entradas es la que queremos habilitar. Si queremos que funciones con el ciclo interno del reloj (T0SE=1) o mediante la señal externa (T0SE=0).
50
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
En la siguiente figura se representa la correspondencia de la señal externa y el valor adjuntoi del contador TMR0:
4.2 El Prescaler El último bloque que falta por analizar es el PRESCALER. Si configuramos el bit PSA del registro OPTION en 0 enviamos al registro TMR0 una señal que primero pasa por el PRESCALER come se muestra en la siguiente figura:
El PRESCALER consiste de un divisor programable de 8 bit que se utiliza para ajustar la frecuencia de entrada al TMR0. En el caso anterior utilizamos un cristal de cuarzo de 4 Mhz con el que obtenemos una frecuencia de 1 Mhz, la cual para muchas aplicaciones puede resultar muy elevada. Utilizando el PRESCALER podemos dividir la frecuencia Fosc/4 configurando oportunamente los bits PS0, PS1 y PS2 en el registro OPTION, de acuerdo a la siguiente tabla:
PS2 0 0 0 0
PS1 0 0 1 1
PS0 0 1 0 1
Divisor 2 4 8 16
Frecuencia a la salida del PRESCALER 500.000 250.000 125.000 62.500
51
www.welgos.net
CURSO
1 1 1 1 Podemos
0 0 1 1 hacer un
INTEGRAL
SOBRE
MICROCONTROLADORES
0 32 31.250 1 64 15.625 0 128 7.813 1 256 3.906 experimento para comprobar el funcionamiento del PRESCALER.
En la lección 2 habiamos realizado un ejercicio con el encendido de cuatro led en donde la secuencia de encendido se dererminaba mediante un retardo por software, basado en el tiempo de ejecución de un ciclo continuo de instrucciones. Ahora vamos a re escribir esta subrutina pero introduciendo un retardo mediante el registro TMR0. Las modificaciones se muestran en el archivo SEQTMR0.ASM. Debemos programar el PRESCALER para obtener una frecuencia de conteo conveniente, para ello se utilizan las siguientes instrucciones al inicio del programa: movlw 00000100B movwf OPTION_REG En la práctica debemos programar los bits TOCS en 0 para seleccionar cual va a ser la fuente del conteo para el PIC, el bit PSA se pone en 0 para asignar el PRESCALER al registro TMR0 en lugar del temporizador Watch Dog (este tema lo trataremos más adelante) y el bit de configuración del PRESCALER a 100 para obtener una frecuencia de división de 1:32. La frecuencia de conteo que obtenemos con el TMR0 será: Fosc = 1Mhz / 32 = 31.250 Hz La subrutina Delay deberá utilizar oportunamente el registro TMR0 para obtener un retardo de un segundo. Veamos como se hace esto. La primera instrucción que viene enseguida del Delay es: movlw 6 movwf TMR0 y movlw 125 movwf Count Las primeras dos instrucciones memorizan en TMR0 el valor 6, de manera que el registro TMR0 vuelve a cero después de 250 conteo (256 – 6 = 250) obteniendo una frecuencia de paso por cero del TMR0 de: 31.250 / 250 = 125 Hz Las instrucciones siguientes memorizan en un registro de 8 bits (Count) el valor de 125 de modo tal que, decrementando este registro en una unidad por cada vez que TMR0 para por cero, se obtiene una frecuencia de paso por cero del registro Count de: 125/125 = 1Hz Las instrucciones dentro del lazo DelayLoop se encargan de controlar si el TMR0 ha llegado a cero, cada vez que se ha reiniciado seis vecesm se decrementa el valor contenido en Count. Cuando Count llega a cero habrá transcurrido un segundo y la subrutina podrá retornar al punto del programa desde donde se invocó. ;************************************************** ; Curso integral de microcontroladores Pic ; SEQTMR0.ASM ; Luces secuenciales con temporizacion via TIMER 0 ; ; (c) 2003, WELGOS electronica
52
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
; http://www.wellgos.com ;************************************************** PROCESSOR 16F84 RADIX DEC INCLUDE "P16F84.INC" ;Setup of PIC configuration flags ;XT oscillator ;Disable watch dog timer ;Enable power up timer ;Disable code protect __CONFIG 3FF1H ORG 0CH Count RES 1 Shift RES 1 ;Reset Vector - Punto de inicio del programa al reset de la CPU ORG 00H ;Conmuta al segundo banco de registros bsf STATUS,RP0 ;Definicion de la linea de I/O (0=salida, 1=entrada) movlw 00011111B movwf TRISA & 7FH movlw 11110000B movwf TRISB & 7FH ;Asigna el PRESCALER al TMR0 y lo configura a 1:32 ;Ver la subroutina Delay movlw 00000100B movwf OPTION_REG & 0x7F ;Conmuta al primer banco de registros bcf STATUS,RP0 ;el registro Shift viene utilizado para representar internamente ;el estado de la linea de salida del puerto B donde se conectan los led ;el bit 0 del registro Shift viene inciado en 1 para iniciar el ciclo ;del primer led. movlw 00000001B movwf Shift ;Lazo de corrimiento MainLoop ;envia sobre el puerto B el registro Shift de manera que cada bit en ;uno activará el led respectivo. movf Shift,W movwf PORTB ;Para rotar las luces se utiliza la instrucción rlf la cual hace ; rotar a la izquierda los bit contenidos en el registro e inserta en ;el bit 0 el estado del bit carry.Por este motivo primero se debe ;limpiar el carry con la instrucción: bcf STATUS,C. bcf STATUS,C rlf Shift,F ;Cuando con la rotacion el 1 llega al bit 4 se debe invertir los ;primeros cuatro bits con los segundos cuatro bits de modo que se pueda ;reiniciar el ciclo desde el bit 0. ;Esto sucede con los bits del registro Shift durante la ejecucion de ;este lazo: ; ; 00000001 <--- Valor inicial (primer led activado) ; 00000010 rlf ; 00000100 rlf ; 00001000 rlf ; 00010000 rlf en este punto se utiliza la instrucción swapf ;obteniendo: ; 00000001 ... btfsc Shift,4
53
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
swapf Shift,F ;Insertar un retardo call Delay ;Retorna a seguir nuevamente el lazo goto MainLoop ;************** ; Subrutinas ;************** ; Retardo de un segundo ; utilizando el registro TMR0 ; ; el ritardo viene obtenido de la frecuencia en la salida del PRESCALER ; por: ; 4Mhz / 4 / 32 = 31.250 Hz ; ... divide por 250 del TMR0 32.250 / 250 = 125 Hz ; ... y por 125 del contador Count 125 / 125 = 1Hz Delay ; Inicializa el TMR0 para obtener 250 conteo antes de llegar a cero. ; El registro TMR0 es un registro de 8 bit que se incrementa ; nuevamentre cuando llega a 255 vuelve a cero. ; Si se inicializa en 6 debera llegar hasta 256 - 6 = 250 ; incrementos antes de llegar a cero. movlw 6 movwf TMR0 ;el registro Count viene inicializado a 125 movlw 125 movwf Count ;Lazo de conteo DelayLoop ;TMR0 vale 0 ? movf TMR0,W btfss STATUS,Z goto DelayLoop ;No, espera... movlw 6 ;Si, carga de nuevo TMR0 y controla si movwf TMR0 ;ha pasado por 125 decfsz Count,1 goto DelayLoop return END
CURSO
INTEGRAL PIC
Capítulo 5
Las interrupciones Las interrupciones es una característica muy especial en los microcontroladores PIC ( y de los microprocesadores en general) que permite la atención inmediata de un evento externo, interrumpiendo momentaneamente el programa en curso para
54
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
ejecutar otra porción especializada del programa para el manejo de dicho evento y una vez ejecutada esta se retorna al programa principal. Podemos hacer un parangón con el mundo real, podemos hacer una analogía y decir que las interrupciones son para el PIC lo que el timbre del teléfono para nosotros. Para poder una llamada telefónica no necesitamos tomar el auricular permanentemente, simplemente hacemos nuestras labores normales y solo las interrumpimos si suena el timbre del teléfono. Cuando terminamos de hablar volvemos de nuevo a nuestras actividades normales. Miremos los elementos en esta analogía: Nuestras actividades normales corresponden al programa en ejecución; La llamada que alguien nos hace corresponde al evento a gestionar; Cuando levanto el auricular corresponde a la respuesta a la interrupción; Y la respuesta que le doy mediante el teléfono corresponde a la subrutina de gestión de la interrupción. Es mucho más eficiente manejar la atención a un evento externo mediante una interrupción que mediante una verificación cíclica desde el programa principal. Gracias al hardware interno del PIC la respuesta a un evento mediante una interrupción es prácticamente inmediata.
5.1 Tipos de eventos y bits de habilitación El PIC16F84A puede manejar interrupciones generadas por cuatro tipos de eventos: 1. El cambio de estado en la línea RB0 (Interrupción externa en el pin RB0/INT). 2. El fin del conteo del registro TMR0 (interrupción por sobreflujo del TMR0). 3. El cambio estado sobre una de las líneas de RB4 a RB7 (interrupción por cambio en el de PORTB). 4. Fin de la escritura sobre una posición de la EEPROM (Interrupción por escritura completa en la EEPROM). La generación de la interrupción de cada uno de estos eventos puede habiliatrse o deshabilitarse independientemente mediante un registro especial denominado INTCON: Si el bit INTE (bit 4) se pone en 1, se habilita la interrupción por cambio de estado en la línea RB0. Si el bit T0IE (bit 5) se pone en 1 se habilita la interrupción por desborde del TMR0. Si el bit RBIE (bit 3) se pone en 1, se habilita la interrupción por cambio de estado en las líneas RB4-RB7. Si el bit EEIE (bit 6) se pone en 1, se habilita ls interrupción por fin de escritura en la EEPROM. Existe un bit que actúa como habilitador general de todas las interrupciones. Esto quiere decir que para que cualquiera de las interrupciones se habilite debe estar este bit activo. Se trata del bit GIE (Global Interrupt Enable bit) ubicado en el bit 7 del registro INTCON.
5.2 Vector de interrupciones y el servicio de interrupción Cualquiera que sea la fuente de la interrupción, esta se manifiesta interrumpiendo la ejecución del programa en curso, memoriza automáticamente en la pila, el valor
55
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
actual del contador de programa (POGRAM COUNTER) y salta a la instrucción ubicada en la posición 0004H, la que recibe el nombre de vector de interrupción. En este punto es donde debemos insertar la subrutina que maneja la interrupción denominada servicio de interrupción. Dentro de una aplicación es posible habilitar varias de las posibles fuentes de interrupción, cuando se entra al servico de interrupción el primer paso de la subrutina es verificar cual de las fuentes fué la que en realidad srcinó la interrupción, para ellos se acude a la bandera de interrupción.
5.3 Bandera de interrupción Dado que cualquier interrupción genera una llamada a la posición 04H, en el registro INTCON se presentan una serie de banderas que nos indican cual evento ha generado la interrupción, veamos: INTF (bit 1) Si vale 1 la interrupción se ha generado por un cambio de estado sobre la línea RB0. T0IF (bit 2) Si vale 1 la interrupción se ha generado por el desborde del TRM0. RBIF (bit 0) Si vale 1 la interrupción se ha generado por un cambio de estado en una de las líneas de RB4 a RB7. Importante: Una vez se ha detectado cual de las banderas srcinó la interrupción, esta se debe borrar (y es responsabilidad del programador) de lo contrario la interrupción correspondiente no se detectará nuevamente.
5.4 Retorno desde un servicio de interrupción Cuando se ha generato una interrupción el PIC deshabilita automáticamente el bit GIE (Global Interrupt Enable) del registro INTCON de modo que se deshabilitan momentáneamente todas las interrupciones mientras se ejecuta el servicio de interrupción. Para poder retornar al programa principal se debe reiniciar en 1 este bit y utilizar la instrucción: RETFIE
5.5 Ejemplo práctico del manejo de una interrupción Veamos ahora un ejemplo práctico del manejo de una interrupción y para ello tomemos como base el programa LED.ASM de la lección 1; recordemos que se trataba del ecendido del LED1 mediante un ciclo continuo utilizando un retardo por software introducido mediante la subrutina Delay. Ahora modificaremos este programa para activar el LED2 de acuerdo a la ejecución del programa principal. El programa que estudiaremos ahora se denomina INTRB.ASM. Si ejecutamos el programa dentro del circuito, podremos apreciar que el LED1 se activa exactamente como lo hacía en el programa LED.ASM. Ahora funcionemos con
56
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
los pulsadores SW1..SW4, veremos que el LED2 se activa inmediatamente y permanece así durante un tiempo 3 veces mayor que el tiempo del LED1. En la práctica, mientras el lazo principal en LED.ASM continua encendiendo el LED 1 utilizando un retardo por software introducido por la subrutina Delay,el PIC por estar pendiente de la presión del pulsador y señalarlo en el LED 2, verá notablemente afectada la frecuencia de encendido del LED 1. Antes de analizar el programa INTRB.ASM veamos la diferencia del comportamiento con respecto a otro programa que efectúa estas mismas operaciones pero sin recurrir al uso de interrupciones. Este programa se corresponde a NOINTRB.ASM. Notemos que la activación del LED 2 en correspondencia al pulsador, se retarda un poco debido a que la lectura del estado de las líneas RB4-7 no se hace mediante una interrupción sino mediante el ciclo del lazo principal. Este ligero retardo se debe a la presencia de la subrutina Delay en el interior de lazo principal.
5.6 Analizando el programa INTRB.ASM Partamos de la directiva ORG 00H que como ya sabemos, ubica nuestro programa después del reset, en la posición 0. Notemos que la primera instrucción que encuentra el PIC es un salto incondicional a la etiqueta Start: ORG 0x00 goto Start seguido de otra directiva: ORG 0x04 QuePORTB,LED2 inidica la dirección de la subrutina que maneja la interrupción: bsf movlw 3 movwf nTick bcf INTCON,RBIF retfie Como se había mencionado en la lección anterior, el manejador de la interrupción debe necesariamente ubicarse a partir de la posición 0x04; para evitar que se encuentre enseguida del reset debemos saltarlo mediante una instrucción de salto incondicional. El servicio de interrupción, en este caso, se limita a activar el LED 2, a cargar en el registro nTick el número de veces que se activará el LED 2 y a borrar la bandera RBIF para permitir que la circuitería interna de generación de interrupciones siga funcionando. La instrucción RETFIE permite que el PIC pueda continuar en el punto del programa donde se encontraba antes de la interrupción.
Como generar una interrupción cuando se active un pulsador ? Después del reset ponemos los siguiente: movlw 10001000B movwf INTCON
57
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
donde ponemos un 1 en el bit GIE (bit 7) que corresponde al habilitador general de los circuitos de generación de interrupciones. También ponemos en 1 el bit RBIE (bit 3) el cual habilita la interrupción por cambio de estado en las líneas RB4-7. Si colocamos los pulsadores PU1, PU2, PU3 y PU4 sobre las correspondientes líneas de I/O RB4, RB5, RB6 y RB7, solo con presionar uno de estos pulsadores obtenemos un cambio de estado y por lo tanto una interrupción.
En el lazo principal, además de la operación de encendido de LED 1, se decrementa el contatore nTick hasta que llega a cero. En correspondencia con esto se prende el LED 2. Ejemplo práctico de manejo de las interrupciones Veamos como manejar las interrupciones. Sigamos utilizando el programa INTRB.ASM pero ahora vamos a srcinar una interrupción con el desborde del TMR0 y de acuerdo a este evento activamos el LED 3. El código de este ejercicio lo vemos en el archivo DBLNT.ASM. Si compilamos el programa DBLINT.ASM y lo montamos sobre el circuito, veremos como el LED 1 parpadea a una sola frecuencia y el LED 3 parpadea a una frecuencia más elevada. Accionando el pulsador obtenemos la subida por tres ciclos del LED 2.
Analizando el programa DBLINT.ASM En el momento de que se presenta una interrupción, en la subrutina del servicio de la interrupción se verifica cual de las fuentes de interrupción generó la situación, para ello consultamos las banderas TOIF (desborde del TMR0) y RBIF (cambio de estado en RB4-RB7): btfsc INTCON,T0IF goto IntT0IF btfsc INTCON,RBIF goto IntRBIF De acuerdo a la bandera activada saltamos a la etiqueta respectiva: IntT0IF ó IntRBIF. Antes de salir del servicio de interrupción debemos recordar borrar las banderas TOIF y RBIF, para poder funcionar nuevamente con dichas interrupciones. ;************************************************** ; Curso integral de microcontroladores Pic ; INTRB.ASM ; ; (c) 2003, WELGOs electrónica ; http://www.wellgos.com ;************************************************** PROCESSOR 16F84 RADIX DEC INCLUDE "P16F84.INC" ;Setup of PIC configuration flags ;XT oscillator ;Disable watch dog timer ;Enable power up timer ;Disable code protect __CONFIG 3FF1H LED1 EQU 0 LED2 EQU 1
58
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
LED3 EQU 2 LED4 EQU 3 ORG 0CH Count RES 2 nTick RES 1 ;Registro utilizado para contar el numero de ;encendidas del LED 1 ;Reset Vector ;Punto de inicio del programa al reset de la CPU ORG 00H ;Salta al cuerpo principal del programa. Este salto es necesario ;para evitar toda la parte de codigo para el manejo de la ;interrupcion. goto Start ;Interrupt vector ;Punto de inicio para toda la subrutina de manejo de la interrupcion ORG 04H ;********************************************************************** ; Servicio de Interrupcion ;********************************************************************** ;Activa el led 2 para señalar que se ha dado una interrupcion bsf PORTB,LED2 ;Inicializa el contador del parpadeo del LED1 movlw 3 movwf nTick ;Borra la bandera RBIF para permitir nuevas interrupciones bcf INTCON,RBIF ;Retorna al programa principal retfie ;********************************************************************** ; Programa principal ;********************************************************************** Start: ;Conmuta al segundo banco de registros para acceder al registro TRISA y ;TRISB bsf STATUS,RP0 ;Definicion de las lineas de I/O (0=salida, 1=Entrada) ;Definicion del puerto A movlw 00011111B movwf TRISA & 7FH ;Definicion del puerto B ;Las lineas de RB0 a RB3 viene programadas como salida para ;conectar los cuatro led ;Las lineas de RB4 a RB7 vienen programadas como entradas para ;conectar los cuatro pulsadores movlw 11110000B movwf TRISB & 7FH ;Conmuta al primer banco de registros bcf STATUS,RP0 ;apaga los led del puerto B bcf PORTB,LED1 bcf PORTB,LED2 bcf PORTB,LED3 bcf PORTB,LED4 ;Habilita la interupcion del cambio de estado en las lineas RB4,5,6,7 movlw 10001000B movwf INTCON ;********************************************************************** ; Lazo principal ;********************************************************************** MainLoop call Delay ;Retardo por software
59
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
btfss PORTB,LED1 ;Led apagado ? goto TurnOnLed1 ;No, lo prende goto TurnOffLed1 ;Si, lo apaga ;Prende led y decremento el contatore de parapadeo TurnOnLed1 bsf PORTB,LED1 ;Controla si LED 2 de señalacion de la interrupcion esta prendido. ;Si esta prendido decrementa el contador nTick ad ogni lampeggio di ;LED1. Quando nTick vale 0 spegne LED 2 btfss PORTB,LED2 ;LED2 prendido ? goto MainLoop ;No, continua a lampeggiare decf nTick,1 ;Si, decrementa nTick btfss STATUS,Z ;nTick = 0 ? goto MainLoop ;No, continua a lampeggiare bcf PORTB,LED2 ;Si, spegne LED2 goto MainLoop ;Continua a lampeggiare ;Spegnimento led TurnOffLed1 bcf PORTB,LED1 ;Spegne LED 1 goto MainLoop ;Continua a lampeggiare ;********************************************************************** ; Subrutina ;********************************************************************** ;Subrutina de retardo por software Delay clrf Count clrf Count+1 DelayLoop decfsz Count,1 goto DelayLoop decfsz Count+1,1 goto DelayLoop return END ;************************************************** ; Curso integral de microcontroladores Pic ; DBLINT.ASM ; ; (c) 2003, WELGOS electronica ; http://www.wellgos.com ;************************************************** PROCESSOR 16F84 RADIX DEC INCLUDE "P16F84.INC" ERRORLEVEL -302 ;Setup of PIC configuration flags ;XT oscillator ;Disable watch dog timer ;Enable power up timer ;Disable code protect __CONFIG 3FF1H LED1 EQU 0 LED2 EQU 1 LED3 EQU 2 LED4 EQU 3 ORG 0CH Count RES 2 nTick RES 1 ;Reset Vector
60
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
;Starting point at CPU reset ORG 00H ;Jump to the main body of program to avoid the interrupt handler ;code. goto Start ;Interrupt vector ;Starting point at CPU interrupts ORG 04H ;********************************************************************** ; Interrupt handler ;********************************************************************** ;Check the interrupt event btfsc INTCON,T0IF goto IntT0IF btfsc INTCON,RBIF goto IntRBIF ;Reset the T0IF and RBIF flags to re-enable the interrupts End_ih bcf INTCON,T0IF bcf INTCON,RBIF ;Go back to the main program retfie ;********************************************************************** ; TMR0 Interrupt handler ;********************************************************************** IntT0IF ;Turn on LED3 if it's off btfsc PORTB,LED3 goto LED3_off bsf PORTB,LED3 goto End_ih LED3_off bcf PORTB,LED3 goto End_ih ;********************************************************************** ; RB4-RB7 interrupt handler ;********************************************************************** IntRBIF ;Turn on LED 2 bsf PORTB,LED2 ;Starts the LED1 blink counter movlw 3 movwf nTick goto End_ih ;********************************************************************** ; Main body ;********************************************************************** Start: ;Commuta sul secondo banco dei registri per accedere ai registri TRISA e TRISB bsf STATUS,RP0 ;Definizione delle linee di I/O (0=Uscita, 1=Ingresso) ;Definizione della porta A movlw 00011111B movwf TRISA & 7FH ;Definizione della porta B ;Le linee da RB0 a RB3 vengono programmate in uscita per essere collegate ai quattro led ;Le linee da RB4 a RB7 vengono programmate in ingresso per essere collegate ai quattro pulsanti
61
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
movlw 11110000B movwf TRISB & 7FH ;Assegna il PRESCALER a TMR0 e lo configura a 1:256 movlw 00000111B movwf OPTION_REG & 7FH ;Commuta sul primo banco dei registri bcf STATUS,RP0 ;Spegne tutti i led collegati sulla porta B bcf PORTB,LED1 bcf PORTB,LED2 bcf PORTB,LED3 bcf PORTB,LED4 ;Abilita l'interrupt sul TMR0 e sul cambiamento di stato delle linee RB4,5,6,7 movlw 10101000B movwf INTCON ;********************************************************************** ; Loop principale ;********************************************************************** MainLoop call Delay ;Ritardo software btfss PORTB,LED1 ;Led acceso ? goto TurnOnLed1 ;No, lo accende goto TurnOffLed1 ;Si, lo spegne ;Accensione led e decremento del contatore di lampeggi TurnOnLed1 bsf PORTB,LED1 ;Controlla se LED 2 di segnalazione dell'interrupt e' gia acceso. ;Se e' acceso decrementa il contatore nTick ad ogni lampeggio di ;LED1. Quando nTick vale 0 spegne LED 2 btfss PORTB,LED2 ;LED2 acceso ? goto MainLoop ;No, continua a lampeggiare decf nTick,1 ;Si, decrementa nTick btfss STATUS,Z ;nTick = 0 ? goto MainLoop ;No, continua a lampeggiare bcf PORTB,LED2 ;Si, spegne LED2 goto MainLoop ;Continua a lampeggiare ;Spegnimento led TurnOffLed1 bcf PORTB,LED1 ;Prende LED 1 goto MainLoop ;Continua el parpadeo ;********************************************************************** ; Subrutina ;********************************************************************** ;Subrutina de retardo por software Delay clrf Count clrf Count+1 DelayLoop decfsz Count,1 goto DelayLoop decfsz Count+1,1 goto DelayLoop return END
62
www.welgos.net
CURSO
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
INTEGRAL PIC
Capítulo 6
El modo Power Down El modo Power Down o modo Sleep es un estado muy particular del funcionamiento del microcontrolador PIC utilizado para reducir el consumo de corriente en el momento en que el microcontrolador no se está utilizando o solo esta a la espera de que ocurra un evento externo. Tomemos por ejemplo, el caso del control remoto del televisor. La mayor parte del tiempo el microcontrolador interno no se encuentra desarrollando ninguna tarea, solo
63
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
espera a que un usuario oprima una de las teclas. Para ahorrar la energía de la batería, es conveniente ponerlo en Sleep. El tiempo efectivo en que trabaja la CPU se limita a los milisegunos necesarios para efectuar la transmisión, el resto del tiempo no se encuentra desarrollando ninguna función en particular. Para evitar el consumo inútil de la batería conviene desactivar buena parte de la circuitería interna y activarla solo en el momento en que se presente un evento externo. Veamos como.
6.1 La instrucción SLEEP La instrucción SLEEP se utiliza para poner el PIC en el modo de Power Down y de esa manera reducir el consumo de corriente de 2 mA (suponiendo una alimentación de 5 voltios y un cristal de 4 Mhz) a casi 2µA, es decir, un reducción del consumo en 1000 veces! Para entrar en modo Power Down solo se debe insertar la siguiente instrucción en un punto cualquiera de nuestro programa: SLEEP Al momento de ejecutar esta instrucción se detendrá el flujo de las demás instrucciones, se desactivarán todos los circuitos internos a excepción de aquellos necesarios para mantener el estado en los puertos I/O (estado lógico alto, bnajo o alta impedancia) y así poder despertar al microcontrolador en cualquier momento. Microchip recomienda conectar al positivo (Vdd) o al negativo (Vss) de la alimentación todas las líneas en alta impedancia o no utilizadas, como la línea RA4/TOCKI (pin 3).
6.2 Despertando al PIC Para despertar al PIC de su estado de reposo se puede utilizar diversas técnicas: 1. Resetear el PIC mediante un 0 en el pin MCLR (pin 4) 2. Timeout del temporizador Watchdog (si se ha habilitado) 3. Verificar si hay una situación de interrupción (interrupción en el pin RB0/INT, cambio de estado sobre el puerto B, fin de escritura en la EEPROM). En los casos 1 y 2 el PIC se resetea y la ejecución reinicia en la posición 0. En el caso 3 el PIC se comporta normalmente para el manejo de una interrupción, ejecutando el servicio a la interrupción y luego regreasando a la ejecución del programa después de la instrucción SLEEP.
6.3 Ejemplo del modo Power Down Veamos ahora un sencillo ejemplo de utilización del modo Power Down y la correspondiente despertada. La modalidad utilizada es la interrupción por cambio de nivel en RB0/INT utilizando un pulsador. El programa utilizado es PDM.ASM. En la práctica, el LED D1 conectado a la línea RB2 paradeará inicando que el programa está en curso. Oprimiendo SW2 el programa ejecutará la instrucción: SLEEP metiendo el PIC en el modo Power Down donde el LED D1 cesará su intermitencia. Para causar la salida del modo Power Down del PICmicro, bastará oprimir SW1 para generar una interrupción y retomar la ejecución del programa.
64
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
;************************************************** ; Curso integral de microcontroladores Pic ; ; PDM.ASM ; Power Down Mode example ; ; (c) 2003, WELGOS electronica ; http://www.wellgos.com ;************************************************** PROCESSOR RADIX DEC 16F84 INCLUDE "P16F84.INC" ;Set chip configuration ;Disable watch dog timer ;Enable power up timer ;XT oscillator ;Disable code protect __CONFIG 3FF1H SWITCH1 EQU 0 SWITCH2 EQU 1 LED1 EQU 2 ORG 0CH ;contador de 16 bit utilizado en la subrutina delay Count RES 2 ;Reset Vector ;Start point at CPU reset ORG 00H ;Jump to main body of program. goto Start ;********************************************************************** ; Interrupt vector ; Start point for every interrupt handler ;********************************************************************** ORG 04H ;********************************************************************** ; Interrupt handler ;********************************************************************** bcf INTCON,INTF ;Reset INTF flag retfie ;Return to the main body ;********************************************************************** ; Main body ;********************************************************************** Start: bsf STATUS,RP0 ;Swap to data bank 1 ;I/O lines definition on port A (0=output, 1=input) movlw 00011111B ;Definition of port a movwf TRISA & 0x7F ;I/O lines definition on port B (0=output, 1=input) bsf TRISB & 0x7F,SWITCH1 ;Switch 1 bsf TRISB & 0x7F,SWITCH2 ;Switch 2 bcf TRISB & 0x7F,LED1 ;Led 1 ;Set to 0 the INTEDG bit on OPTION register ;to have an interrupt on the falling edge of RB0/INT bcf OPTION_REG & 0x7F,INTEDG bcf STATUS,RP0 ;Swap to data bank 0 bsf INTCON,GIE ;Enables interrupts bsf INTCON,INTE ;Enables RB0/INT interrupt bcf PORTB,LED1 ;Turn off LED1 ;**********************************************************************
65
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
; Main loop ;********************************************************************** MainLoop btfss PORTB,SWITCH2 ;If switch2 is down enter in sleep ;Power Down Mode call Delay ;Software delay ;If LED1 in on then turn it off and viceversa btfss PORTB,LED1 ;Led on ? goto TurnOnLed1 ;No, turn it on goto TurnOffLed1 ;Yes, turn it off ;Turn LED1 on TurnOnLed1 bsf PORTB,LED1 goto MainLoop ;Turn LED1 off TurnOffLed1 bcf PORTB,LED1 goto MainLoop ;********************************************************************** ; Software delay ;********************************************************************** Delay clrf Count clrf Count+1 DelayLoop decfsz Count,1 goto DelayLoop decfsz Count+1,1 goto DelayLoop return END
CURSO
INTEGRAL PIC
Capítulo 7
El temporizador watch dog (WDT) En esta lección analizaremos el funcionamiento del temporizador Watchdog (en español es algo como temporizador perro guardián), el cual es un mecanismo que tenemos a disposición para mejorar la fiabilidad de nuestros circuitos basados en PIC. El Watch Dog es un oscilador interno al PIC pero con una circuitería completamente independiente y su objetivo es el de evitar un posible bloqueo de la CPU del micro y reiniciar el PIC para retornar a la ejecución normal del programa. Si desea desbloquear la CPU durante la ejecución del programa principal, debe insertar la instrucción especial: CLRWDT (CLeaR Watch Dog Timer) la cual borrará a intervalos regulares el temporizador Watch Dog Timer. Si la CPU no efectúa esta instrucción antes de terminar el conteo del WDT asumirá que el
66
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
programa se ha bloqueado por cualquier motivo y por tanto efectúa el Reset de la CPU. El periodo mínimo al cual se puede reiniciar la CPU está alrededor de los 18ms (depende de la temperatura y del voltaje de alimentación). Es posible asignar el PRESCALER al temporizador Watch Dog para obtener un retardo hasta de 2.3 segundos. Para habilitar el temporizador Watch Dog se habilita la opción desde el software de programación, mediante la bandera WDTE de la palabra de configuración.
7.1 Asignación del PRESCALER al WDT Activando el bit PSA del registro OPTION_REG es posible asignar el prescaler al Watch Dog Timer para obtener un tiempo de reinicio mayor. El bit PSA se activa mediante la instrucción: BSF OPTION_REG,PSA En caso contrario el prescaler se asignará al TIMER 0. Obviamente una vez que se ha asignado el prescaler al WDT no será posible asignarlo completamente al TIMER 0 y viceversa. Interviniendo en los valores de los bits PS0, PS1 y PS2 del registro OPTION_REG podremos obtener diversos intervalos de retardo. La escogencia correcta deberá hacerse teniendo en cuenta el máximo retardo que requerimos obtener al interior de nuestro programa tras la ejecución de dos instrucciones CLRWDT sucesivas. En la siguiente tabla se muestra la correspondencia entre los valores de estos bits y los intervalos que obtenemos.
7.2 Ejemplo práctico de la utilización del Watch Dog Timer Veamos ahora, como siempre, un ejemplo práctico de la utilización del Watch Dog Timer. Usaremos el mismo esquema circuital del ejemplo anterior (ejemplo4.pdf), y el código fuente del archivo WDT.ASM. En la práctica este ejemplo no difiere mayor cosa del ejemplo utilizado para explicar el modo Power Down. Apenas entre en ejecución, el programa hará parpadear el LED 1. Durante este parpadeo se ejecuta continuamente la instrucción CLRWDT para evitar que la CPU se reinicie ( para este propósito recuerde habilitar la opción WDTE en el momento de la programación). Si oprimimos SW2, la CPU entra en un loop infinito (StopLoop) antes de seguir con la instrucción CLRWDT. Transcurridos alrededor de 2.3 segundos, el Watch Dog Timer efectúa el reset de la CPU y el led comienza nuevamente a parpadear. Podriamos ahora reprogramar el PIC16F84A con el siguiente programa y habiliat el WDTe desde nuestro programador. Note que oprimiento SW2 el parapadeo se bloquea y luego se desbloquea. ;**************************************************
67
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
; Curso integral sobre microcontroladores Pic ; WDT.ASM ; Watch Dog Timer example ; ; (c) 2003, WELGOS electrónica ; http://www.wellgos.com ;************************************************** PROCESSOR 16F84 RADIX DEC INCLUDE "P16F84.INC" ;Configuración de las banderas del chip ;Habilitar el watch dog timer ;habilitar el power up timer ;XT oscillator ;Disable code protect __CONFIG 3FF5H SWITCH1 EQU 0 SWITCH2 EQU 1 LED1 EQU 2 ORG 0CH ;se utiliza un contador de 16 bit para la subrutina de retardo Count RES 2 ;Reset Vector ;Punto de inicio al resetear la CPU ORG 00H ;Salta al cuerpo principal del programa. goto Start ;********************************************************************** ; Vector de interrupción ; Punto de inicio para todos los sevicios de interrupción ;********************************************************************** ORG 04H ;********************************************************************** ; Servicio de interrupción bcf INTCON,INTF ;Reset bandera INTF retfie ;Retorno al cuerpo principal ;********************************************************************** ; Cuerpo principal ;********************************************************************** Start: bsf STATUS,RP0 ;Conmuto al banco de datos 1 ;definiciones I/O en el puerto A (0=output(salida), 1=input (entrada)) movlw 00011111B ;Definición del puerto a movwf TRISA & 0x7F ; definiciones I/O en el puerto B (0=output(salida), 1=input (entrada)) bsf TRISB & 0x7F,SWITCH1 ;Switch 1 bsf TRISB & 0x7F,SWITCH2 ;Switch 2 bcf TRISB & 0x7F,LED1 ;Led 1 ;ponemos en 0 el bit INTEDG del registro OPTION ;para obtener una interrupción en el flanco de bajada de RB0/INT bcf OPTION_REG & 0x7F,INTEDG ;Asignación del PRESCALER al Watch dog timer bsf OPTION_REG & 0x7F,PSA ;Set the PRESCALER to 1:128 bsf OPTION_REG & 0x7F,PS0 bsf OPTION_REG & 0x7F,PS1 bsf OPTION_REG & 0x7F,PS2 bcf STATUS,RP0 ;saltar al banco de datos 0 bsf INTCON,GIE ;habilitar interrupciones bsf INTCON,INTE ;habilito interrupción RB0/INT bcf PORTB,LED1 ;Apagar LED1 ;**********************************************************************
68
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
; lazo principal ;********************************************************************** MainLoop btfss PORTB,SWITCH2 ;Si switch2 esta cerrado entre en StopLoop goto StopLoop ;Detiene la CPU clrwdt ;Clear wtach dog timer call Delay ;retardo por Software ;Si el LED1 esta prendido apaguelo y viceversa btfss PORTB,LED1 ;Led on ? goto TurnOnLed1 ;No, prendalo goto TurnOffLed1 ;Si, apaguelo ;Turn LED1 on TurnOnLed1 bsf PORTB,LED1 goto MainLoop ;Turn LED1 off TurnOffLed1 bcf PORTB,LED1 goto MainLoop ;********************************************************************** ; Retardo por Software Delay clrf Count clrf Count+1 DelayLoop decfsz Count,1 goto DelayLoop decfsz Count+1,1 goto DelayLoop return END CURSO
INTEGRAL PIC
Capítulo 8 Manejo de un display LCD En las lecciones pasadas hicimos algunos experimentos sencillos con diodos led y pulsadores. EN esta lección vamos a desarrollar la interfaz entre nuestro PIC16F84A y una serie de dispositivos más complejos. Inicaremos con un display de cristal líquido o LCD (del inglés Liquid Crystal Display) dotado de dos líneas y 16 caracteres, que es muy fácil de conseguir en el comercio. El esquema eléctrico del circuito es el siguiente:
69
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
En la tabla siguiente se describe la función de cada una de las líneas del LCD. Las descripciones que se encuentran en negrilla nos indican que se utilizan efectivamente en nuestra aplicación de ejemplo. Pin
Nombre
Función
1 2 3
GND VDD LCD
Tierra Se conecta a +5 voltios A este pin se c onecta un voltaj e entre 0 y 5 v oltios(mediante un
4
RS
trimmer) regular contraste delal LCD Register para Select. Sirve el para indicarle LCD si el dato que le llega es un dato (RS=1) o un comando (RS=0) Es un bit de control que le indica al LCD si se quiere escribir un dato en el (R/W=0) o leerlo de el (R/W=1) Enable. Otro bit de control que permite que el LCD reciba datos y comandos. Línea 0 del bus de datos-Las siguientes son los datos que van al LCD Línea 1 del bus de datos Línea 2 del bus de datos Línea 3 del bus de datos Línea 4 del bus de datos Línea 5 del bus de datos Línea 6 del bus de datos Línea 7 del bus de datos
5
R/W
6
E
7 8 9 10 11 12 13 14
DB0 DB1 DB2 DB3 DB4 DB5 DB6 DB7
Para maximizar la utilización de los pines del PIC y el LCD, en esta lección utilizaremos la modalidad de intercambio de datos a 4 bits, para lo cual solo utilizaremos las líneas DB4, DB5, DB6 y DB7. Las líneas DB0, DB1, DB2 y DB3 no las utilizaremos por lo cual las podemos conectar a tierra. La línea R/W del LCD tampoco la utilizaremos por lo que también la conectaremos a tierra. De esta manera se seleccionará el modo de trabajo solo en modo de escritura. Esto quiere decir que en la práctica solo podremos enviar datos al LCD pero no recibirlos.
8.1 Hello World ! 70
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Monte el circuito en el entrenador, compile el código fuente del archivo LCD1.ASM y programa el PIC con el archivo .HEX obtenido. Si desarrolla bien las conexiones, en su display LCD aparecerá la siguiente visualización.
Quisimos poner el famosísimo mensaje de HOLA MUNDO intentando emular un poco lo que hacen la mayoría de los libros de aprendizaje de programación. No quisimos pasar por alto esta tradición. El resultado puede no ser muy emocionante, este es solo el comienzo no se desespere! Si no consigue visualizar nada en el display, asegúrese que el montaje del circuito sea correcto, que el PIC se haya programado correctamente ( colocar el oscilador en XT y deshabiliat el watch dog), será necesario que regule el contraste del LCD por medio del trimmer R2 conectado al pin 3 del display.
8.2 La línea Enable (E) y el Register Select (RS) del LCD Para poder visualizar una escritura sobre el display, el PIC debe enviar toda una sere de comandos transmitidos a través de las líneas del bus de datos (líneas de DB4 a DB7). Para ello se utilizan dos líneas de control con las cuales se comunica al display la operación de transferencia de datos. Las dos líneas de control son el Enable (pin 6 del LCD) y el Register select (pin 4 del LCD). Con la línea Register Select (RS) el PIC le señala al display que el dato presente en el bus es un comando (RS=0) o un dato que se debe visualizar (RS=1). Cuando el PIC transmite un comando. Le informa al LCD el tipo de operación que debe ejecutar, como por ejemplo activar el cursor. Cuando se envía un dato, el PIC le envía directamente los caracteres ASCII que debe visualizar. La línea Enable habilita al display a leer el comando o el dato enviado a través del bus por el PIC. El PIC debe preocuparse de tener en el bus, el dato o el comando necesario antes de enviar la señal de habilitación.
8.3 Multiplexando el bus de datos Si los comandos y los datos se representan en números de 8 bits, como es posible enviarlos al display si el bus de datos se compone solo de 4 líneas? En la práctica podemos utilizar una operación de multiplexación, en la cual un byte se descompone en dos grupos de 4 bits y se trasnmiten sobre el bus en scuencia. Primero se envian los cuatros bits menos significativos y luego los cuatro más significativos. En el código fuente de este ejemplo, todas las operaciones de transmisión de datos y comandos sobre el display vienen seguidas de una serie de subrutinas presentes en el archivo LCD1.ASM que simplifican al máximo la complejidad de nuestro programa. Antes de analizar la subrutina veremos lo que hace el programa principal.
71
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
8.4 Analizando el programa LCD1.ASM En la primera parte del código fuente vienen definidas algunas constantes: ;LCD Control lines LCD_RS equ 2 ;Register Select LCD_E equ 3 ;Enable ;LCD data line bus LCD_DB4 equ 4 ;LCD data line DB4 LCD_DB5 equ 5 ;LCD data line DB5 LCD_DB6 equ 6 ;LCD data line DB6 LCD_DB7 equ 7 ;LCD data Estas definiciones asocian lasline líneasDB7 del PIC (todas conectadas al puerto B) y las
líneas del LCD. Estas se utilizan en el interior de la subrutina de manejo del LCD para identificar fácilmente las líneas del display. tmpLcdRegister res 2 msDelayCounter res 2
Enseguida se reserva espacio para dos registros: tmpLcdRegister , usado en la rutina de manejo del LCD y msDelayCounter usado en la subrutina msDelay la cual genera el retardo por software de 1 ms trabajando con el contenido del registro W. Esta subrutina la utilizaremos siempre dentro de la subrutina de manejo del LCD para generar la temporización necesaria durante la transmisión de datos y comando al LCD. Luego sigue una parte de definiciones de las líneas de conexión entre el PIC y el display y luego llegamos a el llamado de una subrutina que es muy interesante. call LcdInit
LcdInit es una subrutina que debe ser llamada solo una vez al inicio de nuestro programa y es proritaria sobre cualquier otra subrutina del LCD. Esta se ocupa de efectuar todas las operaciones necesarias para inicializar correctamente el LCD y permitir que todas las funciones sucesivas que se le indiquen, se desarrollen correctamente. Con la siguiente instrucción: movlw 00H call LcdLocate se posiciona el cursor del display en la primera fila y primera columna del display. Los caracteres que se envien enseguida se ubicaran a partir de esta posición. Los cuatros bits más significativos del valor colocado en el registro W con la instrucción: movlw 00H
contendrá el número de la fila donde se debe ubicar el cursor, y los cuatro bits menos significativos contendrán el número de la columna. Pruebe cambiar los valores del registro W para obtener diversos posicionamientos. Por ejemplo con el valor 10H obtenemos la siguiente visualización:
con el valor 12H obtenemos:
En este punto, para visualizar cualquier caracter debemos utilizar la instrucción: movlw 'H' call LcdSendData
72
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
El incremento de la posición del cursor se hace automáticamente.
8.5 Subroutinas de gestión del display LCD Veamos brevemente las funciones que efectúa la subrutina de manejo del LCD en el archivo LCD1.ASM. Subrutina
Función Se ocupa de inicializar el display LCD. Debe llamarse solo una vez y prima sobre cualquier otra subrutina de manejo del LCD. No requiere paso de parametros. Borra el contenido visualizado y reposiciona el cursor sobre la primera fila y primera columna del LCD. No requiere paso de parámetros. Posiciona el cursor en el interior del área visible del LCD. Requiere el valor de la fila y la columna en W para posicionar el cursor. Los bits D0 a D3 contienen el valor de la columna (eje Y) y de D4 a D7 el valor de la fila (eje X). La numeración de la columna parte de 0 y aumenta de derecha a izquierda. Permite enviar un caracter ASCII al LCD u visualizarlo en la posición actual del cursor. Requiere en W el caracter ASCII a visualizar. Permite enviar un comando al LCD. Requiere en W el comando. Esta función es interna a las otras y se ocupa del multiplexaje de 8 a cuatro bits.
LcdInit
LcdClear
LcdLocate
LcdSendData
LcdSendCommand LcdSendByte
;************************************************** ; Curso integral sobre microcontroladores Pic ; LCD1.ASM ; ; (c) 2003, WELGOS electrónica ; http://www.wellgos.com ;************************************************** PROCESSOR 16F84 RADIX DEC INCLUDE "P16F84.INC" ;Suppres MPASM warning message 302: ;"Register in operand not in bank 0. Ensure that bank bits are correct" ERRORLEVEL -302 ;Lineas de control del LCD LCD_RS equ 2 ;Register Select LCD_E equ 3 ;Enable ;bus de datos del LCD LCD_DB4 equ 4 ;LCD linea de datos db4 LCD_DB5 equ 5 ; LCD linea de datos db5 LCD_DB6 equ 6 ; LCD linea de datos db6 LCD_DB7 equ 7 ; LCD linea de datos db7 ORG 0CH tmpLcdRegister res res 2 2 msDelayCounter ;Reset Vector ORG 00H Start bsf STATUS,RP0 ;salto al banco 1 movlw 00011111B ;configuro puerto A
73
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
movwf TRISA movlw 11111111B ;configuro puerto B movwf TRISB bcf PORTB,LCD_DB4 ;como salidas las lineas del lcd bcf PORTB,LCD_DB5 bcf PORTB,LCD_DB6 bcf PORTB,LCD_DB7 bcf PORTB,LCD_E bcf PORTB,LCD_RS bcf STATUS,RP0 ;Salto al banco 0 ;inicialización del LCD call LcdInit ;Localizar el cursro del LCD em la fila 0, columna 0 movlw 10H call LcdLocate ;mostrar "HELLO WORLD" movlw 'H' call LcdSendData movlw 'E' call LcdSendData movlw 'L' call LcdSendData movlw 'L' call LcdSendData movlw 'O' call LcdSendData movlw ' ' call LcdSendData movlw 'W' call LcdSendData movlw 'O' call LcdSendData movlw 'R' call LcdSendData movlw 'L' call LcdSendData movlw 'D' call LcdSendData movlw ' ' call LcdSendData movlw '!' call LcdSendData foreverLoop goto foreverLoop ;********************************************************************** ; subrutina de retardo ; ; W = tiempo de retardo requerido en ms (clock = 4MHz) ;********************************************************************** msDelay movwf msDelayCounter+1 clrf msDelayCounter+0 ; lazo interno de 1 ms (alrededor) msDelayLoop nop decfsz msDelayCounter+0,F goto msDelayLoop nop decfsz msDelayCounter+1,F goto msDelayLoop return
74
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
;********************************************************************** ; Init LCD ; Esta subrutina debe invocarse antes de cualquier otra del lcd ;********************************************************************** LcdInit movlw 30 ;espera 30 ms call msDelay ;**************** ; secuencia de Reset ;**************** bcf PORTB,LCD_RS ;LCD en modo de comando ;envia una secuencia de reset al LCD bsf PORTB,LCD_DB4 bsf PORTB,LCD_DB5 bcf PORTB,LCD_DB6 bcf PORTB,LCD_DB7 bsf PORTB,LCD_E ;habilito lcd movlw 5 ;espero 5 ms call msDelay bcf PORTB,LCD_E ;deshabilito LCD movlw 1 ;Wait 1ms call msDelay bsf PORTB,LCD_E ; habilito LCD movlw 1 ;Wait 1ms call msDelay bcf PORTB,LCD_E ; deshabilito LCD movlw 1 ;Wait 1ms call msDelay bsf PORTB,LCD_E ;Enables E movlw 1 ;espero 1ms call msDelay bcf PORTB,LCD_E ;Disables E movlw 1 ;Wait 1ms call msDelay bcf PORTB,LCD_DB4 bsf PORTB,LCD_DB5 bcf PORTB,LCD_DB6 bcf PORTB,LCD_DB7 bsf PORTB,LCD_E ; habilito LCD movlw 1 ;espero 1ms call msDelay bcf PORTB,LCD_E ; deshabilito LCD movlw 1 ;espero 1ms call msDelay ; configuro el bus de datos en 4 bits movlw 28H; call LcdSendCommand ;entro en mos de incremento no de desplazamiento movlw 06H; call LcdSendCommand ;Display ON, Curson OFF, Blink OFF movlw 0CH call LcdSendCommand ;Clear display call LcdClear movlw 30 ;Wait 30 ms call msDelay
75
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
;**************** ; Secuencia de Reset ;**************** bcf PORTB,LCD_RS ;LCD en modo de comando ;envio secuencia de reset al LCD bsf PORTB,LCD_DB4 bsf PORTB,LCD_DB5 bcf PORTB,LCD_DB6 bcf PORTB,LCD_DB7 bsf PORTB,LCD_E ; habilito LCD movlw 5 ;espero 5 ms call msDelay bcf PORTB,LCD_E ; deshabilito LCD movlw 1 ;eseperp 1ms call msDelay bsf PORTB,LCD_E ; habilito LCD movlw 1 ;espero 1ms call msDelay bcf PORTB,LCD_E ; deshabilito LCD movlw 1 ;espero 1ms call msDelay bsf PORTB,LCD_E ;Enables E movlw 1 ;espero 1ms call msDelay bcf PORTB,LCD_E ;Disables E movlw 1 ;espero 1ms call msDelay bcf PORTB,LCD_DB4 bsf PORTB,LCD_DB5 bcf PORTB,LCD_DB6 bcf PORTB,LCD_DB7 bsf PORTB,LCD_E ; habilito LCD movlw 1 ;espero 1ms call msDelay bcf PORTB,LCD_E ; deshabilito LCD movlw 1 ;espero 1ms call msDelay ;bus a cuatro bits movlw 28H; call LcdSendCommand ;Entry mode set, incremento no desplazamiento movlw 06H; call LcdSendCommand ;Display ON, Curson OFF, Blink OFF movlw 0CH call LcdSendCommand ;Clear display call LcdClear ;********************************************************************** LcdSendByte ;guardo valor a enviar movwf tmpLcdRegister ;envio cuatro bits altos bcf PORTB,LCD_DB4 bcf PORTB,LCD_DB5 bcf PORTB,LCD_DB6 bcf PORTB,LCD_DB7 btfsc tmpLcdRegister,4 bsf PORTB,LCD_DB4
76
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
btfsc tmpLcdRegister,5 bsf PORTB,LCD_DB5 btfsc tmpLcdRegister,6 bsf PORTB,LCD_DB6 btfsc tmpLcdRegister,7 bsf PORTB,LCD_DB7 bsf PORTB,LCD_E ; habilito LCD movlw 1 ;espero 1ms call msDelay bcf PORTB,LCD_E ; deshabilito LCD movlw 1 ;espero 1ms call msDelay ;envio cuatro bits bajos bcf PORTB,LCD_DB4 bcf PORTB,LCD_DB5 bcf PORTB,LCD_DB6 bcf PORTB,LCD_DB7 btfsc tmpLcdRegister,0 bsf PORTB,LCD_DB4 btfsc tmpLcdRegister,1 bsf PORTB,LCD_DB5 btfsc tmpLcdRegister,2 bsf PORTB,LCD_DB6 btfsc tmpLcdRegister,3 bsf PORTB,LCD_DB7 bsf PORTB,LCD_E ; habilito LCD movlw 1 ;espero 1ms call msDelay bcf PORTB,LCD_E ; deshabilito LCD movlw 1 ;espero 1ms call msDelay return END
CURSO
INTEGRAL PIC
Capítulo 9 Manejo de una conexión RS232 En esta sección analizaremos como es posible dotar al PIC16F84A de una interface 232 para conectarlo al puerto serial de la computadora. El ejemplo que vamos a realizar utiliza el circuito para el manejo del LCD de la lección 8 al cual le añadiremos la sección RS232 y así realizar un pequeño terminal RS232. En la práctica, sobre nuestro circuito podremos visualizar en el LCD los caracteres ASCII transmitidos desde el puerto serial de nuestro PC utilizando un programa como el Hyperterminal (Windows 95/98/ME/2000/XP), Telix (MS-DOS) o Minicom (Linux). Veamos el diagrama esquemático en la siguiente figura:
77
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Como podemos apreciar estamos y=trabjando sobre la base del circuito del ejercicio anterior pero añadiendo el circuito integrado U3 y el conector DB9 donde se pegamos el puerto serial de la computadora y algunos componentes adicionales. El circuito integrado U3 es un MAX232 (o similar) producido por la empresa Maxim (http://www.maxim-ic.com), se ocupa de convertir las señales RS232 que están entre +/-12 voltios necesarios para transmitir y recibir datos sobre el puerto serial de nuestro PC, a señales de 0/5 voltios que puedan ser manjedos por el PIC. Veamos como funciona en detalle la comunicación serial RS232.
9.1 Que es y para que sirve el RS232 El estandar RS232 define una serie de especificaciones para la transmisión serial de datos entre dos dispositivos denominados DTE (Data Terminal Equipment) y DCE (Data Communication Equipment). Vagamente del nombre podemos intuir, el Data
78
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Communication Equipment es un dispositivo que se ocupa de manejar una comunicación de datos mientras el Data Terminal Equipment es un dispositivo que se ocupa de generar o recibir datos. En la práctica, el RS232 ha sido creada para conectar un terminal de datos (en nuestro caso un computador) con un modem para la transmisión a distancia de datos. Para que exista una conexión de dos computadores es necesario disponer de cuatro dispositivos como se muestra en la figura: un computador (DTE) conectado a un modem (DCE) y otro modem (DCE) conectado al otro computador (DTE). De este modo cualquier dato generado en el primer computador es transmitido a través de RS232 a su respectivo modem el cual lo transmitirá al modem remoto quien a su vez se lo entregará a su computador via RS232.
Para utilizar el RS232 para conectar entre sí dos computadores sin la intervención de ningun modem, debemos simular de alguna manera la conexión intermedia realizando un cable NULL MODEM para poder intercambiar directamente las señales entre ambos equipos DTE. Para conectar el PC a nuestro circuito simularemos un DCE haciendole creer al PC que se ha conectado a un modem. Antes de esto debemos estudiar en detalle el principio de funcionamiento de una comunicación serial.
9.2 La comunicación serial asincrona Para permitir la transmisión de datos entre el PC y el modem, el estandard RS232 define una serie de especificaciones elétricas y mecánicas. Una de estas establece que la comunicación serial puede ser sincrona o asincrona. En nuestro caso analizaremos solo la comunicación serial asincrona ignorando completamente la sincrona debido a que es un poco más compleja y no se encuentra disponible en nuestro PC. Este tema lo abordaremos en detalle en nuestro curso práctico de comunicaciones seriales. Una comunicación serial consiste en generar la transmisión y la recepción de datos desde un punto a otro usando una sola linea eléctrica. En la prática, si deseamos transmitir un byte entero debemos bit a amorse. bit sobre línea eléctrica. Es algo muy parecidoenviarlos a lo quesecuencialmente se hace con el código La la diferencia sustancial está en el hecho de que la generación y la recepción de datos no la hace un telegrafista sino un computador, el cual puede manejar velocidades de transmisión muy superiores.
79
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Veamos un ejemplo prático de como funciona un PC transmitiendo y receibiendo mediante la RS232. La realización del siguiente experimento no es necesaria, debido a que supongo que es muy dificil que en nuestro laboratorio de hobbystas contemos con dos computadoras y un osciloscopio. Para comprender el funcionamiento de lo anteriormente expuesto podemos referirnos a la siguiente figura. Se desarrollamos un copia de esta cable podemos conectar dos computadoras a través de su puerto serial. Esto es un PC transmisor (derecha) y un PC receptor (izquierda).
De esta manera obtedremos la mas sencilla de las conexiones RS232. La línea Transmit Data (TXD) presente en el pin 3 del conector DB9 macho de nuestro computador se conecta a la línea Receive Data (RXD) presente en el pin 2 del segundo PC. Las tierras (GND) presentes en el pin 5 se deben conectar entre sí. Para observar las señales generadas por el PC al transmitir serialmente debemos conectar las líneas TXD y GND a un osciloscopio y ejecutar un programa de emulación como el hyperterminal o similar. Configuramos el puerto serial a 9600 baud, 8 bits de datos, 1 bit de stop, no parity y deshabilitamos el control de flujo (handshake) via hardware con xon/xoff. En este momento cualquier cosa que digitemos desde el PC se transmitirá directamente al puerto serial. Es importante resaltar que nuestro programa de emulación debe estar configurado correctamente de acuerdo al puerto serial que estemos utilizando (COM1 o COM2). Podriamos digitar la letra verificar queCuando se hayasobre recibido correctamente y visualizar la transmisión enAelyosciloscopio. la línea no se encuentra ninguna transmisión en curso, sobre la línea TXD deben haber -12 voltios, que corresponden al estado lógico 1. Para indicarle al PC receptor que se ha iniciado una transmisión, el PC transmisor debe colocar +12 voltios en la línea TXD durante el tiempo que dure transmitir un solo bit. Esto es, por un tiempo inverso a la frecuencia o velocidad de
80
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
transmisión. En nuestro caso, si estamos conectados a 9600 bits por segundo, el voltaje de alimentación será de +12 voltios durante: 1/9600 = 0.104 mS. Esta señal se denomina START BIT y siempre estará presente al inicio de la transmisión de cada byte. Después del start bit viene transmitida la secuencia de bits que componen el caracter ASCII empezando por el bit menos significativo. En el caso de la A mayúscula, corresponde al valor binario 01000001, y su secuencia de transmisión es la siguiente:
Una vez transmitido el octavo bit (bit 7), el PC enviará automáticamente un último bit en 1 denominado STOP BIT con el que se indica la terminación de la transmisión del byte completo. Esta secuencia se repite para cada uno de los bytes que se transmitan sobre la línea. Si en nuestro cable de comunicación conectamos el pin TXD del receptor (pin 3) con el pin RXD (pin 2) del PC trasmisor, podremos efectuar una transmisión RS232 bidireccional.
9.3 Como conectar nuestro circuito de ejemplo Como lo habiamos mencionado, nuestro circuito simula un dispsitivo DCE. Esto significa que el cable que debemos realizar no puede ser del tipo NULL MODEM, este tipo de cables es como el que se utiliza para conectar al PC un modem externo. Dado que los dispositivos DCE siempre vienen dotados de conector DB9 macho, en nuestro circuito (que corresponde a un DCE) debemos utilizar un DB9 hembra. Su descripción de pines se describe en la siguiente tabla:
Pin Pin Pin Pin Pin Pin Pin Pin Pin
1 2 3 4 5 6 7 8 9
Detector de señal de línea recibida (Data Carrier Detect) Datos recibidos Datos transmitidos Terminal de datos listo Tierra Conjunto de datos listo Petición para enviar Listo para recibir Indicador de ring
81
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Algunos PC están dotados de un conector DB-25 en lugar del convencional DB-9, en este caso puede remitirse a la siguiente tabla para hallar la equivalencia: Pin Pin Pin Pin Pin Pin
1 2 3 4 5 6
Tierra de protección Datos transmitidos Datos recibidos Petición para enviar Listo para enviar Conjunto de datos listo
Pin Pin Pin Pin
7 8 20 22
Tierra Detector de señal de línea recibida (Data Carrier Detect) Terminal de datos listo Indicador de ring
El cable de conexión entre el PC y nuestro circuito deberá poseer un conectro femenino en un lado para llegar sin problema a la PC y el otro lado debe ser macho para conectar a nuestro circuito de prueba. La conexión interna de este cable es la que se muestra en la figura siguiente.
9.4 Funcionamiento del MAX232 En nuestro circuito de ejemplo utilizaremos un driver RS232, el cual corresponde a un circuito integrado que permite convertir las señales de +/- 12 voltios en señales de 0/5 voltios que son manejables por el PIC. Siguiendo el esquema eléctrico de nuestro circuito de ejemplo vemos que las señales de transmisión provenientes del PC entran por el pin 3 del conector DB9 hembra hacia el pin 12 de U3. En el pin 12 de U3 se tendrá una señal de 0 voltios cuando sobre el pin 13 lleguen +12 voltios y una señal de 5 voltios cuando en el pin 13 hayan -12 voltios. Las señales presentes en el pin 12 de U3 se envia a la línea RA1 del puerto A del PIC, que en este caso
82
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
será la línea de recepción. Con el pin 18 del PIC (RA1) podemos hacer la analogía con la línea TXD del PC.
De la misma manera, a través del pin 17 (RA0) el PIC genera las señales que se deben enviar al PC. Como vienen en niveles TTL se deben convertir a señales RS232 por medio de U3, para lo cual se conecta al pin 11 (entrada TTL) y por el pin 14 (salida RS232) se envian al PC a través del pin 2 del conector J2.
9.5 Aplicación de ejemplo Finalmente metamole la mano al fuente de nuestra aplicación de ejemplo y observemos como recibir y como transmitir datos desde nuestro PIC. En el archivo LCDTERM.ASM pueden encontrar todo el programa completo de nuestro terminal de ejemplo. Una vez montado nuestro circuito de ejemplo y programado correctamente el PIC16F84 podemos conectar nuestro PC al circuito y alimentarlo. Sobre el diplay aparecerá el cursor parpadeando a la izquierda. En este punto podemos iniciar la ejecución del programa de terminal emulador (hyperterminal) y configurarlo a 9600 bps, 8 data bit, 1 stop bit, sin paridad y sin ningún control de flujo. Probemos ahora digitar cualquier caracter en le PC y observar como se visualizan en el LCD de nuestro circuito. Oprimiendo CTRL-L podemos borrar la visualización actual y escribir nuevamente. Análisis del ahora programa Procedamos a analizar el código fuente de este ejemplo. Partamos de la línea 24 donde encontramos las siguientes directivas: TX equ 0 ;Tx data RX equ 1 ;Rx data
83
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
En donde se asignan las constantes para establecer las líneas del PIC que se van a utilizar como TX y RX. En este caso solo utilizaremos la línea de recepción pues el mini-terminal solo servirá para recibir y visualizar los datos. Estas dos constantes se utilizan respectivamente en las subrutinas de transmisión y recepción de caracteres via RS232: TxChar (línea 421) y RxChar (línea 483). Estas dos subrutinas permiten en la práctica transmitir y recibir bytes en modalidad seral asincrona a 9600 bps, 8 bit de datos, 1 stop bit y sin paridad. Para transmitir un caracter sobre la línea TX basta cargar el registro W con el valor que se va a transmitir y efectuar una llamda a la subrutina TxChar. Por ejemplo, si queremos transmitir el caracter 'A' al PC debemos escribir: movlw 'A' call TxChar
Para recibir caracteres la operación es un poco más compleja. Observemos en nuestro ejemplo la línea 129: MainLoop btfsc PORTA,RX goto MainLoop call RxChar
En la práctica en nuestro programa se hace un loop infinito hasta que no se detecte el estado lógico 0 sobre la línea RX. Cuando esto ocurre, se deduce que es probable que sea un START BIT desde el PC y que en consecuencia siga una serie de bits de datos transmitidos desde el PC. En este punto se debe invocar a RxChar quien se ocupará de leer cada uno de los bits recibidos, los compila y los almacena en el registro ShiftReg. Una vez invocada RxChar se debe borrar el registro ShiftReg en donde se memorizan los bits recibidos. RxChar clrf ShiftReg
el registro movlw 8 BitCount se usa para contar el número de bits que deben llegar movwf BitCount en este momento se debe hacer una espera de alrededor del periodo de 1 bit para recibir justo a tiempo el valor del BIT 0 después de recibido el start bit DELAY BIT_DELAY+BIT_DELAY/2 ;Espera 1.5 bit
ahora si se puede leeer el estado de la línea de RX e inserta este valor en la bandera de CARRY (C) del registro STATUS para luego efectuar una operación de ROTATE RIGHT F TROUGHT CARRY (RRF) con el registro ShiftReg, de modo que todos los bits recibidos se acomodan ordenadamente rotando y partiendo desde el menos significativo, como se muestra en la siguiente figura:
esta lectura se prepra para otra vuelta a intervalos de tiempo pares a la duración de un bit de manera que se logre tener el valor de la línea de RX siempre en el centro del bit en recepción. wDB btfss PORTA,RX
84
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
goto RxBitL RxBitH nop bsf STATUS,C goto RxShift RxBitL bcf STATUS,C goto RxShift RxShift nop rrf ShiftReg,F
retardo por un periodo de tiempo par a 1 bit DELAY BIT_DELAY
continua leyendo cada uno de los bits decfsz BitCount,F goto wDB
RxChar debe haber leído el último bit return
en este punto en el registro ShiftReg debemos escribir el byte a transmitir al PC. Una vez se ha leido el byte proveniente del PC, nuestro programa de ejemplo controla si el byte recibido es un caracter de control o simplemente se trata de un caracter para visualizar en el LCD. El único caracter de control implementado en nuestro miniterminal es el Form Feed (FF) correspondiente al código ASCII decimal 12. La transmisión de este caracter equivale a lo que haciamos en las máquinas de escribir cuando corriamos el carro para avanzar una línea. En nuestro caso se limpia el contenido del LCD. El form feed puede ser trnasmitido desde nuestro simulador de terminal desde el PC oprimiendo la tecla CTRL seguido de la letra L. La siguiente es la parte del código en donde se maneja la recepción de un Form Feed: CheckFormFeed movlw 12 xorwf ShiftReg,W btfss STATUS,Z goto _CheckFormFeed clrf xCurPos clrf yCurPos call LcdClear goto MainLoop _CheckFormFeed
en la práctica se controla si el valor recibido de la subrutina RxChar equivale a 12. En caso afirmativo se borran los registros xCurPos y yCurPos en donde se mantienen los valores de de X y Y del cursor en el display. En este punto se llama la subrutina LcdClear la cual se encarga de enviar el comando correcto al LCD para borrar su contenido. Si el PC no ha transmitido un FF desde el PC, el caracter recibido se envia al display mediante el siguiente código: movf ShiftReg,W call putchar
y luego se retorna a atender el START BIT del próximo caracter con la siguiente instrucción: goto MainLoop
La subrutina putchar en la práctica envia el valor contenido en el registro W al display LCD en la posición en donde se encuentra el cursor (xCurPos y yCurPos). Los registros xCurPos y yCurPos apuntan a la próxima posición en donde se puede escirbir el siguiente caracter recibido desde el PC.
85
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
9.6 LCDPRINT un programa de ejemplo para la utilización de nuestro terminal En el archivo lcdprint.zip puede encontrar el programa ejemplo para utilizar nuestro terminal RS232. El programa se llama LCDPRINT y funciona en ambiente MS/DOS o desde un prompt MS/DOS sobre Windows 95/98/ME. LCDPRINT permite visualizar mensajes en nuestro terminal de una manera bastante sencilla. Basta digitar en el prompt de MS/DOS el comando LCDPRINT seguido del nmero del puerto serial en donde sequeremos encuentrevisualizar conectado nuestro terminal y luego la cadena a visualizar. Si por ejemplo “Adios a todos” en el miniterminal conectado al puerto COM2, deberemos digitar: LCDPRINT /COM2 "Adios a todos" Este programa a pesar de ser muy sencillo puede tener muchas aplicaciones. Por ejemplo, lo podemos utilizar para visualizar mensajes durante el inicio de Windows 95, insertando el comando en el interior del archivo AUTOEXEC.BAT.
9.7 Otro ejemplo con la interfaz RS232 Veamos ahora otro ejemplo de utilización del RS232. En este caso realizaremos un circuito que tiene la posibilidad de hacer transmisión mediante la subrutina TxChar. Se trata de la evolución del circuito mostrado en la sección anterior con 4 led y 4 dipswitch el cual le adicionamos la capacidad de la conexión RS232 para poder manipular los led y leer en el PC el estado de los dipswitch. En la siguiente figura se muestra el diagrama esquemático:
86
www.welgos.net
CURSO
INTEGRAL
87
www.welgos.net
SOBRE
MICROCONTROLADORES
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
En los archivos rs232io.asm y rs232io.zip se encuentran los programas del microcontrolador y el programa en MS/DOS RS232IO que permiten enviar desde el PC el comando de encendido de los LED y de lectura de los cuatro dipswitch.
9.8 Protocolo de comunicación con el PC Como se mencionó nuestro circuito cuenta con cuatro LED denominados LED denominados LED1, LED2, LED3 y LED4 y cuatro pulsadores denominados SWITCH1, SWITCH2, SWITCH3 y SWITCH4. A través de un simple protocolo podemos decidir cual de los cuatro LED vamos a activar y cual de los dipswitch vamos a leer. El protocolo consiste de una serie de códigos de control que el PC puede transmitir a nuestro circuito serialmente. La velocidad de transmisión es de 9600 baud, 8 data bit, 1 stop bit, sin paridad. Comandos de encendido de los LED Podemos activar los LED enviando desde el PC los siguientes comandos: 00h 01h 02h 03h
Activar Activar Activar Activar
LED LED LED LED
1 2 3 4
Comandos para pagar los LED Para desactivar los LED desde el PC podemos utilizar los siguientes comandos: 10h 11h 12h 13h
Desactivar Desactivar Desactivar Desactivar
LED LED LED LED
1 2 3 4
Lectura del estado de los pulsadores Para leer el estado de todos los pulsadores solo necesitamos un solo comando: 20h
Leer el estado de los pulsadores
Cuando el PIC recibe este comando desde el RS232, lee el estado de los bist RB4, RB5, RB6 y RB7 y envia un único código al PC que refleja el estado de los cuatro pulsadores. De este código solo los bits 0,1,2,3 indican el estado de los pulsadores según la siguiente tabla. Bit 1 0 Bit Bit 2 Bit 3
0= SWITCH1 normal, normal, 1: SWITCH1 activado activado 0 = SWITCH2 1: SWITCH2 0 = SWITCH3 normal, 1: SWITCH3 activado 0 = SWITCH4 normal, 1: SWITCH4 activado
88
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Por ejemplo, si solo tenemos el SWITCH 1 oprimido, la respuesta será 01h (00000001 en binario). Si se encuentran presionados los SWITCH 2 y SWITCH 4, la respuesta será 0Ah (00001010 binario).
Programa de prueba El programa de prueba RS232IO.EXE nos permite probar el circuito inmediatamente. El programa funciona en ambiente MS/DOS o prompt MS/DOS sobre Win 95/98. Si hemos conectado el circuito en el COM2, para prender el LED 1 se deberá digitar: RS232IO /COM2 /LED1=ON
Si ahora lo queremos apagar el LED 1 y prender el LED 4 podemos digitar: RS232IO /COM2 /LED1=OFF /LED4=ON
Si ahpra queremos activar solo el LED 3 sin modificar el estado de los otros LED: RS232IO /COM2 /LED3=ON
Podemos conocer el estado actual de los interruptores cun el comando: RS232IO /COM2 /SWITCH
El programa responderá con lo siguiente: Switch Switch Switch Switch
1: 2: 3: 4:
off off ---> Active off
En este supuesto caso, nos indica que solo el SWITCH 3 está oprimido. ;************************************************** ; Curso integral de microcontroladores Pic ; LCDTERM.ASM ; ; 2003, WELGOS electronica ; (c) http://www.wellgos.com ;************************************************** PROCESSOR 16F84 RADIX DEC INCLUDE "P16F84.INC" ;Suppress the following MPASM warning message [# 302]: ;"Register in operand not in bank 0. Ensure that bank bits are correct" ERRORLEVEL -302 ;Flag configuration __CONFIG 3FF1H ;RS232 lines TX equ 0 ;Tx data RX equ 1 ;Rx data ;LCD Control lines LCD_RS equ 2 ;seleccion de registro LCD_E equ 3 ;Enable ;LCD data line bus LCD_DB4 equ 4 ;linea de datos db4 de lcd LCD_DB5 equ 5 ; linea de datos db5de lcd LCD_DB6 equ 6 ; linea de datos db6 de lcd LCD_DB7 equ 7 ; linea de datos db7de lcd ;********************************************************************** ; frecuencia del reloj (4 MHz) ;********************************************************************** BIT_DELAY equ 23 ;Bit delay a 9600 bps ;********************************************************************** ; MACRO – subrutina de retardo con el watch dog ; parametros del macro:
89
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
; ; VALUE: retardo obtenico=((VALUE-1)*4+5)*(1/(Fosc/4)) ; ;********************************************************************** DELAY MACRO VALUE LOCAL REDO movlw VALUE movwf TmpRegister REDO clrwdt ;Clear watch dog timer decfsz TmpRegister,F goto REDO ENDM ;********************************************************************** ; FILE REGISTER ;********************************************************************** ORG 0CH tmpLcdRegister res 2 msDelayCounter res 2 TmpRegister res 1 ;Registro usado por las subrutinas rs232 ShiftReg res 1 ;registro de desplazamiento BitCount res 1 ;contador de bits ;ubicacion del cursor xCurPos res 1 yCurPos res 1 putTempReg res 1 ;Reset Vector ;********************************************************************** ; RESET VECTOR ;********************************************************************** ORG 00H Start bsf STATUS,RP0 ;Swap al banco de registros 1 movlw 00011111B ; movwf TRISA movlw 11111111B ; movwf TRISB bcf PORTA,TX ;liena TX como salida bcf PORTB,LCD_DB4 ; bcf PORTB,LCD_DB5 bcf PORTB,LCD_DB6 bcf PORTB,LCD_DB7 bcf PORTB,LCD_E bcf PORTB,LCD_RS bcf STATUS,RP0 ; ;LCD inizializacion call LcdInit ;Put terminal cursor on 0,0 position clrf xCurPos clrf yCurPos ;Wait until receives a start bit from RS232 line MainLoop btfsc PORTA,RX ;Received a start bit ? goto MainLoop ;No, wait. call RxChar ;Yes, read the byte on receiving... CheckFormFeed movlw 12 xorwf ShiftReg,W btfss STATUS,Z
90
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
goto _CheckFormFeed clrf xCurPos clrf yCurPos call LcdClear goto MainLoop _CheckFormFeed movf ShiftReg,W call putchar goto MainLoop ;********************************************************************** ; Delay subroutine ; ; W = Requested delay time in ms (clock = 4MHz) ;********************************************************************** msDelay movwf msDelayCounter+1 clrf msDelayCounter+0 ; 1 ms (about) internal loop msDelayLoop nop decfsz msDelayCounter+0,F goto msDelayLoop nop decfsz msDelayCounter+1,F goto msDelayLoop return ;********************************************************************** ; Put a char to xCurPos, yCurPos position on LCD ; ; W = Char to show ; xCurPos = x position ; yCurPos = y position ; ; xCurPos and yCurPos will be increase automaticaly ;********************************************************************** putchar movwf putTempReg swapf yCurPos,W iorwf xCurPos,W call LcdLocate movf putTempReg,W call LcdSendData incf xCurPos,F movlw 16 xorwf xCurPos,W btfss STATUS,Z goto moveLcdCursor clrf xCurPos incf yCurPos,F movlw 2 xorwf yCurPos,W btfss STATUS,Z goto moveLcdCursor clrf yCurPos moveLcdCursor swapf yCurPos,W iorwf xCurPos,W call LcdLocate return ;********************************************************************** ; Init LCD
91
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
; This subroutine must be called before each other lcd subroutine ;********************************************************************** LcdInit movlw 30 ;Wait 30 ms call msDelay ;**************** ; Reset sequence ;**************** bcf PORTB,LCD_RS ;Set LCD command mode ;Send a reset sequence to LCD bsf PORTB,LCD_DB4 bsf PORTB,LCD_DB5 bcf PORTB,LCD_DB6 bcf PORTB,LCD_DB7 bsf PORTB,LCD_E ;Enables LCD movlw 5 ;Wait 5 ms call msDelay bcf PORTB,LCD_E ;Disables LCD movlw 1 ;Wait 1ms call msDelay bsf PORTB,LCD_E ;Enables LCD movlw 1 ;Wait 1ms call msDelay bcf PORTB,LCD_E ;Disables LCD movlw 1 ;Wait 1ms call msDelay bsf PORTB,LCD_E ;Enables E movlw 1 ;Wait 1ms call msDelay bcf PORTB,LCD_E ;Disables E movlw 1 ;Wait 1ms call msDelay bcf PORTB,LCD_DB4 bsf PORTB,LCD_DB5 bcf PORTB,LCD_DB6 bcf PORTB,LCD_DB7 bsf PORTB,LCD_E ;Enables LCD movlw 1 ;Wait 1ms call msDelay bcf PORTB,LCD_E ;Disabled LCD movlw 1 ;Wait 1ms call msDelay ;Set 4 bit data bus length movlw 28H; call LcdSendCommand ;Entry mode set, increment, no shift movlw 06H; call LcdSendCommand ;Display ON, Curson ON, Blink OFF movlw 0EH call LcdSendCommand ;Clear display call LcdClear return ;********************************************************************** ; Clear LCD ;********************************************************************** LcdClear ;Clear display movlw 01H call LcdSendCommand
92
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
movlw 2 ;Wait 2 ms call msDelay ;DD RAM address set 1st digit movlw 80H; call LcdSendCommand return ;********************************************************************** ; Locate cursor on LCD ; W = D7-D4 row, D3-D0 col ;********************************************************************** LcdLocate movwf tmpLcdRegister+0 movlw 80H movwf tmpLcdRegister+1 movf tmpLcdRegister+0,W andlw 0FH iorwf tmpLcdRegister+1,F btfsc tmpLcdRegister+0,4 bsf tmpLcdRegister+1,6 movf tmpLcdRegister+1,W call LcdSendCommand return ;********************************************************************** ; Send a data to LCD ;********************************************************************** LcdSendData bsf PORTB,LCD_RS call LcdSendByte return ;********************************************************************** ; Send a command to LCD ;********************************************************************** LcdSendCommand bcf PORTB,LCD_RS call LcdSendByte return ;********************************************************************** ; Send a byte to LCD by 4 bit data bus ;********************************************************************** LcdSendByte ;Save value to send movwf tmpLcdRegister ;Send highter four bits bcf PORTB,LCD_DB4 bcf PORTB,LCD_DB5 bcf PORTB,LCD_DB6 bcf PORTB,LCD_DB7 btfsc tmpLcdRegister,4 bsf PORTB,LCD_DB4 btfsc tmpLcdRegister,5 bsf PORTB,LCD_DB5 btfsc tmpLcdRegister,6 bsf PORTB,LCD_DB6 btfsc tmpLcdRegister,7 bsf PORTB,LCD_DB7 bsf PORTB,LCD_E ;Enables LCD movlw 1 ;Wait 1ms call msDelay bcf PORTB,LCD_E ;Disabled LCD movlw 1 ;Wait 1ms call msDelay
93
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
;Send lower four bits bcf PORTB,LCD_DB4 bcf PORTB,LCD_DB5 bcf PORTB,LCD_DB6 bcf PORTB,LCD_DB7 btfsc tmpLcdRegister,0 bsf PORTB,LCD_DB4 btfsc tmpLcdRegister,1 bsf PORTB,LCD_DB5 btfsc tmpLcdRegister,2 bsf PORTB,LCD_DB6 btfsc tmpLcdRegister,3 bsf PORTB,LCD_DB7 bsf PORTB,LCD_E ;Enables LCD movlw 1 ;Wait 1ms call msDelay bcf PORTB,LCD_E ;Disabled LCD movlw 1 ;Wait 1ms call msDelay return ;*********************************************************************** *** ; Send a character on RS232 ; (9600 baud,8 data bit, 1 stop bit, No parity) ; ; Input: W = Character to send ;*********************************************************************** *** TxChar movwf ShiftReg movlw 8 ;Data lenght movwf BitCount bcf PORTA,TX ;Send start bit nop nop nop nop nop nop nop DELAY BIT_DELAY ;Tx loop TxLoop btfss ShiftReg,0 goto TxLo nop bsf PORTA,TX goto cTx TxLo bcf PORTA,TX goto cTx cTx nop rrf ShiftReg,F DELAY BIT_DELAY decfsz BitCount,F goto TxLoop nop nop nop nop
94
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
bsf PORTA,TX ;Stop bit DELAY BIT_DELAY DELAY 2 nop bsf PORTA,TX DELAY BIT_DELAY DELAY 2 Return ;*********************************************************************** *** ; Receive a character from RS232 ; (9600 baud,8 data bit, 1 stop bit, No parity) ; ; Return code: ; ; ShiftReg: Received character ;*********************************************************************** *** RxChar clrf ShiftReg movlw 8 ;Data lenght movwf BitCount DELAY BIT_DELAY+BIT_DELAY/2 ;Wait 1.5 bit ;Loop di lettura dei bit dati wDB btfss PORTA,RX goto RxBitL RxBitH nop bsf STATUS,C goto RxShift RxBitL bcf STATUS,C goto RxShift RxShift nop rrf ShiftReg,F DELAY BIT_DELAY decfsz BitCount,F goto wDB return END
;************************************************** ; Curso integral de microcontroladores Pic ; RS232IO.ASM ; ; (c) 2003, WELGOS electronica ; http://www.wellgos.com ;************************************************** PROCESSOR 16F84 RADIX DEC INCLUDE "P16F84.INC" ;Suppress the following MPASM warning message [# 302]:
95
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
;"Register in operand not in bank 0. Ensure that bank bits are correct" ERRORLEVEL -302 ;Flag configuration __CONFIG 3FF1H ;RS232 lines TX equ 0 ;Tx data RX equ 1 ;Rx data ;I/O lines on PORTB LED1 equ 0 LED2 equ 1 LED3 equ 2 LED4 equ 3 SWITCH1 equ 4 SWITCH2 equ 5 SWITCH3 equ 6 SWITCH4 equ 7 ;Command code from PC LED1_ON equ 00h LED2_ON equ 01h LED3_ON equ 02h LED4_ON equ 03h LED1_OFF equ 10h LED2_OFF equ 11h LED3_OFF equ 12h LED4_OFF equ 13h GET_SWITCH equ 20h ;********************************************************************** ; Clock frequency related constant (4 MHz) ;********************************************************************** BIT_DELAY equ 23 ;Bit delay a 9600 bps ;********************************************************************** ; MACRO - Delay subroutine with watch dog timer clearing ; ; Macro parameters: ; ; VALUE: Delay obtained = ((VALUE-1)*4+5)*(1/(Fosc/4)) ; ;********************************************************************** DELAY MACRO VALUE LOCAL REDO movlw VALUE movwf TmpRegister REDO clrwdt ;Clear watch dog timer decfsz TmpRegister,F goto REDO ENDM ;********************************************************************** ; FILE REGISTER ;********************************************************************** ORG 0CH ;Register used by msDelay subroutine and DELAY macro msDelayCounter res 2 TmpRegister res 1 ;Register used by RS232 subroutines ShiftReg res 1 ;Shift register BitCount res 1 ;Bit counter DummyReg res 1 ;********************************************************************** ; RESET VECTOR ;********************************************************************** ORG 00H
96
www.welgos.net
CURSO
INTEGRAL
Start bsf STATUS,RP0 ;Swap to register bank 1 movlw 00011111B ;Sets the whole PORTA as input movwf TRISA movlw 11111111B ;Sets the whole PORTB as input movwf TRISB bcf PORTA,TX ;Sets TX line as output bcf TRISB,LED1 ;Set output line on PORTB bcf TRISB,LED2 bcf TRISB,LED3 bcf TRISB,LED4 bcf STATUS,RP0 ;Swap to register bank 0 bcf PORTB,LED1 ;Turn off each leds bcf PORTB,LED2 bcf PORTB,LED3 bcf PORTB,LED4 ;Wait until receives a start bit from RS232 line MainLoop btfsc PORTA,RX ;Received a start bit ? goto MainLoop ;No, wait. call RxChar ;Yes, read the byte on receiving... ;*********************** ; Check for PC commands ;*********************** ;*********************** ; LED1_ON ;*********************** Led1On movlw LED1_ON xorwf ShiftReg,W btfss STATUS,Z goto _Led1On bsf PORTB,LED1 goto MainLoop _Led1On ;*********************** ; LED2_ON ;*********************** Led2On movlw LED2_ON xorwf ShiftReg,W btfss STATUS,Z goto _Led2On bsf PORTB,LED2 goto MainLoop _Led2On ;*********************** ; LED3_ON ;*********************** Led3On movlw LED3_ON xorwf ShiftReg,W btfss STATUS,Z goto _Led3On bsf PORTB,LED3 goto MainLoop _Led3On ;*********************** ; LED4_ON ;*********************** Led4On
97
www.welgos.net
SOBRE
MICROCONTROLADORES
CURSO
INTEGRAL
movlw LED4_ON xorwf ShiftReg,W btfss STATUS,Z goto _Led4On bsf PORTB,LED4 goto MainLoop _Led4On ;*********************** ; LED1_OFF ;*********************** Led1Off movlw LED1_OFF xorwf ShiftReg,W btfss STATUS,Z goto _Led1Off bcf PORTB,LED1 goto MainLoop _Led1Off ;*********************** ; LED2_OFF ;*********************** Led2Off movlw LED2_OFF xorwf ShiftReg,W btfss STATUS,Z goto _Led2Off bcf PORTB,LED2 goto MainLoop _Led2Off ;*********************** ; LED3_OFF ;*********************** Led3Off movlw LED3_OFF xorwf ShiftReg,W btfss STATUS,Z goto _Led3Off bcf PORTB,LED3 goto MainLoop _Led3Off ;*********************** ; LED4_OFF ;*********************** Led4Off movlw LED4_OFF xorwf ShiftReg,W btfss STATUS,Z goto _Led4Off bcf PORTB,LED4 goto MainLoop _Led4Off ;*********************** ; GET_SWITCH ;*********************** GetSwitch movlw GET_SWITCH xorwf ShiftReg,W btfss STATUS,Z goto _GetSwitch swapf PORTB,W ;Read the switch state and send
98
www.welgos.net
SOBRE
MICROCONTROLADORES
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
movwf DummyReg ;it to the PC comf DummyReg,W andlw 0Fh call TxChar goto MainLoop _GetSwitch goto MainLoop ;********************************************************************** ; Delay subroutine ; ; W = Requested delay time in ms (clock = 4MHz) ;********************************************************************** msDelay movwf msDelayCounter+1 clrf msDelayCounter+0 ; 1 ms (about) internal loop msDelayLoop nop decfsz msDelayCounter+0,F goto msDelayLoop nop decfsz msDelayCounter+1,F goto msDelayLoop return ;*********************************************************************** *** ; Send a character on RS232 ; (9600 baud,8 data bit, 1 stop bit, No parity) ; ; Input: W = Character to send ;*********************************************************************** *** TxChar movwf ShiftReg movlw 8 ;Data lenght movwf BitCount bcf PORTA,TX ;Send start bit nop nop nop nop nop nop nop DELAY BIT_DELAY ;Tx loop TxLoop btfss ShiftReg,0 goto TxLo nop bsf PORTA,TX goto cTx TxLo bcf PORTA,TX goto cTx cTx nop rrf ShiftReg,F DELAY BIT_DELAY decfsz BitCount,F goto TxLoop
99
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
nop nop nop nop bsf PORTA,TX ;Stop bit DELAY BIT_DELAY DELAY 2 nop bsf PORTA,TX DELAY BIT_DELAY DELAY 2 return ;*********************************************************************** *** ; Receive a character from RS232 ; (9600 baud,8 data bit, 1 stop bit, No parity) ; ; Return code: ; ; ShiftReg: Received character ;*********************************************************************** *** RxChar clrf ShiftReg movlw 8 ;Data lenght movwf BitCount DELAY BIT_DELAY+BIT_DELAY/2 ;Wait 1.5 bit ;Loop di lettura dei bit dati wDB btfss PORTA,RX goto RxBitL RxBitH nop bsf STATUS,C goto RxShift RxBitL bcf STATUS,C goto RxShift RxShift nop rrf ShiftReg,F DELAY BIT_DELAY decfsz BitCount,F goto wDB return END
100
www.welgos.net
CURSO
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
INTEGRAL PIC
Capítulo 10 Prácticas con el entrenador 10.1 Multiplexaje de teclado En la siguiente figura se muestra la forma de instalar un teclado de 16 elementos, requeriendo de solo 8 líneas I/O para realizar adecuadamente la lectura. Esta configuración se denomina matricial y para manejarla se requiere el multiplexaje.
101
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
En este caso, las líneas del microcontrolador correspondientes a las filas se deben configurar como salidas y las correspondientes a las columnas como entradas. Normalmente las líneas de entrada permanecen en estado alto debido a las resistencias de pull-up. Para manejar este teclado se debe enviar secuencialmente un solo cero por las líneas de salida; por ejemplo, si enviamos un cero por la línea RA1, cuando orpimimosuna tecla de la segunda fila (el, 4, 5, 6 ó 7), un nivel lógico bajo se detectará en el pin correspondiente a las líneas de entrada (RB0, RB1, RB2 ó RB3 respectivamente). De esta manera, si se encuentra un nivel lógico bajo en la línea RB3 podemos concluir que la tecla presionada fué el dígito 7. Si queremos explorar todo este teclsdo, bastará con rotar el cero circularmente, de tal manera que solamente un cero se encuentre en las filas del teclado, cuando se realiza las lecturas de las líneas de entrada (las columnas) como se muestra en la siguiente figura.
102
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Cuando el cero llegue a la fila más significativa del teclado, debe reingresar en la próxima ocasión por la menos significativa, reiniciando la exploración del teclado. Como resultado del programa, un valor comprendido entre 0 y 15 queda almacenado en un registro, dicho valor se muestra en un display de siete segmentos que se ha conectado a los pines RB4 a RB7, para comprobar el funcionamiento del sistema. El proceso se efectúa a una gran velocidad, por lo que se tiene la sensación de que todo el teclado se está sensando permanentemente. Otro aspecto que no se puede olvidar, son los rebotes causados por la pulsación de una tecla. Cuando una tecla se oprime, sus contactos actúan como resortes y la unión eléctrica no es etsbale; se generan una serie de uniones y desuniones mecánicas durante un intervalo significativo de tiempo. Estos rebotes pueden dar lugar a que, en una aplicación real, el programa los interprete como si hubieran generado muchas pulsaciones, si es queno se toman los correctivos del caso. La solución para este problema es que después de la detección de la tecla pulsada se genere un retardo (entre 100 y 125 ms) en la lectura del teclado, de tal manera que se ignoren los contactos subsiguientes debido a los rebotes.
10.2 Multiplexaje de displays de siete segmentos En la siguiente figura se muestran cuatros displays de siete segmentos. Cuatro pines I/O controlan los transistores NPN que alimentan los cátodos de cada uno de los displays, en donde el bit menos significativo controla el display de menor peso. Un puerto de ocho bits maneja cada uno de los segmentos de los displays, en donde el bit menos significativo controla el 103
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
segmento a, elsiguiente el b, y así sucesivamente, hasta llegar al más significativo, que controla el punto decimal del display. Las resistencias tienen como objeto limitar la corriente que fluye a través de los segmentos y que ingresa a los pines del microcontrolador. Por la configuración es fácil deducir que cuando se tiene un nivel bajo en la base del transistor éste se comporta comoun interruptor abierto y no se presenta corriente entre emisor y colector; se necesita tener un uno lógico en las bases de éstos para que el transistor se comporte como un interruptor cerrado y se presente dicha corriente. Pero aún cuando los transistores se comporten como interruptores cerrados, no se encenderá ningún display si la salida del puerto que maneja los segmentos tiene niveles lógicos bajos (ceros); para encenderlo es necesario colocar un nivel lógico alto en el pin de salida correspondiente a cada segmento. Así por ejemplo, si queremos mostrar un tres en el segundo display menos significativo debemos establecer básicamente los siguientes pasos: *Colocar el número binario 0010 en el puerto que controla los transistores Enviar el número binario 01001111 por el puerto que controla los segmentos. •
Un buen observador encontrará que aunque los anteriores pasos consiguen el objetivo propuesto (mostrar en pantalla el número 3) este proceso puede conllevar efectos indeseados. Por ejemplo, si el puerto que controla los segmentos tenía un valor diferente del binario 00000000 o del 01001111, entre la o ejecución de los pasos dados mostrará en Por el display número un símbolo quedos es diferente del se valor deseado. ello, esun conveniente apagar momentáneamente los segmentos, de tal manera que nos permita seleccionar adecuadamente el display en cuestión y posterior a esto, enviar el dato correcto a los segmentos; por lo tanto, un paso 0 que se debe agregar a este proceso es el de colocar el número 00000000 en el puerto que controla los segmentos. Otra opción que permite obtener el mismo resultado, con un proceso diferente sería el siguiente: Colocar el número binario 0000 en el puerto que controla los transistores Enviar el número binario 01001111 por el puerto que controla los segmentos Colocar el número binario 0010 en el puerto que controla los transistores • •
•
Ahora, si pretendemos visualizar no uno sino los cuatro displays de siete segmentos, es necesario empezara controlar los transistores secuencialmente a la vez que se envía por el puerto que controla los segmentos los datos correspondientes al display en cuestión, realizando este proceso a una velocidad tal que de nuevo parezca que el proceso se está realizando simultáneamente sobre todos los displays. El tiempo en que necesitamos sostener el dato en cada display puede variar significativamente, dependiendo fundamentalmente del valor de las 104
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
resistencias limitadoras, del número de dígitos que se tengan que mostrar y de las características propias del display; experimentalmente se encuentra que mostrar cada dígito durante tres milisegundos, cuando se tienen resistencias limitadoras de 100 ohm, proporcionan un brillo aceptable de un display “estándar” y una buena visualización a una distancia prudente.
Un variante para este sistema consiste en utilizar un decodificador para manejar los displays de siete segmentos, en este caso no se requiere la lectura de tablas y el dato correspondiente se puede llevar al puerto directamente.
10.3 Manejo de motor paso a paso Los motores paso a paso se consideran uno de los elementos más importantes en proyectos de automatización, robótica, etc., debido a la 105
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
preisión de sus movimientos y a su naturaleza digital, lo que facilita enormemente su manejo.En este caso ,utilizaremos un microcontrolador PIC como elemento principal para guiar la posición de un motor de esta clase. Primero haremos una breve descrpción de este tipo de motores, luego se muestra la forma de conectarlo al microcontrolador para conseguir un movimiento de paso completo y por último se hace un ejercicio con movimientos en medio paso. Motores paso a paso Utilizaremos motores de cuatro bobinas. Este tipo de motores se identifican porque tienen 5, 6, u 8 cables. En el primer caso existe un cable que es común a todos los demás, para el de 6 cables se tiene un común para cada pareja de bobinas y en el de 8 cables cada bobina es independiente. En la siguiente figura se muestra su estructura, incluyendo los colores de los cables (que son estándares).
Este tipo de motores poseen la ventaja de que pueden operar con una sola fuente, mientras que los motores de dos bobinas requieren polaridad positiva y negativa, haciéndose necesario utilizar circuito en puente. En la figura anterior se muestra la forma de conectar el motor de ocho cables. Debe notarse que los cables rojos y negros se unen para conectarlos a la fuente positiva. De aquí se puede deducir como sería la conexión para 5 y 6 cables. El movimiento del motor se obtiene al energizar las bobinas en un orden determinado. Esto se puede hacer de dos formas: la primera consiste en 106
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
activar una sola bobina a la vez (manejo por ola), la segunda es el manejo de dos fases o bobbinas al mismo tiempo. Con este último método se puede conseguir mayor torque. En la siguiente figura se muestran los diagramas de tiempo de los dos métodos anteriores.
Control del motor a pasos completos Cada uno de los pasos se logra cuando se encienden las bobinas correspondientes según la secuencia. También se debe aclarar que el punto común delas bobinas del motor se debe conectar a +5V, ya que este es el dato suministrado por el fabricante en la plca de datos del mismo.
107
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Para controlar el motor se utiliza el microcontrolador PIC16F84A, el cual está empleando un cristal de 4 MHz y utiliza cuatro pines del puerto A (RA0-RA3) como salidas, para activar o desactivar los transistores que manejan cada una de las bobinas. En la siguiente figura se muestra el diagrama esquemático correspondiente, el cual incluye una tabla con la secuencia que se debe seguir para conseguir que el motor gire. Viendo la tabla de la secuencia se puede deducir que con simples rotaciones de un registro se puede conseguir el objetivo. Cada vez que se enciende la bobina correspondiente a un valor de la tabla, el motor se mueve un paso. Por lo tanto para que el motor de un giro completo, debe dar tantos pasos según el tipo de motor que se esté trabajando. Para que el motor gire en sentido contrario, sólo se debe invertir la secuencia, es decir, leer la tabla en sentido inverso. Cuando el motor no está en movimiento se debe garantizar que todas las bobinas estén desenergizadas. Esto se hace para evitar posibles daños al motor.
108
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Para el ejercicio del motor paso a paso, monte el esquema de la siguiente figura y el programa que se muestra enseguida.
;********************************** ; Curso integral de microcontroladores PIC * ; WWW.WELLGOS.COM * ; MOTOR PASO A PASO * ;********************************** PROCESSOR RADIX
16F84 DEC
INCLUDE "P16F84A.INC" ORG CONTAD CONTAD1 CONTAD2 ORG
0x0C RES RES RES
1 1 1
0
109
www.welgos.net
CURSO
BSF MOVLW MOVWF MOVLW MOVWF BCF
STATUS,RP0 B'11111' TRISA B'00000000' TRISB STATUS,RP0
; ; ; ; ; ;
INTEGRAL
SOBRE
MICROCONTROLADORES
ENTRA AL BANCO 1 CARGA '11111' EN EL REGISTRO DE TRABAJO 'W' CARGA 'W' EN EL PUERTO A CARGA '00000000' EN EL REGISTRO DE TRABAJO CARGA 'W' EN EL PUERTO B SALE DEL BANCO 1 AL BANCO 0
INICIO BTFSC PORTA,0 ; En este puerto va el pulsador de giro a la izquierda GOTO GOTO INICIO1 derecha GOTO DERECHA MOVWF CALL CALL CALL MOVLW MOVWF CALL CALL CALL MOVLW MOVWF CALL
INICIO1 IZQUIER BTFSC PORTA,1 ;En este puerto va el pulsador de giro a la INICIO MOVLW B'00001100' PORTB DIEZ DIEZ DIEZ B'00000110' PORTB DIEZ DIEZ DIEZ B'00000011' PORTB DIEZ
CALL CALL MOVLW MOVWF CALL CALL CALL GOTO
DIEZ DIEZ B'00001001' PORTB DIEZ DIEZ DIEZ INICIO
IZQUIER MOVLW MOVWF CALL CALL CALL MOVLW MOVWF CALL CALL CALL MOVLW MOVWF CALL CALL CALL
B'00001001' PORTB DIEZ DIEZ DIEZ B'00000011' PORTB DIEZ DIEZ DIEZ B'00000110' PORTB DIEZ DIEZ DIEZ
110
www.welgos.net
CURSO
MOVLW MOVWF CALL CALL CALL GOTO
INTEGRAL
B'00001100' PORTB DIEZ DIEZ DIEZ INICIO
;********************************* ; RUTINA DE RETARDO ;*********************************
UNSEG MOVLW MOVWF UNSEG1 CALL DECFSZ GOTO RETURN
.10 CONTAD2 CIEN CONTAD2,1 UNSEG1
CIEN MOVLW MOVWF CLRF UNSEG2 NOP DECFSZ GOTO DECFSZ GOTO RETURN
.100 CONTAD CONTAD1
CONTAD1,1 UNSEG2 CONTAD,1 UNSEG2
DIEZ MOVLW MOVWF CLRF UNSEG3 NOP DECFSZ GOTO DECFSZ GOTO RETURN
.10 CONTAD CONTAD1
CONTAD1,1 UNSEG3 CONTAD,1 UNSEG3
END
111
www.welgos.net
SOBRE
MICROCONTROLADORES
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
10.4 Manejo de motor dc Para activar un motor DC basta alimentadr con voltaje DC sus terminales. Pero como hacer que el motor cambie su sentido de giro? Si cambiamos la polaridad con que alimentamos el motor, se cambia su sentido de giro. Pero como hacer esto desde un microcontrolador? Para activar el motor podemos utilizar un transistor conectado a un relé.
NOTA Si utilize reles, recuerde colocar un diodo en paralelo a la bobina del rele para controlar corrientes de fuga que puedan afectar los circuitos.
En esta figura se muestra una sencilla conexión que permite controlar la activación del motor desde un microcontrolador. Al aplicar un 1 lógico el motor gira hacia adelante y aplicanco un 0 lógico el motor se detiene.
En esta figura, al aplicar un 1 lógico el motor gira hacia atrás y aplicanco un 0 lógico el motor se detiene. Ambos circuitos solo permiten que gire en un solo sentido, hacia adelante en el primer caso y hacia atrás en el Segundo. 112
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Velocidad de Motor La manera más eficiente de controlar esta variable del motor es a través de pulsos para obtener un grado de torque determinado, lo cual se refleja en variación de la velocidad del motor. Pero si lo que se necesita es controlar el motor en ambas direcciones desde un la procesador, se necesita una circuitería adicional. Necesitará En siguiente gráfica se puede apreciar una confugración en Hun porpuente medioH. de relés. Los reles de la parte superior controlar en voltaje positive hacia el motor y los relés inferiores controlan el voltaje negativo hacia el motor.
De esta manera, si se activan los relés superior izquierdo y el inferior derecho, la potencia fluye haciendo que el motor gire hacia adelante. Esto es, 1 en A, 0 en B, 0 en C, y 1 en D.
113
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Para invetir el sentido de giro, se deben activar los reles superior izquierdo e inferior izquierdo, esto es, 0 en A, 1 en B, 1 en C, y 0 en D.
114
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
PRECAUCION: No debe activar la secuencia para que gire hacia ambos lados, puede causar un corto circuito que puede afectar el sistema, por ejemplo activar A y C o B y D.
Puente H Semiconductores El Puente H se puede implementer con transistores normales o transistores de efecto de campo (FETs). En la siguiente figura se muestra como se deben conectar. Estos circuitos de estado sólido proveen las conexiones a la potencia y a la tierra, así como en la conexión con relés. Los drivers superiors necesitan ser Fuentes de corriente para lo cual son buenos los transistores PNP y los P-channel FETs. Los dirvers inferiores deben ser Buenos sumideros de corriente, por lo que se utilizar transistores NPN y N-channel FETs.
115
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Si se activan los dos circuitos superiores, el motor se resiste al giro, de manera que se tiene un mecanismo efectivo de detención. Lo mismo se cumple para el caso de los dos circuitos inferiores. Esto se debe a que el motor es un generador, cuando gira genera un voltaje. Si los terminales del motor se corto cricuitan, el voltaje generado contraresta el intención de giro del motor. Para cuidar los transistores, conviene adicionar diodos que controlen las corriente de fuga generadas por las bobinas del motor en los momentos de la conmutación de la potencia.
116
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Los transistores, por ser dispositivos semiconductores, tiene cierta resistencia, la cual causa que no conduzcan mucha corriente. Los Mosfets son mucho más eficientes, puede aportar mucha más corriente y no se calientan. Ellos por lo general cuentan internamente con los diodos de protección por lo que no necesitan diodos externos. Es importante que los cuatro cuadrantes de los circuitos de Puente H se activen y desactiven apropiadamente. Cuando existe una ruta entre los lados positivo y negativo del puente H además de la del motor, puede ocurrir un corto circuito que afecte el sistema. Existen circuitos integrados puentes H en el comercio, que son mucho más sencillos de manejar, más seguros y más eficientes que hacerlo uno mismo.
10.5 Manejo de publicidad electrónica Una de las tendencias más fuertes de los medios comerciales es el de llegar a sistemas digitales de publicidad. Este minipublik es un buen principio para los aficionados a este campo. En la siguiente figura se muestra el diagrama de conexiones del circuito que sugerimos como plataforma de pruebas. En el CD se puede descargar el código fuente de esta aplicación para que el usuario cree sus propios patrones.
117
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
El funcionamiento básico consiste en mandar alternadamente los datos de las filas y de las columnas a una matriz de diodos led de dimensión 8x8. El dato se manda por todo el puerto B y mediante los pines del puerto A se srcina la señal de reloj que habilita el paso de esos datos hacia las filas y hacia las columnas en el momento exacto que corresponda. El puerto B del microcontrolador se utiliza como bus de datos, conectandose a las líneas D0-D7 de dos flip-flops octales (74374). Las salidas de estos flipflops manejan las líneas de las filas y las columnas. RA0 y RA1 se usan como reloj para la entrada de los datos en las líneas de filas/columnas. Para diseñar una figura se deben poner los datos deseados en la fila en el puerto B y mandar un flanco de subida para activar el reloj del 374 por el puerto A (RA1). Ahora se colocan los datos de la columna en el puerto B y se manda el pulso de activación del flip flop por el puerto A (RA0). Antes de movernos a la siguiente fila, se debe poner FF en las líneas de las columnas para limpiar el display y evitar problemas de “fantasmeo”.
118
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
10.6 Manejo del tiempo real El tiempo real es un elemento muy utilizado en muchas aplicaciones con microcontroladores. Existen circuitos integrados especializados que se conectan al microcontrolador y que permiten manejar el tiempo real incluso el calendario. En este ejercicio utilizaremos un cristal de cuarzo de 32.768 KHz como oscilador, lo que nos permite obtener una base de tiempo real muy precisa, sin necesidad de utilizar ningún circuito integrado externo. Para ello haga el montaje de la siguiente figura.
Para obtener la base de tiempos basta desarrollar una interrupción por TMR0 por cada segundo. En la primera parte del programa se tiene las instrucciones normales del vector de reser donde se direcciona el cuerpo principal del programa y la dirección de la subrutina de interrupción.
;*********************** Reset Vector ORG 0x00 ;Start goto Main_Prog ;Goto Main_Prog routine ORG 0x04 goto Interrupt ;Goto Interrupt routine
119
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Dentro de la interupción se incremetan los registros correspondientes a las unidades y decenas de los segundos, minutos y horas, para obtener luna visualización de la hora en formato militar. ;********************** Rutina de gestion de interrupcion del TMR0 Interrupt call Clock call View_Time bcf INTCON,T0IF ;Clear interrupt flag TMR0 retfie
;Ritorno dopo interrupt
;******************* Rutina de manejo de las horas, minutos, segundos Clock incf Uni_Secondi,F ;Incrementa la unidad de los segundos movlw 0x0A ;Si las unidades de los segundos subwf Uni_Secondi,W ;es inferior a 10 sigue btfss STATUS,Z return movlw movwf
0x00 Uni_Secondi
;Si = 10 borra la unidad de los segundos
incf
Dec_Secondi,F
;Incrementa las decenas de segundos
movlw subwf btfss return
0x06 Dec_Secondi,W STATUS,Z
;Si las decenas de segundos ;es inferior a 6 sigue
movlw movwf
0x00 Dec_Secondi
;Si = 6 borrar las decenas de segundos
Incr_Min ;******************** incf Uni_Min,F movlw 0x0A subwf Uni_Min,W btfss STATUS,Z return
Incremento minutos en programacion
;Incrementa las unidades de minutos ;Si las unidades de minutos son ;inferiores a 10 salta
;********************** Incremento decenas de minutos movlw movwf incf movlw subwf btfss return
0x00 Uni_Min Dec_Min,F 0x06 Dec_Min,W STATUS,Z
;Si = 10 borra las unidades de minutos ;Incrementa las decenas de minutos ;Si decenas de minutos ;inferior a 6 sigue
;********************** Incremento unidades de horas movlw movwf
0x00 Dec_Min
;Si = 6 borra las decenas de minutos
120
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Incr_Ore ;*************************** Incremento horas en programacion incf Uni_Ore,F ;Incrementa las unidades de hora movlw 0x02 ;Si decenas de horas = 2 subwf Dec_Ore,W btfsc STATUS,Z call Ore_2X ;llama la rutina de gestion 24 horas movlw subwf btfss return
0x0A Uni_Ore,W STATUS,Z
;Si unidad de horas ;inferior a 10 sigue
;********************** Incremento decenas de horas movlw movwf incf return
0x00 ;Si = 10 borra las unidades de hora Uni_Ore Dec_Ore,F ;Incrementa las decenas de hora
;********************** Ore_2X movlw 0x04 subwf Uni_Ore,W btfss STATUS,Z return movlw movwf movlw movwf return
0x00 Uni_Ore 0x00 Dec_Ore
;Si la unidad de horas ;es inferior a 4 sale
;Si = 4 borra la unidad de horas ;borra las decenas de horas
10.7 Manejo del modulo infrarrojo Existen diferentes técnicas para detectar la presencia de cuerpos dentro de un determinado entorno, pero los detectores ópticos en base a luz infrarroja son de gran popularidad debido a sus grandes ventajas como por ejemplo su inmunidad ante ambientes ruidosos, humedos o con alta temperatura. Para poner en funcionamiento la barrera, basta generar una frecuencia central de transmisión con una tolerancia de +/- 10%, la cual modula la emisión de luz de los dos diodos LED infrarrojos. Esta frecuencia debe estar alrededor de los 33 KHz. El módulo receptor infrarrojo es un sensor activo que detecta la radiación IR por medio de un fotodiodo y mantiene su salida en un nivel activo alto (5V) mientras no esté recibiendo radiación infrarroja modulada a su frecuencia de enganche. Sin embargo, cuando una radiación infrarroja con frecuencia de 33 KHz alcanza su diodo receptor la salida se coloca a nivel bajo. Veamos como generar la frecuencia de 33 KHz con el microcontrolador. 121
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
10.8 Manejo del frecuencímetro digital con PIC Con el laboratorio de microcontroladores tendrá la opción de adquirir un dispositivo medidor de frecuencia de excelente calidad que se puede constituir en una herramienta de laboratorio muy importante. Sus características principales son: • • • •
Auto rango Visualización en cuatro displays de siete segmentos Rango de frecuencias de 0 Hz a 50 MHz Portátil
En todos los proyectos donde desarrolle generación o lectura de frecuencia con sistemas digitales, este dispositivo puede ser de gran utilidad para realizar todas las comprobaciones del caso. Este dispositivo se ha construido sobre una tarjeta diseñada para ser manipulada por un usuario de manera similar a como lo haría con una punta lógica. Esta característica, sumada al alto rango de lecturas que ofrece, hacen de este instrumento un producto que supera a muchos sistemas similares que se encuentran en el mercado a un costo más alto. Este equipo permite leer frecuencias comprendidas en el rango de 0Hz hasta 50 MHz, y simplemente utiliza un microcontrolador PIC trabajando con un cristal de 4 MHz. El circuito impreso se ha diseñado en forma de “lapicero” para facilitar su manipulación; en él se destacan los cuatro displays de siete segmentos en donde se visualizará el resultado de las mediciones. 122
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Lectura de los diplays Como sólo cuenta con cuatro diplays para visualizar la lectura, se ha adoptado una notación de ingeneiría para mostrar el resultado final. De esta manera los tres primeros dígitos mostrarán un dato que debe ser elevado a la potencia de 10 indicada en el cuarto diplay, es decir, A.BC*10 D. Debido a esta notación, el display del exponente se ha ubicado a la derecha y separado de los tres primeros dentro del circuito impreso. Por ejemplo, una lectura típica sería 1,20 x 105 lo que equivale a 1.200 Hz.
123
www.welgos.net
CURSO
INTEGRAL
SOBRE
ANEXOS CURSO I NTEGRAL PIC
124
www.welgos.net
MICROCONTROLADORES
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
ANEXO Ae Descripción de pines del PIC16F84A 1 RA2 Es una línea de I/O programable como entrada o salida. Corresponde al BIT 2 del PUERTO A.
2 RA3 Es una línea de I/O programable como entrada o salida. Corresponde al BIT 3 del PUERTO A.
3 RA4 / RTCC Es un pin multifuncional que puede ser programado como línea normal de I/O o como línea de reloj para la entrada del contador RTCC. Si se programa como línea de I/O corresponde al BIT 4 del PUERTO A. A diferencia de los otros pines, cuando esta línea funciona como salida, trabaja en configuración de colector abierto.
4 MCLR / VPP En condiciones de normal funcionamento su función es la de Master CLeaR es decir, el reset el cual se activa con un nivel 0. Allí se puede conectar un circuito externo de reset o simplemente conectarlo al voltaje positivo. Cuando el PIC se va a programar "Program Mode" se utiliza como entrada para el voltaje de programación Vpp.
5 VSS Este pin se connecta al negativo de la tensión de alimentacion.
6 RB0 Es una linea de I/O programable como entrada o como salida. Corresponde al BIT 0 del PUERTO B y puede ser programado para generar interrupción.
7 RB1 Es una linea de I/O programable como entrada o como salida. Corresponde al BIT 1 del PUERTO B.
8 RB2 Es una linea de I/O programable como entrada o como salida. Corresponde al BIT 2 del PUERTO B.
9 RB3 Es una linea de I/O programable como entrada o como salida. Corresponde al BIT 3 del PUERTO B.
125
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
1 RB4 Es una linea de I/O programable como entrada o como salida. Corresponde al BIT 4 del PUERTO B.
11 RB5 Es una linea de I/O programable como entrada o como salida. Corresponde al BIT 5 del PUERTO B.
12 RB6 Es una linea de I/O programable como entrada o como salida. Corresponde al BIT 6 del PUERTO B.
13 RB7 Es una linea de I/O programable como entrada o como salida. Corresponde al BIT 7 del PUERTO B.
14 VDD Es el terminal positivo de la alimentación del PIC. En todas las versiones disponibles del PIC16F84 (comercial, industrial y automotriz) la tensión puede puede tener un valor mínimo de 2.0 voltios y un máximo de 6.0 voltios.
5 OSC2 / CLKOUT Es un pin de conexión en el caso que se este trabajando con quarzo para generar el reloj. Es una salida en el caso de que se utilize un oscilador RC u otro oscilador externo.
16 OSC1 / CLKIN Es un pin de conexión en el caso que se este trabajando con quarzo o un circuito RC para generar el reloj. Es una entrada en el caso de que se utilize un oscilador externo.
17 RA0 Es una linea de I/O programable como entrada o como salida. Corresponde al BIT 0 del PUERTO A.
18 RA1 Es una linea de I/O programable como entrada o como salida. Corresponde al BIT 1 del PUERTO A.
126
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
ANEXO B Conjunto de instrucciones del PIC 16F84 Sintaxis, Descripción Microchip Operación equivalente
ADDLW k Suma un literal y W, W = W + k ADDWF f,d Suma W con f, d = W + f (donde d puede ser W o f) ANDLW k AND Literal con W, W = W AND k ANDWF f,d AND W con f, d = W AND f (donde d puede ser W o f) BCF f,b Bit Clear f, f(b) = 0 BSF f,b Bit Set f, f(b) = 1 BTFSC f,b Bit Test f, Skip if Clear, f(b) = 0 ? Si, salta una instrucción BTFSS f,b Bit Test f, skip if Set, f(b) = 1 ? Si, salta una instrucción CALL k llamada a la subrutina en la posición k CLRF f Clear f, f = 0 CLRW Clear W Register, W = 0 CLRWDT Clear Watchdog Timer, Watchdog timer = 0 COMF f,d Complement f, d = not f (donde d puede ser W o f) DECF f,d Decrement f, d = f -1 (donde d puede ser W o f) DECFSZ f,d Decrement f, Skip if 0, d = f -1 (donde d puede ser W o f) si d = 0 salta GOTO k Go to address, salta a la dirección k INCF f,d Increment f, d = f +1 (donde d puede ser W o f) INCFSZ f,d Increment f, Skip if 0 d = f +1 (donde d puede ser W o f) si d = 0 salta IORLW k Inclusive OR Literal with W, W = W OR k IORWF f,d Inclusive OR W with f, d = f OR W (donde d puede ser W o f) MOVLW k Move literal to W, W = k MOVF f,d Move f, d = f (donde d puede ser W o f) MOVWF f Move W to f, f = W NOP No Operation, ninguna operación OPTION Load Option Register, OPTION = W RETFIE Return from Interrupt. Retorna del servicio de interrupción RETLW k Return Literal to W. Retorna de una subrutina con W = k RETURN Return from Subroutine. Retorna de una subrutina RLF f,d Rotale Left f through Carry, d = f << 1 (donde d puede ser W o f) RRF f,d Rotale Right f through Carry, d = f >> 1 (donde d puede ser W o f) SLEEP Go into Standby Mode. Pone el PIC en standby SUBLW k Subtract W from Literal, W = k - W SUBWF f,d Subtract W from f, d = f - W (donde d puede ser W o f) SWAPF f Swap f, f = intercambia los bits 0123 con los bits 4567 del registro f TRIS f Load TRIS. Carga el registro TRIS del registro f, f = W XORLW k Exclusive OR Literal with W, W = W XOR k XORWF f,d Exclusive OR W with f, d = f XOR W (donde d puede ser W o f)
127
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
ADDLW ADD Literal and W Suma la constante k a W Sintaxis:
addlw k Operación equivalente: W=W+k Descripción: Suma la costante k al valor memorizado en el acumulador W y pone el resultado en el acumulador. Ejemplo:
org 00H start movlw 10 addlw 12 ... En este punto del programa el acumulador W valdrá 22. Nota: Esta instrucción afecta los bits Z, DC y C del registro STATUS. ● Z vale 1 si el resultado de la operación vale 0. ● DC vale 1 si el resultado de la operación es un número superior a 15. ● C vale 1 si el resultado es positivo o si el bit 7 del registro que contiene el resultado vale 0 y 1 si el resultado es negativo o si el bit 7 del registro que contiene el resultado vale 1.
128
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
ADDWF ADD W and F Suma el valor contenido en W con el valor contenido en el registro F Sintaxis:
addwf f,d Operación equivalente: d = W + f (donde d puede ser W o f) Descripción: Esta instrucción suma el valor contenido en el acumulador W con el valor contenido en el registro indicado en el parámetro f. El parámetro d es una bandera que indica sobre cual registro debe ser memorizado el resultado. Con d = W el resultado viene memorizado en el registro W Con d = F el resultato viene memorizado en el registro f Ejemplo: Veamos un ejemplo de suma entre dos registros:
add1 equ 0CH add2 equ 0DH org 00H movlw 10 ;Primer sumando = 10 movwf add1 movlw 15 ;Segundo sumando = 15 movwf add2 movf add1,W ;W = add1 addwf add2,W ;W = W + add2 Nota: Esta instrucción influencia los bit Z, DC y C del registro STATUS. ● Z vale 1 si el resultado de la operación vale 0. ● DC vale 1 si el resultado de la operación es un número superior a 15. ● C vale 1 si el resultado es positivo o si el bit 7 del registro que contiene el resultado vale 0 y 1 si el resultado es negativo o si el bit 7 del registro que contiene el resultado vale 1.
129
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
ANDLW AND Literal with W Efectúa AND entre W y una costante k Sintaxis:
andlw k Operación equivalente: W = W AND k Descripción: Efectúa una AND entre el valor contenido en el acumulador W y el valor de la constante k. El resultado se guarda en el acumulador. Ejemplo:
org 00H start movlw 10101010B andlw 11110000B ... De haber seguido este programa, el acumulador W valdría 10100000B. Nota: Esta instrucción influencia el bit Z del registro STATUS. ● Z vale 1 si el resultado de la operación vale 0.
130
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
ANDWF AND W with F Efectúa una AND lógica entre el valor contenido en W y el valor contenido en el registro F Sintaxis:
andwf f,d Operación equivalente: d = W AND f (donde d puede ser W o f) Descripción: Esta instrucción efectúa una AND lógica entre el valor contenido en el acumulador W y el valor contenido en el registro indicado en el parámetro f. El parámetro d y una bandera que indica sobre cual registro debe ser memorizado el resultado. Con d = W el resultado viene memorizado en el registro W Con d = F el resultato viene memorizado en el registro f Ejemplo: La AND lógica puede ser utilizada para enmascarar el valor de algunos bits en el interior de un registro. Si por ejemplo del número binario 01010101B queremos consevar solo los cuatro bits menos significativos para obtener el valor 00000101B, bastará preparar una máscara del tipo 00001111B y formar una AND con nuestro valor de partida, veamos:
movlw 01010101B ;Memoriza en el registro movwf 0CH ;0CH el valor inicial de la máscara movlw 00001111B ;Prepara la máscara de bit andwf 0CH,W ;Efectúa la AND y memoriza el ;resultado en el acumulador W El resultado en W será 00000101B como se quería.
W = 00001111 AND f = 01010101 = ---------------W = 0000010101 La ANDWF influencia el bit Z del registro STATUS que valdrá 1 si el resultado de la operación es 0.
131
www.welgos.net
CURSO
INTEGRAL
BCF Bit Clear F Borra un bit en el registro F Sintaxis:
bcf f,b Operación equivalente: f(b) = 0 Descripción: Esta instrucción borra el bit b del registro indicado en f. Ejemplo:
parm1 equ 0CH org 00H movlw 11111111B ;Valor inicial movwf parm1 bcf parm1,0 ;D0=0 Al termino del programa el registro parm1 valdrá 11111110B. Nota: Esta instrucción no influencia ningún bit de estado
132
www.welgos.net
SOBRE
MICROCONTROLADORES
CURSO
INTEGRAL
BSF Bit Set F Pone en uno un bit en el registro F Sintaxis:
bsf f,b Operación equivalente: f(b) = 1 Descripción: Esta instrucción pone en uno el bit b del registro indicado en f. Ejemplo:
parm1 equ 0CH org 00H movlw 00000000B ;Valor inicial movwf parm1 bsf parm1,0 ;D0=1 Al termino del programa el registro parm1 valdrá 00000001B. Nota: Esta instrucción no influencia algún bit de estado
133
www.welgos.net
SOBRE
MICROCONTROLADORES
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
BTFSC Bit Test F, Skip if Clear Salta la instrucción sucesiva si un bit en el registro F vale 0 Sintaxis:
btfsc f,b Operación equivalente: f(b) = 0 ? Si, salta una instrucción Descripción: Prueba el bit b contenido en el registro indicado por f y se salta la instrucción sucesiva si este vale 0. Ejemplo:
parm1 equ 0CH org 00H movlw 11111110B ;Valor inicial movwf parm1 loop btfsc parm1,0 ;D0 = 0 ? Si, salta goto loop ;No, sigue a loop Este programa sigue en el loop infinito a menos que hagamos el siguiente cambio:
movlw 11111110B ;Valor inicial con la instrucción:
movlw 11111111B ;Valor inicial Nota: Esta instrucción no modifica ningún bit de estado
134
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
BTFSS Bit Test F, Skip if Set Salta la instrucción sucesiva si un bit en el registro F vale 1 Sintaxis:
btfss f,b Operación equivalente:
f(b) = 1 ? Si, salta una instrucción Descripción: Prueba el bit b contenido en el registro indicado en f y salta la instrucción sucesiva si este vale 1. Ejemplo:
parm1 equ 0CH org 00H movlw 11111111B ;Valor inicial movwf parm1 loop btfss parm1,0 ;D0 = 1 ? Si, salta goto loop ;No, sigue a loop Este programa sigue en el loop infinito a menos que hagamos el siguiente cambio:
movlw 11111111B ;Valor inicial con la instrucción:
movlw 11111110B ;Valor inicial Nota: Esta instrucción no modifica ningún bit de estado
135
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
CALL Subroutine CALL Llamada a subrutina Sintaxis:
call k Descripción: Invoca la ejecución de una subrutina memorizada en la etiqueta k. El parámetro k puede especificarse utilizando directamente el valor numérico de la dirección de la etiqueta. Ejemplo:
org 00H call ledOn ... ;Subrutina de encendido de un led ledOn bsf PORTB,LED1 return Cuando la CPU del PIC encuentra una instrucción CALL, memoriza en la pila (STACK) el valor del registro PC + 1 para poder retomar la ejecución de la instrucción sucesiva al CALL, cuando s escribe en el PC la posición de la subrutina se salta a la ejecución de esta última. El valor srcinal del PC se repone a la salida de la subrutina con la ejecución de retorno RETURN o RETLW. En el PIC16F84 se tienen disponibles 8 niveles en el stack, lo cual corresponde al número máximo de CALL re entrantes, o de instrucciones CALL al interior de una subrutina. Nota: Esta instrucción no influencia ningún bit del registro de estado.
136
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
CLRF CLeaR F register Borra el registro F Sintaxis:
clrf f Operación equivalente: f=0 Descripción: Esta instrucción borra el valor contenido en el registro indicado en f. Ejemplo: Si por ejemplo en el registro TMR0 cuya dirección es 01H, la instrucción para borrarlo será:
clrf 01H Si en el inicio de nuestro programa hemos incluido el archivo P16F84.INC, podremos utilizar el nombre simbólico del registro TMR0.
clrf TMR0 Después de la ejecución de esta instrucción, el bit Z del registro STATUS se pone en 1.
137
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
CLRW CLeaR W register Borra el registro W Sintaxis:
clrw Operación equivalente:
W=0 Descripción: Borra el contenido del registro W. Nota: Después de la ejecución de esta instrucción, el bit Z del registro de estado se pone en 1.
138
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
CLRWDT CLeaR WatchDog Timer Reset el temporizador watchdog Sintaxis:
clrwdt Descripción:
Esta instrucción debe ser utilizada cuando programamos el PIC ocn la opción de Watchdog abilitata (fusibile WDTE). En esta modalidad el PIC habilita un timer que, una vez ha transcurrido un determinado tiempo, efectúa el reset del PIC. Para evitar el reset desde nuestro programa deberemos ejecutar cíclicamente la instrucción CLRWDT para borrar el timer. Si no borramos el timer a tiempo, la circuitería del watchdog (perro guardián) interpretará esto como un bloqueo del programa que se está ejecutando actualmente y reiniciará la CPU para desbloquearlo. Ejemplo:
org 00H loop clrwdt
goto loop Nota: Esta instrucción no influencia ningún bit de estado.
139
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
COMF COMplement F Efectúa el complemento del registro F Sintaxis:
comf f,d Operación equivalente: d = NOT f (donde d puede ser W o f) Descripción: Esta instrucción efectúa el complemento del valor contenido en el registro indiricado en el parámetro f. El parámetro d determina el destino del valor obtenido. Con d = W el valor viene memorizado en el registro W Con d = F el valor viene memorizado en el registro f. Ejemplo:
parm1 equ 0CH org 00H movlw 01010101B movwf parm1 comf parm1,F ... Al terminar la ejecución del programa el valor del registro parm1 será 10101010B. Nota: Esta instrucción influencia el bit Z del registro STATUS. ● Z vale 1 si el resultado de la operación vale 0.
140
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
DECF DECrement F register Decrementa el contenido del registro F Sintaxis:
decf f,d Operación equivalente: d = f -1 (donde d puede ser W o f) Descripción: Esta instrucción decrementa el contenido del registro indiricado por el parámetro f. El parámetro d es una bandera que indica sobre cual registro debemos memorizar el resultado. Con d = W el resultado viene memorizado en el registro W Con d = F el resultado viene memorizado en el registro f Ejemplo: Con el siguiente programa escribimos el valor 23H en el registro de la dirección 0CH y luego lo decrementamos en uno. Al terminar la ejecución el registro de la poisición 0CH contendrá el valor 22H.
movlw 23H ;escribe en W el valor 23H movwf 0CH ;Copia en el registro 0CH el valor de W decf OCH,F ;Decremento el valor contenido en el ;registro 0CH Nota: Esta instrucció influencia el bit Z del registro STATUS. ● Z vale 1 sie el resultado de la operación vale 0.
141
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
DECFSZ DECrement F, Skip if Zero Decrementa el valor del registro f y salta la instrucción sucesiva si el resultado vale zero Sintaxis:
decfsz f,b Operación equivalente: d = f -1 (donde d puede ser W o f) si d = 0 salta Descripción: Decrementa el valor del registro indicado por f y si el resultado vale zero, salta la instrucción sucesiva. El resultado del decremento puede memorizarse en el registro f o en el acumulador W de acuerdo al valor de la bandera d. Con d = W el resultado viene memorizado en el registro W Con d = F el resultado viene memorizado en el registro f Ejemplo:
counter equ 0CH org 00H movlw 10 ;counter = 10 movwf counter loop decfsz counter,F ;counter = counter -1 ;counter = 0 ? Si salta goto loop ;No, continua Este programa da 10 vueltas con la instrucción decfsz hasta que counter = 0. Nota: Esta instrucción no modifica ningún bit del registro de estado.
142
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
GOTO GO TO address Lleva la ejecución a la dirección k Sintaxis:
goto k Descripción: Determina un salto del programa en ejecución en la posición k. El parámetro k puede especificarse utilizando directamente el valore numérico de la posición relativa a la etiqueta. Ejemplo:
org 00H loop goto loop Este programa sigue un ciclo (loop) infinito. Nota: Esta instrucción no modifica ningún bit del registro de estado.
143
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
INCF INCrement F Incrementa el valore del r egistro indicado F Sintaxis:
incf f,d Operación equivalente: d = f +1 (donde d puede ser W o f) Descripción: Incrementa el contenido del registro indicado en f y memoriza el resultado en este registro o en el acumulador W de acuerdo al valor de la bandera d: Con d = W el resultado viene memorizado en el registro W Con d = F el resultado viene memorizado en el registro f Nota: Esta instrucción altera el bit Z del registro STATUS.. ● Z vale 1 si el resultado de la operación vale 0.
144
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
INCFSZ INCrement F, Skip if Zero Incrementa el valor del registro f y salta a la instrucción sucesiva si el resultado vale zero Sintaxis:
incfsz f,b Operación equivalente: d = f +1 (donde d puede ser W o f) si d = 0 salta Descripción: Incrementa el valor del registro indicado por f y si el resultado vale zero salta la instrucción sucesiva. El resultado del incremento puede memorizarse en el mismo registro f o en el acumulador W de acuerdo al valor de la bandera d: Con d = W el resultado viene memorizado en el registro W Con d = F el resultado viene memorizado en el registro f Ejemplo:
counter equ 0CH org 00H movlw 250 ;counter = 250 movwf counter loop incfsz counter,F ;counter = counter + 1 ;counter = 0 ? Si salta goto loop ;No, continua Este programa ejecuta 256 - 250 = 6 veces la instrucción incfsz hasta que counter = 0. Siendo counter un registro de 8 bit que cuando llega a 255 y se incrementa asume el valor de 0. Nota: Esta instrucción no modifica ningún bit del registro de estado.
145
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
IORLW Inclusive OR Literal with W Efectúa la OR inclusiva entre W y una costante k Sintaxis:
iorlw k Operación equivalente: W = W OR k Descripción: Efectúa la OR inclusiva entre el valor contenido en el acumulador W y el valor de la costante k. Ejemplo:
org 00H start movlw 00001111B iorlw 11110000B ... De haber seguido este programa. El acumulador W valdrá 11111111B. Nota: Esta instrucción altera el bit Z del registro STATUS.
146
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
IORWF Inclusive OR W with F Efectúa la OR inclusive entre e l valor contenido en W y el valor contenido en el registro F Sintaxis:
iorwf f,d Operación equivalente:
d = f OR W (donde d puede ser W o f) Descripción: Esta instrucción efectúa la OR inclusiva entre el valor contenido en el acumulador W y el valor contenido en el registro indiricado por el parámetro f. El parámetro d determina donde viene memorizado el resultado de la operación: Con d = W el resultado viene memorizado en el registro W Con d = F el resultado viene memorizado en el registro f Ejemplo:
parm1 equ 0CH org 00H movlw 00001111B movwf parm1 movlw 11111111B iorwf parm1,F Al terminar la ejecución el valor del registro parm1 será 11111111B. Nota: Esta instrucción altera el bit Z del registro STATUS. ● Z vale 1 si el resultado de la operación vale 0.
147
www.welgos.net
CURSO
INTEGRAL
MOVLW MOVe Literal to W Asigna a W un valor constante Sintaxis:
movlw k Operación equivalente: W=k Descripción: Asigna al acumulador W el valor constante k. Ejemplo:
org 00H start movlw 20 ... De haber seguido el programa, el acumulador W valdrá 20. Nota: Esta instrucción no altera ningún bit de estado.
148
www.welgos.net
SOBRE
MICROCONTROLADORES
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
MOVF MOVe F Mueve el contenido del registro F Sintaxis:
movf f,d Operación equivalente: d = f (donde d puede ser W o f) Descripción: Esta instrucción copia el contenido del registro indiricado por el parámetro f en el acumulador W o en el mismo registro F. El parámetro d determina el destino. Con d = W el resultado viene memorizado en el registro W Con d = F el resultado viene memorizado en el registro f . En este caso la instrucción altera el bit Z del registro STATUS de acuerdo al valor contenido en el registro f. Ejemplo: El siguiente ejemplo copia el valor contenido en el registro con dirección 0CH en el acumulador W:
movf 0CH,W
149
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
MOVWF MOVe W to F Mueve el contenido del registro W hacia el registro F Sintaxis:
movwf f Operación equivalente: f=W Descripción: Esta instrucción copia el contenido del registro W en el registro indiricado en el parámetro f. Ejemplo: Si por ejemplo vamos a escribir el valor 10H en el registro TMR0. La instrucciones a seguir serían las siguientes:
movlw 10H ;escribe en el registro W el valore 10H movwf 01H ;y lo memoriza en el registro TMR0 Si hemos incluido el archivo P16F84.INC, el código es el siguiente:
movlw 10H ;escribe en el registro W el valor 10H movwf TMR0 ;y lo memoriza en el registro TMR0 Nota: Esta instrucción no altera ningún bit de estado.
150
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
NOP No OPeration Ninguna operación Sintaxis: nop Descripción: Esta intrucción no ejecuta ninguna operación más que hacer un retardo de un ciclo de máquina. Ejemplo: Utilizando un quarzo de 4MHz podremos obtener un retardo de 1µs para una instrucción NOP insertada en nuestro código fuente.
nop ;hace un retardo de 1µs Nota: Esta instrucción no altera ningún bit de estado.
OPTION: load OPTION register 151
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Asigna el valor en W al registro OPTION Sintaxis:
option Operación equivalente: OPTION = W Descripción: Esta instrucción memoriza en el registro especial OPTION el valor contenido en el acumulador W. Ejemplo:
org 00H start movlw 01000100B option
... Nota: Esta intrucción puede presentar problemas de compatibilidad con algunos productos de Microchip. Es más aconsejable es utilizar la siguiente secuencia:
org 00H start bsf STATUS,RP0 ;Activa el banco de registros 1 movlw 01000100B movwf OPTION_REG ... En la práctica se aconseja escribir directamente en el registro OPTION del banco 1 mediante la instrucción MOVWF en lugar de la instrucción OPTION que e el futuro es probable que no la podamos implementar. Esta instrucción no altera ningún bit de estado.
RETFIE: RET From Interrupt Retorna de una interrupción 152
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Sintaxis:
retfie Descripción: Esta instrucción debe insertarse al terminar el código del servicio de interrupción para retornar el control al programa principal. Ejemplo:
org 00H loop goto loop ;Loop infinito org 04H ;Interrupt vector intHandler retfie ;Retorna de la interrupción En este código el programa principal sigue un lazo infinito. Si habilitamos una de las interrupciones del PIC16F84 el control del programa se entregará automáticamente al programa ubicado en la posición 04H (en el ejemplo: intHandler), la instrucción RETFIE permitirá el retorno al lazo principal. Nota: Esta instrucción no altera ningún bit de estado.
RETLW: RETurn Literal to W 153
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Retorna desde una subrutina con una costante en W Sintaxis:
retlw k Descripción: Esta intrucción retorna el control desde una subrutina al programa principal. A diferencia de la instrucción RETURN esta permite pasar a través del acumulador W, el valor constante k al programa principal. Ejemplo:
rtc equ 0CH org 00H call mySub1 movwf rtc ... mySub1 nop retlw 10 Este programa memoriza en el registro rtc el valore 10 pasado desde la subrutina mySub1. Nota: Esta instrucción no altera ningún bit de estado. Ver la instrucción RETURN.
RETURN: RETURN from subroutine 154
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Retorna desde una subrutina Sintaxis:
return Descripción: Esta intrucción debe insertarse antes de terminar el código dentro de una subrutina para permitir retornar la ejecución del programa principal. Ejemplo:
org 00H call mySub1 .... mySub1 nop return Nota: En el PIC16F84 podemos anidar hasta 8 llamados a subrutinas de este tipo:
org 00H call mySub1 .... mySub1 call mySub2 return
mySub2 call mySub3 return
mySub3 return Nota: Esta instrucción no altera ningún bit de estado.
155
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
RLF: Rotate Left F through carry Rota a la izquierda el contenido del registro f passando per il Carry Sintaxis:
rlf f,b Operación equivalente: d = f << 1 (donde d puede ser W o f) Descripción: Rota el bit contenido en el registro que se indique en f hacia la izquierda (desde el bit menos significativo hasta el mas significativo) pasando por el bit CARRY del registro STATUS como se ilustra en la figura:
El contenido del bit CARRY del registro status rota hacia el bit D0 mientras que el valor en la salida del bit D7 se rota hacia el CARRY. El valor del parámetro d determina el destino del resultado obtenido al termino de la rotación: Con d = W el resultado viene memorizado en el registro W dejando tal cual el valor de f Con d = F el resultado viene memorizado en el registro f . Ejemplo:
parm1 equ 0CH org 00H clrf C,STATUS ;borra el CARRY movlw 01010101B ;Valor inicial movwf parm1 rlf parm1,F Al termino del programa el registro parm1 valdrá 10101010B mientras el CARRY valdrá 0. Nota: Esta intrucción solo altera el bit CARRY.
RRF: Rotate Right F through carry 156
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Rota a la derecha el contenido el registro f pasando por el Carry Sintaxis:
rrf f,b Operación equivalente: d = f >> 1 (donde d puede ser W o f) Descripción: Rota los bit contenidos en el registro que se indique en f hacia la derecha (desde el bit mas significativo hasta el menos significativo) pasando por el bit CARRY del registro STATUS como se ilustra en la figura:
El contenido del bit CARRY del registro status rota hacia el bit D7 mientras que el valor en la salida del bit D0 se rota hacia el CARRY. El valor del parámetro d determina el destino del resultado obtenido al termino de la rotación: Con d = W el resultado viene memorizado en el registro W dejando tal cual el valor de f Con d = F el resultado viene memorizado en el registro f . Ejemplo:
parm1 equ 0CH org 00H clrf C,STATUS ;borra el CARRY movlw 01010101B ;Valor inicial movwf parm1 rrf parm1,F Al termino del programa el registro parm1 valdrá 00101010B mientras el CARRY valdrá 1. Nota: Esta intrucción solo altera el bit CARRY.
SLEEP: go into standby mode Pone el PIC en standby 157
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Sintaxis:
sleep Descripción: Esta instrucción bloquea la ejecución programa en curso y pone el PIC en estado de standby (sleep del inglés to sleep, dormir). Ejemplo:
org 00H start sleep
Nota: Esta instrucción no altera ningún bit de estado.
158
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
SUBLW: SUBtract W from Literal Sustrae a k el valor en W Sintaxis:
sublw k Operación equivalente: W=k-W Descripción: Resta a la constante k el valor memorizado en el acumulador W. Ejemplo:
org 00H start movlw 10 sublw 12 ... De haber seguido este programa el acumulador W valdrá 2. Nota: Esta instrucción altera los bits Z, DC y C del registro STATUS. ● Z vale 1 si el resultado de la operación vale 0. ● DC vale 1 si el resultado de la operación es un número superior a 15. ● C vale 1 si el resultado es positivo o si el bit 7 del registro que contiene el resultado vale 0 y 1 si el resultado es negativo o si el bit 7 del registro que contiene el resultado vale 1.
159
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
SUBWF: SUBstract W from F Sustrae el valor contenido en W del valor contenido en el registro F Sintaxis:
subwf f,d Operación equivalente: d = f - W (donde d puede ser W o f) Descripción: Esta intrucción sustrae el valor contenido en el registro W del valor contenido en el registro indiricado en el parámetro f. El parámetro d es una bandera que indica sobre cual registro se debe memorizar el resultado: Con d = W el resultado viene memorizado en el registro W Con d = F el resultado viene memorizado en el registro f Ejemplo: Analizemos un ejemplo extraido de las hojas de datos de la Microchip: Si insertamos la instrucción:
subwf REG1,F Donde reg1 es la dirección de cualquier registro especificado mediante la directiva:
REG1 RES 1 Para un valor inicial de REG1=3 y W=2, después de la ejecución tendremos REG1=1 y C=1 debido a que el resultado es positivo. Para un valor inicial de REG1=2 y W=2, después de la ejecución tendremos REG1=0 y C=1 debido a que el resultado es positivo. Para un valor inicial de REG1=1 y W=2, después de la ejecución tendremos REG1=FFH y C=0 debido a que el resultado es negativo. Nota: Esta instrucción altera los bits Z, DC y C del registro STATUS. ● Z vale 1 si el resultado de la operación vale 0. ● C vale 1 si el resultado es positivo o si el bit 7 del registro que contiene el resultado vale 0 y 1 si el resultado es negativo o si el bit 7 del registro que contiene el resultado vale 1.
SWAPF SWAP F 160
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Intercambia el valore de los cuatro bits más significativos del registro indicado en F con los cuatro bit menos significativos Sintaxis:
swap f,d Operación equivalente: f = intercambia los bit 0123 con los bits 4567 de f Descripción: Intercambia el valor de los cuatro bits menos significativos (D7-D4) contenidos en el registro indiricado en f con los cuatro bits meno significativos (D3-D0) del mismo. El resultado viene memorizado en el acumulador W o en el mismo registro f según el valor de d: Con d = W el resultado viene memorizado en el registro W Con d = F el resultado viene memorizado en el registro f Nota: Esta instrucción no altera ningún bit de estado.
161
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
TRIS: load TRIS register Asigna el valor de W al registro TRIS Sintaxis:
tris f Operación equivalente: TRIS di f = W Descripción: Esta instrución memoriza en uno de los registros especiales TRIS el valor contenido en el acumulador W. El registro TRIS determina el funcionamiento como entrada o como salida de las líneas de I/O del PIC. Existe un registro TRIS por cada uno de los puertos de I/O denominados TRISA, TRISB, etc. Ejemplo:
org 00H start movlw 11111111B tris PORTA ... Nota: En el futuro, para evitar problemas de compatibilidad se aconseja utilizar las siguientes instrucciones en el momento de configurar los puertos:
org 00H start bsf STATUS,RP0 ;Activa el banco registros 1 movlw 11111111B movwf TRISA ... En la práctica se aconseja pasar al banco de datos 1 y utilizar la instrucción MOVWF para configurar los puertos. Nota: Esta instrucción no altera ningún bit de estado.
162
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
XORLW: Exclusive OR Literal with W Efectúa la OR exclusiva entre W y una constante k Sintaxis:
xorlw k Operación equivalente: W = W XOR k Descripción: Efectúa la OR exclusiva entre el valor contenido en el acumulador W y el valor constante k. Ejemplo:
org 00H start movlw 00000000B xorlw 11110000B ... De haber seguido este programa el acumulador W valdrá 11110000B. Nota: Esta instrucción altera los bits Z del registro STATUS. ● Z vale 1 si el resultado de la operación vale 0.
XORWF: eXclusive OR W with F 163
www.welgos.net
CURSO
INTEGRAL
SOBRE
MICROCONTROLADORES
Efectúa la OR exclusiva entre e l valor contenido en W y el valor contenido en el registro F Sintaxis:
xorwf f,d Operación equivalente: d = f XOR W (donde d puede ser W o f) Descripción: Esta intrucción efectúa la OR exclusiva (XOR) entre el valor contenido en el acumulador W y el valor contenido en el registro indiricado en el parámetro f. El parámetro d es una bandera que indica sobre cual registro se va a memorizar el resultado. Con d = W el resultado viene memorizado en el registro W Con d = F el resultado viene memorizado en el registro f
Esta instrucción altera el bit Z del registro STATUS que valdrá 1 si el resultado de la operación es 0. Ejemplo: Si fueramos a efectuar la XOR entre el registro W y el registro REG1 que se ha definido en la posición 0CH con la direttiva:
REG1 EQU 0CH Podriamos utilizar la instrucción IORWF en dos formas dependiendo de donde queremos tener el resultado:
xorwf COUNTER,F ;COUNTER = COUNTER XOR W o:
xorwf COUNTER,W ;W = COUNTER XOR W Nota: La OR exclusiva (XOR) es una operación entre dos bit en donde el bit resultante vale 0 si los dos bits son iguales. En lenguaje ensamblador la XOR se utiliza para comparar dos valores y determinar su igualdad. Veamos como: Si fueramos a determinar si el valor en el registro REG1 es igual a 57H, las instrucciones a seguir son las siguientes:
movlw 57H ;W = Valor a comparar = 57H ;Resultado. W = 57H xorwf REG1,W ;W = W XOR REG1 Efectua la XOR con ;el valor en REG1 btfss STATUS,Z ;Salta la instrucción siguiente si el ;resultato de la XOR vale 0, osea ;si el valor de REG1 es igual a 57H goto diverso ;Salta si es diferente a 57H goto uguale ;Salta si es igual a 57H
164
www.welgos.net
CURSO
INTEGRAL
165
www.welgos.net
SOBRE
MICROCONTROLADORES
CURSO
INTEGRAL
166
www.welgos.net
SOBRE
MICROCONTROLADORES