213
Programador PIC Pablin II Corregido Debido a la gran cantidad de e-mails que recibimos pidiéndonos la forma de programar PICmicros de mas de 18 pines decidimos hacer esta segunda versión de nuestro equipo el cual ahora puede programar micros de 8, 18, 28 y 40 pines así como memorias seriales de la familia 24. Tal como vemos el circuito es esencialmente el mismo que la versión anterior. Los dos diodos en los pines 5 y 6 del puerto paralelo se encargan de unir eléctricamente las salidas D4 y D5 que son las encargadas de comandar Vpp1 y Vpp2 desde el programa ICProg. Dado que nuestro equipo no requiere dos vías de VPP individuales decidimos "puentearlas" con estos diodos para proteger eléctricamente el puerto paralelo de la PC. La llave selectora permite determinar que tipo de PIC se va a programar. Colocándola en la posición superior se pueden programar micros chicos y medianos (de 8 y 18 pines) mientras que colocándola en la posición inferior se pueden programar micros grandes (de 28 y 40 pines).

Programador PIC Pablin II

Embed Size (px)

Citation preview

Page 1: Programador PIC Pablin II

Programador PIC Pablin IICorregido

Debido a la gran cantidad de e-mails que recibimos pidiéndonos la forma de programar PICmicros de mas de 18 pines decidimos hacer esta segunda versión de nuestro equipo el cual ahora puede programar micros de 8, 18, 28 y 40 pines así como memorias seriales de la familia 24.

Tal como vemos el circuito es esencialmente el mismo que la versión anterior. Los dos diodos en los pines 5 y 6 del puerto paralelo se encargan de unir eléctricamente las salidas D4 y D5 que son las encargadas de comandar Vpp1 y Vpp2 desde el programa ICProg. Dado que nuestro equipo no requiere dos vías de VPP individuales decidimos "puentearlas" con estos diodos para proteger eléctricamente el puerto paralelo de la PC. La llave selectora permite determinar que tipo de PIC se va a programar. Colocándola en la posición superior se pueden programar micros chicos y medianos (de 8 y 18 pines) mientras que colocándola en la posición inferior se pueden programar micros grandes (de 28 y 40 pines).

Page 2: Programador PIC Pablin II

Vemos aquí el conexionado de la placa de circuito impreso que contiene los zócalos para los distintos tipos de PICmicro que podemos programar. Pensamos que sería mejor hacer el sistema en dos placas, una con la electrónica en el interior del gabinete y otra con sólo los zócalos para colocar en el exterior del gabinete donde será mas simple insertar o retirar los micros a programar.

Podemos, además, equipar a nuestro equipo de un zócalo de 8 pines adicional como el visto arriba para poder leer y programar memorias seriales de la familia 24.

Como fuente de alimentación debemos usar una de 12V (NO REGULADA) de 300mA en adelante de corriente.

El programa a utilizar es el ICProg, el cual podemos descargar de www.ic-prog.com o encontrarlo en nuestro CD de Enero 2003.

En la pantalla de configuración del programa ICProg establecer como programador el "Propic II programmer" y tildar la casilla "Invertir MCLR". Luego

Page 3: Programador PIC Pablin II

de esto el LED indicador PIC se encenderá indicando que es posible insertar o quitar pics de los zócalos.

IMPORTANTEEl LED marcado como "PIC" indica cuando no hay presencia de tensión de

programación (VPP) en el zócalo. Cuando este LED esta apagado la tensión está presente en los zócalos PIC. Nunca insertar o quitar microcontroladores

de los zócalos estando este indicador apagado.

Programador PIC Pablin

Si bien son muchos los circuitos disponibles en la Web que permiten programar microcontroladores PIC decidimos tomar lo mejor de cada uno de ellos y elaborar uno propio con las características que lo hacen propio para nuestro país (componentes económicos y fáciles de conseguir, software fácil de usar y en español).

El programador PIC Pablin permite leer y grabar PICmicros de 8 y 18 pines así como memorias EEPROM seriales.

Dispone de un zócalo de 18 pines el cual permite conectar, tal como se ve en la plantilla, tanto PIC's como memorias EEPROM seriales. Los PIC's de 18 pines se colocan ocupando la totalidad del zócalo mientras que los PIC's de 8 pines se colocan ocupando la parte superior del zócalo. En tanto las memorias seriales se colocan una hilera anterior al fin del zócalo (el pin 1 de la memoria debe coincidir con el 5 del zócalo).

El LED marcado como "Enc." permite observar que el sistema se encuentra alimentado mientras que el LED marcado como "PIC" se enciende indicando que es seguro insertar o quitar un chip (PIC o memoria) y se apaga por instantes breves cuando una lectura o programación de un PIC está en curso.

Page 4: Programador PIC Pablin II

Mientras este último LED este apagado no se debe quitar o insertar ningún integrado del zócalo.

El funcionamiento del circuito es muy simple: los pines del puerto paralelo 2, 3, 5 y 10 permiten interconectar el circuito con la PC. El pin 2 es el encargado de traer los datos (desde la PC hacia el integrado). El pin 3 es el envío de los pulsos de reloj (desde la PC hacia el integrado). En tanto el pin 10 permite a la PC leer los datos desde el programador. El pin 5, por último, es el encargado de controlar la tensión de programación (Vpp) necesaria para cuando queremos leer o escribir en un PIC.

Los microcontroladores PIC se programan utilizando el mismo protocolo que las memorias EEPROM seriales, por consiguiente el programador sirva tanto para PIC's como para memorias. La tensión de programación VPP es necesaria para indicarle al PIC que deseamos leerlo o programarlo. Si en este pin (que es compartido con la entrada de RESET del micro) ponemos masa el PIC sufre un reset, si ponemos el pin en alto (5v) el PIC trabaja normalmente mientras que si ponemos el pin a 12v el PIC se inicializa en modo programación, quedando dos de los pines de E/S destinados a datos (SDA) y reloj (SCL).

El integrado 74LS04 está formado internamente por seis buffers inversores. Estos nos permiten por un lado obtener niveles TTL a su salida y por el otro no cargar de forma excesiva al puerto. Algunos programadores, como el NOPPP utilizan diodos y resistencias para conectar el PIC directamente el puerto paralelo. Esto funciona en muchas computadoras de escritorio con fuentes poderosas pero en la mayoría de las portátiles que no disponen de tanta corriente el funcionamiento es errático o directamente no funciona. Gracias a la utilización de este buffer podremos utilizar el circuito en cualquier puerto paralelo ya sea de una computadora de escritorio o en un portátil. Se colocan las compuertas en serie para obtener a la salida el mismo nivel de entrada, sin invertir. Las resistencias de 1K dan seguridad al sistema para evitar que circule corriente excesiva.

El control de la tensión de programación lo efectúa el transistor NPN. Estando el pin 5 del puerto paralelo a masa (en 0) tendremos al transistor abierto por lo que la corriente proveniente de +V (12v) pasará por el diodo LED el cual no encenderá y se portará como un diodo común polarizado en directa, pasará por la resistencia limitadora de corriente del LED la cual no ofrecerá mucha resistencia y será inyectada al PIC en su terminal MCLR/VPP. Poniendo en 1 el bit que controla el pin 5 del puerto paralelo, en cambio, el transistor se cierra y hace circular masa hacia el PIC haciendo, además, encender el LED al quedar a masa el otro extremo de la resistencia limitadora de corriente.

El circuito requiere como única alimentación 12V de continua con una corriente de 200mA. Puede usarse cualquier fuente universal siempre que se respete la polaridad. De tener una fuente de mas tensión (13.5v como mucho) no hay problema, se la puede utilizar sin inconvenientes. No es necesario que la fuente sea regulada. Si se tiene una fuente de 12V con mas corriente 1A o incluso mayor se la puede utilizar también sin inconvenientes.

Page 5: Programador PIC Pablin II

Para conectarlo a la PC se puede utilizar un conector hembra centronics para circuito impreso (igual al que tienen las impresoras) o un cable directo hacia el macho DB25.

Vemos la foto del prototipo terminado, en nuestro caso optamos por poner un segundo zócalo para las memorias seriales y dejar el zócalo grande para los PIC's. La resistencia de 1K demás junto al integrado quedó de la etapa de práctica pero no tiene conexión a ninguna parte.

El programa que recomendamos para este programador es el IC-Prog dado que reúne varias características mas que interesantes:

Es muy fácil de usar Interface con botones de acceso rápido a las principales funciones

Permite ver el ASM del programa que se esta por cargar en el PIC (si ! lo obtiene desde el HEX)

Tiene varios idiomas, entre ellos español

Dispone de cinco espacios de memoria (Buffers) para poder tener hasta cinco programas simultáneos.

Page 6: Programador PIC Pablin II

Dentro de una única ventana reúne memoria de programa, memoria EEPROM y bits de configuración.

Hay actualizaciones periódicas con funciones nuevas y problemas resueltos.

Funciona tanto bajo Windows95 como Windows XP así como en versiones intermedias.

Vemos a continuación una captura de pantalla del programa, haciendo click sobre ella se lo puede descargar.

Para configurarlo sólo es necesario presionar F3 y especificar el tipo de hardware programador (seleccionar ProPic 2), indicar el puerto paralelo al cual está conectado y establecer como método de transferencia de información al puerto Direct I/O (en caso de usar Windows 95, 98 o ME) o Windows API (en caso de usar Windows NT, 2000 o XP). El retardo de I/O establecerlo en 10 que es un valor que funciona siempre. Se puede ir reduciendo y probando para lograr el menor retardo posible y así obtener la mayor velocidad de operación. En tanto se debe indicar como única línea invertida la de MCLR. Las demás líneas son normales.

Page 7: Programador PIC Pablin II

El programa no requiere instalación, bastará con descomprimir los únicos dos archivos que lo conforman (el EXE y el SYS) en cualquier carpeta (nosotros usamos C:\ICPROG). Una vez hecho esto ejecutar el EXE con doble click y establecer la configuración (lo pide una única vez).

Si al momento de terminar la configuración del programa los dos LED's están encendidos es señal de buen funcionamiento. Dentro del menú ajustes hay una opción para probar el funcionamiento del programador.

Para comprobar si hay nuevas revisiones visitar www.ic-prog.com

Aclaración:Nosotros utilizamos un regulador de tensión 7805 de 1A dado que es lo que teníamos a mano, pero puede utilizarse un regulador 78L05 (los de 300mA que tienen forma de transistor) sin problemas y con la ventaja de ocupar mucho menos espacio.

Programador para PIC 16F84 y 16F87x

 

Proyecto: Programador para microcontroladores  PIC 16F84 y 16F87x  de Microchip

Fecha : 25 de Setiembre de 2001 (Actualizado 11de Noviembre de 2002)

Autor: TodoRobot 

 

Introducción:

El propósito de este proyecto fue obtener un producto simple que nos permitiese programar los principales microcontroladores con memoria Flash de la firma  Microchip.

Por sus similitudes en la forma de programar  nos decidimos a enfocarnos en los modelos 16F84, 16F84A, 16F870, 16F871, 16F872, 16F873, 16F874, 16F876 y 16F877.  La variedad nos pareció aceptable, por lo que a fin de no complicar el diseño se descartaron los demás modelos.

Dentro de la Web se pueden encontrar muchos sitios dedicados a estos microcontroladores, muy famosos entre los aficionados a la electrónica y la robótica debido a su bajo costo y grandes prestaciones.

 

Circuito del programador:

En el documento picprog-circuit.pdf podemos apreciar el circuito a utilizar.

Page 8: Programador PIC Pablin II

Si observamos el circuito, se pueden apreciar los  tres posibles encapsulados que se pueden hallar dentro de los modelos soportados por este programador  ( PIC 16F8xx ).

A pesar de sus diferencias, se puede ver que básicamente todos tienen las mismas salidas, solo que en los modelos más sencillos estas se ven reducidas. Pero a nivel programación los pines son los mismos (solo que en distinta ubicación en cuanto a número de pin).

Lo ideal sería usar tres zócalos del tipo ZIF  ( Inserción Cero ) para los tres modelos de encapsulado, es decir:  2x 9, 2x 14 y 2x 20.  En caso que el presupuesto sea muy ajustado, se puede recurrir al uso de zócalos comunes, los cuales dan un resultado bastante aceptable.

Las distintas tensiones necesarias para la programación y funcionamiento del PIC 16F8xx se controlan mediante VR1 (78L05) y VR2 (78L12). 

La alimentación de entrada debe ser provista mediante una fuente externa que pueda entregar 15 a 17v de corriente continua y aproximadamente 100mA.

La conexión al puerto paralelo de la PC se debe realizar mediante un conector db25 macho y respetando el conexionado indicado en el circuito. Estos conectores traen el número de cada pin marcado al costado del mismo con lo que no es difícil su identificación. A su vez y para mayor seguridad, en el circuito también se hace mensión al nombre que representa cada línea a usar en el LPT.

En la siguiente figura se puede apreciar el pinout correspondiente al puerto paralelo de la PC:

 Debido a que este circuito está pensado para poder ser usado In Circuit, el mismo podría perfectamente con algunos retoques poder ser incluido dentro de un desarrollo para evitar tener que extraer el chip para su programación. Lo único que se debe tener en cuenta es que en ningún momento el pin MCLR/VPP debe ser conectado directo a VCC, ya que al intentar programar se dañarían los transistores Q1 y Q3 al quedar estos cortocircuitando VCC y GND.

Otra posibilidad muy interesante sería proveer al programador con un conector de salida tipo bornera que permita tener acceso desde el exterior a todos los puertos del micro que se está programando. De esta forma sería muy útil a la hora del desarrollo al permitirnos usar el micro sin necesidad de extraerlo del programador. En el documento salida.pdf se puede apreciar una idea para realizar el conector de salida antes comentado.

 

Page 9: Programador PIC Pablin II

Software

 

PicProg está  preparado para programar los siguientes modelos de la familia de Microchip:

16F84 16F84A

16F870

16F871

16F872

16F873

16F874

16F876

16F877

Page 10: Programador PIC Pablin II

PicProg le permite Programar, Verificar y Borrar todos los modelos anteriormente detallados.

El archivo Hexadecimal (.hex) a grabar debe ser formato Intel  INHX8M. Este es el formato estandar generado por la herramienta de desarrollo MPLAB que puede descargarse gratis en el site de Microchip.

PicProg  fue diseñado para trabajar en entorno Windows 9x.  En el archivo ZIP  picprog-v2.zip se encuentran las instrucciones así como la DLL necesaria para su funcionamiento. Debido a que Windows NT y Windows 2000 son algo limitados a la hora de permitirnos tomar control del hardware de la PC, este software no funciona en esos S.O.

El programa PicProg fue diseñado para leer la configuración a aplicar al PIC directamente desde el archivo Hexadecimal. Esta configuración es la que indicará si el PIC trabajará con Cristal (XT) o una celda RC, si se debe activar el WatchDog, etc. Para que esto sea así, esta configuración se debe incluir dentro del código fuente (ASM) antes de compilar el mismo como se puede ver a continuación:

__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC

El ejemplo anterior corresponde a la configuración para un PIC 16F84. En este caso se está indicando que no se usará Código de Protección (CP), no se usará WatchDog (WDT), se usará Power Up Timer (PWRTE) y se usará oscilador a crital (XT). (según nomenclatura de Microchip).

En caso que el archivo Hexadecimal (.hex) no posea embebida la configuración, esta podrá ser realizada manualmente mediante el botón CONFIGURACION .

Así mismo PicProg tiene la capacidad de autodetectar el PIC instalado o bien también se puede realizar la selección manualmente.

 

Utilizando el software PicProg:

Para ejecutar el software, simplemente se debe debe hacer click sobre el ejecutable PicProg.exe o bien crear un acceso directo al mismo. Una vez cargado, el funcionamiento es muy simple y se encruentra explicado en la ayuda provista con el mismo.

Es importante aclarar que no es necesario borrar el PIC antes de reprogramarlo, ya que PicProg  verifica cada sector de memoria a programar y solo regraba aquellos que son diferentes al actual. De esta manera se favorece la vida útil de la memoria Flash del PIC. Por consiguiente solo es recomendable el borrado total cuando se debe regrabar un micro que fue grabado anteriormente utilizando Código de Protección (CP).

 

Circuito de prueba:

Una vez construido el programador, lo mejor es realizar las primeras pruebas con un proyecto sencillo con el cual se tenga la certeza de su buen funcionamiento y de esa manera nos demuestre que el PIC ha sido correctamente programado.

Este programa puede ser el WALK.HEX, el cual genera un sencillo efecto de secuenciador entre cuatro LED's.

En el siguiente diagrama se aprecia el circuito a utilizar con el programa WALK.HEX:

Page 11: Programador PIC Pablin II

D1, D2, D3 y D4 son los LED's que, si todo funciona correctamente, se prenderán secuencialmente hacia un lado y hacia otro.

Una vez construido, el siguiente paso es grabar en el PIC el programa WALK.HEX , y si todo ha funcionado bien los LED's deberían comenzar a prenderse secuencialmente. 

Si deseas analizar el código fuente de este programa podés descargar WALK.ASM

 

Errores:

 Consulta las Preguntas Frecuentes

 

Recomendaciones:

En la página del fabricante Microchip, se puede encontrar gran cantidad de información necesaria para encarar cualquier proyecto con este microcontrolador.

Ahí mismo se puede descargar en forma gratuita el MPLAB, que es una estación de diseño y depuración para plataforma Windows, la cual les permitirá realizar todos los desarrollos basados en los microcontroladores PIC. 

Una vez instalado el MPLAB, podremos hallar en  C:\Archivos de programa\MPLAB\TEMPLATE\Code  los template que servirán como base para comenzar a programar. Por ejemplo el template correspondiente al PIC 16F84A es  f84atemp.asm

 

IMPORTANTE

Page 12: Programador PIC Pablin II

Se debe desconectar la alimentación del programador antes de extraer o insertar el PIC en el zócalo para evitar daños al chip, así como también al puerto paralelo de la PC.

PicProg ha sido diseñado para trabajar con archivos Hexadecimales en formato Intel  INHX8M , si se intenta usar cualquier otro formato los resultados son impredecibles. Aunque en ningún caso es peligroso para el Chip o el Programador, simplemente el programa se cargará erroneamente o no llegará a cargarse.

EXPERIENCIAS Y PRÁCTICAS

Icon los microcontroladores PIC16F84

Sabado, 03 de Octubre del 2009__________________ Incluir en favoritos si quiere volver a visitarnos.

Introducción.

Este es un acercamiento muy lineal a la escritura de un programa. Muchos escriben y producen unas subrutinas muy pequeñas con saltos (GOTO's) de una subrutina a otra, de modo que los productos saltan por todas partes como 'palomitas de maíz'. El micro es capaz, perfectamente capaz de saltar por un programa, sin embargo este tipo de disposición es muy difícil de seguir por un lector.

EXPERIMENTO 1.

Los comienzos siempre son muy simples, luego gradualmente se hacen más y más complejos. Para seguir los experimentos que se describen en estas páginas se recomienda montar el proyecto "Tarjeta de Pruebas " siguiendo las indicaciones que se dan en dicho artículo, aunque naturalmente el lector puede realizar su propio desarrollo o bien usar un protoboard, a su elección. 

Una vez dispongamos de dicho soporte, las 4 pilas de 1'5V y el chip 'F84A, debemos copiar y pegar el código que hay debajo, para poder completar nuestro primer experimento, al que daremos el nombre ejem01.asm y usando el ensamblador gratuito de Microchip MPLAB, pasarlo a exadecimal (.hex) con el cual tratamos de encender un LED. No hace nada más. El objetivo de este programa es mostrar las pocas líneas de código, necesarias para que el PIC haga esta tarea. Ver el listado:

Page 13: Programador PIC Pablin II

;******************************************************************^; Título: ejem01.asm ^; Autor: V. Garcia ^; Date: 12012006 ^; Deben documentarse todas las rutinas y el motivo de ser ^; (Las tildes estan omitidas de manera intencionada);_________________________________________________________________ ^; Recordar que con: 0 se designa al registro W y con ^ ; 1 se designa al archivo f ^; ^; Que hace => Encender LED 1 ^ ; ^; PIC16F84A ^;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^;;--------------- Encabezado -------------

Start: ORG 0x00BSF STATUS,5 ;Ir a pagina1 a fijar los puertosMOVLW h'00' ;pon 00 en W MOVWF h'05' ;haz todas las líneas RA salida MOVWF h'06' ;haz todas las líneas RB salida BCF STATUS,5 ; Ir a pagina0 para seguir el programa

LED_EN: MOVLW h'254' ;pon 1111 1110 en WMOVWF h'06' ;conecta el primer LEDGOTO LED_EN ; lazo a LED_EN

END

El siguiente es el listado en exadecimal, si no dispone de un ensamblador, puede copiar y pegar en su editor de texto y guárdelo como ejem01.hex para usar con el 'quemador' de chips y comprobar que hace lo que se espera.

:1000000083160030850086008312FF308600FE30A4:040010008600072837:00000001FF

Qué hace el programa.

Las líneas que empiezan con un punto y coma, como ya se ha comentado, son comentarios y no los usa el ensamblador, así que, la primera línea donde realmente comienza el listado, empieza en mnemónicos con una etiqueta Start (Principio), no siempre es necesario usar etiquetas. La instrucción ORG 0x00 indica al micro en ensamblador, donde colocar el programa, al principio de la memoria de programa (Flash). Es un área de datos en el propio micro, en la que se memorizan diversos datos durante la ejecución del programa, este área es la RAM del PIC, definida por el fabricante como área de FILE REGISTER, que se encuentra a partir de la dirección 0x0C. En el PIC, siempre le siguen unas líneas que como se verá, nos permiten el acceso a un juego de registros para la configuración del micro.

La instrucción que sigue BSF STATUS,5 BSF (BIT SET FILE REGISTER)

Page 14: Programador PIC Pablin II

pone a 1 el bit 5 del registro STATUS (0x03), en la posición de memoria RAM especificada, lo que nos permite el acceso a la página1 (o Banco1) donde se deciden las condicionantes que se ocupan de los registros 05 (puerto A) y 06 (puerto B) y ambos registros determinan el estado lógico de cada uno de los pines de dichos puertos A y B.

Con la instrucción MOVLW 00h (MOVE Literal to W register) ponemos el literal 00 en el registro de trabajo W, con la siguiente instrucción MOVWF 05h (MOVE W to File) ponemos el valor del registro W en el registro 0x05 (RP0) que es el Puerto A, que viene definido en el archivo P16F84A.INC, con esto hemos configurado el Puerto A como salida 0000 0000b. Si queremos que sea todo entradas usaremos la instrucción MOVLW FFh seguido de MOVWF 05h, esto pone 1111 1111b, todos los bits del Puerto A (0x05) a 1 como entradas .

En el registro STATUS, encontramos los parámetros RP0 que corresponde al valor 0x05 o lo que es lo mismo el bit5 del registro. Se pone a 1 este bit para cambiar el banco de trabajo y manejar los registros TRISA y TRISB como se verá más tarde.

Por ejemplo, cuando un bit del registro RP0 es 1, la patilla correspondiente del chip (del Puerto A) será entrada y cuando dicho bit lo ponemos a 0, esa patilla será salida. Tengamos en cuenta que, no podemos cargar ninguno de estos registros directamente, en primer lugar se debe poner un valor o número (llamado literal) en W y luego cargar W en el registro deseado. Si cargamos 00 en W y luego W en 05 y 06, todas las líneas del Puerto A y del Puerto B serán puestas como salida.

La siguiente instrucción BCF STATUS,RP0 (Bit Clear File register) cierra esta página1 (banco1) y devuelve el control a las instrucciones del programa de la página 0 (banco 0). Observar el símil BSF (Bit Set, banco1 ) y BCF (Bit Clear, banco 0). Como el F84A sólo tiene dos bancos (0 y 1) usa el estado de un sólo bit para cambiar de banco, otros PICs con más memoria requieren de más bits de control en el mismo registro STATUS.

Esto, en esencia significa que, el programa para encender un LED realmente consiste en tres líneas, la primera línea en la etiqueta LED_EN MOVLW h'254', pone el valor FEh en el registro de trabajo W, la segunda línea MOVWF h'06' copia el valor en W al Puerto B (06). Este puerto es de salida (en realidad es un puerto de Entrada/Salida) cuando el primer bit del Puerto B pase a ALTO, el LED se iluminará, como el programa es muy rápido, se apagará de inmediato y no podremos saber si funciona el programa, entonces, entra en acción la tercera línea del programa.

La tercera línea GOTO LED_EN (del inglés GO TO, ir a), es la instrucción que envía el puntero del programa a la dirección de la etiqueta LED_EN, es el lazo que mantiene el LED encendido por el programa al repetir la secuencia, ya que como se ha dicho, el micro debe estar (corriendo) todo el tiempo, incrementando el programa. Ahora, puede que sea algo confuso lo

Page 15: Programador PIC Pablin II

descrito, sin embargo a medida que avance en estos artículos podrá comprobar que es sencillo y fácil.

El circuito.

Como se aprecia en el esquema, el circuito anterior (Tarjeta de Pruebas) se compone de un microcontrolador PIC16F84, ocho diodos LED y unos pocos componentes adicionales. El Puerto B del PIC  tiene un LED conectado a cada una de sus ocho líneas. El circuito más simple y sencillo se puede ver a continuación.

Todo lo descrito hasta aquí, es cierto, si bien hay otras formas de lograr el mismo resultado, una de las formas es cambiando el sentido del LED, en cuyo caso se debe modificar el valor de la salida del puerto B, donde había

Page 16: Programador PIC Pablin II

un 0 ahora debe presentar un 1, lo que obliga a conectar el ánodo a la salida y la resistencia a la línea de masa (GND), con esto se ha

modificado el programa y sigue mostrando el mismo resultado que el anterior. Entonces, porque se ha usado el primer método.

No ha sido al azar, tengamos en cuenta que el consumo del conjunto LED más resistencia normalmente no supera los 20mA y como la patilla del puerto, admite una corriente mayor, no causará ningún contratiempo, ya que el drenador de salida del puerto soporta dicha carga mejor que tener que aportar dicha corriente que supone un mayor consumo y el consiguiente aporte de calor, este ha sido el principal motivo de usar este método. Este método debe ser considerado por el técnico para reducir consumos innecesarios en los proyectos. Este criterio es el que seguiremos aquí.

La operación del circuito se basa en un programa y este programa está contenido en el chip. Cuando se aplica la energía, el micro empieza en la primera posición de memoria y ejecuta el programa. El programa será guardado en la memoria del micro, durante el "quemado" y en ese único momento están disponibles un número de opciones de oscilador, osc RC (oscilador Res. / Cond.) que debe ser seleccionado y el chip estará listo para ese tipo de oscilador elegido, téngase en cuenta que el montaje sólo responderá al sistema de oscilador en la palabra de configuración que haya elegido al 'quemar', si es RC, LP, TX, etc. Otras opciones disponibles del F84A a configurar son: PWRTE, CP, WDT, las cuales dependen del dispositivo en uso (se recomienda leer el DataSheet correspondiente).

Debido a que el chip puede ser programado y reprogramado de nuevo, lo cierto es que está garantizado por más de 1.000 veces, esto lo hace ideal para la experimentación.

EXPERIMENTO 2.

  Este experimento es similar al anterior, mediante unas pocas líneas añadidas al contenido del programa anterior, hacemos que el LED ahora se encienda y se apague en una secuencia sin fin. El circuito que se usa, es el mismo del ejercicio anterior. Esto se consigue de esta forma: añadimos en la tercera línea, una instrucción CALL (Llamada) que envía al programa a la subrutina con etiqueta 'Delay' y luego se hace un nuevo lazo, veamos.

Se trata de conseguir un retardo 'Delay' con el que poner el estado del LED en un bucle de espera, esta subrutina la llama el programa principal con la instrucción CALL Delay, esto mantiene encendido el LED, cuando termina el bucle, el micro retorna a la línea siguiente donde esta el CALL, en el programa principal MOVLW h'FF' que, carga el literal FF en el registro W y lo pone con la instrucción MOVWF 06, en el Puerto B (salida) y salta de nuevo a la etiqueta Delay (retardo) para esta vez mantener apagado un tiempo el LED.

Al volver del retardo se establece un nuevo lazo, sería conveniente volver a

Page 17: Programador PIC Pablin II

empezar esta parte del programa para repetir los mismos pasos y esto se logra con un lazo que une este punto con el principio mediante el GOTO LED_EN. Véase el listado.

En cuanto a la rutina 'Delay' en sí, lo que ocurre es que, empieza por DECFSZ 1Bh (DECrement File Register Skip If Zero) decrementa una unidad el archivo 1Bh, si no es cero, sigue en la instrucción GOTO Delay para volver a decrementar que devuelve el programa a la instrucción anterior, para decrementarlo una nueva unidad, esto lo hace cada vez que pasa por la instrucción DECFSZ 1Bh.

Cuando el archivo 1Bh llega a 0, entonces salta la instrucción GOTO Delay a la instrucción que sigue que, es otro DECFSZ pero esta vez el archivo es 1Ch y empieza a decrementarlo de uno en uno avanzando la rutina, luego se reinicia la instrucción DECFSZ 1Bh, a la que le sigue el decremento DECFSZ 1Ch, decremento de la instrucción a instrucción hasta llegar a la instrucción (RETURN) de retorno al programa principal. Esto se le llama instrucciones anidadas, ya se tratarán en más detalle.

. . . . . .

LED_EN MOVLW h'FE' ;pon 1111 1110 en WMOVWF h'06' ;conecta el primer

LEDCALL Delay ;Salta al retardoMOVLW h'FF' ;carga W con FF yMOVWF 06 ;apaga el LEDCALL Delay ;Salta al retardoGOTO LED_EN ; lazo a LED_EN

Delay DECFSZ h'1B',1 ; RetardoGOTO DelayDECFSZ h'1C',1GOTO Delay RETURN

END

Se muestran sólo los cambios que nos permiten producir lo previsto en el enunciado. Observar que no se usan los pulsadores, para estos experimentos. A continuación se presenta el listado en hex para que si no puede ensamblarlo lo copie y pegue en su editor de texto y guárdelo como ejem02.hex para el posterior 'quemado' del chip.

:1000000083160030850086008312FF308600FE30A4:1000100086000E20FF3086000E2007289B0B0E283E:060020009C0B0E280800F5:00000001FF

EXPERIMENTO 3.

Page 18: Programador PIC Pablin II

  En este experimento, proponemos encender el LED 1 de una fila de 8 LEDs,

lo apagaremos y encenderemos el siguiente LED 2 esto lo repetiremos en una secuencia hasta llegar al LED 8 con una cadencia de 2Hz, para volver a empezar por el LED 1, esto es todo lo que hace este experimento. El circuito que usaremos es similar al usado en el experimento 1, al que añadimos 7 series LED+R. Lo que más cambiará es el listado del programa que, en este caso, tendrá que sufrir algunas modificaciones como veremos. Este puede ser una modificación del esquema en el caso de no usar la tarjeta descrita.

En el esquema del principio, los cinco pines RA0 a RA4 (puerto A) se usan como pines de entrada, estos son forzados a alto con resistencias a positivo de 10kohms, de modo que cuando los pulsadores no están pulsados la entrada se hace alta (+5V) y cuando uno se pulsa pasa a nivel bajo (0V). El fenómeno de rebote producido, no se contempla esta vez ya que, cuando el programa detecta que el pulsador está cerrado, el tratamiento de parpadeo de los LED's se ejecuta una vez en el tiempo y es más largo que el rebote. No se usan pulsadores en este ejercicio, de modo que no se contemplarán.

Los ocho pines RB0 a RB7 (puerto B) se usan como salida, los ánodos de los LED's se conectan al +5V y cada cátodo es controlado por la resistencia vía PIC, de modo que cuando la salida del PIC es nivel alto (+5V), el LED implicado no luce y cuando el PIC entrega un nivel bajo (0V), lucirá el LED, esto reduce la corriente en el chip. Se usarán LED's de alto brillo con poca corriente de flujo. Este es el listado completo para este experimento.

;******************************************************************^; Título: ejem03-1.asm ^; Autor: V. Garcia ^; Date: 12012006 ^; Deben documentarse todas las rutinas y el motivo de ser ^; (Las tildes estan omitidas de manera intencionada);_________________________________________________________________ ^; Recordar que con: 0 se designa al registro W y con ^ ; 1 se designa al archivo f ^; ^; Que hace => Encender LED 1, lo apaga y enciende el siguiente ^

Page 19: Programador PIC Pablin II

; hasta el LED 8, luego vuelve a emepzar. ^; PIC16F84A ^;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^;;--------------- Encabezado ------------- list p=pic16f84a #include <p16f84a.inc> errorlevel -302 ;Eliminar banco mensajes

;**************** Definicion de Etiquetas ********************STATUS equ h'0003'porta equ h'0005' ; define puerto Aportb equ h'0006' ; define puerto BTRISA equ h'0085'TRISB equ h'0086'

; Estos estan definidos en #include ;w equ h'0000';f equ h'0001'

ra0 equ 00 ;RA0 bitra1 equ 01 ;RA1 bitra2 equ 02 ;RA2 bitra3 equ 03 ;RA3 bitra4 equ 04 ;RA4 bitrp0 equ 06

cnt500u equ 0c ;500usec direccion contador cnt1m equ 0d ;1msec direccion contadorcnt100m equ 0e ;100msec direccion contadorcnt500m equ 0f ;500msec direccion contadorcnt1s equ 10 ;1sec direccion contador

;************* Definicion Modelo Datos ****************; '1':OFF '0':ON

;****** Tabla Modelo ******p00 equ b'01111111'p01 equ b'10111111'p02 equ b'11011111'p03 equ b'11101111'p04 equ b'11110111'p05 equ b'11111011'p06 equ b'11111101'p07 equ b'11111110';;**************** Inicio Programa *********************** org 0 ;Vector Reset goto init org 4 ;Vector Interrupcion BCF INTCON,GIE ;Por si se dispararan las interrupciones goto init

;**************** Proceso Inicial ********************* org 5init: bsf STATUS,RP0 ;Cambiar a Banco1 movlw h'ff' ;Define modo datos entrada movwf TRISA ;Define PORTA en modo Entrada clrf TRISB ;Define PORTB a modo Salida

Page 20: Programador PIC Pablin II

bcf STATUS,RP0 ;Cambia a Banco0; movlw h'ff' ;Pon datos '11111111' en salida movwf portb ;para apagar LEDs

;*********** Modelo 0 Subrutina Salida ***************ptn0 movlw p00 ;Pon datos modelo en movwf portb ;datos salida call t100m ;Espera 100msec movlw p01 ;Pon datos modelo en movwf portb ;datos salida call t100m ;Espera 100msec movlw p02 ;Pon datos modelo en movwf portb ;datos salida call t100m ;Espera 100msec movlw p03 ;Pon datos modelo en movwf portb ;datos salida call t100m ;Espera 100msec movlw p04 ;Pon datos modelo en movwf portb ;datos salida call t100m ;Espera 100msec movlw p05 ;Pon datos modelo en movwf portb ;datos salida call t100m ;Espera 100msec movlw p06 ;Pon datos modelo en movwf portb ;datos salida call t100m ;Espera 100msec movlw p07 ;Pon datos modelo en movwf portb ;datos salida call t100m ;Espera 100msec movlw h'ff' ;Pon datos FF en salida movwf portb ;datos para apagar LED call t100m ;Espera 100msec return ;********************************************************; Subrutina retardo (Timer) para reloj 10MHz ;********************************************************

;************* Subrutina 1msec Timer *****************t1m movlw d'2' ;(1) Pon lazo cnt1 movwf cnt1m ;(1) Guarda lazo cnt1tm1lp1 movlw d'249' ;(1)*2 Pon lazo cnt2 movwf cnt500u ;(1)*2 Guarda lazo cnt2tm1lp2 nop ;(1)*249*2 ajust retardo nop ;(1)*249*2 ajust retardo decfsz cnt500u,f ;(1)*249*2 cnt500u-1=0 ? goto tm1lp2 ;(2)*248*2 No, continua decfsz cnt1m,f ;(1)*2 cnt1m-1=0 ? goto tm1lp1 ;(2) No. Continua return ;(2) Si. final de Cnt ;Total 2501*0.4usec=1msec

;************* 100msec Subrutina Retardo (Timer) ***************t100m movlw d'100' ;Pon lazo contador movwf cnt100m ;Guarda lazo contadortm2lp call t1m ;subrutina 1msec decfsz cnt100m,f ;cnt100m - 1 = 0 ? goto tm2lp ;No. Continua return ;Si. Final de Contador

Page 21: Programador PIC Pablin II

;************* 500msec Subrutina Retardo (Timer) ***************t500m movlw d'5' ;pon lazo contador movwf cnt500m ;Guarda lazo contadortm3lp call t100m ;subrutina 100msec decfsz cnt500m,f ;cnt500m - 1 = 0 ? goto tm3lp ;No. Continua return ;Si. final de Contador

;************** 1sec Subrutina Retardo (Timer) *****************t1s movlw d'2' ;Pon lazo contador movwf cnt1s ;Guarda lazo contadortm4lp call t500m ;subrutina 500msec decfsz cnt1s,f ;cnt1s - 1 = 0 ? goto tm4lp ;No. Continua return ;Si. Final de Contador

;********************************************************; Final del proceso parpadeo LED ;********************************************************

end

Este que sigue, es el archivo en hex que se obtiene al ensamblar el listado anterior, si no dispone de un ensamblador, puede copiar y pegar este archivo en su editor de texto y guárdelo como ejem03-1.hex para el 'quemado' en un chip '84A, con su sistema de programación.

:020000000528D1:0800080005280317FF308500F5:1000100086010313FF308600051C0E200310FE30FE:1000200086001420860D112803309A009B0B162899:0A0030009C0B16289A0B16280800F6:00000001FF

Qué hace el programa.

Las primeras líneas del programa, definen las igualdades (equ) y los parámetros que se van a usar. Aquí, se han definido las variables ra0-ra4 no usadas y  RP0, seguidamente se define una tabla modelo binario de ocho líneas de datos, cada vez que se llame con:

   movlw p00        ; carga literal en el registro W (el literal va desde p00 a p07)   movfw portb    ; presenta valor en puerto b   call t100m         ; llama subrutina retardo

su valor se enviará a la salida (puerto B), alternando con los retardos necesarios para encender el LED que corresponda en cada caso, esto se repite. Posteriormente se define la subrutina de retardo desde donde se vuelve a la rutina principal. 

Page 22: Programador PIC Pablin II

La rutina de tiempos aquí usada, como se aprecia, es bastante completa ya que

presenta hasta cuatro alternativas permitiendo un retardo de: 1 milisegundo, 100 milisegundos, 500 milisegundos y 1 segundo, lo cual, la hace interesante a la hora de aplicar en distintas ocasiones. Le aconsejo que la estudie con atención, le puede servir en sus proyectos.

  Sin embargo, nos parece muy extenso este listado, podemos hacer lo mismo de forma más simple. Esto mismo se hace poniendo un 0, en el puerto b de salida (registro 06h), esto pone a 0 el bit más alto y así el primer LED se iluminará. Entonces el bit se rota (cambia) un lugar a la derecha con una instrucción RLF (Rotation Left File, rotación a la izquierda de un bit) del contenido de F, pasando por el bit de acarreo C, esto conecta el siguiente LED en la fila. Es importante 'aclarar' (poner a 0) la bandera C (acarreo) antes de usar una instrucción de rotar, ya que cuando se conecta el micro, la bandera C puede estar en 1, con esto nos aseguramos que los LED's se desplazaran, que es lo que deseábamos. Este es el listado en ensamblador que se puede copiar, pegar y guardar con el nombre ejem03.asm.

;******************************************************************^; Título: ejem04.asm ^; Autor: V. Garcia ^; Fecha: 20-01-2006 ^; Version:0.0 ^; Codigo para: PIC16C84 y PIC16F84 ^; Clock: 4MHz , XT. -> Ciclo = 1 uS. ^; Reset: Power On Reset. ^; Watch Dog: Inhabilitado. ^; Proteccion de codigo: Inhabilitado. ^; Ficheros requeridos: H16f84a.inc ^; Placa uControladora: Circuito de cátodos de LEDs a +Vcc. ^; ^; (Las tildes estan omitidas de manera intencionada) ^;_________________________________________________________________ ^; Recordar que con: 0 se designa al registro W y con ^; 1 se designa al archivo f ^; Pulsador sin rebotes enciende un LED ^; Que hace => A de encender el LED 1 apagarlo, encender LED 2 y ^; apagarlo, sigue hasta LED 8. La secuencia se invierte y sigue ^; desde LED 8 hasta LED 1 ^;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^;--------------- Encabezado -------------;********************************************************************; LIST p=PIC16F84A ; Directiva para definir micro. #include <p16f84a.inc> ; Fichero estandard de cabezera.; ;******************** DEFINICIONES **********************************; Todas las definiciones estan en 'include ', por tanto; solo se definen las localesporta equ h'0005' ; define puerto Aportb equ h'0006' ; define puerto B

con1 equ 0x0C ; Variable de temporizacion.

Page 23: Programador PIC Pablin II

con2 equ 0x0D ; Variable de temporizacion.

;******************** COMIENZO DEL PROGRAMA ********************; SE DEFINEN BANCOS #define banco1 bsf STATUS,RP0 ;Macro para abreviar el BANCO 1

;pone a 1 el bit5 del registro status#define banco0 bcf STATUS,RP0 ;Macro para abreviar el BANCO 0

;pone a 0 el bit5 del registro status

ORG 0x00 ; Vector de Reset. GOTO inicio ; Programa Principal.

;************************************************************delay: CLRF con1 ;lazo exterior

MOVLW 0xF0MOVWF con2

; RETURN ;esta linea es de pruebaloop: DECFSZ con1,F ;lazo interior

GOTO loopDECFSZ con2,FGOTO loopRETURN

;;******************** PROGRAMA PRINCIPAL ********************

inicio: banco1 ; Banco 1.CLRF TRISB ; aclara puerto B, pone a 0 , todo salidas banco0 ; Banco 0.

MOVLW 0xff ; PORTB 11111111.MOVWF portb ;BCF STATUS,C ;Preparado para rotar, pone a 0 el bit C

; Desplazar portB a la izquierda, usamos la instruccion ROTAR

gira_i:BTFSS portb,7 ;si el bit 7 = 1 salta y rota a derechaANDLW 01 ;si no, AND entre literal y W

sigue_i: BTFSC portb,7 ; portb = 00?goto $+3 ; no, salta 2 lineasmovlw 0xff ; si, pon 255 enmovwf portb ; portbBCF STATUS,C ;Asegura que en primera

; rotacion ingrese 0 en PORTBRLF portb,F ;rota archivo F a izq. (F = '1111 1110')CALL delay ;salta a retardoGOTO gira_i ;vuele a girar.

; END ; Fin de programa.

Qué hace el programa.

Se definen los parámetros en las primeras líneas, registros, puertos y variables. Además en este caso he querido plasmar otra forma posible de definir las variables para manejar los bancos (banco0 y banco1). Para ello he definido las macros banco1 y banco0, mediante las cuales se realiza la

Page 24: Programador PIC Pablin II

configuración de los mismos. El tema de macros no se describirá aquí.

Seguidamente en Inicio, se ve como se aplican. En este punto recalco el modo de poner a cero todos los bits de un puerto, en este caso el puerto B (TRISB) mediante la instrucción CLRF (aclarar

registro f). En las líneas siguientes, se carga el puerto B con el literal FF y con BCF (Bit Clear File) se pone a 0 el bit C, con lo que estamos listos para empezar a desplazar el LED encendido, por la barra de LEDs.

Sigue la subrutina de retardo y ahora empieza la rutina principal gira_i el primer paso comprueba el estado del bit7 =1 del puerto b, luego comprueba si es 0 y mediante la instrucción RLF (Rota Left File) nos desplaza a la izquierda una posición (rotación del bit), en cada iteración del lazo de la subrutina, encendiendo, apagando y desplazando el LED en cada momento. Si en BTFSC portb,7 es 0, se carga el puerto b con 255 para podar seguir desplazando el LED.

Se puede observar un RETURN inhabilitado en la rutina de retardo, esto lo uso para comprobar el buen funcionamiento de las subrutinas, una vez comprobada, pongo el consabido punto y coma delante y a seguir. El listado en hex que sigue, por si no lo quiere ensamblar, lo puede copiar, pegar y guardar como ejem03.hex en un archivo con el que puede quemar el '84A para probar su funcionamiento.

:020000000528D1 :06000A008316860183123B:10001000FF3086000310861F0139860D10200B2843:100020008C01F0308D008C0B13288D0B13280800E9:00000001FF

Como siempre el circuito y esquema electrónico es el mismo mostrado en la figura anterior.

EXPERIMENTO 4. 

  En este caso, propongo producir un programa que encienda un LED y lo desplace en un sentido por la barra, cuando llegue al final regrese y repita esta secuencia en el otro sentido. Digamos que, con este programa obtendremos la clásica barra de LEDs del famoso coche 'Fantástico'. A tenor de lo visto en los ejemplos anteriores parece sencillo y así lo voy a demostrar. El listado sería el siguiente: 

;******************************************************************^ ; Título: ejem04.asm ^ ;  Autor: V. Garcia ^ ;  Fecha: 20-01-2006 ^ ; Version: 0.2 ^ ; Codigo para: PIC16C84 y PIC16F84 ^ ; Clock: 4MHz , XT. -> Ciclo = 1 uS. ^ ; Reset: Power On Reset. ^

Page 25: Programador PIC Pablin II

; Watch Dog: Inhabilitado. ^ ; Inhabilitado. ^ ; Ficheros requeridos: H16f84a.inc ^ ; Placa uControladora: Circuito de cátodos de LEDs a +Vcc. ^ ; ^ ; (Las tildes estan omitidas de manera intencionada) ^ ;_________________________________________________________________ ^ ; Recordar que con: 0 se designa al registro W  y con ^ ; 1 se designa al archivo f    ^ ; Pulsador sin rebotes enciende un LED   ^ ; Que hace => A de encender el LED 1 apagarlo, encender LED 2 y    ^ ; apagarlo, sigue hasta LED 8. La secuencia se invierte y sigue    ^ ; desde LED 8 hasta LED 1 ^ ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ;--------------- Encabezado ------------- ;******************************************************************* ; LIST p=PIC16F84A ; Directiva para definir micro. include "p16f84a.inc" ; Fichero estandard de cabezera. ;******************** DEFINICIONES *********************************

con1 equ 0x0C ; Variable de temporizacion. con2 equ 0x0D ; Variable de temporizacion.

;******************** COMIENZO DEL PROGRAMA  ******************** ; SE DEFINEN BANCOS#define banco1 BSF STATUS,RP0 ;Macro para abreviar el BANCO 1

;pone a 1 el bit5 del registro status#define banco0 BCF STATUS,RP0 ;Macro para abreviar el BANCO 0

;pone a 0 el bit5 del registro status ORG 0x00 ; Vector de Reset. GOTO inicio ; Programa Principal.

;****************** SUBRUTINA DE TIEMPO ************* delay: CLRF con1 MOVLW 0xF0 MOVWF con2 ; return ;es de prb loop: DECFSZ con1,F GOTO loop DECFSZ con2,F GOTO loop RETURN ;************************************************************ ;******************** PROGRAMA PRINCIPAL ******************** inicio: banco1 ; Banco 1. CLRF TRISB ; aclara   banco0 ; Banco 0. MOVLW 0xff ; PORTB 11111111. MOVWF PORTB ; BCF STATUS,C ;Preparado para rotar

Page 26: Programador PIC Pablin II

; PORTB Rota hacia la izquierda, usamos la instruccion ROTAR

gira_i: BTFSC PORTB,7 ;si el bit7 = 0 salta y rota a derecha GOTO sigue_i ;no, sigue izquierda. GOTO gira_d ;sigue_i: RLF PORTB,F ;rota archivo F a izq. (F = '1110') CALL delay ;

BTFSC PORTB,0 ;salta y rota si bit0 = 0 GOTO gira_i

BSF PORTB,7 ; PORTB Rota hacia la derechagira_d: BTFSC PORTB,0 ;salta y rota si bit0 = 0 GOTO sigue_d GOTO gira_isigue_d: RRF PORTB,F CALL delay GOTO gira_d ; END ; Fin de programa.

Qué hace el programa.

Si el lector sigue el flujo del programa puede comprender que, he recurrido a dos rutinas encadenadas idénticas en la forma: gira_i y gira_d ambas están entrelazadas, trataré de describir como funcionan.

Al llegar el programa a gira_i, encuentra la instrucción BTFSC portb,7 que comprueba si el bit7 del puerto B está a 0, como dicho bit7 es 0, el programa sigue y salta a la etiqueta sigue_i, en ese momento rota izquierda con RLF seguido de un salto al retardo para que el LED se vea encendido, al regresar comprueba si está a 0 el bit0, si no lo está vuelve a gira_i, repitiendo estos pasos hasta que el bit0 es 0, en cuyo caso salta hasta BSF PORTB,7 para poner a 1 el bit7, luego sigue con gira_d donde comprueba el estado del bit0 que, estará a 1 y saltará a sigue_d para rotar a derecha seguido de un CALL a pausa, al volver hará un GOTO gira_d, repitiendo estos pasos.

Al llegar el programa a la instrucción CALL delay saltará a la posición de la etiqueta (subrutina de retardo) delay, limpia el registro cont1 y carga el registro cont2 con el valor F0h, decrementa el registro cont1 que esta a 00 y por tanto ahora esta a FFh (GOTO loop) hasta que es 0 y en ese momento decrementa el registro cont2 (GOTO loop) hasta que es 0 cerrando el lazo por segunda vez. Cuando termine esta subrutina (pausa), volverá a la instrucción siguiente a la que le hizo saltar. Espero haber aclarado el flujo del programa.

Sigue está el listado en hex del archivo un vez ensamblado, como siempre, puede copiar y pegar en un editor de texto y guardarlo como ejem04.hex para posteriormente quemar un PIC17F84A y comprobar su eficacia.

:020000040000FA

Page 27: Programador PIC Pablin II

:1000000009288C01F0308D008C0B04288D0B0428FE:100010000800831686018312FF3086000310861BBA:1000200012281728860D012006180F288617061893:0A0030001A280F28860C012017285B:00000001FF

Con este ejercicio ponemos el punto y aparte por esta vez, seguiremos con estos ejemplos en la segunda parte .  

Manual Rápido del MPLAB Hoy: Sabado, 03 de Octubre del 2009__________________ Incluir en favoritos si

quiere volver a visitarnos.

Introducción.

En los proyectos que se describen en estas páginas utilizaremos el software de uso libre como es el MPLAB, si por alguna razón el lector quiere usar la versión que he manejado en estos artículos puede bajarse la versión 5 (¡ojo! pesa 11MBytes y si su conexión no es rápida puede tardar algo de tiempo) El motivo es que hemos de entender y aprender a utilizarlo para ensamblar nuestros proyectos, hacerlo fácil y esto es lo que vamos a describir aquí.

Si no se dispone de esta herramienta recomendamos se obtenga es gratis, para poder seguir nuestros pasos. En programación como ya se ha dicho en estas páginas, existen unas directivas generales que se utilizan de forma repetida y por ese motivo se ha descrito una plantilla del programador que encontrará en estás páginas, como herramienta menor de ayuda.

El entorno de trabajo MPLAB vers5, necesita de una configuración de las instrucciones para 'que vaya como la seda', ya hemos documentado este apartado en otras ocasiones y lo vamos a repetir aquí. Para empezar, se debe documentar todo nuestro trabajo, esto significa que los comentarios aclaratorios necesarios son: Nombre del Autor, Archivo, Fecha y Descripción de qué hace el programa y para este fin el MPLAB dice que detrás de "; " todo se considera comentario y no se tendrá en cuenta al compilar el listado.

Podemos hacer una primera incursión en el MPLAB para tener una visión general de cómo proceder a compilar un listado que tengamos en formato .asm, después entraremos en detalles más extensos. Estos son los pasos:

1. Ejecutar el programa MPLAB. Hay disponibles cuatro menús de iconos, como

Page 28: Programador PIC Pablin II

muestra la figura de abajo. Elegir el

segundo menú para empezar un proyecto y el primero, para ejecutar distintas acciones de análisis.

2. Menú File-New, mostrará un cuadro de dialogo que dice: 'A project is not currently opened' o sea, que no hay un proyecto disponible, 'desea crear uno', pulsamos sobre la opción Yes para empezar. Si ya lo hemos usado

con un proyecto y al salir lo guardamos, ahora nos propondrá si queremos abrirlo, pulsamos sobre la opción Yes para continuar con el proyecto.

3. Mostrará una ventana 'New Project' en la celda correspondiente daremos un nombre a nuestro proyecto y se puede elegir el directorio en el que guardarlo y pulsamos OK. 

4. Empezaremos a crear nuestro proyecto en la ventana 'Edit Proyect' como se ve en la imagen de abajo a la izquierda.

5. En esta ventana hay cinco celdas en las que debemos introducir datos: En la primera, 'Target Proyect' aparecerá el nombre de nuestro proyecto. 'Include Path', 'Library Path' y 'Linker ...', se dejan como están. En 'Development Mode' nos aseguramos que el sistema de desarrollo es el correcto 'MPLAB SIM PIC16F84' y en la cleda de abajo en 'Language Tool Suite', se encuentra Microchip.

Ahora viene la parte más compleja si se quiere, en el menú 'Project' la opción 'Edit Project' o CRTL+F3, abre un cuadro de dialogo, en la parte de abajo en 'Project Files' aparecerá el nombre del archivo que vamos a producir con la extensión [.hex], al seleccionarlo, a su derecha se activará el botón 'Node Properties...', lo pulsamos, aparecerá una nueva ventan con cuatro zonas diferenciadas, como se aprecia en la imagen de abajo, en la parte de arriba aparece la celda 'Node' con el nombre del proyecto y la extensión hex, a su derecha la celda ' Language Tool' que normalmente no se toca.

En la zona central, se encuentra una cuadricula 'Options' con seis columnas y distintas descripciones, observar que algunas no están activas, en definitiva y para acortar, deben estar activadas, en 'On' las

Page 29: Programador PIC Pablin II

siguientes: 'Hex Format', 'Error File', 'List File', 'Case Sensitivity' y 'Default radix' y activada en 'Off' la de 'Cross-reference File'. Ya se describirán más adelante estos criterios, ver esto en la imagen que sigue.

Debajo, en la zona 'Command Line', se muestran las ordenes que se han generado en según lo asignado en el apartado anterior. En la última zona 'Additional Command Line Options' estará en blanco. Y para cerrar pulsamos OK.

6. Se mostrará la ventana en blanco, de título Untitle1, donde se debe escribir nuestro programa (código fuente). Sin embargo como ya se ha dicho, en muchas ocasiones ya lo dispondremos de nuestro editor más habitual, podemos traer el código fuente hasta la carpeta donde tenemos el proyecto con la extensión .prj . Entonces con el 'Edit Project' pulsamos el botón 'Add Mode...' y nos abrirá una ventana para seleccionar la carpeta en la que localizamos la que contiene el archivo con la extensión .asm que ya tenemos guardado y luego pulsamos 'Aceptar'. Ahora el archivo 'puntoasm'  se muestra debajo del anterior y para cerrar pulsamos 'OK'. 

7. Digamos que, ya está en el simulador MPLAB el listado, por fin podremos compilar el programa.

8. Es el momento de acceder al 'Menú-Project' y 'Make Project' o simplemente pulsamos la tecla F10. Esto abrirá una nueva ventana como la de la derecha, en la que se mostrará una barra de progreso de color verde e inmediatamente debajo, unos indicadores con los Errores, Warnings, Menssages, etc. si es que los hay, aunque no siempre hay errores. 

Normalmente si hay errores, presentará una ventana como la mostrada debajo que, nos indicará todos los errores producidos y su localización el número de línea en la que se encuentra cada uno. Para corregir los errores, haremos doble clic en uno de ellos, el puntero se desplaza hasta la línea del listado de código que contiene el error, para que así lo modifiquemos. Revisamos las instrucciones que hayamos puesto, para corregir los fallos.

Page 30: Programador PIC Pablin II

Una vez rectificados los errores, volveremos al paso 7 y procederemos a la nueva compilación del programa, verificaremos que no se hayan producido errores o los rectificaremos hasta lograr la depuración del programa. Recuerde que nadie es perfecto y aprenda de sus errores.

El caso más común es que después de ciertas correcciones no presente errores, quizás una atención (warning) y obtendremos el listado en hexadecimal que se ha creado en la misma carpeta donde está el proyecto, éste es el que tenemos que usar con el 'quemador'de chips descrito en otro artículo de la serie, para comprobar si nuestro proyecto refleja nuestros deseos, en caso de no ser así, debemos realizar los cambios necesarios en el programa y volver a empezar el proceso de compilar de nuevo hasta lograr nuestro propósito y luego a por otro proyecto.

Como estimular al MPLAB

Esta bien, cuando hemos terminado de ensamblar un listado .asm y antes de quemar el chip con el código generado por este, es conveniente en muchas ocasiones, proceder a simular la ejecución del archivo hexadecimal generado para mayor seguridad y para esto el MPLAB incorpora una herramienta que nos permite realizar dicha simulación. Hasta aquí, todo es normal, en el caso especial de necesitar estimular una línea, es decir, como por ejemplo, simular que se ha presionado un pulsador en un momento de la simulación, aquí es donde se necesita dominar esta herramienta.

En menú Window, disponemos de las ventanas que más nos servirán para seguir con detalle la evolución de la simulación, también están los iconos propios en las barras de menú que se menciona al principio de este artículo.

Page 31: Programador PIC Pablin II

Destaca la ventana del stack o pila, aquí se verán en acción la pila con sus 8 niveles y que el último en ingresar es el primero en salir, para eso tiene que estar la simulación en activo.

La ventana que mayor importancia le doy, en la de 'S

pecial Function Register', o registros de función especial de la izquierda, en esta se aprecia la evolución de los distintos registros con sus valores cambiantes según el valor resultante de la ejecución de cada instrucción. Todo esto es posible examinarse mediante la ejecución del programa en el modo, paso a paso (step to step) o animado (animate). Es conveniente que el interesado haga su propia simulación en ambos modos y compruebe lo que ocurre en cada momento.

Otra ventana es la de 'Program Memory' a la derecha que, nos muestra la evolución del programa instrucción a instrucción, obsérvese las columnas que empiezan por 0000, corresponde a la localización en memoria y a su derecha con 4 dígitos, corresponde al código de la instrucción de esa línea, las siguientes columnas se refieren a la etiqueta, a la instrucción propiamente y a sus valores.

En Modify, podemos modificar el valor de un registro en un momento dado, para no tener que esperar tanto tiempo de ejecución como ocurre con un retardo. Sigamos con la simulación.

En el menú Debug/Simulator Stimulus.../Asincronus Stimulus tenemos la ventana donde se pueden configurar las señales que deben influir en la simulación como son, pulsadores, señales de reloj, etc. Al abrir esta ventana, muestra 12 botones que, en principio indican Stim 1(P), Stim 2(P), etc. Con el botón derecho del ratón sobre uno de ellos, mostrará una ventana para seleccionar distintas opciones. En nuestra simulación se trata de sendos pulsadores en el puerto de entrada, por ej. RA2, RA3 y RA4.

En el mencionado menú emergente, se selecciona Assign pin... RA0, ahora es RA0 (P), nuevamente haremos click con el botón derecho sobre el mismo botón pero esta vez seleccionamos Toggle aquí significa pulsador, con RA3 y RA4 se procede del mismo modo.

Una vez configurados estos botones, debemos iniciar el generador de tiempos que, como un generador de reloj, se encarga de enviar los pulsos a los terminales de puerto, indicados por los botones de estimulo anteriores, en la secuencia prevista.

Page 32: Programador PIC Pablin II

Ahora, en Debug/Simulator Stimulus.../Clock Stimulus, en la celda Stimulus pin, elegimos RA2. En la secuencia de reloj High y Low anotamos 4 que, es la marca espacio de la señal o sea, el ancho del pulso H y L. Si fuera necesario, añadir los demás botones de tiempos pulsando Add.. y para aplicar todo esto, pulsamos sobre Apply. Por fin están configurados los estímulos.

Antes de empezar la simulación, se debe hacer un Reset de la simulación, imagen de la derecha.

Al pulsar el Reset, la simulación se inicializa y los valores de los registros empiezan a moverse según se ejecutan las instrucciones. En este momento debemos disponer cinco ventanas en pantalla; la de proyecto, para seguir el programa; la de registros, para ver la evolución de los mismos; la de memoria que,

permite ver los valores de memoria en uso y la de tiempos y estímulos, ver posición en la figura para su mejor apreciación.

LA SIMULACIÓN.

Es el momento de iniciar la simulación, en menú Debug/Run/Step se inicia el simulador en modo paso a paso, este modo nos permite apreciar el trasvase de información entre los registros que intervienen al ejecutar una instrucción, una vez iniciado y dependiendo del programa a simular, podemos optar por la opción de ejecución animada mediante Debug/Run/Animate o usar Ctrl+F9, que empezará desde el punto en el que se encuentre en ese momento hasta el final del programa. Si hubiera algún error, se produce una parada que muestra una ventan emergente indicando el motivo, para poder corregir el error.

El proceso de simulación podemos pararlo con una pulsación en el icono semáforo rojo, para seguir sólo pulsamos Ctrl+F9 y seguimos la tarea, debe seguirse el proceso para entender lo que ocurre con nuestro programa. En alguna ocasión el programa nos pide que se presione un pulsador o requiere una señal de entrada por una línea de un puerto, esto puede parecer un

Page 33: Programador PIC Pablin II

problema de, como interactuar con el programa.

Supongamos que el programa trata de un temporizador que, se pone en marcha cuando se aprieta el pulsador A que está en RA1, iniciando el retardo de 1 minuto, al termino del mismo se activa un LED indicando que ha transcurrido el minuto. En ese caso al simular el programa, se ejecutará hasta la instrucción del lazo de espera a que se presione el pulsador y no avanzará hasta que le llegue esa señal. Para interactuar, usamos una herramienta que genera ese pulso en RA1 y podremos seguir. Estamos en el lazo. 

Entonces abrimos la ventana Asincronus Stimulus y le ponemos RA1 en el primer botón y la opción Toggle, a continuación en la venta Clock Stimulus, ponemos lo que se indica en su apartado anterior que lo describe muy bien. Con esto, ya podemos seguir la simulación, las señales necesarias se producirán en el momento adecuado y se apreciará su efecto. Sin embargo, justo en nuestro programa se produce un retardo que para la simulación puede ser tedioso su seguimiento, no hay problema, está todo previsto en el MPLAB, en el menú Debug/Execute/Execute An Opcode..., elegimos la opción return y pulsamos Execute, en ese mismo momento habremos salido del lazo de retardo que nos retenía y seguirá la simulación si no hay otra condicionante.

OTRO MÉTODO.

Cuando haga la simulación de un retardo, como ya se ha comentado o ha de emplear largo tiempo en decrementar un registro, es interesante conocer esta posibilidad de Modificar que nos brinda el MPLAB.

Por ej. Estamos simulando un programa que crea una señal cuadrada a la salida RB0, para ello utiliza el TMR0 y la interrupción por desbordamiento del mismo, asignando el prescaler con un factor de división de 1/2. De esta forma las interrupciones saltarán a intervalos fijos de tiempo. Invirtiendo el estado de RB0 durante las interrupciones se conseguirá una onda cuadrada perfecta. 

Page 34: Programador PIC Pablin II

Cuando estemos ejecutando el código y lleguemos a la rutina 'hacer nada', nos detenemos y debemos acceder a File Registers Window , en el menú Window/File Registers, se verá el cuadro Ventana Registros. Si nos fijamos en el

código, el registro PCL está aumentando con cada instrucción, cuando llega a la rutina 'hacer nada', el valor es 08 como muestra la imagen, al detenernos el registro mantiene el valor, ahora vamos a modificar el valor de este registro, para reducir el tiempo de espera.

Con el botón derecho del ratón, hacemos un click justo sobre 08 y luego en File Register(s) como se aprecia en la imagen de la derecha y nos muestra un cuadro de

diálogo Modify (ver debajo). 1) En él seleccionar en Address, el registro que vamos a modificar, en este caso 01 2) en Data/Opcode el nuevo valor para ese registro en este caso ff (este valor hace que llegue al máximo de la cuenta), tal como se ve en esta imagen.  Y3) Luego le damos a Write (escribir) y se habrá modificado el valor del registro 0x01, para seguir la simulación.

Ahora si, le damos a F7 para ver que el registro adquiere el nuevo valor, con la siguiente F7, el registro se desborda y hace que el programa avance en su ejecución saliendo del lazo y saltando a la subrutina de servicio de interrupción (RSI) BCF INTCON,2 en la simulación, esto quiere decir que todo va correctamente y nos ahorramos una larga espera.

Que podemos decir de una temporización de 50 segundos, lo que hacemos allí es verificar que los respectivos registros (19h,1Ah, 1Bh, 1Ch y 1Dh) se decrementan con cada iteración del programa, de modo que, nuevamente nos encontramos ante un prolongado tiempo de espera para verificar una rutina que ha entrado en un lazo de retardo y ya conocemos su funcionamiento.

Con este ejemplo puede darse por aclarado el uso de algunas de las opciones que nos ofrece esta herramienta que es el MPLAB.

DESENSAMBLADOR.

En alguna ocasión cuando por motivos extraños, se pierde un listado en asambler (.asm) y solo dispones del listado en hexadecimal. La mejor forma

Page 35: Programador PIC Pablin II

de proceder para disponer del listado es usar un desensamblador, personalmente recomiendo el que viene integrado en el MPLAB.

El procedimiento es el siguiente:

En el menú File, ir a Import y elegir el archivo en hexadecimal (.HEX)

En el menú View, ir a Program Memory; dispone de tres opciones:    OPCODE HEX, MACHINE y SYMBOLIC.

Sobre la pantalla, botón derecho pulsar 'Output to file' para terminar.

"Vaya a FILE, IMPORT y elija el archivo .HEX que desee desensamblar. Luego vaya a VIEW, PROGRAM MEMORY y fíjese que abajo tiene 3 opciones. OPCODE HEX,  MACHINE , SYMBOLIC. Luego botón derecho sobre la pantalla '... Output to file' y listo ya puede tener un .asm del archivo elegido. Eso sí, luego será trabajo suyo determinar que es variable y que no lo es, etc."

 

Más adelante y si tengo tiempo abordaré este tema con más profundidad en el que hablare de cómo influir en el MPLAB para simular la acción de un pulsador o un interruptor, por ejemplo, aunque entiendo que ya hay artículos en la red que lo describen muy bien y desde aquí lo hago constar. Este párrafo lo redacté en 2005, en estos momentos ya se ha modificado para mejor.

Descripción del Juego de Instrucciones de los PIC16F84A

Sabado, 03 de Octubre del 2009__________________ Incluir en favoritos si quiere volver a visitarnos.

LOS REGISTROS(También llamados ARCHIVOS )

CARACTERÍSTICAS GENERALES DE LOS

Page 36: Programador PIC Pablin II

PIC16F84A.

Hay solo 35 instrucciones en el PIC16F84A, con códigos de instrucción de 14 bits de ancho. Todas las instrucciones ocupan una palabra y todas consumen un ciclo, excepto las de salto o bifurcación que usan dos. La velocidad máxima de funcionamiento 20MHz (200 ns x instr.). Típicamente a 4MHz (1us x instr.), con 1024 palabras (14 bits) de memoria de programa FLASH.

El PIC16F84A tiene 68 bytes de RAM y 64 bytes de EEPROM de datos, tiene 12 registros de función específica FSR. Con 8 niveles de Pila hardware y tres modos de direccionamiento: directo, indirecto y relativo. Dispone de cuatro fuentes de interrupción y  13 pines de E/S (puertoA de 5 bits y el puertoB de 8 bits), con control individual bidireccional y dispone de un Timer0/ Contador con reloj independiente y la gran ventaja dispone de Perro Guardián (WDT). Este dispositivo tiene otras particularidades que lo hacen seriamente aconsejable, algunas de estas se detallan en otros artículos de esta serie y en las hojas de características del fabricante Microchip.

El PIC16F84A tiene un contador de programa de 13 bits capaz de dirigir 8 kilobytes x 14 espacio de memoria de programa. Para el F84A, el primer 1 kilobyte x 14 (0000h-03FFh) físicamente es implementado (Figura 2-1). El tener acceso a una posición anterior de la dirección físicamente puesta en práctica causará un recirculado. Por ejemplo, para posiciones 20h, 420h, 820h, C20h, 1020h,

Page 37: Programador PIC Pablin II

1420h, 1820h, y 1C20h, la instrucción será la misma. El vector RESET (REPUESTO) está en la dirección 0000h y el vector INTERRUPT está en la 0004h, con cuatro fuentes de interrupción, véase el documento interrupciones descrito en estas páginas.

Hay dos bloques de memoria en el PIC16F84A, estos son la memoria de programa y la memoria de datos. Cada bloque tiene su propio bús, de modo que el acceso a cada bloque pueda ocurrir durante el mismo ciclo de oscilador. La memoria de datos adicional mayor puede ser direccionada en la RAM de objetivo general y los Registros de Función Especiales (SFRs). La operación de los SFRs que controla el "corazón" (reloj) está descrita aquí.

Los SFRs usados para controlar los módulos periféricos son descritos en la sección que habla de cada módulo individual periférico.

El área memoria de datos también contiene la memoria de datos EEPROM. Esta memoria no es mapeada directamente en la memoria de datos, pero es mapeada indirectamente. Es decir, un puntero de dirección indirecta, especifica la dirección de la memoria de datos EEPROM para lectura/escritura. Los 64 octetos de datos de la memoria EEPROM tienen la gama de dirección 00h-3Fh. Más detalles de la memoria EEPROM se pueden encontrar en la Sección 3.0 de las hojas de características.

La memoria de datos es dividida en dos áreas. La primera, es el área de Registros de Función Especial (SFR), mientras la segunda es el área de Registros de Propósito General (GPR). Los SFRs controlan el modo de operación del dispositivo. Partes de memoria de datos son mapeadas, esto es tanto para el área SFR como para el área GPR. El área GPR es mapeada para permitir una capacidad mayor de 116 bytes de RAM de propósito general.

Las áreas mapeadas del SFR son para los registros que controlan las funciones periféricas. Los bancos requieren el empleo de bits de control para la selección de banco. Estos bits de control son localizados en el Registro STATUS. En la figura 2-2 se muestra la organización de mapa de memoria de datos.

Las Instrucciones MOVWF y MOVF pueden mover valores del registro W a cualquier posición en la RAM al archivo de registro ("F") y viceversa. Se puede tener acceso directo a toda la memoria de datos utilizando la dirección absoluta de cada archivo de registro o indirectamente mediante los Registros de Función Especial (SFR). La dirección indirecta usa el valor actual del bit RP0 para el acceso en las

Page 38: Programador PIC Pablin II

áreas mapeadas de memoria de datos.

La memoria de datos es dividida en dos bancos que contienen los Registros de Propósito General y los Registros de Función Especial. El banco 0 se selecciona por el aclarado (0) del bit de RP0 (STATUS<5>). Al activar el bit RP0 se selecciona el Banco 1. Cada Banco se extiende hasta 7Fh (128 bytes). Las doce primeras posiciones de cada Banco son reservadas para los Registros de Función Especial. El resto, son Registros de Propósito General, implementados en la práctica como la RAM estática.

REGISTROS DE PROPÓSITO GENERAL GPR.

Cada Registro de Propósito General (GPR) es de 8 bits de ancho y es direccionado directa o indirectamente por los SFR. Las direcciones de GPR en el Banco 1 son mapeadas a direcciones en el Banco 0. Como un ejemplo, direccinando la posición 0Ch u 8Ch tendremos acceso al mismo GPR.

REGISTROS DE FUNCIÓN ESPECIAL SFR.

Los Registros de Función Especial SFR (Figura 2-2 y Tabla 2-1) son usados por la CPU y funciones periféricas para controlar la operación del dispositivo. Estos registros son la RAM estática.

Los registros de función especial pueden ser clasificados en dos juegos, central y periférico. Aquellos asociados con las funciones principales son descritos en esta sección. Aquellos relacionados con la operación de los rasgos periféricos son descritos en la sección para aquel rasgo específico.

Page 39: Programador PIC Pablin II

En otros artículos describiremos otros registros y su forma de uso, los bits que se usan y cómo influyen las banderas que activan. Por ahora, vamos a seguir con la descripción de las instrucciones que es el fondo de este documento. Veamos primero el formato de las instrucciones.

Page 40: Programador PIC Pablin II

A continuación vemos el juego de instrucciones de los PIC12CXXX, entre ambas.

Page 41: Programador PIC Pablin II

Debajo, muestro unas tablas originales del juego de instrucciones de los PIC16C/FXXX, resumidas.

Page 42: Programador PIC Pablin II

Esta es una tabla de las instrucciones extendidas (algunas macros), admitidas por el sistema MPLAB, que podemos usar en nuestros listados, para generar los programas propuestos, aunque no estén en las tablas del los PIC16FXXX, al compilarlos con el MPLAB, nos generan el código asm adecuado.

Page 43: Programador PIC Pablin II

Si buscamos en la carpeta donde instalamos el MPLAB (p.e. C:\Archivos de programa\MPLAB) la ayuda llamada DEVICE.HLP, podemos encontrar un listado completo de las instrucciones especiales que usa el MPLAB y que nos permitirán mejorar nuestros listados, esta es una muestra. Además, en las hojas de datos de Microchip, vienen todas las instrucciones de estos chips, quizás el lector piense, porqué me he tomado tantas molestias en plasmar aquí tanta información que ya existe, la razón es que, no está en castellano (español) o la que hay es muy técnica y no está al alcance de mucha gente, por otra parte, no creo que esté demás que alguien la exponga desde otro punto de vista.

NOTA.

1- La palabra Literal significa "NÚMERO" como el número 9 o 16h. El número 16h es un número exadecimal y en valores decimales esto representa el número: "veintidós".  2- Destino de la instrucción según el designador OP: Si el bit de código OP de la instrucción es 0, el destino es W y si es 1, el destino es el registro f, o sea, se selecciona el destino donde se guarda el resultado de una operación.

Page 44: Programador PIC Pablin II

Nota2. Cuando una instrucción termina con W el destino del resultado será el registro W, o termina con F el destino del resultado será el registro el archivo f, se define con el designador '0' o '1' de la propia instrucción.

                0 = W                1 = F 

Por ej.:     ADDWF 1F,0 el resultado es almacenado en el registro de trabajo W.                   ADDWF 1F,1 el resultado es almacenado en el mismo registro (F).

Seguidamente se hace una descripción detallada de las instrucciones que, son generales para todos los PIC's, además de las particularidades de cada instrucción, por orden alfabético que, presentan para cada micro tanto para el PIC16F84A como para el PIC12C508A.

NOTA. Se usaran algunos términos extraños para acomodar (agilizar) algunas expresiones anglosajonas. 

Ej.: AND'ed para expresar la aplicación de la operación de producto lógico (AND) entre dos términos o            XOR'ed que se aplica a la operación lógica OR exclusiva (XOR) entre dos términos.

El lector, deberá diferenciar entre el nombre del registro/[archivo] y el contenido del registro/[archivo].

ADDLW Esto significa: Agregar (sumar) el Literal al registro W (acumulador o registro de trabajo) resultado en W. ADDLW 00 al  FF Un número fijo (llamado literal) es sumado al registro W (registro de trabajo). El literal (número) puede estar comprendido entre el 00 y FF. En el registro STATUS se ven afectadas tres banderas (o flags) por la orden ADDLW (Z, DC y C), ver debajo.

C    Se pone a 1 si se produce un acarreo desde el bit de mayor peso (desbordamiento).DC Se pone a 1 si se genera un acarreo del bit 3 al bit 4.Z     Se pone a 1 si el resultado de la operación es cero.

Esta instrucción no está disponible para el '508A. Si quiere usar esta instrucción en el '508A o un programa en él la requiere/contiene, emplee las 3 instrucciones siguientes:

Por ejemplo  en el F84:

    ADDLW 80            ; mueve 80h a W

Sustitúyala en el '508A por:MOVWF 13h ; Mueve W a cualquier archivo MOVLW 80h ;poner 80h en W ADDWF 13h ;sumar el archivo 13h a W

Page 45: Programador PIC Pablin II

ADDWF Esto significa: Suma aritmética de W y un archivo (f).ADDWF 00 a 1F,0 El resultado es almacenado en el registro de trabajo W, debido al valor 0 en la instrucción.ADDWF 00 a 1F,1 El resultado es almacenado en el mismo archivo, debido al valor 1 del designador en la instrucción.

ADDWF (sumar) el contenido del registro W con el contenido de un archivo. El resultado puede ser guardado en el registro W (designador = 0) o emplazado en el archivo llamado (designador = 1). Con la orden ADDWF, en el registro STATUS se ven afectados los bits: C (Carry), Z (Cero) y el DC (Dígito Carry).

Si el resultado de una instrucción ADD rebasa FF, la bandera C (Carry) es puesta a 1, si tiene cualquier otro valor es 0. Si el resultado de una instrucción ADD es cero 0000 0000, la bandera Z (Cero) se pone a 1 y 0 si tiene cualquier otro valor.

La suma se realiza en aritmética binaria pura y sin signo. Si hay un (desborde) acarreo del bit 7, es decir que el resultado es mayor de 255, el bit C (bandera Carry) resulta 1, en caso contrario resulta 0. El PIC supervisa si hay acarreo del bit 3, es decir que, la suma de los dos mitades (nibbles) menos significativas (bits 0 a 3) resulta mayor de 15, el bit DC (digit carry) se pone a 1, en caso contrario se pone a 0.

Por ejemplo: Si agregamos 21h a 3Ch, el resultado es 5Dh, esto no afecta  la bandera Carry, por lo que la bandera DC (dígito carry) será puesta a 1, pero si a 2Dh le agregamos 3Eh, el resultado es 6Bh, lo que desborda el contador (6B>FF) por lo que la bandera C (Carry) será puesta a 1. Ejemplos : banderas banderas 1010 0010 1101 0000 + 0100 1111 C DC Z + 0110 1111 C DC Z 1111 0001 0 1 0 0011 1111 1 0 0

ANDLW   Esto significa: producto lógico AND del Literal con el registro W. Ver también ANDWF.ANDLW 00 a FF El objetivo de la operación es, descubrir cuantos bits de L y W, en binarios están a 1. Si ambos bits son cero, el resultado es cero y la instrucción usada en este caso es XOR. Esta instrucción hace un AND lógico entre un número fijo (literal) y el contenido del registro W, el resultado es colocado en el registro W. Con la orden ANDLW, en el registro STATUS se ven afectados los bits: C (Carry), Z (Cero) y el DC (Dígito Carry). El literal puede ir de 00 a FF.

La operación AND puede decirse que se usa para enmascarar (separar o quitar) los bits que nos interesen. Por ejemplo: 

  0Fh enmascarará (quita) los cuatro bits altos (nibble alto) y   F0h quitará los cuatro bits bajos (nibble bajo). Veamos como se usa:

Page 46: Programador PIC Pablin II

Utilización del 0Fh:  ANDLW 0x0F      Primer número:               1001 0011 [Número en W anterior

a la instrucción ANDLW]     Segundo número (0F):    0000 1111 [Número L Máscara]       Respuesta al AND:         0000 0011 [Al aplicar la función AND entre ambos] (ANDed)

Utilización del F0h:  ANDLW 0xF0      Primer número:              1001 0011  [Número en W anterior a la instrucción ANDLW]      Segundo número (F0):  1111 0000  [Número L Máscara]       Respuesta al AND:        1001 0000  [Al aplicar la función AND entre ambos] (ANDed)

ANDWF   Esto significa: Operación AND producto lógico de W con el archivo f [ AND'ed entre W y f]. Ver también ANDLW.ANDWF 00 a 1F, 0 El resultado se almacena en el registro W, por el valor 0 en la instrucción.ANDWF 00 a 1F, 1 El resultado se almacena en el archivo f, por el valor  en la instrucción.

Al registro W se le aplica el producto AND con un archivo f. Como dos archivos juntos no se pueden operar (AND), un archivo debe ponerse en W y se hace AND con el segundo archivo. Véase arriba para hacer operaciones de enmascarar con la operación AND. Con la instrucción  ANDWF, sólo se afecta la bandera Z (cero). Si la respuesta es cero, la bandera Z en el registro STATUS se pone a 1, si la respuesta es distinta de cero, la bandera se pone a 0.

BCF Esto significa: Bit Clear File (pon a "0" o aclara el bit indicado (detrás de la coma) en el archivo f ). Ver también BSF.BCF 00 a 1F, bit Hay sobre 300 instrucciones (incluidas en los micros, trabajando internamente) para esta orden. Hay 79 archivos en el PIC16F84A, los 13 primeros archivos se llaman Registros de Función Especial (SFR's), el resto (66) se llaman Archivos de Propósito General (GPR's) del 0Ch a 4Fh. No afecta los bits de STATUS.

BCF se usa para limpiar [clear] un bit (pone a 0 el bit identificado en el archivo f). Por ej.: BCF 06h,5  significa que el bit 5 del archivo 06 debe ser puesto a "0" (aclarado), el resto de bits no se influyen. Ver figura de la derecha. El archivo 6 contiene líneas de E/S comúnmente se llaman I/O del puerto.

BSF Esto significa: Bit Set File (poner a 1 el bit indicado, en el archivo f). Ver también BCF.

Page 47: Programador PIC Pablin II

BSF 00 a 1F, bit Hay casi 300 instrucciones para esta orden. Hay 79 archivos en el PIC16F84A, de las que los primeros 13 son los SFR's y los siguientes 66 son los conocidos GPR's. Estos GPR's ocupan del 0Ch al 4Fh y cada uno tiene 8 bits. BSF significa poner a 1 lógico el bit especifico en el archivo f. No afecta los bits de STATUS.

Por ejemplo: BSF 06h,5 indica que el bit 5 del archivo 6 será puesto a 1, este archivo 6 contiene 8 líneas E/S, comúnmente se llaman líneas I/O del puerto. El resultado es la inversa a la instrucción anterior, el 0 se sustituye por un 1.

BTFSC Esto significa: Bit Test, Skip if Clear ( Bit de Test, Salta si es "0").BTFSC 00 a 1F, bit Hay casi 300 instrucciones para esta orden, para cubrir los 79 archivos, cada uno con 8 bits. BTFSC significa, comprobar el bit identificado en el registro llamado y si es 0 saltar una instrucción (no ejecuta la instrucción que sigue).  No afecta los bits de STATUS.

Se ve mejor con un ejemplo: BTFSC 06h,4 es la forma de comprobar si el bit 4 en el archivo 6 es "0", si es cero, salta la próxima instrucción (pasar sin ejecutar) y continuar con la posterior.

Etiqueta: BTFSC 06h,4       ; comprueba si el bit 4 es 0                  GOTO Etiqueta2  ; si no es 0, salta hasta Etiqueta2                  CALL Dlay            ; si es 0, llama a subrutina Dlay.

BTFSS Esto significa: Bit Test, Skip if Set (Bit de Test, Salta si es "1"). BTFSS 00 a 1F, bit También hay casi 300 instrucciones para esta orden, para cubrir los 79 (4Fh) archivos, cada uno con 8 bits. BTFSS significa, comprobar el bit identificado en el registro llamado y salta la próxima instrucción si es 1. No afecta los bits de STATUS.

En BTFSS 3,2 comprobamos el bit 2 del registro 3 y si dicho bit es 1, salta la próxima instrucción, si no, continua con la siguiente.

Etiqueta: BTFSS 03h,2           ; comprueba si el bit 2 es 1                 GOTO Etiqueta2      ; si no, va a Etiqueta2                 CALL Dlay                ; si es 1, llama a subrutina Dlay para seguir. ; si es 1 viene a esta instrucción y sigue.

CALL Esto significa: Llamada incondicional a subrutina. 

En un programa, esto se escribe como: CALL Salida o CALL Tono1, etc. donde Salida o Tono1 son etiquetas. Un RETURN debería encontrarse al final de la subrutina CALL para que el micro vuelva a la siguiente instrucción después de la instrucción CALL que la llamó, de lo contrario se producirá un desborde de pila, con el consiguiente bloqueo del programa. No afecta los bits de STATUS.

CALL Etiqueta Los programas deberían ser escritos de forma que las

Page 48: Programador PIC Pablin II

pocas primeras instrucciones pongan al micro en el Inicio de Programa Principal. El "Programa Principal" se localizará físicamente al final del listado y éste puede estar en el final de la memoria o a mitad del camino, si el programa es aproximadamente 250 bytes de largo. 

Después de las primeras instrucciones que llevan al micro a: GOTO Inicio, se colocan todas las subrutinas necesarias para el programa. Con una orden CALL se llamará a las subrutinas y al final de cada subrutina debe tener una instrucción RETURN. Una llamada remota puede hacer de subrutina pero esta segunda subrutina no puede llamar otra subrutina.

Cada vez que se ejecuta una instrucción CALL, un valor de dirección es colocado (empujado) en la Pila (Stack), entonces el micro sabe donde volver después de ejecutada la subrutina, la Pila sólo puede tener 8 niveles de alto, entonces es necesario llevar cuidado para no quedarse sin Pila (Stack). Ver también GOTO, RETURN y RETLW. Ejemplo: Loop2: BTFSS 05,2 ;¿esta apretado el pulsador? GOTO Loop2 ;No. Salta a Loop2 MOVLW 01 ;SÍ. XORWF 06,1 ; encender el LED

CALL Delay ;Llamada a rutina de Retardo GOTO Loop1 ; para ver LED encendido.

Delay: DECFSZ 1Bh,1 ; Subrutina anidada de Retardo GOTO Delay ; retardo exterior DECFSZ 1Ch,1 ; retardo interior GOTO Delay RETURN

CLRF Esto significa: Clear f [Limpia f] (poner a 0 los 8 bits del archivo f)CLRF 00 a 1F El contenido de un archivo se pone a 0 (Clear) y el bit Z del registro STATUS es puesto a 1, esto es, los ocho bits  se ponen a "0". Por esto hay que tener en cuenta el bit Z (cero, flag Z). Los 12 primeros archivos son SRF's y los siguientes 68, del 07h al 4Fh son los llamados GPR's.

CLRW Esto significa: Clear W (limpiar el registro de trabajo - llamado acumulador en otros micros)

CLRW El registro W (de trabajo) es aclarado, todos los bits son puestos a 0. Cuando el W es puesto a 0, la bandera cero (flag Z) es puesta a 1, en otras palabras la bandera Z del registro STATUS es puesta a 1.

CLRWDT Esto significa: aClarado (puesta a 0) del Temporizador Perro Guardián (El bit WDT = 0).

CLRWDT La instrucción repone (resetea) el Temporizador Perro Guardián, esto también repone el preescaler del WDT y consume 2 ciclos maquina. Ejemplo:

Page 49: Programador PIC Pablin II

Operación: 00h → WDT 0 → WDT prescaler, 1 → TO 1 → PD Afecta Status: TO, PD

COMF Esto significa: Complemento del archivo f.

COMF 00 a 1F,0 El resultado estará en W por el valor 0 detrás de la coma.

COMF 00 a 1F,1 El resultado estará en f. El contenido f es complementado (los 0's se cambian a 1's y los 1's a 0's).

DECF Esto significa: Decremento del archivo f . 

DECF 00 a 1F,0 El resultado estará en W. El contenido del archivo f es decrementado y puesto "W".

DECF 00 a 1F,1 Aquí, el resultado estará en f. El contenido del archivo "f" es decrementado, significa que es deducido (tomado) 1 del archivo. Si el archivo es 0000 0000 esto da la vuelta a 1111 1111 (255) afectando a la bandera Z. Cuando el archivo es 0000 0001 y se ejecuta una instrucción DECF, el archivo pasa a 0000 0000 y la bandera Z (cero) del STATUS se pone a 1, en otro caso es 0.

DECFSZ Esto significa: DECrement f, Skip if Zero (Decrementa el archivo f y salta si es 0). 

DECFSZ 00 a 1F,0 El resultado estará en W.

DECFSZ 00 a 1F, 1 El resultado estará en f. La instrucción DECFSZ tiene muchos empleos. Un empleo importante está en una subrutina de retardo. En esta rutina la instrucción DECFSZ crea un lazo en el que el micro es enviado a una instrucción por encima-del-programa y se ejecutará un juego de instrucciones una y otra vez, esta es una táctica de perdida de tiempo para crear un retardo. No afecta al registro STATUS.

Cada vez que el micro llega a DECFSZ, el contenido del archivo es decrementado y si el archivo no es cero, se ejecutará la siguiente instrucción en el programa. La siguiente instrucción es normalmente GOTO y ésta envía de nuevo al micro por encima-del-programa. Por ej.:

ret:     DECFSZ 0Ch,0         ; Decrementa 0C y si es 0, salta una línea            GOTO ret                  ; no es 0, ejecuta esta línea            ...                             ; si es 0, viene hasta aquí.            ...                             ;sigue programa

GOTO Esto significa: Bifurcación Incondicional.

GOTO k  GOTO es la bifurcación incondicional en la que el micro es

Page 50: Programador PIC Pablin II

enviado a la dirección especificada. Esta instrucción carga simplemente la constante k en el registro PC (contador de programa). Esta es la típica instrucción de salto incondicional a cualquier posición de la memoria de programa. La constante literal k es la dirección de destino del salto, es decir la nueva dirección de memoria de programa a partir de la cual comenzarán a leerse las instrucciones después de ejecutar la instrucción GOTO. No afecta al registro STATUS.También se usa $-n o $+n donde n es el número de líneas que ha de, volver atrás o avanzar en el programa. Por ej.  ret DECFSZ 0Ch,0     ; decrementa 0Ch, si es 0 salta 1 instrucción         GOTO $-1           ; No, vuelve 1 línea atrás. No requiere etiqueta.         ...                       ; Si, sigue programa

INCF Esto significa: Incrementar el archivo f.

INCF 00 a 1F,0 El resultado del incremento estará en W.

INCF 00 a 1F,1 El resultado estará en f. El contenido del archivo 'f' es incrementado, esto simplemente significa que se agrega 1 al archivo, si el archivo es 1111 1111 (255) esto da la vuelta a 0000 0000. Cuando el archivo es FFh y se ejecuta la instrucción INCF, el archivo pasa a 0000 0000 y la bandera Z (cero) es puesta a 1 en otro caso es 0.

INCFSZ Esto significa: INCrement f and Skip if 0 (Incrementar el archivo f y salta si es 0).

INCFSZ 00 a 1F,0 El resultado estará en W.

INCFSZ 00 a 1F,1 El resultado estará en f. Normalmente la función de decremento DECFSZ se usa para crear un retardo, pero también se puede usar un INCFSZ. No afecta al registro STATUS.

Esto trabaja así: Si el contenido de un archivo es incrementado y el resultado no es 0, entonces la siguiente instrucción es ejecutada con un GOTO una dirección anterior y ejecutará otro INCFSZ. Eventualmente el archivo será 1111 1111 y el próximo incremento lo devolverá a 0000 0000, el resultado será cero y la instrucción GOTO será ignorada, ejecutándose la siguiente instrucción.

IORLW Esto significa: Inclusive OR Literal con W.

IORLW 00 a FF El contenido del archivo W es sumado (lógico) [OR'ed] con un número. El resultado es colocado en registro de trabajo W, el número literal puede ser desde 00 a FF. Afecta al bit Z del registro STATUS.

Esto es simplemente una operación OR (suma lógica) y el objeto de su realización es cambiar dos o más bits a "1", si un bit es ORed con 0, la respuesta no se altera, si el bit es ORed con 1, el resultado es 1.

Ejemplo: Si el registro W  

Page 51: Programador PIC Pablin II

                se carga con  1111 0000 (es una máscara de 4 bits altos F0h) y            un número como   0100 1110 (4Eh) es ORed con W,              el resultado es  1111 1110 (FEh).

IORWF Esto significa: Inclusive OR con el archivo f

IORWF 00 a 1F,0 El resultado estará en W.

IORWF 00 a 1F,1 El resultado estará en f. El contenido del registro W es ORed con el archivo f, esto simplemente es una operación "OR" y el objeto de su realización es cambiar dos o más bits a "1". Si un bit es ORed con 0, la respuesta no se altera, si el bit es ORed con un 1 el resultado es 1. Afecta al bit Z del registro STATUS.

Ejemplo: Si el registro W es cargado con 1111 0000 (F0h es una máscara de 4 bits altos) y un                     archivo con un número como 0100 1110 (4Rh) es ORed                              con W, el resultado es 1111 1110 (FEh).

MOVF Esto significa: Mueve el contenido del archivo 00 a 1F dentro y fuera del archivo o al W.

MOVF 00 a 1F,0 El contenido del archivo es movido al W. El resultado estará en W.

MOVF 00 a 1F,1 El resultado estará en f. Para esta instrucción MOVF 00 a 1F,1 el contenido es movido fuera del archivo y devuelto a él otra vez, pero no entra en W. Esto es una prueba útil ya que la bandera Z (cero) del STATUS se ve afectada. Si el contenido es cero, la bandera Z es puesta a 1, si el contenido es 1, la bandera Z es 0.

MOVFW  Esta instrucción no es correcta y sin embargo el MPALB la admite. Porque ocurre esto.   MOVFW 00 a 1F La instrucción:  MOVFW    PORTB es una macro del MPLAB que significa mueve el contenido del PORTB al registro de trabajo W, esto lo mismo que escribir esta instrucción más correcta: MOVF   PORTA,W con esto evitamos confusiones.  De modo que, las instrucciones: MOVF   FF,W    y    MOVFW    FF    son idénticas.

MOVLW  Esto significa: Mueve Literal a W.

MOVLW 00 a FF Un número f (Literal) es cargado en el registro W. El Literal puede ser 00 a FF. No afecta al registro STATUS.

MOVWF Esto significa: Copia W al archivo llamado f.

MOVWF 00 a 1F Esta instrucción copia datos del registro W al archivo f. No afecta al registro STATUS.

Page 52: Programador PIC Pablin II

NOP Esto significa: Ninguna operación. Es decir, el micro no realiza ninguna operación, sólo consume el tiempo de 1 instrucción.

OPTION Esto significa: Carga registro OPTION. El contenido del registro W es cargado en el registro OPTION.

RETFIE Esto significa: Cuando hay una interrupción, RETURN con valor de lo alto de la Pila y lo deja en el PC.RETFIE Carga el PC con el valor que se encuentra en la parte superior de la pila, asegurando así la vuelta de la interrupción. Pone a 1 el bit GIE, con el fin de autorizar o habilitar de nuevo que se tengan en cuenta las interrupciones. TOS → PC, 1 → GIE. No afecta al registro STATUS.

RETLW Esto significa: RETURN con Literal en W.

RETLW 00 a FF El registro W es cargado con el valor del literal, normalmente devuelve un dato procedente de una tabla. El Contador de Programa (PC) es cargado de la cima de la pila (Stack), que corresponde a la dirección de RETURN de programa. No afecta al registro STATUS.

RETURN Esto significa: Retorno de Subrutina. Esta instrucción está al final de una rutina o subrutina. No afecta al registro STATUS.

RLF Esto significa: Rotar el archivo f a Izquierda con aCarreo (Carry).

RLF 00 a 1F,0 El resultado se almacena en W.

RLF 00 a 1F,1 Resultado se almacena en f. El contenido de un archivo, es rotado un bit a la izquierda por la bandera Carry (acarreo), esto requiere de 9 desplazamientos para recuperar el valor original del archivo. Afecta al bit C del STATUS.El uso de: RLF.....Reg, Destino........; rota los bits de un registro un lugar la izquierda.   

Si Reg = b'00010110'

Después de la instrucción: Reg = b'0010110C'  donde C es el valor del bit STATUS,C en el momento de ejecutarse la instrucción RLF.Veamos en mas detalle, cómo trabaja la función RLF:Un grupo de 8 bits es registro, o sea:     Registro = B7 B6 B5 B4 B3 B2 B1 B0Al aplicar la instrucción RLF.....Reg,F   ocurre que: (STATUS,C <== B7) <== B6 B5 B4 B3 B2 B1 B0 (C <== STATUS,C)

Esto significa que, todos los bits de Reg son rotados (desplazados) una

Page 53: Programador PIC Pablin II

posición hacia la izquierda. El espacio generado a la derecha de Reg es decir, el bit0 (B0) del registro, es ocupado por el valor que tenía en ese momento el bit C del registro STATUS. A su vez, el Bit7 (B7) de Reg sale del Registro y se rellena con el bit C del registro STATUS.

Repasemos otra vez. Reg = b'00001100' (Ch = .12) y STATUS,C = 0Aplicamos;  RLF Reg,F   Entonces: Reg = b'00011000' (18h = .24) y STATUS,C = 0

Podemos comprobar que antes de aplicar la RLF, Reg valía 12 en sistema decimal. Después de la instrucción RLF Reg vale 24. Hemos multiplicado a Reg por dos, utilizando la instrucción RLF. Ahora, consideremos el siguiente caso:

Reg = b'00001100' (Ch) y STATUS,C = 1Aplicamos;  RLF Reg,F   Entonces: Reg = b'00011001' (19h = .25) y  STATUS,C = 0

En este caso, antes de la aplicación de RLF Reg valía 12 en decimal y después de aplicar la instrucción Reg vale 25 en decimal, por qué ocurre este error si hemos aplicado la misma instrucción al mismo registro Reg. Debemos considerar el motivo.

El motivo radica en que el bit C  del registro STATUS, antes de ejecutar la instrucción RLF, valía 1, en el segundo caso y ocupó el bit0 del Reg al ejecutar la instrucción RLF. Por tanto, en este segundo caso, al hacer RLF Reg,F equivale a hacer Reg * 2 + 1.

Precauciones a tener en cuenta para evitar incurrir en este error. Para asegurarnos en una multiplicación por dos, siempre limpiaremos el bit C del STATUS antes de aplicar la instrucción RLF, asegurándonos así que el bit STATUS,C no "corrompa" la operación.

Ej.:  BCF STATUS,C          ;Limpiar STATUS,C para asegurar que no "ensucia" la multiplicación        RLF Registro,F           ;y ahora, si. Rotar el Registro a la izquierda.

Se puede rotar más veces a la izquierda, lo que en buena lógica es lo mismo que hacer Reg * 2 * 2, etc.

RRF Esto significa: Rotar el archivo a la Derecha por Carry (aCarreo).

RRF 00 a 1F,0 En este caso el resultado se almacena en W.

RRF 00 a 1F,1 Y en este el resultado se almacena en f. El contenido de un archivo es rotado un bit a la derecha por la bandera Carry (acarreo), esta instrucción corrompe el registro al introducir el valor de C en el bit7, por tanto, debemos usar una instrucción de aclarado del bit C antes de usar RRF, otro modo de lograr esto, requiere de 9 desplazamientos para recuperar el valor

Page 54: Programador PIC Pablin II

original del archivo.

La instrucción: RRF Reg,Destino       ; rota los bits de un registro un lugar hacia la derecha.

Veamos: Reg = b'00011000' (18h = .24)

Aplicamos:    RRF Reg,F        y    Reg = b'C0001100'

Donde C es el valor que tenía el bit C de STATUS en el momento de ejecutar la instrucción RRF. Veamos en detalle cómo trabaja la función RRF:

Sabemos que un grupo de 8 bits es registro, o sea: Registro = B7 B6 B5 B4 B3 B2 B1 B0

Al aplicar la instrucción:   RRF.....Reg,F   ocurre que: (STATUS,C ==> C) B7 B6 B5 B4 B3 B2 B1 ==> (B0 ==> STATUS,C)

Esto significa que todos los bits de Reg son desplazados una posición hacia la derecha. El espacio generado a la izquierda de Reg, es decir, el bit7 (B7) de registro, será ocupado por el valor que tenía en ese momento el bit C del registro STATUS. A su vez, el Bit0 (B0) de Reg sale de Reg y rellena el bit C del registro STATUS.

Supongamos que:  Reg = b'00011000' (18h = .24)  y STATUS,C = 0

Al aplicar:   RRF Reg,F     Reg = b'00001100' (Ch = .12)  y STATUS,C = 0

Aquí, podemos comprobar que antes de aplicar la RRF, Reg valía 24 en sistema decimal. Después de la instrucción RRF Reg vale 12, por lo que hemos dividido a Reg por dos, utilizando la instrucción RRF. Sin embargo, veamos el caso en el que:

Reg = b'00011000' (18h = .24) y STATUS,C = 1

Al aplicar:   RRF Reg,F     Reg = b'10001100' (8Ch = .140)  y STATUS,C = 0

En este caso Reg, antes de la instrucción RRF valía 24 en sistema decimal. Y después de la instrucción RRF Reg vale 140. Este error ocurre por que el bit C de STATUS, en este caso, antes de ejecutar la instrucción RRF valía 1, el cual al ejecutar la instrucción RRF, ocupó el bit7 del registro Reg.

Debemos considerar el motivo para evitar incurrir en este error, difícil de depurar. Para asegurar una división por dos, limpiaremos el bit C del registro STATUS antes de realizar cualquier instrucción RRF y asegurarnos que el bit STATUS,C no "corrompa" la división.

Ej.: BCF STATUS,C            ;Limpia STATUS,C para asegurar que no "corrompe" la división         RRF Registro,F             ;y ahora si. Rota el Registro a la derecha.

Por la misma lógica rotar dos veces a la derecha un registro equivale a decir

Page 55: Programador PIC Pablin II

Registro / 2 / 2, lo que simplificado es Registro / 4, y así sucesivamente.

SLEEP Esto significa: SEELP (Dormir, bajo consumo). Pone a 0 el flag PD# (Power Down) y el flag TO# (Timer Out) se pone a 1. O sea, el bit de estado de energía-baja es aclarado, el bit de estado de interrupción es puesto a 1, el Temporizador Perro Guardián y su preescaler son aclarados (puestos a 0) y el procesador es puesto en el modo Sleep (bajo consumo) con el oscilador parado.

Para salir de este estado, es necesaria una de estas causas:      Provocar un Reset activando el MCLR.      Por desbordamiento del WDT (Watchdog) si quedo operativo en el modo reposo.      Generando una interrupción distinta a TMR0 ya que ésta se desactiva con la propia instrucción SLEEP.

SUBLW Esto significa: Restar W del Literal. 

SUBLW 00 a FF EL registro W es restado (método de complemento a 2) del valor Literal, el resultado es colocado en el registro W. Esta instrucción no está disponible en el juego de instrucciones del '508A, usar estas 5 instrucciones, ejemplo: SUBLW 80h. Sustituir por: MOVWF 13h ;Mover W a cualquier archivo MOVLW 80h ;Poner 80h en W MOVWF 14h ;Mover W a cualquier archivo MOVF 13h,0 ;Mover 13h a W SUBWF 14h,0 ;Restar W del archivo 14h

SUBW F Esto significa: Restar W del archivo.

SUBWF 00 a 1F,0 El resultado estará en W.

SUBWF 00 a 1F,1 El resultado estará en f. Restar por el método de complemento a 2, el registro W del archivo (de 00 a 2F).

SWAPF Esto significa: Swap Nibbles (intercambio de bits) en el archivo f.

SWAPF 00 a 1F,0 El resultado estará en W.

SWAPF 00 a 1F,1 El resultado estará en f. Los nibbles (niveles) superiores e inferiores de un archivo 00 a 1F son cambiados.

TRIS 06 o solamente TRIS   Esto significa: Carga Registro TRIS. Ver también OPTION 0DFh en la Biblioteca de Rutinas. 

Esta instrucción carga a TRIS con el contenido de W, usamos TRIS 06 para

Page 56: Programador PIC Pablin II

recordar que se está refiriéndose al PuertoB (determinando la naturaleza de Entrada/Salida de cada una de las líneas) cuando el programa se transfiere a un PIC F84.

Las dos instrucciones de configuración (set-up) son:

          MOVLW  xxh        ;Cargar W con un valor literal (recordar que para el '508A el Bit3 [GP3] debe ser 1).

          TRIS 06                ;Cargar TRIS con el valor de W.

Nota: El '508A sólo tiene 6 líneas en el puerto y usa sólo los 6 bits inferiores. Si W es 0000 1000 todas las líneas son salida excepto GP3, ya que GP3 sólo puede ser ENTRADA.

Si se requiere usar la instrucción TRIS en un '508A, son necesarias las siguientes 4 instrucciones:           BSF 03,5         ;Seleccionar pagina 1

           MOVLW 08     ;Haga GP3 entrada           MOVWF 06     ;Cargar el archivo TRIS (como estamos en page1, esto no es salida port 6)            BCF 03,5         ;Seleccionar Page0

XORLW Esto significa: Exclusivo OR Literal con W.XORLW 00 a FF El contenido del registro de W es XOR'ed con un valor literal (el contenido de W se hace un XOR lógico con el valor literal), el resultado es colocado en el registro W.

XORWF Esto significa: Exclusivo OR W con el archivo f.

XORWF 00 a 1F,0 El resultado estará en W.

XORWF 00 a 1F,1 El resultado estará en f. Exclusivo OR del contenido del registro W con un archivo (00 a 1F).

Con esto, damos por terminada la descripción de las instrucciones para la familia PIC. En próximos artículos pondremos en acción los conocimientos adquiridos en este artículo, sin embargo personalmente recomiendo que se haga una copia en papel para tener a mano en sus proyectos, esto le facilitará el proceso de programación ayudándole a recordar la función de las instrucciones y ganará tiempo en sus proyectos.

JUEGO DE INSTRUCCIONES

Page 57: Programador PIC Pablin II

de los PIC Hoy: 3 Octubre 2009.                Incluir en favoritos, para volver a visitarnos.         

Creado por: V. García.

Juego Reducido de Instrucciones (RISC) de  los PIC.

Como se indica es un juego reducido de instrucciones sólo son 35, así que, no nos resultará demasiado complicado manejar estas pocas instrucciones, aunque es cierto que no es necesario retener en la memoria qué hace cada una, esto resultaría una extrema labor para cualquiera de nosotros y no es esto lo que se pretende, se trata de disponer de una referencia a la que acudir, en caso de dudas y continuar con nuestro trabajo que es la programación. Para lograr cierta soltura a la hora de programar, es muy conveniente realizar cuantas más practicas mejor, sólo con la practica se puede lograr la agilidad en cualquier disciplina.

Una forma de familiarizarse con las instrucciones que aquí se describen, es utilizar las librerías de rutinas y tratar de comprender el motivo por el que se ha usado cierta instrucción y no otra que se nos haya ocurrido. Por cierto, es interesante usar las rutinas que se entregan y procurar adaptarlas a las características y circunstancias que nos convengan en cada aplicación, el motivo es que estas rutinas sabemos que funcionan por lo tanto será mejor aprovechar un trabajo hecho y comprobado frente al riesgo de la aventura. Y sin más preámbulos empecemos con las instrucciones.

Términos resaltados en Rojo indican que no tienen correspondencia con el '508A.  

ADDLWADDWFANDLWANDWFBCFBSFBTFSCBTFSS

CALLCLRF CLRWCLRWDTCOMFDECFDECFSZ

GOTOINCFINCFSZIORLWIORWF

MOVFMOVLWMOVWFNOPOPTION

RETFIERETLWRETURNRLFRRF

SLEEPSUBLWSUBWFSWAPFTRISXORLWXORWF

NOTACIÓN PARA NÚMEROS

Siempre dependerá de la herramienta en uso, normalmente se usa lo que sigue:

Decimal :  '100D'  ó  .100 Hexadecimal  : '64H'  ó  0x64  ó  64h

Page 58: Programador PIC Pablin II

Octal : '144O' o 144O Binario : '01101100b' ASCII :  'C'

NOTACIÓN PARA REGISTROS Y LITERALES w : Registro W, es el registro de trabajo, similar al acumulador. f  : Campo de 5 bits (fffff),contiene la dirección del banco de registros,

que ocupa el banco 0 del área de datos.        Direcciona uno de esos registros.

k : Representa una constante de 8 bits. d : Bit del código OP de la instrucción. Si d=0, el destino es W, y si

d=1 el destino es f. O sea, en la instrucción se selecciona el destino donde se guarda el resultado de la operación.

b : Determina la posición de un bit dentro de un registro de 8 bits, (o sea, tomará valores entre 0 y 7)

FLAGS

Los Flags o banderas son marcadores, representados por bits dentro del registro STATUS, y son resaltados en la tabla siguiente:

     P

A2P

A1P

A0T

O#P

D#Z

DC

C

      - - - - - X X X Z   : Flag (bandera) Zero, se pone a 1 cuando una operación lógica o aritmética da 0

(cero) como resultado. En cualquier otro caso se pone a 0. C  : Flag (bandera) Carry, se pone a 1 cuando la operación que le afecta sobrepasa

el nivel de representación del procesador, en nuestro caso es de 8 BIT's, de esta manera si sumamos a 11111111b un 00000011b el resultado sería 00000010b mas 1 y el Bit Carry pasaría a 1 para advertir de esta circunstancia. En otras palabras, cuando se rebasa la cuenta de 255 y pasa por 0 en la cuenta el Bit Carry se pone a 1.

DC : Flag carry del nibble inferior, este se comporta igual que el Bit Carry, solo que el límite de representación son los 4 bits inferiores, de esta manera si tenemos 00001111b (0Fh) y sumamos 00000111b (07h), el resultado será 00010110b y el Bit DC se pone a 1, el Bit Carry estará a 0 al no superarse los 8 bits y el Bit Z a 0 al ser el número diferente de 0.

Procure entender y no le queden dudas respecto a los FLAGS, éstos conceptos son esenciales, no obstante ya se aclararán en la medida que vaya avanzando en los artículos que siguen. Sobre todo se recomienda que revise los estados de los registros mediante herramientas como MPASM, cuando lea el artículo sobre el uso de esta herramienta que de uso libre, se aclararán las posibles dudas.

NIBBLES

Todos los registros del F84 y el ' 508A comprenden 8 "celdas" en las que se coloca un 'cero' o un 'uno'. Las ocho celdas se separan en dos grupos llamados Nibbles (niveles), uno superiores de 4 celdas (Nibble Alto) y otro

Page 59: Programador PIC Pablin II

inferiores de 4 celdas (Nibble Bajo).

Nº Bit 7 6 5 4 3 2 1 0Regist

ro0 0 0 0 0 0 0 0

nibble alto

nibble bajo

ADDLW ADD Literal to W   ADDWF ADD W to F

ADDLW k   ADDWF f,d

111x kkkk kkkk  0001 11bf ffff00 0111 dfff ffff

  1/1

W + k -> WW + k -> WW AND f -> W si d=0

 W + f -> f

W + f -> W  si d=0

PA1 PA0 TO# PD# Z DC C

- - - - X X X 

PA2 PA1 PA0 TO# PD#

- - - -

Se pone a 1 si se produce un acarreo desde el bit de mayor peso.

Se pone a 1 si se genera un acarreo del bit 3 al bit 4. Se pone a 1 si el resultado de la operación es cero.

Añade el contenido de W al contenido de k y almacena el resultado en W. Atención: Esta operación no existe en los PIB12C5XX.

 

C Se pone a 1 si se produce un acarreo desde el bit de mayor peso.DC Se pone a 1 si se genera un acarreo del bit 3 al bit 4.Z Se pone a 1 si el resultado de la operación es cero.Añade el contenido de W al contenido de f y almacena el resultado en W si  d=0 y en f si d=1.

ADDLW 0x15h  Si antes de la instrucción:W = 10h = 0001 0000 bAl ejecutarse la instrucción: W = 10h + 15h = 25hW = 0001 0000 b + 0001 0101 b = 0010 0101 b

 

ADDWF FSR.0Si antes de la instrucción: W = 17h y FSR = C2h como d=0Al ejecutarse: W = 17h + C2h = D9h

 

Volver

ANDLW AND Literal and W   ANDWF AND W with F

ANDLW k   [Etiqueta] ANDWF f,d

kkkk kkkk1001 kkkk Kkkk

 0001     01df ffff00 0101 dfff ffff

  1/1

W AND k -> W  f entre 0 y 127     b entre 0 y 7W AND f -> f     si d=1W AND f -> W  si d=0

PA1 PA0 TO# PD# Z DC C

- - - - X - - 

PA2 PA1 PA0 TO# PD#

- - - -

Z Se pone a 1 si el resultado de la operación es cero.Ejecuta un AND lógico entre el contenido  de W y el literal k y lo almacena en W.

 

Efectúa la operación AND lógico entre el contenido del el contenido de f y almacena el resultado en W. Si en f si d =1.   Z Se pone a 1 si el resultado de la operación es 0.

Page 60: Programador PIC Pablin II

ANDLW 0x5FSi antes de la instrucción W = A3hAl ejecutarse: W = 0101 1111 b AND 1010 0011 b == 0000 0011b = 03h

 

ANDWF FSR,1Si antes de la instrucción.W = 17h = 0001 0111 b y FSR = C2h = 1100 0010 bAl ejecutarse: W = 17h = 0001 0111 bFSR = 0001 0111 b AND 1100 0010 b = 0000 0010 b = 02h

Volver

Bit Clear F   BSF Bit Set F

[Etiqueta] BCF f,b    [Etiqueta] BSF f,b 

bbbf ffff00bb bfff ffff

 0100 bbbf ffff01 11bb bfff ffff

f entre 0 y 127     b entre 0 y 7   

 f entre 0 y127    b entre 0 y 71 -> b(f)

  1/1

PA1 PA0 TO# PD# Z DC C

- - - - - - - 

PA2 PA1 PA0 TO# PD#

- - - -

Pone a 0 el bit b del archivo f   Pone a 1 el bit b del archivo f

BCF FLAG_REG,7Si antes de la instrucción el registro:FLAG_REG = C7h = 1100 0111 b      Al ejecutarse la instrucción, el registro queda con valor:FLAG_REG = 47h = 0100 0111b

 

Si antes de la instrucción el registro tiene el valor:FLAG_REG = 0Ah = 0000 1010b Al ejecutarse la instrucción, el registro queda con valor:FLAG_REG = 8Ah = 1000 1010 b

Volver

Bit Test, Skip If Clear   BTFSS Bit Test, Skip If Set

[Etiqueta] BTFSC f,b   [Etiqueta] BTFSS f,b

bbbf ffff10bb bfff ffff

 0111 bbbf ffff01 11bb bfff ffff

  1/1 o 2

f entre 0 y 127      b entre 0 y 7Salta (Skip) si b(f)=0

 f entre 0 y 127      b entre 0 y 7Salta (Skip) si b(f)=1

PA1 PA0 TO# PD# Z DC C

- - - - - - - 

PA2 PA1 PA0 TO# PD#

- - - -

Si el bit número b del registro f es cero, la instrucción que sigue a ésta se ignora (Skip) y se trata como un NOP. En este caso y sólo en este caso, la instrucción BTFSC precisa de dos ciclos para ejecutarse. 

 

Si el bit número b del registro sigue a ésta se ignora (Skip) y se trata como un NOP. En este caso y sólo en este caso, la instrucción BTFSS precisa de dos ciclos para ejecutarse. 

Aqui BTFSC FLAG,1FALSE GOTO Process_Code TRUE.Si antes de la instrucción : PC = dirección AquiAl ejecutarse: if FLAG <1> = 0, PC = dirección TRUEif FLAG <1> = 1, PC = dirección FALSE

 

Aqui BTFSS FLAG,1FALSE GOTO Process_Code TRUE.Si antes de la instrucción : PC = dirección AquiAl ejecutarse: if FLAG <1> = 0, PC = dirección FALSE if FLAG <1> = 1, PC = dirección TRUE

Volver

Subrutina CALL   CLRF Clear f with f

[Etiqueta] CALL k   [Etiqueta] CLRF f

kkkk kkkk0kkk kkkk kkkk

 0000    011f ffff00 0001 1fff ffff

  1/1

Page 61: Programador PIC Pablin II

k entre 0 y 2047Para los 16c5X: PC + 1 -> Pila, k -> PC(0-7),0 ->PC(8)PA2 a PA0 -> PC(9-11)Para los 16c64, 71, 74, 84PC +1 -> Pila, k -> PC(0-10), PCLATH(3,4) -> PC(11,12)

 f entre 0 y 12700h -> f1 -> Z

PA1 PA0 TO# PD# Z DC C

- - - - - - - 

PA2 PA1 PA0 TO# PD#

- - - -

Guarda la dirección de vuelta en la Pila y después llama a la subrutina situada en la dirección cargada en el PC.Atención: El modo de cálculo de la dirección difiere según la familia PIC utilizada. También hay que posicionar bien PA2, PA1, PA0 (16c5X) o el registro PCLATH (en los demás PIC), antes de ejecutar la instrucción CALL.

 

Pone el contenido del registro f a cero y activa el bit [Flag] Z.Z se pone a 1 si el resultado de la operación es 0.

Aqui CALL THERESi antes de la instrucción: PC = dirección AquiAl ejecutarse:  PC = dirección (THERE)TOS = dirección (Aqui + 1)

 CLRF REGSi antes de la instrucción. REG =5AhAl ejecutarse REG = 00h             Flag Z = 1

Volver

Clear register W   CLRWDT Clear Watchdog Timer

[Etiqueta] CLRW    [Etiqueta] CLRWDT

0100 00000001 0000 0011

 0000 0000 010000 0000 0110 0100

  1/1

 00 -> WDT y 0 -> predivisor del temporizador.Los bits TO# y PD# del registro State se ponen a 1.

PA1 PA0 TO# PD# Z DC C

- - - - 1 - - 

PA2 PA1 PA0 TO# PD#

- - - -

Pone el registro W a 00h y pone a 1 el bit [flag] Z, si el resultado de la operación 0.  

Pone a 00h el registro WDT contador del temporizador Watchdog, así como el predivisor.TO# y PD# se ponen a 1 cuandoCLRWDT o SLEEP.TO# se pone a 0 si el temporizador Watchdog se desborda.

Si antes de la instrucción. W = 5AhAl ejecutarse: W = 00hflag Z = 1

 

CLRWDTSi antes de ejecutarse la instrucción: WDT = ?Al ejecutarse: WDT = 00h   Preescaler WDT = 0bit de estado TO = 1bit de estado PD = 1

Volver

Complement F   DECF Decrement F to F

[Etiqueta] COMF f,d   [Etiqueta] DECF f,d

01df ffff1001 dfff ffff

 0000 11df ffff00 0011 dfff

  1/1

~f -> f           f entre 0 y 127 ~f -> W

 f - 1 -> f      si d = 1            f entre 0 y 127f - 1 -> W   si d = 0 

PA1 PA0 TO# PD# Z DC C

- - - - X - - 

PA2 PA1 PA0 TO# PD#

- - - -

Page 62: Programador PIC Pablin II

Complementa el contenido del registro f bir a bit. El resultado lo almacena de nuevo en f si d = 1 (borra lo anterior) o en W si d = 0 (f no varía).

se pone a 1 si el resultado de la operación es 0.

 

Decrementa el contenido del registro resultado se guarda en W si d=0 (Z Se pone a 1 si el resultado de la operación es 0.

COMF REG1,0Si antes de la instrucción: REG1 = 13h como d = 0Al ejecutarse: REG1 = 13h = 0001 0011 bW = ECh = 1110 1100 b           flag Z = 0

 

DECF CNT,1Si antes de la instrucción: CNT = 01hAl ejecutarse: CNT = 00hbit [flag] Z = 1

Volver

DECFSZ Decrement F, Skip If Zero   GOTO Salto Incondicional with F

[Etiqueta]  DECFSZ f, d   GOTO k

11df ffff1011 dfff ffff

 101k     kkkk kkkk10 1kkk kkkk

  1/2

f - 1 -> f     si d=1 ;    f entre 0 y 127 salta si d= 0 ;  f - 1 -> W  

 

En el caso de los 16c5X:k -> PC(0-8), PA2 PA1, PA0 -> PC(9-11)En el caso de los 16c64,71,74 y 84:k -> PC(0-10), PCLATH(3,4) -> PC(11,12)

PA1 PA0 TO# PD# Z DC C

- - - - - - - 

PA2 PA1 PA0 TO# PD#

- - - -

Decrementa el contenido del registro f en una unidad. El resultado se guarda en W si d=0 (f no varia)  y en f si d=1Si el resultado es nulo, se ignora la siguiente instrucción y en ese caso la instrucción dura dos ciclos.

 

Llama la subrutina situada en la dirección cargada en el registro PCAtención: El modo de cálculo de la dirección difiere según la familia de PIC utilizada. También hay que posicionar correctamente PA2, PA1, PA0 (16c5X) o la parte baja de k, se carga en PCL y la alta en PCLATH (en los demás PIC) antes de ejecutar la instrucción GOTO. Se trata de un salto incondicional.

AQUI DECFSZ CNT,1GOTO LOOP CONTINUE; Si antes de la instrucción: PC = dirección AQUI

Al ejecutarse: CNT = CNT -1Si CNT = 0 entonces PC = dirección CONTINUESi CNT no = 0 entonces PC = dirección AQUI + 1

 - Ocupa 2 ciclos de reloj. Ejemplo: GOTO retardo1 Antes:       PC = Origen Después: PC = Destino (retardo1)

Volver

Incremento F   INCFSZ Incrementa F, Skip (salta) if Zero

INCF f, d   INCFSZ f, d

10df ffff1010 dfff ffff

 0011 11df ffff00 1111 dfff ffff

  1/1(2)

f + 1 -> f si d=1f + 1 -> W si d=0

 

d = [0,1],         f entre 0 y 127f + 1 -> f si d=1f + 1 -> W si d=0En ambos casos: Salta si f + 1 = 0

PA1 PA0 TO# PD# Z DC C

- - - - 1 - - 

PA2 PA1 PA0 TO# PD#

- - - -

Page 63: Programador PIC Pablin II

Incrementa en 1 el contenido de f. El resultado se almacena de nuevo en f, si d=1, o en W si d=0 (en este caso f no  

Incrementa el contenido de f en una unidad. El resultado se guarda de nuevo en f si d=1, o si d=0 en W (en este caso f no varia). Si el resultado es nulo, salta la siguiente instrucción y en este caso, esta instrucción dura dos ciclos

  

Volver

Inclusive OR Literal con W   IORWF Inclusive OR W With f

IORLW k   IORWF f, d

kkkk kkkk1000 kkkk kkkk

 0001 00df ffff00 0100 dfff ffff

  1/1

W OR k -> W     k entre 0 y 255  W OR f -> f si d=1    W OR f -> W si d=0

PA1 PA0 TO# PD# Z DC C

- - - - 1 - - 

PA2 PA1 PA0 TO# PD#

- - - -

Efectúa un OR lógico inclusivo entre el contenido de W y el literal k y almacena el resultado en W

 Efectúa un OR lógico inclusivo entre el contenido de W y el contenido de f y almacena el resultado en f, si d=1 o en W si d=0

IORLW 0x35     = 00110101   W = 0x9Ah    = 10011010

Después: W = 0xBFh   = 10111111 IORWF  Reg,0 Antes:      W=0x91, Después: W=0x93,  Reg=0x13

Volver

MOVE F   MOVLW Move Literal to W with F

MOVF f,d   MOVLW  f

00df ffff1000 dfff ffff

 1100 kkkk kkkk11 00xx kkkk kkkk

  1/1

f -> f si d=1     f entre 0 y 127f -> W si d=0

  k -> W      f entre 0 y 127

PA1 PA0 TO# PD# Z DC C

- - - - 1 - - 

PA2 PA1 PA0 TO# PD#

- - - -

Pone el contenido de f en f,  si d=1 o f en Wsi d=0 ; Pone Z a 1 si operación = 0

Atención: El desplazamiento de f en f que parecería inútil, permite comprobar el contenido de f con respecto a cero ya que esta instrucción afecta sobre el bit Z

 

Carga W con el literal k

MOVF Reg,0

Después:  W = al valor del Reg MOVLW  0x5A

Después: Reg = 0x4F,    W = 0x5A

Volver

MOVWF Move W to F   NOP No Operation

MOVWF W,f   NOP

001f ffff0000 1fff ffff

 0000 0000 000000 0000 0xx0 0000

  1/1

   f entre 0 y 127   Ninguna

Page 64: Programador PIC Pablin II

PA1 PA0 TO# PD# Z DC C

- - - - - - - 

PA2 PA1 PA0 TO# PD#

- - - -

con el contenido de W  Consume un ciclo de maquina y ocupa un lugar en la memoria de programa. Se usa para hacer retardos.

MOVWF Reg,0    Reg = 0xFF,  W = 0x4F

Después: Reg =0x4F  ,  W = 0x4F   

Volver

OPTION Load Option Register   RETFIE Return From Interrupt

OPTION   RETFIE

0000 00100000 0110 0010

  00 0000 0000 1001

  1/2

W -> OPTION   Pila -> PC, 1 -> GIE

PA1 PA0 TO# PD# Z DC C

- - - - - - - 

PA2 PA1 PA0 TO# PD#

- - - -

Carga el registro OPTION con el contenido de W.Atención: Esta instrucción no debe utilizarse en otros chips que no sean los PIC 16c5x. Sin embargo, es correctamente interpretada por los chips 16c64, 71, 74, 84 con el fin de asegurar una compatibilidad ascendente.

 

Carga el PC con el valor que se encuentra en la parte superior de la pila, asegurando así la vuelta de la interrupción. Pone a 1 el bit GIE, con el fin de autorizar de nuevo que se tengan en cuenta las interrupcionesAtención: Esta interrupción dura dos ciclos. Esta instrucción no existe para los PIC 16c5X. TOS = top of stack

 RETFIEAl ejecutarse: PC = TOS GIE = 1

Volver

RETLW Return with Literal in W   RETURN Return from Subroutine with F

RETLW   RETURN

01xx kkkk kkkk  00     0000 0000 0000

  1/2

K --> (W); TOS --> PC   Pila -> PC

PA1 PA0 TO# PD# Z DC C

- - - - - - - 

PA2 PA1 PA0 TO# PD#

- - - -

Carga el registro W con el literal k y después carga el PC con el valor de la parte superior de la PILA, efectuando así, un retorno de subrutina.  

Carga el PC con el valor que se encuentra en la parte superior de la pila, efectuando así una vuelta a la subrutina. Se trata de la instrucción RETLW simplificadaAtención: Esta instrucción dura dos ciclos. Esta instrucción no existe en los PIC 12c5XX, usar RETLW

   

Volver

Rotate Left F through Carry   RRF Rotate Right F through Carry

  RRF f, d

Page 65: Programador PIC Pablin II

01df ffff1101 dfff ffff

 0011 00df ffff00 1100 dfff ffff

  1/1

ver descripción   ver descripción

PA1 PA0 TO# PD# Z DC C

- - - - - - 1 

PA2 PA1 PA0 TO# PD#

- - - -

Rotación de un bit a la izquierda del contenido de f, pasando por el bit de acarreo C. Si d=1 el resultado se almacena en f si d=0 el resultado se almacena en W

 

Rotación de un bit a la derecha del contenido de f, pasando por el bit de acarreo C. Si d=1 el resultado se introduce en f, si d=0 el resultado se amacena en W

RLF Reg1,0 ; d = 0 result. en Wantes: Reg1=1110 0110b ; flag C = 0 después: W =1110 0110b ; flag C = 1

  RRF Reg1,0 ; d = 0 result. en Wantes: Reg1=1110 0110b ; flag C = 1después: W =1110 0110b ; flag C = 0

Volver

Sleep   SUBLW Substract W from Literal

  SUBWF f, d

0000 00110000 0110 0011

 11 110x kkkk kkkk

  1/1

0 -> PD, 1 -> TO, 00 -> WDT, 0 -> Predivisor del WDT   k - W -> W

PA1 PA0 TO# PD# Z DC C

- - - -       

PA2 PA1 PA0 TO# PD#

- - - -

Pone el circuito en bajo consumo con parada del oscilador. Pone a 0 el flag PD y el TO se pone a 1.

Puede salir de este estado por: 1. Activar MCLR para provocar Reset.2. Desbordamiento de WDG si operativo3. Generar interrupción diferente a TMR0.

 

Sustrae el contenido de W del literal k y almacena el resultado en W. La sustracción se realiza en complemento a dosAtención: Esta instrucción no existe en los Pic 12c5XX

  

Volver

SUBWF Substract W from F   SWAPF Swap F to F

SUBWF f, d   SWAPF f, d

10df ffff0010 dfff ffff

 11 11df ffff00 1110 dfff ffff

  1/1

f - W -> f si d=1f - W -> W si d=0

 f(0-3) -> f(4-7) y f(4-7) -> f(0-3)Resultado -> f si d=1Resultado -> W si d=0

PA1 PA0 TO# PD# Z DC C

- - - - 1 1 1 

PA2 PA1 PA0 TO# PD#

- - - -

Sustrae el contenido de W del contenido de f, y almacena el resultado en W si d=0 y en f si d=1. La sustracción se realiza en complemento a dos

 

Intercambia los cuatro bit de mayor peso por los cuatro de menor peso de f, y almacena el resultado en W si d=0, y en f si d=1

  

Volver

Page 66: Programador PIC Pablin II

Load TRIS Register   XORLW Exclusive OR Literal With W

  XORLW k

0000 0fff0000 0110 0fff

 1111 kkkk kkkk11 1010 kkkk kkkk

  1/1

W -> registro TRIS del puerto f    W OR (Exclusivo) k -> W

PA1 PA0 TO# PD# Z DC C

- - - - - - - 

PA2 PA1 PA0 TO# PD#

- - - -

Carga el contenido de W en el registro TRIS del puerto f.Atención: Esta instrucción no debe utilizarse en otros circuitos que no sean los Pic 16c5X. No obstante, es correctamente interpretada por los circuitos 16c64, 71, 74, 84, con el fin de asegurar una compatibilidad ascendente

 

Efectúa un OR lógico exclusivo entre el contenido de W y el contenido del Literal K y almacena el resultado en W

  

Volver

XORWF  Exclusive Or W with F      

XORWF f,d    

10df ffff0110 dfff ffff    

   

W OR (Exclusivo) f -> f si d=1 W OR (Exclusivo) f -> W si d=0

   

PA1 PA0 TO# PD# Z DC C

- - - - 1     

PA2 PA1 PA0 TO# PD#

- - - -

OR Exclusiva W con f resultado en f   ej. XORWF 0C,1    

  

LAS INTERRUPCIONES

en los PIC

Hoy es: Sabado, 03 de Octubre del 2009__________________ Incluir en favoritos si quiere volver a visitarnos.

Introducción.

Hemos avanzado en nuestro empeño de aprender un poco mas a cerca de la programación de los micros PIC y no podemos continuar sin atender unas de las más importantes instrucciones ("herramientas") como son las interrupciones. Veremos que hay dos tipos de interrupción en los micros

Page 67: Programador PIC Pablin II

PIC16X84 y vamos a descubrir como podemos usarlas en nuestro provecho.

Las Interrupciones.

Es una de las características de los microcontroladores, de las más importantes que constituye la capacidad de sincronizar la ejecución de programas con acontecimientos externos; es decir, cuando se produce una interrupción, el micro automáticamente deja lo que esté haciendo, va a la dirección 04h de programa y ejecuta lo que encuentre a partir de allí hasta encontrarse con la instrucción RETFIE que le hará abandonar la interrupción y volver al lugar donde se encontraba antes de producirse dicha interrupción. Hemos de diferenciar entre dos tipos de interrupciones posibles en un PIC16X84:

1. - Mediante una acción interna. El desbordamiento de la Pila (Stack) por una operación indebida, por ejemplo: Al completarse la escritura de datos en una EEPROM.Por desbordamiento del registro TMR0 al rebasar el valor 255 (FFh) a 0.2. - Mediante una acción externa, la más útil. Al producirse un cambio del nivel en uno de sus pines por una acción externa.Estando en el modo de reposo (SLEEP), un cambio de nivel en el pin RB0/INT .Un cambio de nivel en uno de los pines  RB4 a RB7 estando configurados como entrada.

Cuando ocurre un evento de los descritos anteriormente, se produce una petición de interrupción, guardando el valor actual del PC (contador de programa) en la Pila, sea cual sea la fuente de la interrupción, se pone a cero el bit7 GIE (Global Interrupt Enable), con lo cual inhibe cualquier otra petición de interrupción, el registro PC se carga con el valor 0004h que, es la posición del vector de interrupción. Aquí, empieza la ejecución del programa de atención a la interrupción ISR (Rutina de Servicio de Interrupción). El tiempo de procesamiento de la ISR debe ser lo más breve posible, para que se ejecuten las otras interrupciones ya que, pueden habilitarse más de una de ellas. Además, cualquier tipo de interrupción también puede sacar al micro del modo de reposo (SLEEP).

Como he apuntado, una interrupción puede ser inhibida sólo si existe otra interrupción en curso. Esto se debe a que, una interrupción está controlada por dos bits que indican la fuente de la interrupción, un bit actúa como bandera (flag) indicando si se ha producido una interrupción y el otro bit, actúa como bit de inhibición o prohibición de la interrupción en sí, debido a que existe otra interrupción en ejecución y todo esto se realiza de forma automática por parte del micro.

Ecir, el bit GIE es el responsable del permiso de interrupción que se borra automáticamente cuando se acepta una interrupción evitando así que se produzca ninguna otra interrupción mientras se atiende a la primera. Estos bits de control se encuentran en el registro INTCON (0Bh y 8Bh). Estos bits

Page 68: Programador PIC Pablin II

corresponden al registro INTCON que cambia de nivel 0 a 1 cuando se produce la interrupción, excepto el último bit (bandera) que se encuentra en el registro EECON1. Véase los detalles de los bits de INTCON.

REGISTRO INTCON

Bit7 GIE

1 = Todas las Interrupciones habilitadas0 = Todas las Interrupciones inhábiles

Bit Enabled Interrupt Global

Bit6 EEIE1 = Habilitación Activada0 = Desactivada

Bit Interrupciones de Periféricos

Bit5 T0IE1 = Habilitación Activada0 = Desactivada

Bit Interrupción del TMR0

Bit4 INTE1 = Habilitación Activada0 = Desactivada

Bit Interrupción externa

Bit3 RBIE1 = Habilitación Activada0 = Desactivada

Interrupción por cambio Puerto B

Bit2 T0IF1 = TMR0 desbordado0 = No desbordado

Bandera del TMR0- Borrar por software

Bit1 INTF

1 = Hubo interrupción externa0 = No hubo interrupción externa

Bandera RB0/INT- Borrar por software

Bit0 RBIF1 = Uno o más pines cambiaron de nivel

Bandera en RB4 : RB7- Borrar por software

Page 69: Programador PIC Pablin II

0 = Ningún pin ha cambiado de nivel.

Las acciones que debe tener en cuenta el programador al crear sus programas, son las siguientes:

1. Cuando se produce una interrupción el bit7 GIE se pone a 0. 2. El valor del PC se guarda en la Pila (Stack) con el valor 0004h, que es el vector de interrupciones. 3. La rutina de atención a la interrupción debe empezar con un salto a la posición de memoria de programa, antes, debe guardar todos los registros que puedan ser modificados por la interrupción y explorar las banderas para determinar la causa de la interrupción. 4. Dependiendo de la causa, la rutina de interrupción se bifurcará a la subrutina correspondiente. 5. Antes de volver al programa principal, se deben devolver los valores originales salvados de los registros anteriores a la interrupción y además limpiar (poner a 0) las banderas que indican la fuente de la misma. 6. Como última instrucción de la rutina de interrupción usar RETFIE, que cargar el PC con el valor de Pila y el bit GIE se pondrá automáticamente a 1.

Para detectar interrupción: TOIF (bandera (Flag) de interrupción por desbordamiento de TMR0)

Para habilitar interrupción: TOIE (habilita la interrupción por desbordamiento de TMR0)

Por tanto, el bit7 GIE, es el encargado de la activación global que habilita las interrupciones al ponerse a 1 y al reconocer una interrupción se pone a 0 de forma automática, evitando se produzca otra interrupción mientras se atienda la actual. El bit GIE se pone de nuevo a 1 al retornar de la atención a la interrupción al encontrar una instrucción RETFIE. Para el resto de los bits (banderas o flags) no está previsto ningún tratamiento de puesta a cero, por lo que es el propio programa de atención a la interrupción, el que le corresponde tratarla y las banderas (flags) que indican la interrupción, debe ponerlas a 0 (cero).

Antes de seguir, hago hincapié en que, si bien cada bandera cambia o se pone a 1 al producirse una interrupción, es tarea del propio programador, borrarla o ponerla a cero nuevamente, ya que si no lo hace, el micro siempre permanecerá interrumpido o lo que es lo mismo, creerá que la interrupción se está produciendo continuamente.

En resumen, el micro sólo tiene un vector de interrupción en la dirección 0x04h, así que, con cualquier interrupción el PC se carga con 0004h y el programa de atención a la interrupción (que llamamos ISR) se encarga de comprobar el estado de las banderas para determinar que dispositivo causó

Page 70: Programador PIC Pablin II

la interrupción y actuar según lo previsto, la propia ISR se encargará de guardar los registros implicados al principio de la rutina para poder devolver sus estados originales al regresar de la rutina. Ver el siguiente ej.

;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^; Nombre: Demo de Interrupciones ^; Que hace => Encender un LED en RB1, lo haremos dormir y ^; despertarlo al accionar un pulsador en RB0/INT lo encenderá para ^; hacerlo dormir hasta la siguiente interrupcion que lo apagará. ^; --- Descripcion del circuito --- ^; El pin 7 (RB1) conectado al anodo del LED, el catodo a masa. ^; El pin 6 (RB0/INT) conectado a positivo a traves de R de 10K ^; El pin 6 (RB0/INT) conectado a contacto pulsador, el otro a masa.^;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

LIST P=16F84#include <P16F84a.INC>

ACUM equ h'000C' ;se declara acumSTAT equ h'000D' ;se declara stat

#DEFINE BANCO0 BCF STATUS,5

Org 0x00 ;Posicion 0 de la Memoria de Programa (apuntador);Viene cuando hay una interrupcion.

goto inicio ;Va a la etiqueta INICIO

ORG 0x04 ;viene cuando hay una interrupcionGOTO rsi ;salta a rutina de rsi que atiende la interrupcionORG 0X05

; ****Bits del registro OPTION ******************************* ; bit8 = 0 Resistencias de polarización deshabilitadas ; bit7 = 0 Interrupción externa por flanco bajada (no usada) ; bit6 = 0 Fuente de reloj, interno (Usa TMR0 como temporizador) ; bit5 = 0 Flanco de señal externa (no lo usamos) ; bit4 = 0 Divisor asignado al TMR0 ; bit3 = 1 bit2 = 1 bit1 = 0 División por 128 ; *******************************************************

;---- Inicio ------ini BSF status,RP0 ; configurando puertos

MOVLW 01 ; carga w con 0000 0001MOVWF trisb ; RB0/INT es entradaBCF option_reg,6 ; seleccionamos flanco descendenteBCF status,RP0

;---- Activa interrupciones ----BSF intcon,GIE ; habilita todas las interrupcionesBSF intcon,INTE ; que sean interrupciones externasCLRF portb ; limpia el puerto B

dormir SLEEPGOTO dormir ; poner a dormir

;---- rutina servicio interrupcionesrsi BTFSC portb,0 ; verifica que se suelte el pulsador

GOTO rsi ; espera ; comenzamos guardando el contenido del W

MOVWF ACUM ; Copia el acumulador al registro acumMOVF status,W ; Guarda STATUS en el acumuladorBANCO0 ; para restaurarlos antes de volverMOVWF STAT ; Copia el acumulador al registro STAT

Page 71: Programador PIC Pablin II

BTFSC portb,1 ; y ahora sí, si el led está a 1GOTO off_led ; ir a off_led para apagarloBSF portb,1 ; sino, encender el LEDBCF intcon,INTF ; borrar bandera de interrupciónGOTO HECHO ; salta a restaurar valoresRETFIE ; antes de volver

off_led BCF portb,1 ; apaga el LEDBCF intcon,INTF ; borra bandera de interrupción

; Restauramos los valores del W y statusHECHO MOVF STAT,W ; Guarda el contenido de STAT en el W

MOVWF STATUS ; Restaura el STATUSSWAPF ACUM,F ; Da la vuelta al registro ACUMSWAPF ACUM,W ; Vuelve a dar la vuelta al registro ACUM

; y lo restaura

RETFIE ; retorna al programa principalEND

Como referencia, debemos guardar el contenido del registro W y del registro STATUS, para lo cual "no se debe usar la instrucción MOVF" porque corrompe la bandera Z, modificando el registro STATUS. En las hojas del fabricante recomienda el código del siguiente ej. a la hora de tratar una rutina de servicio de interrupciones y puede tomarse, de forma general, procurando adaptarlo a la exigencia del usuario.

; ======== Inicio - Rutina de Servicio de Interrupción ========= ; ========== Guardando W y el Registro de Estado ========== MOVWF R_W ; Guardamos W en R_W (R_W=0x0A) SWAPF STATUS,W ; invertimos los nibbles del registro STATUS (STATUS=0xAF) y

; lo pasamos a W, (W=0xFA). Si ponemos f en SWAPF STATUS,f

; se guardara en el mismo registro STATUS MOVWF R_STAT ; Guardamos el contenido de STATUS en (R_STAT=0xFA) . . . . ; Aqui atendemos la rutina ISR . . ; Deberia configurarse banco como se requiera ; ======== Fin - Rutina de Servicio de Interrupción =========== ; ======== Restaurando W y el Registro de Estado =========== SWAPF R_STAT,W ; invertimos los nibbles del registro R_STAT

; y lo pasamos a W (R_STAT=0xFA), (W=0xAF) MOVWF STATUS ; Restauramos STATUS (STATUS=0xAF) ; estado original del banco SWAPF R_ACUM,F ; invertimos los nibbles de R_ACUM (R_ACUM=0xA0) que SWAPF R_ACUM,W ; invirtiéndolo nuevamente lo pasamos a W, ahora W=0x0A

; RETFIE

En este ejemplo; R_W y R_STAT son registros auxiliares en los que se

Page 72: Programador PIC Pablin II

guardan los valores del registro W y del registro Status. Lo que se ha hecho:

Se guarda el registro W en R_W Se guarda el registro STATUS en R_STAT Se ejecuta la rutina de servicio de interrupciones. Y antes de salir de

la ISR Se restablece el registro STATUS (y el bit seleccionado del banco) Se restablece el registro W

Espero que se haya aprovechado la descripción del tema de las interrupciones y los registros que de algún modo se relacionan con las mismas, para avanzar en los conocimientos de la programación. En próximos artículos veremos como aplicar estos conocimientos.

EL REGISTRO TMR0 Un temporizador especial.

Hoy: 3 Octubre 2009,              Incluir en favoritos, para volver a visitarnos.        Creado por: V. García.

Introducción.

Debido a la importancia de este registro, se ha optado por realizar un artículo en exclusiva para este registro. Se supone que el lector tiene unos conocimientos básicos para la comprensión y seguimiento del contenido de este artículo, sobre los microcontroladores y en especial sobre los microPICs. Esto es lo que nos hace emprender este proyecto. La medida constante del tiempo es en sí, una constante Universal del hombre, en todas sus facetas y esta no es una rama que escape a esta sentencia.

Una función muy habitual de los programas para controlar dispositivos consiste en contar intervalos de tiempo, el elemento que realiza esta función se llama temporizador (Timer), en ocasiones cuenta impulsos provenientes del mundo exterior, entonces el elemento destinado a tal fin se llama contador. Ahora bien, si las labores de temporizador o contador en un programa, las asignáramos al programa principal le robarían mucho tiempo al procesador en detrimento de actividades más importantes, es decir, en el tiempo que emplea en temporizar o contar, no puede atender otras rutinas. Por este motivo se diseñan recursos específicamente orientados a estas misiones. Este tipo de circuitos, se conocen con el nombre de RTCC (Real Time Clock Counter) y también como Timer/Counter (Temporizador/Contador).

Especificación Detallada para PIC16F84A. En este artículo, explicaré los

Page 73: Programador PIC Pablin II

datos específicos del registro TMR0 para este PIC.  

Especificaciones del temporizador (TMR0)

La figura que sigue se muestra el temporizador (TMR0) y el temporizador perro guardián (WDT) en diagrama de bloques. Al pié de la figura (en amarillo) los bits relacionados, de cada registro que afecta el ajuste de los temporizadores.

El Preescaler que, está en el centro de la figura, puede ser usado por el TMR0 o por el WDT. La figura anterior muestra el preescaler conectado a TMR0. El bit PSA (bit 3) del OPTION_REG determina a cual de los dos es conectado el preescaler. El preescaler es un contador programable cuyo rango es determinado por los bits PS0, PS1, PS2 (bits 0, 1 y 2) de OPTION_REG. TMR0 es un contador binario de 8 bit que puede contar hasta 256. Cuando el contador rebasa la cuenta de 255 (FFh) a 0 (00h) ocurre una interrupción por desbordamiento y el bit T0IF (bit 2) del registro INTCON es puesto a 1. El hardware está diseñado tal que cuando ambos el GIE (bit 7) y TOIE (bit 5) del registro INTCON son H ("1") la interrupción ocurre y el PC (program counter) va la dirección 004h, para comenzar la operación de programa.

Una cuenta 256 de TMR0, a veces es corta. Por ejemplo, cuando el reloj interno es 20MHz, la frecuencia de entrada del contador es 5MHz. (Fosc/4). El período de este pulso de reloj es de 200ns (1 / 5Mhz = 0.2 µs.). Para

Page 74: Programador PIC Pablin II

desbordar el TMR0 se necesitan 0.2 µs. x 256 (51.2 µs.). Entonces para ampliar este período se usa el preescaler.

El preescaler se puede usar para dividir la entrada por 2, 4, 8, 16, 32, 64, 128, o 256.

Por ejemplo, cuando el preescaler es puesto para dividir por 2, hay 1 pulso de salida por cada 2 pulsos de entrada al preescaler. Si ponemos a 256, habrá 1 pulso de salida por cada 256 pulsos entrada. Así que, el tiempo de desbordamiento de TMR0 se puede hacer más largo modificando el valor del preescaler. En el ejemplo anterior cuando el preescaler fue puesto a 256, el tiempo de desbordamiento se hizo 51.2 µs. x 256 = 13,107.2 µs. (aproximadamente 13 milisegundos).

La entrada al temporizador (TMR0) puede ser un reloj externo o el reloj interno. Para usar el reloj externo, el bit T0CS (bit 6) del registro OPTION_REG y bit 4 del registro TRISA debe ser puesto a "1". Esto pondrá el pin RA4/T0CKI en el modo entrada de reloj (TMR0 CLOCK IN). El borde de las transiciones de subida o de caída del pulso de reloj, también, se pueden seleccionar por el bit T0SE (bit 5) del registro OPTION_REG. Así, "0" para el borde creciente y "1" para el borde de caída.

En la entrada al temporizador (TMR0) hay un circuito de sincronización de reloj. Usando un reloj externo, el conteo del borde de subida y caída de reloj no se sincronizará con el reloj interno, esto afectaría la sincronización de la interrupción. Dicho circuito sincroniza la entrada de escritura de TMR0 con el reloj interno. La sincronización se alcanza en un máximo de 2 ciclos.

El oscilador del Temporizador Perro Guardián (WDT) es independiente del reloj de la CPU. La interrupción WDT se produce aproximadamente cada 18 ms. 

Generalmente, para prevenir un tiempo mayor de la condición del WDT debe ser reiniciado de vez en cuando vía software, usando la instrucción CLRWDT. Ver imagen de la derecha. Si el Temporizador no es reiniciado antes de la interrupción, la CPU forzará un reinicio a la posición de dirección inmediatamente después del encendido (Power up).

El preescaler puede ser usado para ampliar el período de interrupción. En este caso, los valores de contador son diferentes del TMR0. El preescaler puede ser puesto a uno de los ocho valores 1, 2, 4, 8, 16, 32, 64 o 128. Cuando se pone a 128, la interrupción es aproximadamente 2 segundos (18msec x 128 = 2,304msec).

La función del temporizador perro guardián (WDT) debe prevenir una operación incorrecta del software. (Ej.: Ejecutar instrucciones que no son parte del programa. Lazo: Ejecutar la misma parte repetidamente). La función WDT no es siempre necesaria. Si hay un error en el programa, por lo general, puede reconocerse que hay un mal funcionamiento por el modo en

Page 75: Programador PIC Pablin II

el que éste se desarrolla (esto, no se realiza del modo que se esperaba). Si el WDT reinicia el PIC, no se puede ser capaz de entender, que hizo que, el programa funcionara mal.

En ocasiones es mejor, no usar el temporizador perro guardián. Para desactivar la operación del temporizador perro guardián, resetee el bit WDT de la palabra de configuración (2007) del programa de memoria a "0" cuando grabe el micro en su quemador de PICs.

Hemos visto las especificaciones generales del temporizador TMR0 y el WDT. Ahora, con más detalle, continuaremos con las características de los registros que intervienen en módulo Timer0, que nos permiten configurar su capacidad.

El registro TMR0.

Los PICs poseen un registro llamado TMRO, es un temporizador/contador de 8 bits. El registro TMR0 es un temporizador especial del módulo Timer0. El módulo Timer0, tiene las características que se indican a continuación:

• Temporizador/contador de 8 bit • Capacidad de Lectura/Escritura • Software de 8 bits con Preescaler programable • Selección de Reloj Interno o externo • Interrupción por desbordamiento (al pasar de) FFH a 00H • Selección del Borde (de subida o bajada) para el reloj externo

El registro TMR0 como se ha dicho, es un temporizador especial del módulo Timer0, es decir, es un contador de 8 bits cuyo contenido, se incrementa con una frecuencia constante en cada oscilación de su señal de reloj Ftmr0 programable por hardware. Por su estructura de 8 bits, el máximo de la cuenta está en 256 (podemos contar hasta 28 = 256 valores, entre 0 y 255).

Este registro TMR0, también puede usarse de modo que, permita contar eventos externos, según el valor del bit 5 (TOCS) del registro OPTION. Si este bit 5 está a 1, TMR0 cuenta pulsos de entrada por RA4 y se le llama Contador, por el contrario, si el bit 5 está a 0, TMR0 (como ya se ha descrito más arriba) cuenta pulsos internos de reloj de frecuencia constante (en modo temporizador) y se le llama Timer.

Si nos interesa, se puede insertar un divisor de frecuencia programable (preescaler). Como se ha dicho, este divisor puede ser utilizado indistintamente como preescaler del TMR0 o como postscaler del WDT (Watch Dog Timer), según lo programemos por software.

A diferencia de otros registros, el valor que contiene el registro TMR0 se incrementa continuamente. De modo que, si asignamos el valor 10,

Page 76: Programador PIC Pablin II

después de un ciclo de instrucción, el contenido del registro comienza a ser incrementado a 11, 12, 13 y así sucesivamente con una cadencia constante y totalmente independiente de la ejecución del resto del programa.

Una vez alcanzado el valor 255, en la cuenta siguiente, se desborda el registro TMR0, es decir, es puesto a cero automáticamente, cuando pasa de FFh a 00h, comenzando entonces a contar nuevamente desde cero y no desde el valor originalmente cargado. Además, en el momento de pasar por cero, se activa la bandera TOIF, bit 2 del registro INTCON por desbordamiento del TMR0, generándose la interrupción, sólo si el Control Global de Interrupciones está activado GIE = 1, INTCON bit 7. La frecuencia de conteo es directamente proporcional a la frecuencia de reloj aplicada al dispositivo que, como se ha dicho, puede ser modificada, programando adecuadamente los bits de configuración del preescaler.

La primera figura, es un diagrama simplificado de los bloques del módulo Timer0 y preescaler. La información adicional está disponible en el "Manual de Referencia de la Familia PIC ® de Gama Media MCU" (DS33023).

La tabla anterior debe despejar las posibles dudas al principiante, respecto del registro TMR0 y el módulo Timer0. El registro TMR0 está localizado en la dirección 01h y el módulo Timer0, es un módulo que tiene asociados los registros TMR0, OPTION_REG, TRISA e INTCON, como muestra la tabla.

En los PIC's de gama media, el módulo Timer0 es un módulo interno de los micros y el registro TMR0, como ya se ha mencionado, es un registro de 8 bits que interviene en las operaciones de interrupciones producidas por el módulo Timer0 que veremos con detalle.

El módulo Timer0.

El módulo Timer0 es un dispositivo que como se ha descrito (ver imagen), puede funcionar de dos formas: como contador de pulsos externos o como temporizador para calcular intervalos de tiempo.

El denominado módulo Timer0 en las hojas de datos (descrito más arriba), es un Temporizador/Contador de 8 bits habitual en los microcontroladores PIC16F84 (en otros modelos, es posible encontrar módulos adicionales de

Page 77: Programador PIC Pablin II

8 ó 16 bits cuyo funcionamiento básico, es el mismo). Antes de explicar el funcionamiento y uso con ejemplos del Timer0, para evitar confusiones, debemos definir los tres conceptos siguientes:

Frecuencia de oscilación (Fosc): Es la frecuencia externa del PIC (mediante un cristal de cuarzo, un resonador, etc.).

Frecuencia interna (Fint): Es la frecuencia del reloj interno de instrucciones, generada a partir de la frecuencia de oscilación externa.

Frecuencia TMR0 (Ftmr0): Es la frecuencia constante, después del preescaler, a la entrada del TMR0.

Nota.- En los microcontroladores PIC, la frecuencia Fint difiere de la frecuencia Fosc, ya que para mantener la compatibilidad con los diseños originales es necesario dividirla por cuatro.

El tiempo empleado en una temporización se puede calcular a partir de un ciclo de instrucción (es decir, si estamos trabajando con un XT de 4 Mhz, es una instrucción por cada microsegundo, 1µs), según la formula:

Cuando los pulsos provengan del reloj interno (Fint), el Timer0 se utilizará para generar interrupciones periódicas mediante una cuenta programada. Puesto que conocemos la frecuencia de funcionamiento y en base a un valor que cargaremos en el contador del timer TMR0 podremos temporizar eventos.

Cuando dicha señal provenga de una fuente externa (patilla RA4/T0CKI) del microcontrolador (Fext), es especialmente útil para contar el número de pulsos que dicha señal genera en el tiempo ya que cada pulso de dicha señal incrementa el valor del TMR0.

El esquema simplificado del Timer0, se puede ver en la figura que sigue:

Page 78: Programador PIC Pablin II

El Timer0, usado como temporizador, puede contar períodos de tiempo exactos, acumulándolos en un registro auxiliar, cada vez que ocurra un pulso de entrada podemos consultar el registro auxiliar y comparar el incremento acumulado desde el anterior pulso. Conocidos los períodos, podemos calcular el tiempo transcurrido.

Además como se describió más arriba, de las dos formas de reloj descritas, también podemos configurar que el disparo de la señal, sea por flanco ascendente o descendente. Esto lo podemos realizar con los siguientes bits de control:

T0SC (Timer0 Select Clock) (bit5) del registro OPTION: Indica el origen del reloj del contador, oscilador interno (1) o señal externa (0).

T0SE (Timer0 Set Edge) (bit4) del registro OPTION: Cuando se selecciona señal externa, indica el flanco activo que se usará (1 ascendente; 0 descendente).

El preescaler.

Un circuito adicional en el Timer0, es el preescaler, este circuito, nos permite modificar la frecuencia del reloj de entrada del Timer0, dividiendo ésta y generando una nueva señal de menor frecuencia a su salida que, será la señal de reloj (Ftmr0) de entrada al registro TMR0. El preescaler, es una ayuda para cuando la señal de entrada es una frecuencia demasiado alta para nuestros propósitos y necesitamos reducirla.

El preescaler es un divisor de frecuencia programable que, se utiliza normalmente para lograr tiempos largos y se puede aplicar al TMR0 o al WDT, esto se configura en el bit PSA (bit3) del registro OPTION.

Para configurar el preescaler del registro TMR0, como veremos en la siguiente sección, usaremos 4 bits del registro OPTION, el PSA y tres bits que nos permiten dividir la frecuencia de una señal de entrada por  2, 4, 8, 16, 32, 64, 128 o 256. En caso de utilizar un divisor por 1, la señal de salida es la de entrada sin ningún cambio.

Page 79: Programador PIC Pablin II

Por ejemplo, si usamos como oscilador externo del PIC un cristal de 4Mhz, entonces el reloj interno de instrucciones funciona a

    Fint = 4Mhz /4 = 1 Mhz = 1 µs.

  Si el Timer0 usa la señal del reloj interno y la pasamos por el preescaler configurado para una división por 4, la señal a la salida del preescaler será Fpresc = 250 Khz.

La configuración se realiza con los siguientes bits de control:

PSA (Post Scaler Assignament) (bit3) del registro OPTION: Indica si el postscaler es asignado "1" al WDT o "0" al Timer0.

PS2:0 (bit2:0) del registro OPTION: Indican el valor del divisor a utilizar en el postscaler (consultar tabla para los valores).

Nota de Microchip:Al alimentar el PIC o después de un overflow por WDT, el postscaler esta asignado al WDT. Si se asigna el postscaler al Timer0, es posible que ocurra un reset por el WDT (incluso aun deshabilitado). Por esto se recomienda usar CLRWDT antes de reasignar el postscaler:

clrwdt ;borra postscaler y WDT movlw b'11110001' ;reloj externo por flanco de caida movwf OPTION_REG ;preescaler 1:4 asignado al Timer0

Registro OPTION

Page 80: Programador PIC Pablin II

Para el cálculo del divisor de frecuencia en PS2 - PS1 - PS0, usaremos la tabla siguiente:

Aprovechamos este punto para insertar la tabla de los registros pertenecientes a INTCON, ya que nos ayudarán a comprender mejor los Bits implicados en el proceso de temporizadores con el TMR0.

Page 81: Programador PIC Pablin II

Temporizaciones con TMR0.

Veamos en la practica, como hacer una temporización con el registro TMR0. Por lo descrito, el tiempo empleado en una temporización se puede calcular a partir de un ciclo de instrucción, es decir, si usamos un XT de 4 Mhz, 1 instrucción por cada microsegundo, necesitaremos el valor del divisor de frecuencia (el que se selecciona con los bit's PS2, PS1 y PS0) y también el complemento del valor cargado en TMR0 (es decir 255 - TMR0), la ecuación que nos permite realizar el cálculo es la que siguiente:

       Temporización = Ciclo de instrucción * (255-TMR0) * Divisor de Frecuencia         [1]

Generalizando:   Retardo = 4 * Tosc (µs) * (256 - Valor cargado en TMR0)

Page 82: Programador PIC Pablin II

* (Rango del preescaler) .  .  .  . [2]

1) Supóngase que necesitamos una temporización de 1s (1000 milisegundos), si usamos un cristal XT de 4 Mhz y a demás como divisor de frecuencia seleccionamos 8 (los bits PS2, PS1, PS0 = 0, 1, 0). Sabemos que, 1 seg. = 1000 ms = 1000000 µs y como 1 ciclos/µs es el tiempo empleado en ejecutarse una instrucción, aplicando la ecuación anterior, tenemos:

255 - TMR0 = Temporización (en microsegundos) / (1 ciclo/µS * Div. de Frec.)

que sustituyendo: 255-TMR0 = 1000000 µs/(1 ciclo/µs * 8) 255-TMR0 = 1000000 /(8 ciclos) 255-TMR0 = 125000 ciclos 255-TMR0~= 125 ciclos

Por lo tanto TMR0 se debe cargar con: 255 - TMR0 = 125, que despejando nos proporciona el valor de TMR0 = 255 - 125 = 130 (82h).

El valor que se debe cargar en TMR0 es 82h. Entonces empezará a contar los 130 ciclos necesarios para desbordarse, produciendo así la interrupción. El tiempo empleado es el previsto, 1000000µs = 1µs.

2) Calculemos en este caso, el máximo retraso que es posible obtener con el módulo Timer0, usando la señal interna de reloj de un PIC genérico que usa un cristal de 4 Mhz.

El mayor retraso se puede obtener con el mayor divisor del preescaler ÷256 (PSA2,1,0 = 111), un valor 0 para el TMR0 (contará desde 0 a 255 antes del desbordamiento, es decir, 256 incrementos).

Como Fosc= 4 Mhz el retraso máximo es:  Retardo - TMR0 = (256 * 256) * (4/ 4 Mhz) = 65,566 ms

3) En esta ocasión, utilizando el módulo Timer0 vamos a crear una función que genere un retardo de un milisegundo, el cual incrementa un contador cuyo valor se muestra por el PORTC de un PIC16F877.

Ahora, veamos como realizar una función de retardo. Debemos tener en cuenta que el reloj es de 20 Mhz, entonces según la formula [2],

1 (20x10^6) = 0.05 µs ; los ciclos para hacer 1 ms

1 ms = x * 0.05 ; y despejando x

x= 1000 / 0.05 = 20.000 ciclos.

Page 83: Programador PIC Pablin II

Por lo tanto, necesitamos 20.000 ciclos para hacer 1 ms. Si, cada instrucción toma 4 ciclos en realizarse, las instrucciones que necesitamos son: 20.000/4 = 5.000 instrucciones para tener nuestro retardo de 1 ms (en el caso de contar ciclos de instrucción en lugar de los pulsos en RA4).

Un ciclo de instrucción = 4 * Fosc

  Que, multiplicado por un numero X, obtendremos que,

Retardo = Un ciclo de instrucción * X         luego:

Retardo_R = 4 * Fosc * TMR0

Según esta expresión, debemos considerar que el tiempo máximo sería:

Retardo_R = 4 * Fosc * 256     Ahora si tenemos un clock de 4MHz conectado al PIC tendríamos: 256 µs.

Además sabemos que el modulo timer 0 posee un preescaler que serviría para amplia el retardo. Si lo usamos debemos configurar el bit PSA a 0 . Si seteamos el bit PS2, PS1 y PS0 a 1 el preescaler tendría un valor de 256.

Retardo_T0_Pre = 4 * Tosc * TMR0 * Preescaler.

  Retardo_T0_Pre = 4.0.25 µs * 256 * 256 = 65536 µs = 65.536 ms

Con esto no alcanzamos a generar un segundo. Sin embargo podemos usar un registro que sirva para efectuar varios bucles. En tal caso, podríamos lograr retardos mayores:

Retardo = Bucle * Retardo_T0_Pre

   Retardo = Bucle * 65,536 ms         ; Como el Retardo debe ser 1segundo

1000 ms = Bucle * 65,536       ;Bucle = 15.25

Como vemos generar el retardo es bastante fácil teniendo en cuenta que hemos de definir una rutina que se encargue de comparar o contar las veces que el TMR0 produce los desbordes hasta llegar a 256 cuentas.

Resumiendo

Sabemos que, la bandera T0IF del registro INTCON (bit2) que se pone a 1 siempre que hay un desborde en el Registro TMR0 es decir cuando pasa de 255 a 0. Esta bandera puede servir nuestros intereses ya que una vez producido el desborde el bit T0IF permanece en "1" y es necesario que lo pongamos a "0".

Otro punto importante a recordar es que, debemos cargar el TMR0 con el

Page 84: Programador PIC Pablin II

valor apropiado para conseguir el retardo deseado. Supongamos que se necesita un retardo de 10 us. Entonces nuestro algoritmo sería:

• T0IF = 0 • Poner (256 - 246) 10 en el registro TMR0 • Comprobar cuando T0IF sea 1

Se ha cargado el TMR0 con 10 ciclos de instrucción (10 µs), lo que supone 10 cuentas de desbordamiento del TMR0, porque 10 cuentas = 1 T0IF. La que sigue podría ser una formula para el cálculo del retardo que necesitamos:

Retardo = Ciclo_instrucción * Valor_TMR0 * Valor_Preescaler * Bucle 

Esto nos indica que puede haber otras soluciones.

Según lo descrito, el registro OPTION_REG debería configurarse así: OPTION_REG = 1100 0110     ;

Esto se puede traducir como:

MSB 1   Todas las resistencias de carga (Pull up) desconectadas 1   Flanco para la interrupción ascendente 0   Pulsos de reloj interno Fosc/4 0   Cada flanco ascendente incrementa TMR0 0   Divisor de frecuencia se asigna al TMR0 1   \ 1   } Valor del preescaler = 128

LSB 0   /

El programa que cumpla lo considerado, puede ser el siguiente:

list p=16f627A ;Comando que indica el Pic usado include "p16f628A.inc" ;Etiquetas genéricas para el

Pic16F877

CONTA EQU 0x20 ;Variable CONTA en dirección 0x20 hexadecimal

ORG 0x00 ;Inicio del programa en la posición cero de memoria inicio:

BSF STATUS,RP0 ;Ir banco 1BCF STATUS,RP1

CLRF TRISA ;PORTA salida

MOVLW b'11000110' ;Configuración del modulo TMR0MOVWF OPTION_REG ;Preescaler = 128

BCF STATUS,RP0 ;Ir banco 0BCF STATUS,RP1

Page 85: Programador PIC Pablin II

CLRF PORTC ;PORTC = 0

bucle:CALL retardo ;Llama la rutina de retardoINCF PORTC,F ;Incrementa el valor del PORTCGOTO bucle ;Ir bucle

retardo: ;T = 4 * Tosc * Valor de TMR0 * Preescaler

MOVLW d'64' ;Cargar el valor de CONTA para 1 segundo

MOVWF CONTA

espera1:CLRF INTCON ;Deshabilitar interrupcionesMOVLW d'134' ;Cargar el valor de TMR0 para 122

cuentasMOVWF TMR0 ;(Complemento)

espera:BTFSS INTCON,T0IF ;Esperar desborde del TMR0GOTO esperaDECFSZ CONTA,F ;Decrementar el registro CONTA hasta

ceroGOTO espera1 ;Si no es cero: ir a espera1RETURN ;retorno de call

END

Con esto, estoy convencido que se ha descrito con extensión y puede darse por cerrado el tema. Esta información se ha obtenido de distintas fuentes y de la red.

MANUAL PRACTICODEL PROTEUS VSM

Hoy: 3 Octubre 2009,              Incluir en favoritos, para volver a visitarnos.        Creado por: V. García.

Introducción.

Las ventajas de que disponemos actualmente los que nos dedicamos a la electrónica aplicada en cualquiera de sus facetas, es realmente para tener en cuenta. Hace poco tiempo (ciertamente, cada vez queda más lejos), no disponíamos de las herramientas físicas y las de software con las prestaciones que se presentan en estos tiempos. Esto es verdaderamente bueno. En lo referente a equipos físicos, el que empieza es evidente que no pueda disponerlas, sin embargo en el apartado de software, existen una serie de herramientas que prestan gran ayuda a los diseñadores incluso a los que empiezan, facilitando su tarea y aprendizaje en los últimos, esto

Page 86: Programador PIC Pablin II

repercute en un mejor aprovechamiento del tiempo y un mayor rendimiento.

Hay una gran variedad de paquetes EDA (Herramientas de CAD Electrónico) estas herramientas unas mas conocidas que otras entre ellas podemos citar: TangoPCB, Elegance, Livewire, Proteus VSM, ExpresPCB, Eagle, etc. Todas son marcas registradas, algunas de ellas disponen de versiones demo que pueden servir para conocer su funcionamiento. Aquí, nos ocuparemos del PROTEUS©, se disponen de manuales en español, muy muy buenos y muy extensos, los cuales sacarán de dudas a quien las tenga, más tarde les doy algunos enlaces.

Una de estas herramientas es la que nos ocupa en este práctico y rápido manual con un nivel superficial. Se trata es poner en manos del estudiante, lector o interesado, las bases mínimas para poner en práctica las ideas o necesidades que le surjan en el ejercicio de su trabajo o simplemente para su entretenimiento (hobby), por lo tanto, será sólo eso un asomo al uso de esta herramienta de diseño y análisis electrónico, dejando para otros manuales ya existentes la labor de desarrollar en profundidad su conocimiento a fondo.

El objetivo de esta clase tutorial es de mostrar, por la creación de un simple esquemático, como conducir una simulación interactiva que usa Proteus VSM. Mientras nos concentramos en el empleo de Componentes Activos y las instalaciones de eliminación poe depurado de fallos del editor ISIS también miraremos lo básico de presentar una dirección de circuito esquemática y general. La cobertura plena de estos temas puede ser encontrada en el Manual ISIS.

PROTEUS VSM.

La herramienta PROTEUS© es un entorno integrado diseñado para la realización completa de proyectos para construcción de equipos electrónicos en todas sus etapas. Proteus el Sistema Virtual de Modelado (VSM) combina el modo mixto la simulación de circuito de SPICE, componentes animados y modelos completos de diseños basados en microprocesador para facilitar la co-simulación del microcontrolador. Esta herramienta dispone de los módulos conocidos por: Captura de esquemáticos ISIS, Layout de ARES PCB y Simulador (ProSpice/VSM). Por primera vez, es posible desarrollar y probar diseños antes de construir un prototipo físico.

Captura de Esquemático ISIS.

Una vez instalado el programa, iniciar ISIS, se presenta la suite de diseño en la que se aprecian dos zonas, a la izquierda un visor del plano del proyecto, debajo, la ventana para mostrar dispositivos y a la derecha la zona de trabajo propiamente dicha, en la que el diseñador trazará los circuitos eléctricos con sus componentes, posteriormente podrá ejecutar un

Page 87: Programador PIC Pablin II

modelo virtual que simule su proyecto en funcionamiento.

En la columna de la izquierda pulsamos sobre el botón P que nos antepone la ventana de librerías, en esta ventana elegiremos el dispositivo que necesitemos con doble-click, eligiendo otros componentes del mismo modo, lo que enviará dichos dispositivos a la ventana principal, en la columna de la izquierda donde aparecen los componentes a usar. Incorpora una librería de más de 6.000 modelos de dispositivos digitales y analógicos. En posteriores tutoriales se describirá su funcionamiento.

Layout de ARES PCB.

Es la herramienta que usaremos para la elaboración de nuestras placas de circuito impreso, ARES dispone de un posicionador automático de elementos, con generación automática de pistas. El diseñador con experiencia ya no tiene que hacer el trabajo duro, es el PC quien se encarga de esta tarea.

PROSPICE.

Se trata de una herramienta de simulación de circuitos según el estándar industrial. La versión básica, suministrada con todas las versiones de Proteus, sólo soporta análisis de transitorios.

VSM.

VSM es la herramienta integrada que incluye PROTEUS, se trata de un completo simulador para esquemas electrónicos que contienen microprocesador. El corazón de VSM es ProSPICE, un producto que combina un núcleo de simulación analógica usando el estándar SPICE3f5,

Page 88: Programador PIC Pablin II

con modelos animados de los componentes electrónicos y los microprocesadores que comprenden el circuito, tanto si el programa se ha escrito en ensamblador como si se ha utilizado un lenguaje de alto nivel, permitiendo interactuar con nuestro diseño, utilizando elementos gráficos animados realizando operaciones de indicadores de entrada y salida.

La simulación se realiza en tiempo casi real, los efectos se pueden considerar prácticamente como a tiempo real. Incorpora prácticos controles de depuración paso a paso y visualización del estados de las variables. La característica más sorprendente e importante de VSM es su capacidad de simular el software que se ejecuta en el microcontrolador y su interacción con cualquier componente electrónico digital o analógico conectado a él.

Ejecución del programa con microprocesadores.

Como podremos comprobar y según dice el fabricante, la característica más sorprendente e importante de VSM es su capacidad de simular el software que se ejecuta en el microcontrolador y su interacción con cualquier componente electrónico digital o analógico conectado a él.

Veamos un ejemplo sencillo: Trazamos un circuito sencillo compuesto por unos pocos componentes alrededor de un microcontrolador como el PIC16F84A, el siguiente puede ser el esquema de lo descrito.

En el esquema se aprecia un pulsador P1, un LED con su resistencia R2 de seguridad, la resistencia R1 para el reset y el micro PIC16F84A. Al usar el puerto B como entrada, por software reducimos componentes, como son las resistencias de pull-up del puerto B que internamente ya dispone.

Page 89: Programador PIC Pablin II

Uso del Capturador ISIS

Una vez iniciado el programa, elegimos los componentes que se van a usar. Pulsamos sobre el icono , esto abrirá una ventana como la que se muestra debajo, en ella se aprecian tres columnas con distintas posibilidades:

  La columna de la izquierda tiene una celda en la que podemos entrar el código del dispositivo deseado y podemos automatizar su búsqueda, para ello hemos de conocer el nombre con el que figura en las librerías disponibles, en otro caso no dará buenos resultados.

Debajo de esta celda se encuentra un área con nombre "Category:" en ella se ven los nombres de las categorías de los dispositivos y series que aparecen en las librerías, debajo las subcategorias con algo mas de definición por familias y debajo se muestra los distintos fabricantes.

En la medida en que elijamos las distintas categorías, así, se podrá seleccionar con una mayor precisión, el dispositivo deseado para la realización más exacta de nuestro proyecto. Aún así, puede que no se disponga del dispositivo exacto, es el momento de actualizar o pedir información al fabricante por una opción que nos pueda interesar.

La columna central, nos mostrará una lista con una cierta cantidad de elementos y una descripción, dependiendo del elemento que estemos buscado, podremos encontrar el dispositivo necesitado, moviendo la corredera correspondiente, al seleccionarlo su símbolo y su representación

Page 90: Programador PIC Pablin II

esquemática será mostrada en la columna de al lado. Estas operaciones se tienen que realizar por cada uno de los elementos que constituyen nuestro circuito, de modo que al llegar a esta situación, habiendo encontrado el dispositivo buscado, para ganar tiempo sólo hay que dar un doble-click sobre el mismo y sin cerrar esta ventana podremos seguir buscando más elementos. Cuando demos por terminada la lista de componentes pulsaremos "OK" para salir.

Es de especial interés que al elegir un componente (siempre que sea posible) nos decidamos por el que disponga de simulación animada, como pueden ser componentes de entrada (generadores, motores) o de salida (LEDs, Display, LCD, motores). La figura de la derecha puede ayudar al lector a identificar los elementos esenciales para localizar, seleccionar, girar y emplazar cada uno de los componentes en un determinado circuito.

El botón corresponde a las librerías y muestra el contenido de las mismas, esto no lo vamos a ver aquí, ya que se trata de un repaso rápido sobre esta maravillosa herramienta, hay otros manuales muy buenos que están hechos en español, por citar uno de ellos podemos citar los; 11 video Tutoriales, hechos por Germán Tojeiro sobre Proteus entre otros, buscando en la red puede encontrar información en páginas sobre el tema.

Una vez seleccionados todos los componentes necesarios para el desarrollo del circuito esquemático, procederemos a la ubicar en el área de trabajo cada unos de los componentes. Para ello, seleccionamos en la columna de la izquierda el componente a ubicar, por ej. el microcontrolador, en el visor de arriba se muestra la posición del componente, si es necesario el usuario mediante las flechas de girar y rotar adecuará la posición del mismo con un click en el lugar elegido. Ahora seguirá con los demás componentes, procurando ubicarlos en lugares cercanos entre si para que estén relativamente juntos como se aprecia en el gráfico que se muestra más arriba.

Quizás el lector ya haya creado el listado del programa que vamos a implementar en esta práctica, en otro caso este es el momento de hacerlo o talvez se decida por copiar y pegar el listado que está aquí, para evitar que surjan problemas derivados de la ruta entre el Proteus y el propio  programa en asm, es conveniente que éste se ubique en una carpeta donde esté el Proteus. Si ya tenemos todo como se ha descrito, es el

Page 91: Programador PIC Pablin II

momento de seguir.

Con esto ya tenemos el circuito terminado. Si queremos simularlo entonces debemos proceder de la siguiente forma. En la barra de menú, seguir estos pasos: ir a Source/Add/Remove... como se aprecia en la imagen.

Ahora, con el menú Source, se abre una persiana con distintas opciones que describiremos, seleccionamos la primera Add/Remove souce fikes esto presenta a ventana de abajo, en la que primero seleccionamos la herramienta para generar el código (Code Generation Tool), en este caso MPASM, luego seleccionamos el fichero en código asm que contiene el programa que deseamos ejecutar en el micro, exactamente el mismo que cargaríamos en el chip real, con el buscador dentro de la carpeta donde lo tengamos, con el botón "Change", no actuaremos sobre los flags en este caso y pulsamos "OK" para finalizar, se cerrará la ventana.

Page 92: Programador PIC Pablin II

El siguiente paso es elegir la herramienta para definir la generación del código (Define Code Generation Tools...), en la celda de la persiana "Tool" seleccionamos MPASM, el resto no se toca y para terminar pulsar OK.

Volver a "Source" en la opción "Setup External Text Editor" del menú, nos puede servir para indicarle al ISIS que queremos usar nuestro editor habitual, en otro caso no se toca. Cuando lo tenemos todo configurado, entonces usaremos la opción "Build" para que nos genere el archivo HEX, podría ser que tuviéramos algún error en cuyo caso nos mostrará en una ventana indicando donde y cuales son las líneas que dan el error para su corrección. La última opción, nos sirve para editar el archivo en ASM, con el que corregir los posibles errores.

Personalmente llegado el caso de la aparición de errores, hago una copia del programa en asm y mediante el MPLAB hago la depuración del código, una vez he solucionado todos los errores, hago un copiado del programa terminado y lo pego en el sitio donde estaba en el Proteus, ahora ya lo tengo depurado, sin embargo lo de nuevo por el "Build" para que me confirme lo evidente, este paso no es necesario si también he copiado el archivo hex generado por el MPLAB.

Page 93: Programador PIC Pablin II

El siguiente paso es: Seleccionar el microcontrolador en el esquema (en este caso PIC16F84A), estará resaltado en rojo, entonces pulsamos el botón izquierdo del ratón (dije, el izquierdo, ¡se ha borrado el componente!, hacer CRTL-Z, volverá todo a su sitio) y se abrirá la siguiente ventana:

En primer lugar si es el caso, modificaremos la frecuencia del reloj, en la imagen, la celda con asterisco, según tengamos previsto. Después, en "Program File:", pulsaremos sobre la carpeta que aparece y buscaremos el archivo HEX que se ha generado (debe estar en el mismo sitio que el listado ASM) seleccionar y aceptar, si se tienen mas definiciones o propiedades se pueden indicar en el apartado del pié del cuadro y aceptar

Page 94: Programador PIC Pablin II

en OK. Con esto el programa ISIS, ya dispone de la información básica necesaria para proceder a la simulación virtual del programa.

Panel de simulación.

Las simulaciones interactivas son controladas por un simple VCR, como el panel que se comporta como un mando a distancia normal. Este control se sitúa en el lado izquierdo inferior de la pantalla. Si no es visible se debe seleccionar la opción de Animación de Circuito del menú de Gráfico. Hay cuatro botones con los que se suele controlar el flujo del circuito.

- El botón Play, inicia la ejecución continuada del programa. - El botón de modo PASO simple o paso a paso para seguir con detalle el proceso, lo que nos ayudará a la hora de depurar nuestro programa. Si el botón es presionado y liberado entonces avanzará la simulación un paso, si el botón se mantiene presionado entonces los avances de animación continuamente hasta que el botón sea liberado. - El botón de PAUSA suspende la animación y entonces puede ser reactivada pulsando el botón de PAUSA otra vez, o solo dado un paso presionando el botón de PASO. El simulador también entrará en el estado de pausa si encuentran un punto de interrupción. - El botón de PARADA indica a PROSPICE deja de hacer la simulación en tiempo real. Toda la animación es parada y el simulador es descargado de la memoria. Todos los indicadores son reinicializados a sus estados inactivos pero los actuadores (interruptores etc.) conservan sus ajustes existentes.

Se puede configurar el incremento de tiempo de paso simple, usando el botón de PASO vía el cuadro de diálogo de Configuración de Circuito Animado (es decir la cantidad de tiempo avanzado por cada vez que se presione del botón). La capacidad de tiempo de paso es útil para supervisar el da la vuelta más estrechamente y la vista en el movimiento lento que afecta que.

Page 95: Programador PIC Pablin II

Notar que el botón de paso simple sobre el panel de control de animación es usado para avances incrementales de sistema, pero no para pasos simples por el código donde requieren la regularidad específica - eliminando fallos del código se comenta con detalle aquí.

Durante una animación, el tiempo de simulación actual y la carga media de CPU se muestran en la barra de estado. Si la potencia de la CPU es insuficiente para controlar la simulación en tiempo real, la lectura mostrará el 100 % y el tiempo de simulación dejará de avanzar en tiempo real. Aparte de esto, ningún daño a resaltar de simular muy rápido circuitos, como el sistema automáticamente regula la cantidad de simulación realizada por marco de animación.

Aparte de componentes ordinarios electrónicos, las simulaciones interactivas generalmente aprovechan, usan Componentes especiales Activos. Estos componentes tienen un número de estados gráficos y vienen en dos condiciones: Indicadores y Actuadores. Los indicadores muestran un estado gráfico que se cambia según algún parámetro moderado del circuito, mientras los Actuadores permiten determinar por el usuario su estado, para luego modificar alguna característica del circuito.

Los actuadores son designados por la presencia de los pequeños símbolos de marcador rojos que pueden ser pulsados con el ratón para manejar el control. Si se tiene un ratón con una rueda, también se pueden manejar los actuadores señalando en ellos y haciendo rodar la rueda en la dirección apropiada.

LA SIMULACIÓN.

Tradicionalmente, la simulación de circuitos ha sido un asunto no interactivo. En los primeros días, complejos listados fueron preparados a mano, cuya salida consistía en un montón de números. Si se tenía suerte, obtenían una salida pseudo-gráfica trazada con asteriscos para mostrar el voltaje y formas de onda de las corrientes.

Page 96: Programador PIC Pablin II

Recientemente, se ha convertido en norma la captura esquemática sobre pantalla grafica, pero el proceso de simulación es todavía no-interactivo [se dibuja el circuito, se imprime y entonces] se estudia el resultado en una especie de procesado posterior.

Esto es en esencia, si el circuito que se prueba es esencialmente estático en su comportamiento, por ejemplo, un oscilador que oscila a 1MHz simplemente. Sin embargo, si se diseña una alarma antirrobo y se quiere averiguar que pasa cuando un ladrón sin llaves entra el (PIN) número de identificación personal incorrecto en el teclado numérico, la función requerida se hace bastante poco práctica y hay que recurrir a un prototipo físico. Esto es una vergüenza, cómo trabajando en el "ciberespacio" que tiene tanto para ofrecer en términos de productividad de diseño y sin embargo carece de este tipo de simulador.

Sólo en círculos educativos, se ha hecho una tentativa para presentar la simulación de un circuito como la vida real, en la electrónica, donde es posible actuar recíprocamente con el circuito mientras éste es simulado. El problema aquí ha sido que, los modelos de componentes animados han sido arduamente codificados en el programa. Sólo un número limitado de dispositivos simples se han ofrecido, como motores eléctricos, interruptores, bombillas, etc. y estos son de poco uso al usuario profesional. Además, la calidad de simulación de circuito a menudo no se aproximaba mucho a lo deseado. Por ejemplo, un producto principal de este tipo no tiene ninguna información de temporizadores dentro de sus modelos digitales.

Si el programa escribe en uno de los puertos del micro, los niveles lógicos en los circuitos cambian de acuerdo con esto. Y si los circuitos provocan el cambio en el estado de alguno de los pines del microprocesador, entonces estos se visualizarán en pantalla de acuerdo al programa ejecutado. Exactamente como en la vida real.

Los modelos de CPU utilizados por VSM emulan por completo los puertos de entrada y salida, las interrupciones, los temporizadores, los puertos USART y cualquier otro periférico presente en cada uno de los microprocesadores soportados. A diferencia de un simulador de software más sencillo, la interacción de todos estos periféricos con los circuitos externos, se realiza completamente utilizando modelos de ondas.

El simulador VSM, si el proyecto lo requiere, puede simular esquemas electrónicos que contengan más de un microprocesador. Para lo cual, simplemente se colocan los microprocesadores en el esquema y se cablean entre sí o con el resto de la circuitería. VSM es una herramienta única por su capacidad de ejecutar simulaciones cercanas al tiempo real de sistemas completos basados en microprocesadores. Sin embargo, su potencia real se descubre al realizar simulaciones en el modo de ejecución del programa paso a paso. Es entonces cuando se comprueba que VSM trabaja justo igual que el depurador de software preferido.

Page 97: Programador PIC Pablin II

La mejor descripción es una muestra, continuando con el ejemplo que venimos desarrollando. En este punto, pulsaremos el mencionado botón para ejecutar la simulación. Que ocurre al pulsar "Play". En primer lugar, el circuito muestra unos puntos rojos en algunos extremos de ciertos componentes, si reparamos en ello, veremos que esto ocurre en los puntos que en un caso real estarían en nivel lógico alto, el color de los que están a nivel bajo se representan en azul, esto no indica en un primer momento, mucha información de los estados en los puntos que nos interesen controlar, como se puede ver en la imagen.

Se ha modificado en el circuito, el componente LED estándar por un LED "animado", es decir, que interactúa, cuando una corriente adecuada le atraviesa, el LED modifica su apariencia mostrando que está activado como en el mundo real. Además, se observa que en este estado, los componentes que configuran el circuito, no pueden ser modificados, esto es debido al hecho de estar ejecutándose la simulación. En la barra de mensajes LOG, se muestra en verde, la cuenta del tiempo transcurrido de la simulación.

Por otra parte, si actuamos con el puntero del ratón sobre el componente identificado como pulsador, si todo transcurre bien, observamos que el contacto del pulsador conectado al micro, cae de nivel al ser pulsado y esto conmuta el estado del LED, esto es debido al código que se está ejecutando junto con la simulación. Con cada pulsación, se conmuta el estado del LED. En definitiva, esto es lo que se esperaba en la simulación, lo que confirmaría que el código que hemos escrito es correcto y adecuado para nuestros requisitos.

Esto es una simulación simple y como ya está depurado el programa no ha habido problemas en los que hayamos tenido que entrar a discutir o describir, no obstante, es cierto que no siempre será tan simple, por ese motivo vamos a contemplar un caso en el que se tenga que solucionar un problema, en el que tengamos que localizar un tramo de código el cual

Page 98: Programador PIC Pablin II

tengamos que cambiar o modificar en algún modo.

Simulación al Paso.

Cuando estamos simulando un programa, se pueden dar dos casos, uno como el anterior, donde todo va bien, aunque es más probable que se produzca algún tipo de error, en cuyo caso sería deseable poder acceder, en tiempo de ejecución al código que generamos, para ver in-situ su comportamiento. Y en este caso, para que podamos averiguar que ocurre y en que punto del programa se produce el resultado indeseado o el problema por llamarlo de algún modo, se encuentra la simulación al Paso. Veamos un caso concreto.

Listado fuente.

Para los objetivos de nuestra clase tutorial, hemos preparado el programa siguiente que permitirá al PIC controlar los semáforos. Este programa en un archivo fuente llamado TL.ASM.

LIST p=16F84 ; PIC16F844 es el procesador objetivo

#include "P16F84.INC" ; cabecera del archivo Include

CBLOCK 0x10 ; Macro de memoria temporal state l1,l2 ENDC

org 0 ; vector de inicio. goto setports ; salta al codigo de inicio

org 4 ; vector Interrupt.alto: goto alto ; sentarse a esperar

sin hacer nada.

setports: clrw ; poner cero en W. movwf PORTA ; Asegura que PORTA es cero

antes de habilitarlo. movwf PORTB ; Asegura que PORTB es cero

antes de habilitarlo. bsf STATUS,RP0 ; Selecciona Bank 1 clrw ; Mascara para todos

los bits como salida. movwf TRISB ; poner en registro TRISB. bcf STATUS,RP0 ; Regresa al Bank 0.

initialise: clrw ; estado inicial. movwf state ; ponlo.

loop: call getmask ; Convierte state a mascara de bits. movwf PORTB ; escribelo en el portb

Page 99: Programador PIC Pablin II

incf state,W ; Incrementa state en W. andlw 0x04 ; mantener cerca de cero. movwf state ; Ponlo en a la memoria call wait ; Esperar goto loop ; y lazo

; Función para devolver mascara de bits del estado actual en puerto de salida.

; El nibble superior contiene los bits para un juego de luces y el ; nibble bajo los bits para otros juego. Bit 1 es rojo, 2

es ambar ; y bit 3 es verde. El bit 4 no se usa.

getmask: movf state,W ; mueva state a W addwf PCL,F ; añadir la compensación de W

a PCL retlw 0x41 ; state==0 es Verde y Rojo retlw 0x23 ; state==1 es Ambar y

Rojo/Ambar

retlw 0x14 ; state==3 es Rojo y Verde retlw 0x32 ; state==4 es Reojo/Ambar y

Ambar.

; Función que usa dos lazos para alcanzar un retardo.wait: movlw 5 movwf l1

w1: call wait2 decfsz l1 goto w1 return

wait2: clrf l2w2: decfsz l2 goto w2 return

END

De hecho, hay un error deliberado en dicho código, esto lo veremos más adelante. Este listado lo puede encontrar en los ejemplos del propio Proteus.

Enlazando el archivo fuente.

La siguiente etapa debe enlazar el programa al diseño para que podamos simular su comportamiento. Hacemos esto con las órdenes sobre el Menú Source. Ir al Menú Source y ahora seleccionar la Orden Agregar/Quitar Archivos Source. Hacer click en botón Nuevo, buscar (Change) hasta alcanzar el directorio "Samples\Tutorials" y seleccionar el archivo TL.ASM. Hacer click sobre Abrir y el archivo debería aparecer en la lista bajo el Nombre del archivo de Código original.

Page 100: Programador PIC Pablin II

Ahora tenemos que seleccionar el instrumento de generación de código para el archivo. Para nuestros objetivos el instrumento MPASM bastará. Esta opción debería estar disponible de la lista desplegada y entonces pulsando el botón izquierdo se seleccionará de forma habitual. (Notar que si se planea usar un ensamblador nuevo o el compilador por primera vez, se tendrá que registrar usando la orden de Definir Instrumentos de Generación de Código).

Finalmente, es necesario especificar que archivo debe ejecutar el procesador. En nuestro ejemplo este será tl.hex (el archivo exadecimal producido por MPASM subsiguiente al tl.asm ensamblado). Para enlazar este archivo al procesador, botón derecho sobre el PIC en el esquema y pulsar luego el izquierdo sobre Editar Propiedades. Esto creará la forma de diálogo de Componente de Revisión que contiene un campo para el Archivo de Programa. Si esto no esta ya especificado en el tl.hex entrar a mano la ruta al archivo o buscar la posición del archivo vía el botón '?' a la derecha del campo. Una vez que usted ha especificado el archivo exadecimal a controlar pulse Aceptar para salir  del diálogo.

Ahora ya hemos enlazado el archivo fuente al diseño y hemos especificado el Generador de Código que se usará. Una explicación más detallada sobre el Sistema de Control de Código está disponible en la documentación de ayuda.

Simulando el circuito.

Para simular el circuito, pulsar con el ratón sobre el botón Play del panel de animación en el inferior de la pantalla y déjelo. La barra de estado debería aparecer con el tiempo que la animación ha sido activa. También deberíamos notar que uno de los semáforos es verde mientras el otro es rojo y el estado lógico de los pines se puede ver sobre el esquema. Nota, sin embargo, que los semáforos no cambian su estado. Esto está previsto, un error (bug) deliberado que hemos introducido en el código. En esta etapa, sería apropiado eliminar fallos de nuestro programa e intentar aislarlos del problema.

Depurar el programa.

Para asegurar que estamos atentos en la eliminación de fallos del circuito, pararemos la simulación corriente. Una vez que se ha hecho esto se puede comenzar a eliminar fallos, presionando CTRL+F12. Dos ventanas deberían aparecer - 1) propiedad valores CPU Registros corrientes y 2) propia que muestra el código fuente original del programa. Cualquiera de estas puede ser activada en el Menú Debug es un servidor de otras ventanas informativas. También podemos activar la Ventana Watch Window en la que podemos supervisar los cambios apropiados de la variable state. Una explicación completa de estas características está disponible en la sección titulada Watch Window en la documentación de ayuda.

Page 101: Programador PIC Pablin II

Centrándonos por ahora en la ventana Source, en el lado izquierdo notar el icono flecha sobre punto rojo. Esto, con la línea resaltada indica la posición actual del contador de programa (PC). Para poner un punto de interrupción (breackpoint) aquí pulsar ENTER, el punto de ruptura siempre se resaltará la línea. Si quisiéramos limpiar el punto de ruptura lo podríamos hacer pulsando ENTER otra vez, pero en este momento lo dejaremos puesto.

Ajustar el Punto de Ruptura.

Mirando el programa, se pueden ver los bucles rotar sobre sí mismo en un ciclo que se repite. Por lo tanto es una buena idea el poner un punto de interrupción al principio de este lazo antes de empezar. Esto se puede hacer, pulsando el botón Pausa y resaltando la línea (en la dirección 000E) con el ratón y entonces pulsar F9. Luego pulsar F12 para poner el programa a correr. El programa se detendrá en el punto de ruptura que pusimos al principio del bucle.

El programa en el Menú Debug da una lista de las llaves de depuración, pero principalmente usaremos F11 para seguir el programa. Ahora pulsar F11, entonces la flecha roja de la izquierda (puntero) bajará a la próxima instrucción. Qué hemos hecho realmente, hemos ejecutado la instrucción "clrw" y se ha parado. Se puede verificar esto, viendo el registro W en la ventana de CPU Registros, advirtiendo que se ha puesto a cero.

Necesitaríamos determinar lo que esperamos que suceda en la ejecución de la próxima instrucción y entonces probarla, para ver si sucede realmente. Por ejemplo, la próxima instrucción del programa, debe mover el contenido del registro W al PUERTO A, es decir el Puerto A se debe limpiar. Debe advertirse que, ambos puertos han sido aclarados, listos para la salida (como indica el registro TRISB) y que la variable state ha sido puesta correctamente a 0. Ejecutar esta instrucción y verificar en la ventana CPU Registros, que esto es verdad. Continuar en esta línea, hasta que se alcance el punto de ruptura por segunda vez. Para ver mejor como se producen los pasos, pongamos otro punto de ruptura justo en la línea 0015, pulsando F9 y sigamos.

Como esto es una función de CALL (llamada) tenemos la opción de al Paso (pulsando F10), pero para asegurarnos pasaremos por cada instrucción. Al pulsar F11 aquí nos saltará a la primera línea ejecutable de la función de getmask y se parará. Al dar un paso más, vemos que la operación move era acertada ya que se 'aterriza' en el lugar correcto, para agregar una desviación de cero en la tabla de consulta. Por lo tanto, cuando volvemos al programa principal, tenemos la máscara que nosotros esperábamos. Dar aún un paso más para escribir la máscara al puerto y podemos ver el resultado correcto en el esquema. Un nuevo paso otra vez para incrementar state, también es un éxito como se ve en la ventana CPU Registros, donde el valor para el registro W es incrementado en 1.

Page 102: Programador PIC Pablin II

Un paso nos tomará la instrucción diseñada para mantener state cerca de cero cuando se incrementa por arriba de 3. Esto, no funciona como debería, se puede ver en la Ventana Watch. Claramente, state se debe incrementar aquí para indicar 1 en la orden, para poner la máscara correctamente en la próxima ejecución del lazo.

Nos tomará un paso la instrucción diseñada, para mantener el registro state cerca de cero, cuando se incremente por encima de 3. Esto, no funciona como debería, se puede ver en la Ventana Watch. El registro state debe ser claramente incrementado para indicar 1 aquí de modo que la máscara sea puesta correctamente en la próxima ejecución del lazo.

Encontrar el fallo (bug).

Un vistazo más de cerca revela que el problema es causado por la orden AND con 4 en vez de 3. Los estados que queremos ver de la tabla son 0,1,2,3 y cualquiera de éstos sumado (ANDed) con 4 da 0. De ahí que al correr la simulación el estado de los semáforos no cambia. La solución del problema es cambiar simplemente en la instrucción AND (sumar) a state con 3 en lugar de 4. Esto significa que state se incrementará a 3 y cuando el registro W es incrementado a 4 state devolverá un 0. Una solución alternativa sería de probar simplemente para el caso cuando el registro "W" tenga 4 y para reiniciarlo poner a cero.

Este es un corto ejemplo que ilustra lo básico de las técnicas de depuración de fallos disponibles en Proteus VSM, hay mucha funcionalidad adicional disponible. Se recomiendan que se mire la sección sobre Nivel de Depuración de código fuente (Source Level Debugging) para una explicación más detallada.

NOTA. En próximos artículos, siempre que lo requiera el caso, trataré de utilizar este programa de simulación y depuración que es Proteus, para mostrar otras cualidades de esta herramienta, de modo que el interesado pueda ampliar sus conocimientos. Este pequeño manual producto de mi experiencia, parte de la ayuda que acompaña al Proteus y de lo aprendido en los tutoriales que tan bien ha elaborado el profesor Germán Tojeiro, al que quiero felicitar desde aquí.

MICROCONTROLADORES PIC I

Sabado, Octubre 03, 2009_______________________ Incluir en favoritos si

Page 103: Programador PIC Pablin II

quiere volver a visitarnos.   Creado por: V. García.

Introducción.

Bienvenidos al inicio de la clase "Microprocesadores PIC". Estas páginas, mostrarán cómo se forma la estructura básica del dispositivo, directamente por el programa, métodos y técnicas, queremos acercarnos a uno de los microcontroladores que, por diversas razones más auge ha adquirido en los últimos tiempos, podemos decir que, ha invadido nuestras expectativas de trabajo, con un amplio margen de aplicaciones. Habrá sugerencias sobre como modificar el código para que usted pueda adaptar el PIC para satisfacer sus necesidades dentro de sus usos. Incluiré los mínimos diagramas de arquitectura internos, esto suele conducir a la turbación. Si alguien quiere mirar las hojas de datos (datasheet), entonces puede localizarlos en el sitio web de Microchip.

Esto es necesario al principio, ya que, nadie ha empezado desde CERO AL CUADRADO, toda la ayuda disponible va dirigida al principiante. Estando apartado, como educador durante los pasados años, puedo ver esto y si Ud. está de acuerdo, le fascinará con el acercamiento que he hecho. Esto no es un acercamiento convencional ya que esto implicaría muchos términos nuevos y complicaciones. Esto es, un ACERCAMIENTO SIMPLE, una vez que se domine el arte de programar, podrá poner un programa con sus habilidades junto con la información del mismo en sus proyectos.

Como digo, una marea de usuarios, estudiantes e ingenieros vienen utilizando para sus proyectos, algún microcontrolador de la familia PIC. Doy por supuesto que, el lector dispone de conocimientos básicos sobre electrónica digital, para los usuarios más avanzados o incluso con una formación media, podrán resultar estas primeras entregas algo superfluas, pero ya llegarán los capítulos avanzados.

Aquí presentare unos artículos sobre las posibilidades, rutinas y proyectos que, se han creado para tal fin, alguno me han llegado de colaboradores o algunos que me he atrevido a traducir a nuestro idioma [castellano], para que también los que utilizamos este idioma, podamos aprender y llevar a cabo los ejercicios que se proponen y así obtener un conocimiento mayor y más profundo si cabe, de unos microcontroladores que, nos pueden aportar una solución tanto personal como profesional para nuestros proyectos.

Con esta documentación el estudiante, de nuestros artículos PIC, estará preparado para la programación de estos dispositivos y para el diseño de sistemas digitales y/o analógicos basados en los mismos. Otro objetivo es, hacer lo más económico posible estos artículos, reduciendo en lo posible los gastos, aunque sin embargo, los estudiantes serán capaces de hacer estos ejercicios con muy pocos gastos, aún así, inevitablemente habrán algunos pequeños gastos.

Para empezar, deberemos centrar nuestro esfuerzo en unos chips o

Page 104: Programador PIC Pablin II

dispositivos muy concretos. Microchip fabrica una amplia gama de microcontroladores y distribuye los microcontroladores PIC, ofreciendo un entorno de desarrollo semi-gratuito, se trata del MPLAB, con esta aplicación como veremos, podemos programar, compilar y simular nuestros proyectos.

Los microcontroladores PIC, basados en la arquitectura RISC (Juego Reducido de Instrucciones), contemplan la mayoría de las características de esta arquitectura, destacando el juego de instrucciones homogéneo, reducido número de instrucciones y alta velocidad. Hay muchas versiones de chips diferentes disponibles, algunos tipos básicos de memoria reducida, otros superiores los que tienen convertidores digitales o analógicos y hasta los constituidos por A/D y PWM.

Para ayudar al principiante a entrar en la programación, los microcontroladores PIC16F84A y los PIC12C508A, en adelante nos referiremos con 'F84 al PIC16F84 o '508A al PIC12C508A. Cuando se aprende a manejar uno de estos chips, conociendo su arquitectura y su reducido repertorio de instrucciones, será muy fácil aplicar los principios a otros tipos de la gama.

En estos artículos describiremos los aspectos relevantes para el uso y control del 'F84A es la versión con un "puerto y medio" y el más pequeño como es el '508A, ambos dispositivos son muy pequeños en el mundo de los 'micros' pero ambos son el medio para empezar. La designación de pines de ambos se muestra en estas imágenes.

Page 105: Programador PIC Pablin II

Se ha elegido la gama de dispositivos PIC, porque son los más económicos y quizás lo mejor para el principiante. Quizás alguien se pregunte por qué he realizado tanta información para la programación de estos chips, cuando ya existe una enorme cantidad disponible en libros y en otros sitios de la red desde hace tiempo y he de añadir, muy buena.

Una razón es que los seguidores de este sitio, habrán comprobado que desde hace años se presentan distintos tratados sobre la electrónica siempre desde un aparente desorden, quiero decir, sin jerarquía de que artículo va antes de cual otro, hasta cierto punto, esto obedece a un sistema con el que se pretende que nadie sienta la necesidad hacer un ordenado método de la adquisición de conocimientos. 

Lo cotidiano de un técnico es que, cada día aprende una nueva técnica para desarrollar un trabajo y sin duda, sobre la marcha aplica sus conocimientos, sin embargo nadie le indica como aplicarlos, simplemente ocurre. Por lo tanto, creo que, el método de cómo se adquieren los conocimientos no es muy importante, lo verdaderamente importante es comprender lo que se lee.

Se que para algunos, estructurar los temas responde a la experiencia de que, el usuario que por primera vez estudia los micros o microcontroladores, le resultará mas sencillo aprender primero lo referente a la constitución interna del dispositivo y la arquitectura general de los microcontroladores, para una vez dominada ésta, pasar entonces a los detalles electrónicos de la circuitería y la programación. Sin embargo, en este manual no se establece ese orden, sino que, el propio usuario tiene la flexibilidad para optar por otras secuencias, esperando generar así, mayor interés en seguir aprendiendo.

Y esto es lo que he hecho. No se necesita saber el álgebra Booleana, matemáticas complejas o la forma de cómo hacer un doble XOR, haremos todo de manera simple y se será capaz de programar. El 'curso' también muestra como comunicar (interfaz) los chips con dispositivos externos, tomando ideas de un proyecto y aplicándolas a otro, se puede crear un

Page 106: Programador PIC Pablin II

circuito totalmente nuevo con la mayor destreza.

Alguien dijo, "hay una cosa asombrosa sobre la programación, un programa puede ser producido usando una idea sumamente compleja o una idea muy simple. El resultado final es el mismo, aunque el caso simple pueda tener unas instrucciones más para alcanzar el resultado final". ¡Y, quien se preocupa por unas pocas instrucciones de más, cuándo el micro procesa sobre 1.000.000 de instrucciones por segundo, sí, un millón por segundo!

EL PIC12C508A.

Comenzaremos con un programa simple de siete líneas para controlar un LED en un prototipo que, llamaremos Destello '508A. Recuerde dar nombre a sus experimentos, ya nos ocuparemos de esto. No se preocupe por ahora, si no entiende el significado de los parámetros que siguen. El programa enciende un LED, esto es todo lo que hace. El objetivo de este programa es mostrarle el número mínimo de líneas de código requerido para conseguir que haga algo el microcontrolador PIC.

Inicio BSF 03,5 ; inicia el registroMOVLW 3E ; mueve 3Eh = 0011 1110b al registro WMOVWF 06 ; copia W en f, apaga el bit0 o GP0BCF 03,5 ; bit de borrado

Salida MOVLW 01 ; inicia lazo de retardoMOVWF 06 ; copia W en f, pone a 1 la salida GP0

(enciende LED)GOTO Salida ; retorna al principio del lazo.

Este simple programa para el 12C508A, iluminará un LED, repitiendo esta secuencia de forma indefinida, hasta que falte la energía al circuito. El circuito consta de un LED además del '508A, conectando tres patillas del CI, las dos de energía y la correspondiente al pin 7 (Propósito General In/Out línea GP0) y el programa. Este sería el organigrama que ilustra esta rutina que hace lucir un LED.

Page 107: Programador PIC Pablin II

Esta figura, muestra un programa con los 4 pasos siguientes: Inicio, pone la salida activa [1] (inicia lazo), retardo de encendido de 0'1 segundo por la propia instrucción, desactivar pone la salida a [0] y produce un retardo de apagado de 0'9 segundos, volviendo al principio del lazo (loop), no vuelve a "inicio", solo a la etiqueta "salida".  

La parte que se debe recordar es que, el procesador (el corazón del microcontrolador) debe mantenerse corriendo (latiendo) todo el tiempo. El chip contiene un oscilador de 4MHz, ésta frecuencia es dividida internamente por 4 para que en cada microsegundo, sea procesada una instrucción. Esto permite hacer muy fácil, rutinas de retardo exactas.

En este caso no necesitamos tiempos de retardo exactos, sin embargo podremos obtener resultados vía programa y el circuito trabajará exactamente como se proponga. El programa requiere de 0'1 segundo, esto quiere decir que se tendrá que producir un retardo de 100.000 ciclos [sin hacer nada],  mientras la salida se mantiene encendida (EN). Acto seguido, el mismo programa solicita 0'9 segundos. Esto significa un retardo de 900.000 ciclos de nuevo, mientras la salida está en la condición apagado (AP).

La rutina necesaria está descrita a continuación (se puede copiar y pegar), son unas pocas líneas, se distinguen tres columnas:

Etiqueta          Comandos             ;Comentarios

Flash BSF 03h,5 ;Selecciona Pagina 1 MOVLW 00 ;pone literal 00 en W MOVWF 06 ;para hacer GP0 salida BCF 03h,5 ;y vuelve a pagina0

Loop1 BSF 06,0 ;Pone a 1 el bit0 del archivo 06h

Page 108: Programador PIC Pablin II

CALL Delay1 ;salta a Delay1 BCF 06,0 ;Pone a 0 el bit0 del archivo 06h MOVLW 09 ;fuerza un 9 en W MOVWF 0C ;activa lazo

AA1 CALL Delay1 ;salta al retardo Delay1 DECFSZ 0C ;decrementa registro 0Ch y salta si es Cero GOTO AA1 ;repite lazo GOTO Loop1 ;salta a Loop1

Delay1 MOVLW 82h ;crea 130 lazos MOVWF 1A

DelX DECFSZ 1B ;256 decrementa para volver a 1A GOTO DelX ;2µs instrucciones DECFSZ 1A GOTO DelX RETURN

Sin embargo, antes de empezar a realizar este ejercicio, debería tenerse en cuenta que, un microcontrolador PIC12C508A, sólo se puede 'quemar' una vez (OTP), debido a que las celdas que componen su memoria reciben una descarga eléctrica durante la programación, el efecto producido 'quemado' no se puede cambiar. El fabricante garantiza que el chip es capaz de mantener el programa durante muchos años. Según esto, antes de utilizar el '508A, debemos asegurarnos completamente que el programa nos satisface y cuando el proyecto entero esté terminado, entonces pasarlo al '508A.

Hay otra forma más rápida de conseguir experiencia en nuestras practicas de programación si utilizamos un chip PIC16F84A. Esta es una versión mayor del '508A y por suerte casi todas las características del '508A se pueden encontrar en el 'F84. Esto quiere decir que podemos tratar el 'F84 como un '508A y usar los registros y los pines de entrada/salida que corresponden al '508A, el código escrito para el 'F84 puede ser cargado en un '508A y este puede ser incluido en un proyecto.

Como el '508A es mucho más económico que el 'F84 y nos propusimos hacer un proyecto muy barato, este es el otro motivo, además porque el 'F84 puede ser programado y borrado cerca de 1.000 veces y esto nos ahorra malgastar chips. Podemos hacer todas nuestras prácticas de programación con un solo 'F84 y poner el programa acabado, en un '508A y el proyecto estará terminado.

Verá en los siguientes artículos que, el 'curso' es completamente práctico y la mayor parte se consigue con la programación. Nuestros objetivos se deben conseguir con la programación, así que, puede producir los proyectos de microcontrolador y vender sus propios chips programados por poco. Esto es algo que, nunca ha sido posible hacerse antes.

Esto quiere decir que, nuestro 'curso' está en marcha a pesar de todo. Por este motivo, no censuro a cada uno de los grupos de usuarios del PIC o cada uno de los productores de programadores económicos ya que, el lector necesitará la ayuda de estas fuentes, una vez que consiga su 'equipo' para la programación. Todos estos otros grupos tienen una considerable entrada

Page 109: Programador PIC Pablin II

de valores por la programación de PIC, se entiende, otra cosa que debe recordar, es el concepto de programación mediante una Biblioteca de Rutinas y la utilización del 'F84A como una herramienta de desarrollo para sus proyectos simples.

Los dos chips en los que nos centraremos como se ha dicho, son el PIC12C508A y PIC16F84A, estos le permitirán que pueda empezar a crear proyectos equivalentes a 6 u 8 chips (o aún más de la vieja tecnología de puertas y contadores etc.), sus cosas y otros productos como cerraduras electrónicas que usan una tarjeta para el acceso, las tarjetas de seguridad que transmiten un dato o más, demostraciones, juegos, dispositivos telefónicos, alarmas, dispositivos interfaces, osciladores, en robótica y otras partes.

Como dijo un programador: ' Ya nunca usaré el 555 otra vez '. Cada una de las ideas y proyectos que ya han sido producidos sobre y para un módulo de 'tipo intérprete' ahora puede ser creado con un sólo chip y producido en menos de 1/4 del coste.

Seguro que nuestro curso tendrá la disculpas de los que ya programáis con uno de esos módulos caros. Bastante a menudo se les ocurrirá una idea, que sea conveniente para su comercialización. Entonces es cuando el proyecto tendrá que ser convertido en un diseño mucho más barato para hacerlo comercializable. Y aquí es donde intervenimos, para que el coste de un chip, prototipo (placa PCB), un juego de discos, programa, libros y será capaz de lanzar su propio producto. Pero obviamente tendrá que comenzar por el principio y familiarizarse con el código y las capacidades de los distintos chips. Por lo dicho respecto al '508A, tomamos la decisión de usar el 'F84A.

EL PIC16F84A

Aquí se muestra visto por la cara superior el símbolo y nombre de las patillas o pines de un PIC16F84A y similares, más adelante estos datos se ampliarán y reincidiremos sobre ellos.

Page 110: Programador PIC Pablin II

En este dispositivo sus pines están organizados en puerto y medio, es decir, los pines RA0-RA4 corresponde a medio puerto A y los pines RB0-RB7 son el puerto B, a parte se encuentran los pines de oscilador OSC1 y OSC2, el de MCLR (aclarado maestro) y los propios de suministro de energía (Vdd y Vss). A continuación, describiré ligeramente para que se utiliza cada uno:

RA0 a RA4RA es un puerto bidireccional (I/O). Es decir este puede ser configurado como una entrada o una salida, según interese. El número después de RA es el bit relativo, el número puede ser (0 a 4). Así que, tenemos un puerto de 5 bit direccional donde cada bit puede ser configurado individualmente como Entrada o Salida. Recordar que al tratarse de un puerto, un bit se considera una línea o pin del puerto.

RB0 a RB7RB es un segundo puerto bidireccional (I/O). Esto se comporta exactamente del mismo modo que RA, excepto que hay 8 bits implicados, el número puede ser de 0 a 8 y cada bit como en RA, puede ser configurado individualmente como Entrada o Salida y también es una línea (pin) del puerto.

OSC1 y OSC2Estos pines conocidos también como CLKIN y CLKOUT, en CLKIN puede conectarse un reloj externo, o donde conectamos un cristal, red RC o un resonador externo, para que el microcontrolador tenga una especie de 'pulso cardíaco'. Debemos recordar que según el tipo de generador que decidamos usar de los descritos, es el que debe usarse a la hora de 'quemar' el programa, ya que si se cambia no oscilará o puede dar problemas de oscilación. 

MCLR Este pin tiene dos utilidades, es usado como (Reset) para borrar posiciones de memoria dentro del PIC (cuando queremos reiniciar de nuevo el programa). En el uso normal, este pin se conecta al terminal de suministro positivo, personalmente recomiendo intercalar un resistor de al menos 1k. El

Page 111: Programador PIC Pablin II

segundo uso es en el momento de la programación de este chip, el terminal MCLR es el pin por el que se aplica la tensión de programación por el software de quemado, en ese momento no se usa el resistor de 1k.

INTEste es un pin de entrada que puede ser supervisado. Si este pin se pone alto (1), haremos que el programa comience de nuevo, se pare o cualquier otra función simple que deseemos. Básicamente se usa para " despertar" al dispositivo como ya se describirá en otros artículos.

TOCK1Este pin es otra entrada de reloj, que maneja un temporizador interno. Este se utiliza en casos extremos en ausencia del reloj principal. Normalmente no se utiliza éste modo.

VDD y VSSEstos son los pines de suministro de energía, VDD es la línea del positivo y VSS es la línea del negativo, masa o 0V. La tensión máxima de la fuente de suministro que se puede usar sin deteriorar el dispositivo para su normal funcionamiento son 6V y el mínimo de 2V, aunque recomiendo utilizar un diodo rectificador de paso en el caso de tensiones de 6V. 

NOCIONES

Todo lo que hace el micro es, configurar y manejar bits entre distintos registros. Estos

registros están implementados en la memoria RAM interna con un ancho de 8 bits, cada bit de cada registro o archivo tiene una función especifica. Los registros de las primeras posiciones en la memoria RAM, como ya se describe en otro artículo, se les ha dado el nombre de SFR (Registros de Función Especial), los de las siguientes posiciones son los de propósito general y se llaman GPR.

EL PIC16F84A DISPONE DE DOS CLASES DE MEMORIA.

Hay dos bloques de memoria en el PIC16F84A, estos son la memoria de programa y la memoria de datos. Cada bloque tiene su propio bús, de modo que el acceso a cada bloque puede ocurrir durante el mismo ciclo del oscilador.

Una es, la memoria flash que se encarga de almacenar y gestionar el programa, la memoria del 'F84A es de 1k (1024 celdas o palabras) cada

Page 112: Programador PIC Pablin II

celda tiene un ancho de palabra de 14 bits y tiene la particularidad de que aunque se desconecte o falte la energía, no se altera su contenido. Sin embargo, el contenido permite ser reescrito sobre 10.000 veces, por medio de los llamados grabadores de microchips, con los que se procede al 'quemado', borrado y lectura de los programas.

La memoria de datos adicional mayor puede ser direccionada en la RAM de propósito general y los Registros de Función Especial (SFRs). La operación de los SFRs que controla el "corazón" se describe aquí. Los SFRs usados para controlar los módulos periféricos son descritos en la sección que habla

de cada módulo individual periférico.

El área memoria de datos también contiene la memoria de datos EEPROM. Esta memoria no es directamente mapeada en la memoria de datos, pero es mapeada indirectamente. Es decir, un puntero de dirección indirecta, especifica la dirección de la memoria de datos EEPROM para lectura/escritura. Los 64 octetos de datos de la memoria EEPROM tienen la gama de dirección 00h-3Fh. 

Memoria de Programa.

Los PIC16FXX tienen un contador de programa de 13 bit capaz de direccionar un espacio de memoria de programa de 8 kilobyte x 14. Para el PIC16F84A, el primer kilobyte x 14 (0000-03FFh) físicamente esta implementado (figura de la izquierda). El tener acceso a una posición superior a la dirección físicamente puesta en práctica causará un recirculado. Por

ejemplo, para posiciones 20h, 420h, 820h, C20h, 1020h, 1420h, 1820h, y 1C20h, la instrucción será la misma. El vector RESET está en 0000h y el vector interrupt está en 0004h, esto le puede parecer enrevesado, sin embargo pronto verá como se le aclaran las ideas.

Memoria de Datos.

La memoria de datos se divide en dos áreas. La primera, es el área de Registros de Función Especial (SFR), mientras la segunda es el área de Registros de Propósito General (GPR). Los SFRs controlan el modo de operación del dispositivo.

Page 113: Programador PIC Pablin II

Partes de memoria de datos son mapeadas, esto es tanto para el área SFR como para el área GPR. El área GPR es mapeada para permitir una capacidad mayor de 116 octetos de RAM de propósito general. Las áreas mapeadas del SFR son para los registros que controlan las funciones periféricas. Estos bancos requieren del empleo de bits de control para la selección de banco.

Estos bits de control mencionados antes, se localizan en el registro STATUS. La figura de la derecha, muestra la organización del mapa de memoria de datos. Las instrucciones MOVWF y MOVF pueden mover valores del registro W a cualquier posición en el archivo de registro ("F") y viceversa.

Se puede tener acceso directo a toda la memoria de datos utilizando la dirección absoluta de cada archivo de registro o de modo indirecto mediante los Registros de Función Especial (SFR). El direccionado indirecto usa el valor actual del bit RP0 para el acceso a las áreas mapeadas de memoria de datos.

Como se ha dicho, la memoria de datos se divide en dos bancos que contienen los RPG y los SFR:

El banco 0 se selecciona por el aclarado (puesta a 0) del bit RP0 (STATUS<5>).

El banco 1 se selecciona al poner a 1 (Set) el bit RP0.

Cada Banco se extiende hasta 7Fh (128 bytes). Las doce primeras posiciones de cada Banco son reservadas para los Registros de Función Especial, el resto son Registros de Propósito General, implementados en la práctica como RAM estática.

Los Registros de Función Especial se usan por la CPU y funciones periféricas para controlar la operación del dispositivo. Estos registros son la RAM estática. Los registros de función especial pueden ser clasificados en dos juegos, central y periférico. Aquellos asociados con las funciones principales son descritos en esta sección. Aquellos relacionados con la operación de los rasgos periféricos son descritos en la sección para aquel rasgo específico.

EMPEZAMOS

Resumiendo, cuando se pone a correr el micro, la primera posición a la que llega es la 0000h, lo que se conoce por Vector de Reset, esto puede ocurrir por cualquier causa externa o interna como, inicio, reinicio, reset, despertado por cambio en los pines, timer0, etc. como ya describirá en otros artículos.

Luego en la posición 0004h, se encuentra el Vector de Interrupción, a esta posición llega el programa cuando esta habilitada la interrupción y ocurre un evento bien sea interno del micro o por una interrupción externa. Ver la

Page 114: Programador PIC Pablin II

imagen de la izquierda.

Hay un espacio de memoria destinada al programa del usuario, puede apreciarse que sólo se han implementado 1k (hasta 03FFh). A partir de las últimas posiciones hay un espacio de memoria reservado, este espacio está en la posición 2007h y se conoce como Palabra de Configuración, en el que se configura el oscilador, se habilita el Temporizador Perro Guardián y otros. A esta parte sólo se accede para escribirla mediante el interfaz de usuario y grabador en el quemado del chip.

La otra clase es la memoria RAM, que está compuesta por dos partes similares llamadas bancos, cada banco dispone de 80 bytes (00h a 4Fh). El ancho de palabra de estos bancos es de 8 bit. En los 12 primeros registros del 00h al 0Bh de cada banco se encuentran los registros de función especial SFR que se usan permanentemente por el programa, en los que se configuran los puertos y demás opciones ya descritas. Los siguientes 68 registros desde 0Ch a 4Fh, estos son los registros de propósito general GPR, usados por el usuario. Ver imagen de la derecha.

Al conectar la energía al micro, el micro empieza a correr con el contenido por defecto del valor de los registros FSR y empieza a correr nuestro programa. El contenido tanto de los registros SFR como GPR con los que hemos cargado el programa, estarán cambiando continuamente al ritmo de ejecución de las líneas del propio programa, por lo que en el momento de desconectar la energía, los valores contenidos en los registros SFR y GPR definitivamente se pierden. Los registros con el mismo nombre en ambos bancos, indican que el contenido es el mismo en ambos, esto se conoce como mapeado.

Existe otro tipo de memoria de 8 bits de ancho, muy utilizada la EEPROM, que se usa como memoria permanente de datos. El diferente ancho de palabra de estas memorias la RAM-EEPROM de 8 bits y la FLASH de 14 bits están conectadas a la CPU con buses diferentes. Esta arquitectura tiene la ventaja de que el tamaño de las instrucciones no está relacionada con los datos de la RAM lo que permite ser optimizada para que cualquier instrucción ocupe una sola posición de la memoria permitiendo una mayor velocidad y menor longitud de programa.

El cometido de los principales registros SFR, está descrito en el artículo 'descripción de instrucciones' de esta serie de artículos.

Este artículo continua en la segunda parte. En próximos artículos seguiremos con descripciones y prácticas para adquirir la practica y experiencia en programación.

Page 115: Programador PIC Pablin II

Programación de micro chips PIC

Sabado, 03 de Octubre del 2009__________________ Incluir en favoritos si quiere volver a visitarnos.

Introducción a programar PIC.

Este es un acercamiento a la escritura de un programa, muy lineal. Muchos escriben y producen subrutinas muy pequeñas con saltos (llamados GOTO) de una subrutina a otra de modo que los productos saltan por todas partes como 'palomitas de maíz'. El micro es capaz, perfectamente capaz de saltar por un programa, sin embargo este tipo de disposición es muy difícil de seguir por un lector.

Es mucho más fácil seguir la secuencia de acontecimientos y así, muy pronto será capaz de escribir programas similares a los de la sección de proyectos de cualquier empresa. De nuevo recordamos que el PIC12C508A sólo debería ser usado en proyectos donde coste y ahorro espacial tiene suma importancia.  

Los artículos que necesitaremos son:

1. Biblioteca de términos y Lista de rutinas. 2. Juego de instrucciones para ' 508A y F84 . 3. Un archivo hex del final de estos artículos. 4. Alguna de las siguientes herramientas:

- Programador ICProg u otro similar.- Tablero 'protoboard' para experimentos.- Un chip reprogramable PIC16F84A.

5. Cualquier proyecto para un chip ' 508A.

Por donde empiezo.

Lo normal es que, el lector se pregunte: ¿por donde comienzo?. Este artículo es el punto de partida, con él se cubren dos de los microcontroladores más pequeños y más simples de la gama del PIC, son el '508A y el 'F84 que con los instrumentos de desarrollo que se describen, se puede entrar un programa con un bajo costo.

Los dos micros internamente, son casi idénticos excepto un par de diferencias menores, no así en lo físico:

'508A '508A 'F84A 'F84A

Page 116: Programador PIC Pablin II

5 líneas

de entrada/salida

13 líneas

de entrada/salida

 

1 única línea de entrada

 

511 direcciones para

programa

1020 direcciones para

programa

1 única grabación (OTP)

1.000 grabacio

nes posibles

33 instrucci

ones

36 instrucci

ones

Hay diferencias entre los dos, pero para mantener las cosas simples, podemos pensar que el 'F84 es dos veces tamaño del '508A. Si seguimos esta línea, seremos capaces de desplazarnos de un dispositivo al otro según la complejidad del proyecto. Ya que ambos microcontroladores tienen el mismo juego de instrucciones (hay diferencias muy pequeñas descritas en otros artículos en estas páginas), el lector, sólo tiene que aprender unas 33 a 36 instrucciones para ser capaz de crear un programa.

Estas 33 o 36 se amplían a más de 2.000 instrucciones cuando se considera que cada bit en cada archivo puede ser puesto a EN [1] (Encendido, Alto), limpiado ([CLEARed], aClarado) o probado (TESTed), pero sólo tenemos que recordar 33 palabras "similares al inglés" conocidas como mnemónicos, para crear un programa sin usar un leguaje de alto nivel. Una de las ventajas de los micros PIC es el margen de seguridad, esto significa que, el programa que se trasvasa a un chip no puede ser leído por nadie más, en el mejor de los casos sólo pueden conseguir un juego embrollado de figuras.

Un símil de un micro PIC es como un libro con las páginas en blanco, éste tiene un área donde se coloca el programa. El programa lo crea uno mismo y lo carga en el chip mediante un dispositivo llamado "quemador". Aquí utilizaremos el quemador IcProg ya mencionado (si utiliza el XP © o Win2000 ©, necesitará el driver adecuado), ambos son gratis y puede servir para gran número de dispositivos distintos, yo he probado algunos y todos son muy sencillos, con 4 hilos (señales) puede trazarse uno y usarlo "in-situ", como el Policristalino, del que ya trato en otro artículo.

Como ya se ha dicho en la introducción, hemos hallado un modo de permitir programar desarrollos en un '508A sin desperdiciar ningún chip. Para esto se usa un módulo que se llama Quasi '508A. Este módulo Quasi '508A, nos permite escribir programas por etapas y probarlos en un módulo llamado el

Page 117: Programador PIC Pablin II

Expreso 12c508A 6V.

El módulo Quasi '508A es realmente un 'F84 cableado para que funcione como un '508A y esto significa que el programa se puede reprogramar cuantas veces sea necesario, durante el desarrollo del programa. El 'F84 constituye el módulo Quasi '508A es quemado y sacado en los proyectos de Prácticas y para otras aplicaciones. Una vez se desarrolla y perfecciona el proyecto, éste puede ser quemado en un OTP más económico el '508A y ensamblado en el proyecto desarrollado, el programador mantiene la opción de modificar el contenido. Este es el motivo por el que programar con PIC puede ser una forma provechosa de trabajo.

Qué necesito.

Para crear un programa para el '508A, disponemos de los artículos que se exponen en estas páginas y otras de otros autores. Los programas pueden ser escritos en un cuaderno o sobre papel, de allí serán transferidos a un programa de computador, cada línea se escribe con la ayuda de los mnemónicos, un lenguaje de programación medio inglés, a medio camino entre usuario y compilador.

De este modo el programa es convertido a código hexadecimal mediante el programa MPLAB de MicroChip, es libre, sin costo y está disponible a través del propio enlace. El archivo .hex creado, se envía al microcontrolador en formato binario (1's y 0's) para quemarlo en la memoria del chip.

No debe preocuparse por la falta de espacio de programa de 1FF posiciones del ' 508A. Esto equivale a más de 500 líneas de código, si en unas páginas de papel escribe 50 instrucciones, esto representa más de 10 páginas. Realmente, sólo se dispone de 255 posiciones para su uso, pero esto, evidentemente es un programa muy largo. Sin embargo, en el mejor de los casos, si se necesita un espacio mayor, recomiendo revisar la gama de productos de la empresa Microchip, es muy extensa y crece cada día.

Un punto a recordar; cuando se escribe y desarrolla un programa, éste consistirá en, muchas subrutinas que siguen a una rutina principal. Éstas subrutinas se llamarán una o muchas veces entre sí. De modo que cuando un programa se hace largo, debemos encontrar cómo puede usar las subrutinas que ya se han escrito y entonces el programa se hará más eficiente.

NOTACIÓN EN HEX.

Todos los valores en un programa se escriben en HEX. Esto hace la escritura de un programa más compleja, por la comprensión del hex que nos acerca un poco más a cómo trabaja y nos permite resolver los valores para las líneas de entrada o salida de puerto individual. 

Los valores del programa se cargan en un registro llamado registro de trabajo

Page 118: Programador PIC Pablin II

(W), estos valores se llaman LITERALES. Un literal es simplemente otro nombre del valor o número. El código hex tiene una base de dieciséis números que son:          0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A= diez, B= once, C= doce, D= trece, E= catorce y F= quince. Como se debe recordar, 12 en decimal es igual a 0C en hex y 16 en decimal es igual a 0F. Es fácil ver que 3E (igual a sesenta y dos) es un valor hex, para hacer fácil reconocer valores hex como 23 o 41 u 82, colocaremos una 'h' pequeña después del valor, así: 41h, 23h, 82h.

Un registro puede contener un valor desde 00 a FFh que representa un valor desde cero a doscientos cincuenta y cinco en decimal. Véase que la página de hex valora de 00 a 1FF en otro de los artículos, para ver la notación estructurada en hex. Puede que nos lleve algo de tiempo entender el hex, pero mientras se lo piensa, hay otro concepto que se debe considerar: BINARIO-a-HEX.

Todos los registros del '508A y el 'F84 comprenden 8 "celdas" en las que se coloca un 'cero' o un 'uno'. Las ocho celdas se separan en dos grupos, uno de 4 celdas superiores y otro de 4 celdas inferiores. Las 4 celdas superiores llamadas 'nibble' alto y las 4 celdas inferiores, 'nibble' bajo. Para leer el valor completo de un registro hex, se combinan ambos 'nibble' alto y 'nibble' bajo.

Nº Bit 7 6 5 4 3 2 1 0

Registro

0 0 0 0 0 0 0 0

nibble alto

nibble bajo

Cada línea GP (una línea GP es una línea entada/salida de Propósito General) corresponde a un bit en el archivo 06. La línea GP0 (bit0) corresponde al Bit Menos Significativo (LSB) y GP1 corresponde al siguiente bit (bit1). Ahora, aquí viene el bit más difícil de en tender, pero esto es lógico. 

REGISTRO 06h

 MSB

   MSB

      LSB

'508A

- - -GP4

GP3

GP2

GP1

GP0

F84A

RB7RB6

RB5

RB4RB3

RB2

RB1

RB0

Para poner GP0 como línea de salida, el bit menos significativo (LSB) en el archivo 06 debe ser 0, "0" significa salida. 

Hacer GP0 BAJO:

Page 119: Programador PIC Pablin II

MOVLW 08   ;Carga w con 0000 1000 TRIS 06        ;carga el registro TRIS BCF 06,0      ;haz el bit 0 BAJO 

Para poner GP0 como línea de entrada, el bit menos significativo (LSB) en el archivo 06 debe ser 1, "1" significa entrada.

Hacer GP0 ALTO: 

MOVLW 08       ;Carga w con 0000 1000 TRIS  06;           ; carga en registro de TRIS BSF  06,0          ;haz bit 0 ALTO 

Suponga que quiere hacer GP0, GP1 y GP2 como entradas. Los tres bits bajos deben ser "1", esto pone el archivo = 0000 0111 = 07. Suponga ahora que quiere configurar GP3 como entrada, el valor del archivo será = 0000 1000 = 08. Suponga ahora que quiere configurar GP5 y GP3 como entradas, el valor del archivo será = 0010 1000 = 28h, el resto serán salidas.

Se puede introducir cualquier combinación de líneas como entrada o salida y es esencial entender la notación en hex para poner el valor a cargar el archivo 06. El archivo 06 tiene un nombre genérico, se le conoce como Puerto_A y sólo tiene 6 bits funcionales (no se si es casualidad que tenga 6 bits y le llamen registro 06), todos los demás archivos tienen 8 bits. Necesitamos conocer el valor hex cuando se cargue en un archivo por que puede tengamos que saber:

a) Cuando cierto bit es puesto EN, en un archivo siendo incrementado.b) El archivo máximo que contendrá una tabla.c) El modelo de salida cuando un contador ha sido 'cargado'.

Al escribir programas, se implican valores binarios en todos las etapas y el hex es simplemente más corto de mostrar  que el binario usando 2 dígitos. El hex es fácil de ver y leer, además mentalmente se puede convertir de binario a hex y de binario a hex muy rápidamente.

LOS ARCHIVOS.

El ' 508A contiene 32 archivos o registros de los cuales los primeros siete (00h a 06h) se llaman Registros de Función eSpecial (FSR) y los siguientes 25 (07h a 1Fh) son archivos o Registros de Propósito General (GPR). El F84 tiene doce SFR (00h a 0Bh) y los siguientes sesenta y ocho (0Ch a 4Fh) se llaman 'Archivos'.

Veinte archivos son comunes al ' 508A y al F84. Estos son: 0Ch, 0Dh, 0Eh, 0Fh, 10h, 11h, 12h, 13h, 14h, 15h, 16h, 17h, 18h, 19h, 1Ah, 1Bh, 1Ch, 1Dh, 1Eh, 1Fh. Estos son, los archivos que usaremos. Cada archivo tiene 8 bits que pueden tomar el valor 0 o 1, cuando todos los bits son Cero (0000 0000), el archivo tiene valor cero.

Page 120: Programador PIC Pablin II

Cuando el LSB es 1, el archivo tiene el valor de 1, ya hemos mostrado como 'nibble' bajo en los incrementos del archivo F (ver Notación de hex) al principio del artículo. El siguiente incremento después de 0F produce 0001 0000 = 10h, luego 0001 0001 = 11h. Al incrementar del archivo 1111 1111 = FF darán la vuelta a 0000 0000. Antes de dejar el hex, hay una habilidad más que necesitará. Esto convierte binario a hex luego podrá poner bits EN [1] en un archivo.

El ajuste de bits solos es fácil. Aquí está la tabla:

  Binario      Valor    Bit0000 0001 = 01h = bit00000 0010 = 02h = bit10000 0100 = 04h = bit20000 1000 = 08h = bit30001 0000 = 10h = bit40010 0000 = 20h = bit50100 0000 = 40h = bit61000 0000 = 80h = bit7

Para poner EN [a 1] DOS o MÁS BITS en el 'nibble' alto o bajo, léalo. Recuerde, se llama bit más bajo al bit0 y el más alto es el bit7. Para poner EN los bit2 y bit3, el valor binario es: 0000 1100. Tómese como referencia la tabla anterior, en la que se puede ver que esto es 08h más 04h. Y ¿cómo se suma 08h y 04h? Simple, se toma el valor más alto 08 y se añaden cuatro cuentas, así; + nueve, + A, + Be y + Ce, la cuenta nos da 0Ch.

Para poner EN los bit6, bit5 y bit4, el procedimiento es: 0111 0000. Esto es 40h más 20h más 10h. Para hacer las cosas simples, tomamos los nibble altos, o sea, 4h más 2h más1h, esto suma 7h, entonces la respuesta es 70h.

Otro ejemplo: para poner EN los bit7, bit6, bit5 y bit4, el procedimiento es: 1111 0000 = 80h mas 40h mas 20h mas 10h. El nibble alto de esto es: 8h+4h+2h+1h, empezamos con el 8 e incrementamos cuatro cuentas, así: nueve, A, Be y Ce, ahora incremento dos cuentas: De y E y entonces incremento una cuenta eFe. Esto da  F y le añado el nibble bajo 0, la respuesta es: F0h. Esto, le llevará algo de tiempo para tener pericia, pero trabaje sobre esto, ganará tiempo cuando lo domine.

EL REGISTRO DE TRABAJO (W)

El registro W o de trabajo es el registro más importante en el chip. Este registro actúa como una cesta en un supermercado, recogiendo un valor del programa, como un Literal, un byte de datos de una tabla, un valor de cualquiera de los archivos o bits de datos del puerto de entrada y entregándolo a otro archivo o al puerto de salida.

El puerto de salida es el archivo 06 y cualquier valor entregado a este archivo vía W, está disponible para transferirlo. Esto también ocurre al revés,

Page 121: Programador PIC Pablin II

cualquier valor del mundo exterior presente en este archivo, es entregado al archivo 06 y del archivo 06 éste valor puede ser pasado al registro de trabajo W. El registro de trabajo puede ser limpiado (puesto a cero) o cargado con un número (llamado literal).

Los bits del registro de trabajo W no pueden ser comprobados, limpiados o poner EN ni intercambiar los nibbles, tampoco puede ser incrementado, decrementado o rotados sus bits, estas operaciones tienen que hacerse sobre un valor en un archivo. El registro de trabajo W es un concepto, no tiene una posición de dirección, simplemente lo llamamos "W" en una instrucción, es simplemente 'El portador' o 'Ayudante' en el sistema.

EL DESIGNADOR.

Hay rasgos en el juego de instrucciones del PIC que lo hacen muy 'poderoso'. Por este motivo pensamos que una instrucción sola incorpora dos o tres cosas. En los primeros microprocesadores, una instrucción sólo hacía una cosa y por eso se necesitaban muchas instrucciones en el juego de instrucciones. Uno de los rasgos inteligentes del juego de instrucciones del PIC es el designador, éste es el número 1 o el 0 adicional a la instrucción para decirle al micro donde poner el resultado de la operación.

Si tomamos la instrucción ANDWF 0C,1 el resultado es colocado en el archivo 0C. Si usamos la instrucción ANDWF 0C,0 el resultado es colocado en el registro W. Hay una importancia obvia al seleccionar la instrucción correcta, con la primera instrucción se cambia el contenido del archivo 0C, mientras que en la segunda instrucción no cambia 0C y puede que no queramos cambiar 0C.

Con algunas instrucciones es más fácil de ver el objetivo del designador. Por ejemplo, MOVF 0C,1 simplemente mueve el contenido del archivo 0C dentro y fuera de 0C y cambia las banderas (flags). Esto no pone el contenido en W, para poner el contenido en W, debe ser usada la instrucción MOVF 0C,0.

Al escribir un programa es importante incluir el designador, si se olvida el compilador (MPASM) agregará un 'falta designador' y presentará la condición. Se debe comprobar que no falta el designador, puede producir el resultado no requerido, por ejemplo: MOVF 0C,1 no pone el contenido de 0C en W, esto simplemente mueve el contenido (mete y saca) de 0C.

ESCRITURA DE UN PROGRAMA.

El programa en un ' 508A comienza en 000 y se extiende a 1FF, esto es un número hexadecimal y corresponde a 512 posiciones (512 líneas de código). Sólo podemos usar hasta 511 posiciones de dirección, la posición superior es usada por el micro como un valor de calibración (OSCCAL).

Page 122: Programador PIC Pablin II

Por las aplicaciones podremos hablar de (juegos, demostraciones, temporizadores, contadores, etc.) 511 líneas de código es un buen tamaño de programa, especialmente cuando se considera que el chip es capaz de tomar el espacio de 5 o más chips en el proyecto. Antes de la escritura de un programa, se debería examinar los proyectos que se han incluido en este sitio, así como las Librerías de términos y rutinas, para tener alguna idea de que se puede hacer con el micro.

Esto también nos dará una idea de como son escritas las instrucciones y el tipo de instrucción requerida para una operación particular. El modo más fácil de aprender es con el ejemplo y gastando tiempo con proyectos y en mirar las rutinas de bibliotecas que nos iniciaran en los 'bloques de partida'.

 La mayor parte de las ideas que acuden escribiendo un programa no llegan a verse en la versión final del proyecto, vamos a ver lo que el programador piensa cuando él produce una rutina. En primer lugar, él tiene que resolver lo que el proyecto ha de hacer. Él no se preocupa del programa o del micro, por el momento, solamente piensa lo que él quiere VER que el proyecto ha de hacer. En primer lugar produce una descripción total en forma de ensayo, toma apuntes o produce un organigrama. Todo lo referente a micro, patillas, LED's de colores, tiempos y tipos de sonidos vendrán más tarde.

ORGANIGRAMAS Y ORGANIGRAMAS.

Algunas escuelas de pensamiento creen que un organigrama es esencial para acertar el programa. Si el lector no está puesto con los símbolos de los organigramas o cómo producir tal carta, no se preocupe, otras escuelas consideran el tema, son absolutamente innecesarios. Para los que son entusiastas de los organigramas, sólo hay tres símbolos de organigrama que tiene que conocer. Estos son:   Ovalo de inicio o parada, rectángulo que ejecuta una operación y el diamante de decisión donde tomar una decisión como un "SI" o "NO", "Entrada" o "Salida". Estas formas se conectan con líneas con flechas que indican la dirección de flujo del programa.

Un organigrama ayuda a otros a entender qué hace el programa y da una

Page 123: Programador PIC Pablin II

idea de su complejidad. El mejor modo de comenzar un proyecto nuevo es, escribir una descripción de la operación entera. Luego se separa en secciones y se coloca cada paso de 'operaciones' en un rectángulo. Cualquier etapa de toma de decisiones se colocan en un diamante, entonces se unen con líneas y flechas y ¡Vaya! ¡hemos producido nuestro propio organigrama!

Después se toma cada sección y se convierte en los pasos que pueden ser realizados por el microcontrolador. Aquí es donde empieza la aplicación de los conocimientos del programa. Para hacer esto tiene que entender el juego de instrucciones, sólo entonces podremos escribir las instrucciones correctas. Es muy importante ponerlas en el orden correcto entonces el resultado será exactamente como se esperaba.

EL PROGRAMA MÁS SIMPLE.

El programa más simple se encarga de cargar el registro de trabajo W con el valor "1" y la salida del mismo en GP0. Si un LED en serie con una R resistencia de 470 a 1kOhms se conecta a GP0, esto iluminará el LED cuando esta instrucción se ejecute.

Pero antes de que podamos controlar este sencillo programa, tenemos que "estructurar" el puerto GP0 para que sea una salida, como se describe en el artículo. Así que, volvamos al principio.

;=============== PROGRAMA MUY SIMPLE ========== ; GP0 = SALIDA ; GP3 = ENTRADA ;===================================== Sistema MOVLW 3E TRIS 06 ;carga archivo TRISB Salida MOVLW 01 ;carga W con 1 MOVWF 06h ;pone GP0 alto GOTO salida

GP0 Es una de las líneas de entrada/salida del chip, antes de que un programa ponga un valor en la salida, esta línea del puerto debe ser

Page 124: Programador PIC Pablin II

"establecida" para que GP0 sea una salida. GP0 es el bit0 del registro TRIS y debe ser "0" para ser una salida. Los haremos "1" (entrada) para demostrar el hecho que el puerto del '508A tiene sólo 6 líneas, así , el registro TRIS será; 0011 1110 = 3Eh. Ya que usamos el Quasi'508A para el desarrollo del programa, las instrucciones para la "estructuración" son así:

Sistema MOVLW 3E ;pone GP0 como salida TRIS 06h ;Carga archivo TRISB

GP0 es ahora una línea de salida, esto entregará un EN al mundo exterior cuando sea cargado un "1" en el bit0 del archivo 06, se han usado estas instrucciones:

MOVLW 01 ;Carga W con 1 MOVWF 06h ;Mueve W al archivo 06

La línea GP0 producirá un EN y si tenemos un LED conectado a esta línea se iluminará cuando las dos instrucciones anteriores más las instrucciones de estructura son ejecutadas. Cuando este programa es cargado en un chip, sobre el módulo Qasi '508A, se puede pensar en un puntero imaginario que comienza en la primera instrucción y se pasa a la unidad central para la ejecución.

El 'puntero' es el Contador de Programa, este empieza en 000 e incrementa una posición a la vez y alimenta el código (en la dirección) a la unidad central donde es interpretado. Una vez el micro es puesto a operar, no se para y sigue bajo el programa. En el programa anterior, el Contador de Programa "escapará al final del programa", para impedir esto es necesario pasar instrucciones adicionales para "dirigir" el contador de programa, arriba se muestra el programa completo.

El primer 06h en el programa no es el registro de puerto, este es el TRISB. El segundo 06h es el puerto de entrada /salida. La instrucción GOTO crea un lazo para hacer ir al micro a la etiqueta "salida". Una vez el micro entra en este lazo, nunca sale, a menos que falte la energía.

Las instrucciones para hacer el LSB en el registro TRIS como salida son:

MOVLW 3Eh ;Pone 0011 1110 en W para hacer GP0 una salida TRIS 06h

El valor binario 0011 1110 muestra que los bits 6 y 7 no se usan, como el '508A tiene sólo 6 líneas de puerto y el resto de líneas serán líneas de entrada (como muestran los "1"), excepto el bit más bajo, que será una salida. En otras palabras, sólo tenemos que hacer bit0 un cero. El valor en W se

Page 125: Programador PIC Pablin II

moverá al registro de TRIS y esto hará del BIT Menos Significativo en TRIS una salida. El puerto se establece ahora con el LSB una salida. Esta línea se llama GP0 (línea 0 Propósito General).

LOS ARCHIVOS .ASM

Los programas se escriben usando las 33/36 instrucciones PIC en una libreta o editor y guardados con la extensión .asm (punto asm). Cuando un programa se escribe como muestra el 'programa mas simple', lo llaman código ensamblador y se guarda con la extensión .asm. Es decir, se ha escrito para un ensamblador, llamemos al ensamblador que usaremos MPASM y esto localizará todas las etiquetas y las convertirá en una dirección, convirtiendo las instrucciones para trabajar en código máquina. El resultado es un archivo con extensión .hex.

OTRO PROGRAMA SIMPLE

Podemos incluir un botón pulsador, a añadir en nuestro "programa más simple". El pulsador se agrega al circuito para que cuando éste sea pulsado, GP3 vea un alto [a esto se le llama lógica positiva]. Ahora el programa se activa para cuando se pulsa el botón encienda un LED, esto debe ser convertido en un juego de instrucciones que puedan ser ejecutadas por el ' 508A.

El programa necesita para hacer esto un lazo, entonces el pulsador se detectará cuando sea presionado y conectará el LED y cuando sea liberado el pulsador el LED se apagará.

ADJUNTAR AL PROGRAMA MÁS SIMPLE MOVLW 3E TRIS 06 ;GP0 salida, GP3 entrada btn BTFSS 06,3 ;comprueba GP3, detecta si es

pulsado GOTO Libre ; si si, salta esta línea GOTO Pulsdo Pulsdo BSF 06,0 ;activa GP0 GOTO btn

Page 126: Programador PIC Pablin II

Libre BCF 06,0 ;apaga GP0 GOTO btn

De ahora en adelante, todos lo programas contienen un lazo, el programa más simple anterior es el único programa que usa un lazo "callejón sin salida", un programa normal es una forma de lazo completamente funcional, ya que el micro ejecuta instrucciones a razón de aproximadamente un millón por segundo, un lazo se ejecutará muchas veces por segundo.

Las instrucciones en el lazo deben incluir un detector de botón pulsado o no, dando una salida ALTA o BAJA sobre una línea cambiando EN o AP el LED, estableciendo el registro TRIS para que GP0 sea una salida y GP3 sea una entrada. Las dos primeras líneas del programa son las mismas que en el programa más simple, sin embargo la línea btn BTFSS 06,3 es el detector de pulsado o no. Esta instrucción comprueba el bit3 del archivo 06 (archivo del puerto), el micro 'lee' el puerto y comprueba el bit3 para ver si lo pone alto.

El micro saltará la siguiente instrucción del programa si el bit es alto, cuando el pulsador es presionado, la línea será alta y el bit3 será puesto EN. Si el bit está EN (botón pulsado) el micro ejecutará la instrucción GOTO pulsdo.

GOTO libre GOTO Pulsdo

Hemos creado dos ramas en el programa, la rama libre, cuando está liberado el pulsador y la rama pulsado, cuando está presionado.

Si el bit es EN, el pulsador estará presionado. El juego de instrucciones para la mini-rutina son: Pon alto GP0 y entonces ir a btn y vigila la entrada: Pulsdo BSF 06,0  y GOTO btn

Si el bit está limpio [Clear], entonces será bajo por lo tanto el pulsador no está presionado. Ahora tenemos que producir una o más instrucciones para la mini-rutina de 'aclarado' [Clear]. Las instrucciones para aclarado limpiarán el bit0 del puerto para que la línea GP0 sea Baja y el LED se apagará:  libre  BCF 06,0 ; apagar el LED.

Ahora el micro debe ser enviado atrás para vigilar el puerto otra vez y comprobar la condición del pulsador, esta instrucción es GOTO btn. El programa estará constantemente formando lazos con la instrucción para vigilar el pulsador y cambiar el LED encendido o apagado.

LED QUE DESTELLA

Si queremos hacer que un LED encienda y apague automáticamente, necesitaremos un juego de instrucciones diferente, en primer lugar necesitamos instrucciones para poner el LED alto, luego una rutina para mantenerlo encendido por un periodo de tiempo (llamado rutina de retardo), además instrucciones para poner el LED apagado y finalmente una rutina de

Page 127: Programador PIC Pablin II

retardo.

El programa al llegar al final vuelve atrás donde el LED se activa, el resultado es un LED intermitente. El organigrama anterior describe mejor esta secuencia usando los símbolos mostrados antes. Esto ayuda a ver el número de pasos implicados en el programa. Del organigrama podemos deducir una disposición para el programa.

Sistema - - - -- ; Las instrucciones de estructuración ; van - - - -- ; aquí GOTO principal Retardo - - - -- ; Las instrucciones de

retardo ; van aquí ; RETLW 00 inicio - - - -- ;Conecta instrucciones - - - -- ; van aquí llamada de retardo - - - -- ; instrucciones apagar LED

van aquí - - - -- ; instrucciones apagar LED

van aquí llamada de retardo GOTO inicio

Esto sigue con una segunda parte, los proyectos diseñados para ejercitarse el

Page 128: Programador PIC Pablin II

lector se encuentran disponibles en otros artículos. 

PRIMER PROYECTO CON EL PIC 16F84A

Sabado, 03 de Octubre del 2009__________________ Incluir en favoritos si quiere volver a visitarnos.

Introducción.

Esta es la primera incursión en este apartado de programación para microcontroladores PIC, pretendo mostrar algunos proyectos con los que el interesado en aprender a programar microcontroladores PIC, consiga ciertos conocimientos y cierta fluidez, al mismo tiempo que disponga de una 'librería' de rutinas en la que inspirarse a la hora de plantear un proyecto o la solución a un posible problema que le surja. 

El Primer Proyecto.

Esta pretende ser una aproximación muy lineal a la escritura de un programa. Son muchos los que escriben y producen subrutinas muy pequeñas con saltos (GOTO's) de una subrutina a otra, de modo que el programa salta por todas partes como 'palomitas de maíz'. El micro es capaz, perfectamente capaz de saltar por un programa, sin embargo, éste tipo de disposición es muy difícil de seguir incluso por un lector avezado.

Es mucho más fácil seguir la secuencia de acontecimientos y así, muy pronto seremos capaces de escribir programas similares a los de la sección de proyectos de cualquier empresa." - Así, empieza otro de los artículos que tengo en esta web.

En incontables sitios se utiliza un listado de apoyo al que se inicia en la programación, dicho listado describe qué hace dicho listado. En este caso describe, cómo controlar el encendido y apagado de un punto de luz mediante un diodo LED. Después de considerar otros modos de empezar este camino, he llegado a la conclusión que, por algo hay que empezar y ese camino trazado por otros puede que sea el mejor y en ello estamos.

Se debe utilizar un editor de texto que no añada códigos extraños, puede utilizarse el Bloc de Notas, aunque hay otros más adaptados a la programación que ofrecen mejores prestaciones como el EditPlus2, eso lo dejo a elección del lector. El MPLAB integra un editor eficiente, aunque tiene sus "cosas" y distingue

Page 129: Programador PIC Pablin II

entre mayúsculas y minúsculas, así que, decídase por un criterio y sigamos.

El listado del programa en lenguaje ensamblador se muestra en las líneas siguientes, recuérdese que cualquier línea que empieza por un ';' (punto y coma) se interpretará como un comentario sin efecto en el programa, estas líneas sirven de ayuda y recomiendo utilizarlas para una mejor comprensión de qué hace el programa en ciertos momentos.

El listado debe ser guardado con la extensión .asm  

01 ;******************************************************************* 02 ; Autor: V. Garcia 03 ; Fecha:06/07/2005 04 ; Titulo: rutina1.asm 05 ; Programa de ejemplo para detallar las lineas que lo integran y 06 ; detallar rutinas. 07 ;******************************************************************

* 08 list p=16F84 09 #include "p16F84A.inc" ;Encabezado para el MPLAB 10 11 ; Igualdades o "equ" y Mapa de memoria 12 13 port_a equ 0x05h ;registro del puerto A 14 port_b equ 0x06h ;registro del puerto B 15 trisa equ 0x05h ;registro trisa 16 trisb equ 0x06h ;registro trisb 17 status equ 0x03h ; 18 count1 equ 0x0Ch ;variables que usemos siempre a 19 count2 equ 0x0Dh ; partir de la direccion 0Ch 20 count3 equ 0x0Eh

22 org 0x00 ;origen del programa 23 goto Primero ;se pone este GOTO para que salte al

principio;

25 Primero: bsf status, RP0 ;selecciona banco 1 para configurarlo 26 bcf tris_b, 03 ;pone a 0 el bit 3 (RB3) como

salida 27 bcf status, RP0 ;selecciona banco 0, para

continuar programa

29 inicio: 30 call flash ;Llama la subrutina flash para destellar

brevemente LED 31 call ret_largo ;Llama la subrutina ret_largo, donde

espera un tiempo 32 goto inicio ;Hazlo otra vez, y otra vez, ...

34 ;Subrutina para destellar el LED, una vez 25 flash: 36 bsf port_b, 03 ;pone a 1 el bit 3 del puerto B, que

enciende el LED 37 call ret ;llama la subrutina para retardo corto,

mientras el LED luce

Page 130: Programador PIC Pablin II

38 bcf port_b, 03 ;pone a 0 el bit 3 del puerto B, que apaga LED 39 return ;retorna al punto de llamada.

41 ;Retardo largo, lazo de subrutina que llama la subrutina de retardo corto 42 ret_largo: ;inicializar contador retardo

largo 43 movlw 0x03Fh ;carga el acumulador con el valor 3Fh 44 movwf count3 ;mueve el contenido del acumulador a

count3,

45 largo1: call ret ;llama la subrutina retardo corto 46 decfsz count3, 1 ;Decrementa count3, guarda el resultado en

F y;si no es cero salta la siguiente

instruccion. 47 goto largo1 ;vuelve a decrementar mientras largo1 no

sea 0 48 return ;si es 0, regresa al punto de llamada.

50 ;La subrutina de retardo corta con dos lazos anidados. - 51 ret: movlw 0xFF ;Carga el acumulador con el valor FF 52 movwf count1 ;mueve contenido del acumulador a count1

;para iniciar lazo externo. 54 ret1: movlw 0x0Fh ;Carga el acumulador con el valor 0Fh 55 movwf count2 ;mueve contenido del acumulador a count2

;para iniciar lazo interno 57 ret2: decfsz count2, 1 ;decrementa contador de lazo interno,

guarda el resultado en F ;si no es cero salta una instruccion.

58 goto ret2 ;volver a la subrutina ret2 otra vez (lazo ret2) 59 decfsz count1, 1 ;decrementa count1 (lazo externo) si

contador no es cero; salta una instruccion.

60 goto ret1 ;vuelve a decrementar mientras ret1 no sea 0. 61 return ;si es 0, retorna al punto de llamada. 63 END ; Termina el programa

Lo qué hemos hecho.

Recordar que todo lo que hay en una línea, detrás de un punto y coma (';') son comentarios que no influyen en el programa ensamblador MPLAB, sólo se usan como ayuda. Para que el listado tenga cierta coherencia, se recomienda utilizar el tabulador en 8 para crear los espacios necesarios y que haya claridad en el listado. En el listado anterior, se ha incluido el número de línea como ayuda a esta descripción, no se deben poner en su programa.

En las primeras líneas se hacen los comentarios que describen cual es el motivo del archivo. ;******************************************************

Page 131: Programador PIC Pablin II

******* ; Autor: V. Garcia Fecha: 06/07/2005 ; Titulo: rutina1.asm ; Prueba para detallar las líneas que lo integran ; ;*************************************************************

En las líneas 8 y 9 se indica al ensamblador que vamos a trabajar con el PIC 16F84, es necesaria su inclusión. La definición de etiqueta estándar de PIC16F84A es leída según la directriz INCLUDE. Los archivos de definición generalmente son instalados en el lugar ;       C:\Program Files\Mplab\p16f84a.inc

Al respecto del MPLAB, como este programa no admite cabeceras mayores de 60 digitos, es conveniente que creemos un carpeta, para contener nuestros ejemplos o proyectos, como C:\Archivos de Programa\Mplab\proyetos\, donde guardaremos los listados, esto nos evitará algunos errores, cuando vayamos a compilar posteriormente. ;**************************************** 8 list p=16F84 ;Define tipo de procesador 9 #include "p16F84A.inc" ;Encabezado ;****************************************

En las líneas de la 13 a 17 se declaran las "equ" o igualdades, de la memoria. ;**************************************** 13 port_a equ 0x05h ;registro del puerto A    14 port_b equ 0x06h ;registro del puerto B 15 trisa equ 0x05h ;registro trisa 16 trisb equ 0x06h ;registro trisb 17 estado equ 0x03h ;****************************************

En las siguientes líneas se definen las etiquetas y direcciones de uso personal llamadas de propósito general, las direcciones de los registros personales u otros que vayamos a utilizar en el programa, éstas las decide el analista en función de sus necesidades y según el mapa de memoria que empieza en 0Ch, en el caso del F84. Debe observarse, donde empieza dicho mapa de memoria que, puede variar en cada modelo de microcontrolador.  ;****************************************** 18 conta1 equ 0x0Ch ;define contador 1.- Variables que usemos siempre a 19 conta2 equ 0x0Dh ;define contador 2 partir de la direccion 0Ch 20 conta3 equ 0x0Eh ;define contador 3 ;******************************************

En la línea 22, se encuentra el origen del programa, es decir, al iniciar el programa o al dar tensión de la fuente de alimentación al micro, es donde irá el programa cada vez que se inicie o cada véz que se resetea o hay un corte de

Page 132: Programador PIC Pablin II

suministro. Le sigue la orden de salto GOTO que hace saltar al programa hasta la etiqueta que le sigue, en este caso Primero ;****************************************** 22 org 0x00 ; origen del programa 23 goto Primero ;se no este GOTO para que salte al principio ;******************************************

El las líneas siguientes se definen donde empiezan las posiciones de memoria; los bancos 0 y 1, los PuertoA, PuertoB y los TRISA y el TRISB con sus posiciones. Al referirnos al Puerto A o Puerto B, nos estamos refiriendo implícitamente al Banco 0, ya que el banco 0 no dispone de los tres registros TRIS y OPTION, por este motivo se llama de 'memoria paginada', ver el mapa de memoria siguiente.

El Registro STATUS está definido por los 8 bits siguientes:

Según las hojas de especificaciones, la memoria de datos se divide en múltiples bancos, que contienen los GPRs (Registros de Objetivo General) y los SFRs (Registros de Función Especial). Los Bits RP0 y RP1 son los bits de selección de banco, el 'F8A tiene los banco 0 y banco 1, con un sólo bit se direccionan 2 bancos (los

Page 133: Programador PIC Pablin II

que tiene el F84), con dos bits 4 bancos, etc.

Bti7

Bit6Bit5

Bit4

Bit3

Bit2

Bit1

Bit0

IRP

RP1

RP0

TO PD Z DC C

  1 Banco 1 operativo

  0 Banco 0 operativo

La tabla anterior, muestra que los bancos vienen definidos por el estado del bit (5) RP0, de modo que, si RP0 = 1 el Banco 1 es el banco operativo, en el cual dispondremos la configuración de los puertos y definiremos los estados especiales de cada registro en el que debamos intervenir, como los puertos y el estado de sus bits. Si RP0 = 0 el Banco 0 es el banco operativo. En este banco 0 es donde se ejecuta el programa con sus rutinas y subrutinas.

Con viene aclarar este tema, ya que siempre produce confusiones en los que se inician en la programación.

    NO SE DEBE CONFUNDIR, POSICION DE MEMORIA DE UN REGISTRO, CON SU CONTENIDO (SU VALOR).

Veamos un ejemplo:

-Tenemos una mesa con cuatro grandes cajones numerados del 0 al 3 (son los bancos de memoria).-Cada cajón contiene carpetas numeradas desde el 0 al 127 (son los 128 registros de cada banco).-Y cada carpeta admite un máximo de 256 folios (el mayor valor que puede adoptar un registro de 8 bits, de 0 a 255)

Entendido este concepto, si necesitamos archivar 12 folios en la carpeta 43 del cajón 2. Cómo lo haríamos.

Se procedería de esta forma:

BSF STATUS,RP1 ; para seleccionar el banco 2 ó 3 (cajón 2 ó 3) BCF STATUS,RP0 ; aquí defino banco 2 (elijo cajón 2, entre el

2 y el 3) ; ahora, el segundo paso movlw .12 ; cojo los 12 folios y addwf .43, 1 ; los archivo en la carpeta y se los añado a

lo que ya tenía el cajón 43.

Nota. - Los valores expresados se harán en hexadecimal acompañados al final de una

h, en caso de hacerlo en binario con una b y cuando sea en decimal anteponer un (.) punto.

Page 134: Programador PIC Pablin II

- Las etiquetas y nombres de registros se expresarán en una silaba de 8 letras, se admite el subguión '_' para unir dos.- Los nombres de los registros, conviene definirlos en minúsculas, así pues, Port A o Puerto A, lo pondremos siempre como una sola palabra porta o puertoa o también porta o puerto_a, el modo de definición es importante ya que, en el programa siempre nos tendremos que referir del mismo modo, véase el archivo inc del micro usado para más detalles. Otro ejemplo, en lugar de 'PuertoA equ 05' podemos poner 'porta equ 05' y cada vez que nos referimos al Puerto A, lo haremos como 'porta'. Sin embargo, es conveniente no modificar las definiciones que ya dispone el archivo que viene por defecto con la terminación .inc

A continuación, en las siguientes líneas, como ya se ha mencionado, definimos los pines de entrada y salida: ;****************** Mapa de memoria

******************* 22 Primero: bsf status, RP0 ;selecciona banco 1 para

configurarlo 23 bcf tris_b, 3 ;pone a 0 el bit 3 (RB3) como

salida 24 bcf status, RP0 ;selecciona banco 0, para

continuar programa ;***************************************************

Las instrucciones bsf (bit set file) ponen un bit RP0 del registro 'status' a 1. Como ya se dijo, si el bit 5 del registro status está a 1, entonces estamos trabajando en el banco 1, se hace esto para definir los pines de entrada/salida de los puertos del micro. 

En esta sección se puede encontrar una disposición algo modificada aunque no presenta diferencias de cara al micro. Me estoy refiriendo a una definición como:

;****************** Mapa de memoria ******************* 22 BSF 03,5 ;Ir al banco 1 23 MOVLW 0F ;Pon 0000 1111 en W para 24 MOVWF 05 ; hacer RA0, RA1, RA2 y RA3

entradas 25 BCF 03,5 ;Ir a banco 0 26 GOTO Primero ;***************************************************

Incluso como:

;****************** Mapa de memoria ******************* 22 bank1 ;Seleccion del Banco 1 23 movlw 0x01 ;w = 0x01 24 movwf trisb ;Bit 0 de trisb en "1" RB0 = IN;

RB1-RB7 = 0 25 clrf trisa ;trisa = 0, Todo el Puerto RA =

Salida 26 bank0 ;seleccion del Banco 0

Page 135: Programador PIC Pablin II

;*************************************************** Aunque para esto, antes deberemos definir bank1 y bank0, en la sección "equs", como sigue:

;****************** Mapa de memoria ******************* 18 #define bank1 bsf status,5 ;Macro para abreviar

el banco 1 19 #define bank0 bcf status,5 ;Macro para abreviar

el banco 0 ;***************************************************

Ahora, sigue la rutina principal que hace llamadas mediante la instrucción CALL, a distintas subrutinas. ;*****************************************************

******* 27 inicio: ;Etiqueta de la rutina principal 28 call flash ;Llama la subrutina flash para

destellar brevemente LED 29 call ret_largo ;Llama la subrutina ret_largo,

donde espera un tiempo 30 goto inicio ;Hazlo otra vez, y otra vez, ... ;******************************************************

*******

Le sigue la subrutina encargada de encender y apagar el LED (en este ejempo)  ;*****************************************************

******* 32 ;Subrutina para destellar el LED una vez,

brevemente 33 flash: 34 bsf port_b, 03 ;pone a 1 el bit 3 del puerto

B, que enciende el LED 35 call ret ;llama a subrutina retardo corto,

mientras, luce LED 36 bcf port_b, 03 ;pone a 0 el bit 3 del puerto

B, que apaga LED 37 return ;retorna al punto de llamada. ;******************************************************

******

Si es el caso, definiremos nuevas rutinas que realicen nuevas tareas, como es un retardo corto y uno largo. Cuando las secuencias de encendido y apagado se suceden muy rápido, puede ser de utilidad usar un retardo, permitiendo que el efecto se aprecie por el ojo, debemos tener presente que el microcontrolador es muy rápido y no permite ver ciertos eventos si no se usan los retardos. ;******************************************************

****** 39;Retardo largo lazo de la subrutina que llama la

subrutina retardo corto

Page 136: Programador PIC Pablin II

40 ret_largo: ;inicializar contador retardo largo 41 movlw 0x03Fh ;carga el acumulador con el

valor 3Fh 42 movwf count3 ;mueve el contenido del

acumulador a count3, 43 44 largo1: 45 call ret ;llama la subrutina retardo

corto 46 decfsz count3, 1 ;Decrementa count3,

guarda el resultado en F ;y si no es cero salta la siguiente

instruccion. 47 goto largo1 ;vuelve a decrementar

mientras largo1 no sea 0 48 return ;si es 0, regresa al

punto de llamada. ;******************************************************

******

El resto del listado una vez más se describe así. 50 ;La subrutina de retardo corta con dos lazos

anidados. 51 ret: movlw 0xFF ;Carga el acumulador con el valor

FF 52 movwf count1 ;mueve contenido del

acumulador a count1 ;para iniciar lazo externo.

54 ret1: movlw 0x0Fh ;Carga el acumulador con el valor 0Fh 55 movwf count2 ;mueve contenido del

acumulador a count2 ;para iniciar lazo interno

57 ret2: decfsz count2, 1 ;decrementa count2 lazo interno, guarda el ; resultado en F y si es cero salta la

siguiente instruccion. 58 goto ret2 ;volver a la subrutina ret2

otra vez (lazo ret2) 59 decfsz count1, 1 ;decrementa count1 (lazo

externo) y si count1 ; es cero saltate la siguiente instruccion. 60 goto ret1 ;si no, vuelve a decrementar

mientras ret1 no sea 0. 61 return ;si es 0, retorna al punto

de llamada. 63 END ;Termina el programa

Page 137: Programador PIC Pablin II

Este listado nos ha servido para describir ciertas partes interesante en el desarrollo de un programa escrito en ensamblador para los micros de la familia PIC. En próximos trabajos desarrollaremos otros interesantes proyectos que tengan utilidad práctica.

El ensamblador.

Una vez terminado el listado mnemónico con las instrucciones que hayamos considerado necesarias para el proyecto, debemos ensamblarlo con una herramienta que la misma empresa creadora del PIC nos proporciona gratis, como es el MPLAB©, esta la podemos encontrar en este enlace, si el lector no está familiarizado con esta herramienta, le recomiendo que lea con atención esta guía rápida, con la que puede empezar a probar con este listado que acabamos de describir, ya que entiendo que por su extensión e importancia merece un artículo a parte.

El siguiente es el listado en hex exadecimal, el que tendremos que quemar en el PIC16F84A, con el quemador que dispongamos. Si no dispone del ensamblador, puede copiar y pegar el siguiente listado que, puede guardar con el nombre "rutina1.hex", resultado de ensamblar el código descrito.

:1000000083168611831206200A20032886151020E5:10001000861108003F308E00102

08E0B0C2808003F:10002000FF308C000F308D008D0

B14288C0B1228A4:020030000800C6:00000001FF

Puede leer un tutorial con referencia a la herramienta del IcPorg, en este enlace, para poder grabar su microcontrolador PIC.

Descripción electrónica.

Aquí se muestra el esquema y circuito eléctrico necesario, para utilizar el programa que posteriormente grabaremos 'quemaremos' en un PIC. El proyecto pretende ser el primero de una serie que nos permita aprender cómo producir un programa. Para empezar será necesario disponer de las hojas de datos del PIC16F84A que hay en este sitio, de modo que el estudiante pueda seguir mejor las descripciones.

El esquema.

Page 138: Programador PIC Pablin II

Según las características del PIC16F84A, el pin de reposición o Reset, es el pin 4, el cual debe conectarse a la línea positiva de Vcc. Sin embargo personalmente no me parece muy seguro esto y opté por utilizar una red RC típica, formada por una resistencia y un condensador que aseguren la correcta reposición (Reset) del 'F84A, cuando se ponga a 0 hasta cargarse el condensador. En la mayoría de los circuitos que se pueden ver, para el reset, no incorporan el condensador, ya que, es necesario poner esta patilla a positivo para que el micro pueda correr, por lo que el emplo del condensador, queda a su criterio.

El motivo del circuito es muy simple, se trata de hacer que un diodo LED destelle. Evidentemente tenemos que empezar desde abajo, nadie nace con conocimientos avanzados, creo que es conveniente empezar por lo más simple y procurando asimilar los pasos, para ascender en los conocimientos de la programación.

Nota.- Cuando tengamos terminado el listado del programa y lo hayamos ensamblado (pasado a HEX), debemos tener presente que a la hora de quemar el chip, decidamos si usaremos para el reloj, un cuarzo o una red RC, en caso de RC, en el programador activaremos la opción RC para que funcione, si es un oscilador cerámico. En caso de usar un cuarzo activar la opción XT en el programador y lo quemaremos con estas opciones, de lo contrario no funcionará y no encontraremos fallos en el programa.

En el momento de grabar (quemar) el micro, se produce la palabra de configuración, la responsable de indicarle al micro como se ha condicionado su estructura. Es conveniente conocer mas acerca de la Palabra de Configuración, lo que ya se ha comentado en este tutorial. 

El circuito.

Para mantener las cosas económicas y fáciles, utilizaremos la opción de oscilador RC, si bien, este oscilador no es particularmente estable, servirá para este proyecto al igual que en otros muchos. El esquema (muy simple) que se utilizará es el anterior y el pcb, este:

Page 139: Programador PIC Pablin II

Aunque la línea de Vcc del esquema dice ser de 5V, puede ser utilizada una tensión menor, una de 3V o 4' 5V que, son valores más normalizados, aun así, he intercalado un diodo 1N4007 con el que asegurar la polaridad y la tensión incluso para 6V. Como puede apreciarse el esquema es muy sencillo, en esencia debido a la presencia del PIC y en la siguiente figura se muestra el circuito muy simple ejecutado sobre la placa de pruebas. Probablemente el lector haya programado anteriormente y le parezca esto demasiado elemental, espero que sepa disculpar y tenga paciencia, no todos están a la misma altura.

Es muy sencillo como se ha mencionado, pero es una práctica que sólo pretende ayudarnos a comprender los pasos a seguir en la programación en ensamblador (.asm) de un proyecto y su puesta en funcionamiento. En próximos artículos se tratan nuevos temas, hay mucho que desarrollar y practicar.

Page 140: Programador PIC Pablin II
Page 141: Programador PIC Pablin II

Sabado, 03 de Octubre del 2009__________________ Incluir en favoritos si quiere volver a visitarnos.

Introducción.

Este es un acercamiento muy lineal a la escritura de un programa. Muchos escriben y producen unas subrutinas muy pequeñas con saltos (GOTO's) de una subrutina a otra, de modo que los productos saltan por todas partes como 'palomitas de maíz'. El micro es capaz, perfectamente capaz de saltar por un programa, sin embargo este tipo de disposición es muy difícil de seguir por un lector.

EXPERIMENTO 1.

Los comienzos siempre son muy simples, luego gradualmente se hacen más y más complejos. Para seguir los experimentos que se describen en estas páginas se recomienda montar el proyecto "Tarjeta de Pruebas " siguiendo las indicaciones que se dan en dicho artículo, aunque naturalmente el lector puede realizar su propio desarrollo o bien usar un protoboard, a su elección. 

Una vez dispongamos de dicho soporte, las 4 pilas de 1'5V y el chip 'F84A, debemos copiar y pegar el código que hay debajo, para poder completar nuestro primer experimento, al que daremos el nombre ejem01.asm y usando el ensamblador gratuito de Microchip MPLAB, pasarlo a exadecimal (.hex) con el cual tratamos de encender un LED. No hace nada más. El objetivo de este programa es mostrar las pocas líneas de código, necesarias para que el PIC haga esta tarea. Ver el listado:

;******************************************************************^; Título: ejem01.asm ^; Autor: V. Garcia ^; Date: 12012006 ^; Deben documentarse todas las rutinas y el motivo de ser ^; (Las tildes estan omitidas de manera intencionada);_________________________________________________________________ ^; Recordar que con: 0 se designa al registro W y con ^ ; 1 se designa al archivo f ^; ^; Que hace => Encender LED 1 ^ ; ^; PIC16F84A ^;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^;;--------------- Encabezado -------------

Start: ORG 0x00BSF STATUS,5 ;Ir a pagina1 a fijar los puertosMOVLW h'00' ;pon 00 en W MOVWF h'05' ;haz todas las líneas RA salida MOVWF h'06' ;haz todas las líneas RB salida BCF STATUS,5 ; Ir a pagina0 para seguir el programa

LED_EN: MOVLW h'254' ;pon 1111 1110 en WMOVWF h'06' ;conecta el primer LEDGOTO LED_EN ; lazo a LED_EN

END

Page 142: Programador PIC Pablin II

El siguiente es el listado en exadecimal, si no dispone de un ensamblador, puede copiar y pegar en su editor de texto y guárdelo como ejem01.hex para usar con el 'quemador' de chips y comprobar que hace lo que se espera.

:1000000083160030850086008312FF308600FE30A4:040010008600072837:00000001FF

Qué hace el programa.

Las líneas que empiezan con un punto y coma, como ya se ha comentado, son comentarios y no los usa el ensamblador, así que, la primera línea donde realmente comienza el listado, empieza en mnemónicos con una etiqueta Start (Principio), no siempre es necesario usar etiquetas. La instrucción ORG 0x00 indica al micro en ensamblador, donde colocar el programa, al principio de la memoria de programa (Flash). Es un área de datos en el propio micro, en la que se memorizan diversos datos durante la ejecución del programa, este área es la RAM del PIC, definida por el fabricante como área de FILE REGISTER, que se encuentra a partir de la dirección 0x0C. En el PIC, siempre le siguen unas líneas que como se verá, nos permiten el acceso a un juego de registros para la configuración del micro.

La instrucción que sigue BSF STATUS,5 BSF (BIT SET FILE REGISTER) pone a 1 el bit 5 del registro STATUS (0x03), en la posición de memoria RAM especificada, lo que nos permite el acceso a la página1 (o Banco1) donde se deciden las condicionantes que se ocupan de los registros 05 (puerto A) y 06 (puerto B) y ambos registros determinan el estado lógico de cada uno de los pines de dichos puertos A y B.

Con la instrucción MOVLW 00h (MOVE Literal to W register) ponemos el literal 00 en el registro de trabajo W, con la siguiente instrucción MOVWF 05h (MOVE W to File) ponemos el valor del registro W en el registro 0x05 (RP0) que es el Puerto A, que viene definido en el archivo P16F84A.INC, con esto hemos configurado el Puerto A como salida 0000 0000b. Si queremos que sea todo entradas usaremos la instrucción MOVLW FFh seguido de MOVWF 05h, esto pone 1111 1111b, todos los bits del Puerto A (0x05) a 1 como entradas .

En el registro STATUS, encontramos los parámetros RP0 que corresponde al valor 0x05 o lo que es lo mismo el bit5 del registro. Se pone a 1 este bit para cambiar el banco de trabajo y manejar los registros TRISA y TRISB como se verá más tarde.

Por ejemplo, cuando un bit del registro RP0 es 1, la patilla correspondiente del chip (del Puerto A) será entrada y cuando dicho bit lo ponemos a 0, esa patilla será salida. Tengamos en cuenta que, no podemos cargar ninguno de estos registros directamente, en primer lugar se debe poner un valor o número (llamado literal) en W y luego cargar W en el registro deseado. Si cargamos 00 en W y luego W en 05 y 06, todas las líneas del Puerto A y del Puerto B serán puestas como salida.

La siguiente instrucción BCF STATUS,RP0 (Bit Clear File register) cierra esta página1 (banco1) y devuelve el control a las instrucciones del programa de la página 0 (banco 0). Observar el símil BSF (Bit Set, banco1 ) y BCF (Bit Clear, banco 0). Como el F84A sólo tiene dos bancos (0 y 1) usa el estado de un sólo bit para cambiar de banco, otros PICs con más memoria requieren de más bits de control en el mismo registro STATUS.

Page 143: Programador PIC Pablin II

Esto, en esencia significa que, el programa para encender un LED realmente consiste en tres líneas, la primera línea en la etiqueta LED_EN MOVLW h'254', pone el valor FEh en el registro de trabajo W, la segunda línea MOVWF h'06' copia el valor en W al Puerto B (06). Este puerto es de salida (en realidad es un puerto de Entrada/Salida) cuando el primer bit del Puerto B pase a ALTO, el LED se iluminará, como el programa es muy rápido, se apagará de inmediato y no podremos saber si funciona el programa, entonces, entra en acción la tercera línea del programa.

La tercera línea GOTO LED_EN (del inglés GO TO, ir a), es la instrucción que envía el puntero del programa a la dirección de la etiqueta LED_EN, es el lazo que mantiene el LED encendido por el programa al repetir la secuencia, ya que como se ha dicho, el micro debe estar (corriendo) todo el tiempo, incrementando el programa. Ahora, puede que sea algo confuso lo descrito, sin embargo a medida que avance en estos artículos podrá comprobar que es sencillo y fácil.

El circuito.

Como se aprecia en el esquema, el circuito anterior (Tarjeta de Pruebas) se compone de un microcontrolador PIC16F84, ocho diodos LED y unos pocos componentes adicionales. El Puerto B del PIC  tiene un LED conectado a cada una de sus ocho líneas. El circuito más simple y sencillo se puede ver a continuación.

Page 144: Programador PIC Pablin II

Todo lo descrito hasta aquí, es cierto, si bien hay otras formas de lograr el mismo resultado, una de las formas es cambiando el sentido del LED, en cuyo caso se debe modificar el valor de la salida del puerto B, donde había un 0 ahora debe presentar un 1, lo que obliga a conectar el ánodo a la salida y la resistencia a la línea de masa (GND), con esto se ha modificado el programa y sigue mostrando el mismo resultado que el anterior. Entonces, porque se ha usado el primer método.

No ha sido al azar, tengamos en cuenta que el consumo del conjunto LED más resistencia normalmente no supera los 20mA y como la patilla del puerto, admite una corriente mayor, no causará ningún contratiempo, ya que el drenador de salida del puerto soporta dicha carga mejor que tener que aportar dicha corriente que supone un mayor consumo y el consiguiente aporte de calor, este ha sido el principal motivo de usar este método. Este método debe ser considerado por el técnico para reducir consumos innecesarios en los proyectos. Este criterio es el que seguiremos aquí.

La operación del circuito se basa en un programa y este programa está contenido en el chip. Cuando se aplica la energía, el micro empieza en la primera posición de memoria y ejecuta el programa. El programa será guardado en la memoria del micro, durante el "quemado" y en ese único momento están disponibles un número de opciones de oscilador, osc RC (oscilador Res. / Cond.) que debe ser seleccionado y el chip estará listo para ese tipo de oscilador elegido, téngase en cuenta que el montaje sólo responderá al sistema de oscilador en la palabra de configuración que haya elegido al 'quemar', si es RC, LP, TX, etc. Otras opciones disponibles del F84A a configurar son: PWRTE, CP, WDT, las cuales dependen del dispositivo en uso (se recomienda leer el DataSheet correspondiente).

Debido a que el chip puede ser programado y reprogramado de nuevo, lo cierto es que está garantizado por más de 1.000 veces, esto lo hace ideal para la experimentación.

EXPERIMENTO 2.

  Este experimento es similar al anterior, mediante unas pocas líneas añadidas al contenido del programa anterior, hacemos que el LED ahora se encienda y se apague en una secuencia sin fin. El circuito que se usa, es el mismo del ejercicio anterior. Esto se consigue de esta forma: añadimos en la tercera línea, una instrucción CALL (Llamada) que envía al programa a la subrutina con etiqueta 'Delay' y luego se hace un nuevo lazo, veamos.

Page 145: Programador PIC Pablin II

Se trata de conseguir un retardo 'Delay' con el que poner el estado del LED en un bucle de espera, esta subrutina la llama el programa principal con la instrucción CALL Delay, esto mantiene encendido el LED, cuando termina el bucle, el micro retorna a la línea siguiente donde esta el CALL, en el programa principal MOVLW h'FF' que, carga el literal FF en el registro W y lo pone con la instrucción MOVWF 06, en el Puerto B (salida) y salta de nuevo a la etiqueta Delay (retardo) para esta vez mantener apagado un tiempo el LED.

Al volver del retardo se establece un nuevo lazo, sería conveniente volver a empezar esta parte del programa para repetir los mismos pasos y esto se logra con un lazo que une este punto con el principio mediante el GOTO LED_EN. Véase el listado.

En cuanto a la rutina 'Delay' en sí, lo que ocurre es que, empieza por DECFSZ 1Bh (DECrement File Register Skip If Zero) decrementa una unidad el archivo 1Bh, si no es cero, sigue en la instrucción GOTO Delay para volver a decrementar que devuelve el programa a la instrucción anterior, para decrementarlo una nueva unidad, esto lo hace cada vez que pasa por la instrucción DECFSZ 1Bh.

Cuando el archivo 1Bh llega a 0, entonces salta la instrucción GOTO Delay a la instrucción que sigue que, es otro DECFSZ pero esta vez el archivo es 1Ch y empieza a decrementarlo de uno en uno avanzando la rutina, luego se reinicia la instrucción DECFSZ 1Bh, a la que le sigue el decremento DECFSZ 1Ch, decremento de la instrucción a instrucción hasta llegar a la instrucción (RETURN) de retorno al programa principal. Esto se le llama instrucciones anidadas, ya se tratarán en más detalle.

. . . . . .

LED_EN MOVLW h'FE' ;pon 1111 1110 en WMOVWF h'06' ;conecta el primer

LEDCALL Delay ;Salta al retardoMOVLW h'FF' ;carga W con FF yMOVWF 06 ;apaga el LEDCALL Delay ;Salta al retardoGOTO LED_EN ; lazo a LED_EN

Delay DECFSZ h'1B',1 ; RetardoGOTO DelayDECFSZ h'1C',1GOTO Delay RETURN

END

Se muestran sólo los cambios que nos permiten producir lo previsto en el enunciado. Observar que no se usan los pulsadores, para estos experimentos. A continuación se presenta el listado en hex para que si no puede ensamblarlo lo copie y pegue en su editor de texto y guárdelo como ejem02.hex para el posterior 'quemado' del chip.

:1000000083160030850086008312FF308600FE30A4:1000100086000E20FF3086000E2007289B0B0E283E:060020009C0B0E280800F5:00000001FF

Page 146: Programador PIC Pablin II

EXPERIMENTO 3.

  En este experimento, proponemos encender el LED 1 de una fila de 8 LEDs, lo apagaremos y encenderemos el siguiente LED 2 esto lo repetiremos en una secuencia hasta llegar al LED 8 con una cadencia de 2Hz, para volver a empezar por el LED 1, esto es todo lo que hace este experimento. El circuito que usaremos es similar al usado en el experimento 1, al que añadimos 7 series LED+R. Lo que más cambiará es el listado del programa que, en este caso, tendrá que sufrir algunas modificaciones como veremos. Este puede ser una modificación del esquema en el caso de no usar la tarjeta descrita.

En el esquema del principio, los cinco pines RA0 a RA4 (puerto A) se usan como pines de entrada, estos son forzados a alto con resistencias a positivo de 10kohms, de modo que cuando los pulsadores no están pulsados la entrada se hace alta (+5V) y cuando uno se pulsa pasa a nivel bajo (0V). El fenómeno de rebote producido, no se contempla esta vez ya que, cuando el programa detecta que el pulsador está cerrado, el tratamiento de parpadeo de los LED's se ejecuta una vez en el tiempo y es más largo que el rebote. No se usan pulsadores en este ejercicio, de modo que no se contemplarán.

Los ocho pines RB0 a RB7 (puerto B) se usan como salida, los ánodos de los LED's se conectan al +5V y cada cátodo es controlado por la resistencia vía PIC, de modo que cuando la salida del PIC es nivel alto (+5V), el LED implicado no luce y cuando el PIC entrega un nivel bajo (0V), lucirá el LED, esto reduce la corriente en el chip. Se usarán LED's de alto brillo con poca corriente de flujo. Este es el listado completo para este experimento.

;******************************************************************^; Título: ejem03-1.asm ^; Autor: V. Garcia ^; Date: 12012006 ^; Deben documentarse todas las rutinas y el motivo de ser ^; (Las tildes estan omitidas de manera intencionada);_________________________________________________________________ ^; Recordar que con: 0 se designa al registro W y con ^ ; 1 se designa al archivo f ^; ^; Que hace => Encender LED 1, lo apaga y enciende el siguiente ^ ; hasta el LED 8, luego vuelve a emepzar. ^; PIC16F84A ^

Page 147: Programador PIC Pablin II

;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^;;--------------- Encabezado ------------- list p=pic16f84a #include <p16f84a.inc> errorlevel -302 ;Eliminar banco mensajes

;**************** Definicion de Etiquetas ********************STATUS equ h'0003'porta equ h'0005' ; define puerto Aportb equ h'0006' ; define puerto BTRISA equ h'0085'TRISB equ h'0086'

; Estos estan definidos en #include ;w equ h'0000';f equ h'0001'

ra0 equ 00 ;RA0 bitra1 equ 01 ;RA1 bitra2 equ 02 ;RA2 bitra3 equ 03 ;RA3 bitra4 equ 04 ;RA4 bitrp0 equ 06

cnt500u equ 0c ;500usec direccion contador cnt1m equ 0d ;1msec direccion contadorcnt100m equ 0e ;100msec direccion contadorcnt500m equ 0f ;500msec direccion contadorcnt1s equ 10 ;1sec direccion contador

;************* Definicion Modelo Datos ****************; '1':OFF '0':ON

;****** Tabla Modelo ******p00 equ b'01111111'p01 equ b'10111111'p02 equ b'11011111'p03 equ b'11101111'p04 equ b'11110111'p05 equ b'11111011'p06 equ b'11111101'p07 equ b'11111110';;**************** Inicio Programa *********************** org 0 ;Vector Reset goto init org 4 ;Vector Interrupcion BCF INTCON,GIE ;Por si se dispararan las interrupciones goto init

;**************** Proceso Inicial ********************* org 5init: bsf STATUS,RP0 ;Cambiar a Banco1 movlw h'ff' ;Define modo datos entrada movwf TRISA ;Define PORTA en modo Entrada clrf TRISB ;Define PORTB a modo Salida bcf STATUS,RP0 ;Cambia a Banco0;

Page 148: Programador PIC Pablin II

movlw h'ff' ;Pon datos '11111111' en salida movwf portb ;para apagar LEDs

;*********** Modelo 0 Subrutina Salida ***************ptn0 movlw p00 ;Pon datos modelo en movwf portb ;datos salida call t100m ;Espera 100msec movlw p01 ;Pon datos modelo en movwf portb ;datos salida call t100m ;Espera 100msec movlw p02 ;Pon datos modelo en movwf portb ;datos salida call t100m ;Espera 100msec movlw p03 ;Pon datos modelo en movwf portb ;datos salida call t100m ;Espera 100msec movlw p04 ;Pon datos modelo en movwf portb ;datos salida call t100m ;Espera 100msec movlw p05 ;Pon datos modelo en movwf portb ;datos salida call t100m ;Espera 100msec movlw p06 ;Pon datos modelo en movwf portb ;datos salida call t100m ;Espera 100msec movlw p07 ;Pon datos modelo en movwf portb ;datos salida call t100m ;Espera 100msec movlw h'ff' ;Pon datos FF en salida movwf portb ;datos para apagar LED call t100m ;Espera 100msec return ;********************************************************; Subrutina retardo (Timer) para reloj 10MHz ;********************************************************

;************* Subrutina 1msec Timer *****************t1m movlw d'2' ;(1) Pon lazo cnt1 movwf cnt1m ;(1) Guarda lazo cnt1tm1lp1 movlw d'249' ;(1)*2 Pon lazo cnt2 movwf cnt500u ;(1)*2 Guarda lazo cnt2tm1lp2 nop ;(1)*249*2 ajust retardo nop ;(1)*249*2 ajust retardo decfsz cnt500u,f ;(1)*249*2 cnt500u-1=0 ? goto tm1lp2 ;(2)*248*2 No, continua decfsz cnt1m,f ;(1)*2 cnt1m-1=0 ? goto tm1lp1 ;(2) No. Continua return ;(2) Si. final de Cnt ;Total 2501*0.4usec=1msec

;************* 100msec Subrutina Retardo (Timer) ***************t100m movlw d'100' ;Pon lazo contador movwf cnt100m ;Guarda lazo contadortm2lp call t1m ;subrutina 1msec decfsz cnt100m,f ;cnt100m - 1 = 0 ? goto tm2lp ;No. Continua return ;Si. Final de Contador

Page 149: Programador PIC Pablin II

;************* 500msec Subrutina Retardo (Timer) ***************t500m movlw d'5' ;pon lazo contador movwf cnt500m ;Guarda lazo contadortm3lp call t100m ;subrutina 100msec decfsz cnt500m,f ;cnt500m - 1 = 0 ? goto tm3lp ;No. Continua return ;Si. final de Contador

;************** 1sec Subrutina Retardo (Timer) *****************t1s movlw d'2' ;Pon lazo contador movwf cnt1s ;Guarda lazo contadortm4lp call t500m ;subrutina 500msec decfsz cnt1s,f ;cnt1s - 1 = 0 ? goto tm4lp ;No. Continua return ;Si. Final de Contador

;********************************************************; Final del proceso parpadeo LED ;********************************************************

end

Este que sigue, es el archivo en hex que se obtiene al ensamblar el listado anterior, si no dispone de un ensamblador, puede copiar y pegar este archivo en su editor de texto y guárdelo como ejem03-1.hex para el 'quemado' en un chip '84A, con su sistema de programación.

:020000000528D1:0800080005280317FF308500F5:1000100086010313FF308600051C0E200310FE30FE:1000200086001420860D112803309A009B0B162899:0A0030009C0B16289A0B16280800F6:00000001FF

Qué hace el programa.

Las primeras líneas del programa, definen las igualdades (equ) y los parámetros que se van a usar. Aquí, se han definido las variables ra0-ra4 no usadas y  RP0, seguidamente se define una tabla modelo binario de ocho líneas de datos, cada vez que se llame con:

   movlw p00        ; carga literal en el registro W (el literal va desde p00 a p07)   movfw portb    ; presenta valor en puerto b   call t100m         ; llama subrutina retardo

su valor se enviará a la salida (puerto B), alternando con los retardos necesarios para encender el LED que corresponda en cada caso, esto se repite. Posteriormente se define la subrutina de retardo desde donde se vuelve a la rutina principal. 

La rutina de tiempos aquí usada, como se aprecia, es bastante completa ya que presenta hasta cuatro alternativas permitiendo un retardo de: 1 milisegundo, 100 milisegundos, 500 milisegundos y 1 segundo, lo cual, la hace interesante a la hora de aplicar en distintas ocasiones. Le aconsejo que la estudie con atención, le puede servir en sus proyectos.

Page 150: Programador PIC Pablin II

  Sin embargo, nos parece muy extenso este listado, podemos hacer lo mismo de forma más simple. Esto

mismo se hace poniendo un 0, en el puerto b de salida (registro 06h), esto pone a 0 el bit más alto y así el primer LED se iluminará. Entonces el bit se rota (cambia) un lugar a la derecha con una instrucción RLF (Rotation Left File, rotación a la izquierda de un bit) del contenido de F, pasando por el bit de acarreo C, esto conecta el siguiente LED en la fila. Es importante 'aclarar' (poner a 0) la bandera C (acarreo) antes de usar una instrucción de rotar, ya que cuando se conecta el micro, la bandera C puede estar en 1, con esto nos aseguramos que los LED's se desplazaran, que es lo que deseábamos. Este es el listado en ensamblador que se puede copiar, pegar y guardar con el nombre ejem03.asm.

;******************************************************************^; Título: ejem04.asm ^; Autor: V. Garcia ^; Fecha: 20-01-2006 ^; Version:0.0 ^; Codigo para: PIC16C84 y PIC16F84 ^; Clock: 4MHz , XT. -> Ciclo = 1 uS. ^; Reset: Power On Reset. ^; Watch Dog: Inhabilitado. ^; Proteccion de codigo: Inhabilitado. ^; Ficheros requeridos: H16f84a.inc ^; Placa uControladora: Circuito de cátodos de LEDs a +Vcc. ^; ^; (Las tildes estan omitidas de manera intencionada) ^;_________________________________________________________________ ^; Recordar que con: 0 se designa al registro W y con ^; 1 se designa al archivo f ^; Pulsador sin rebotes enciende un LED ^; Que hace => A de encender el LED 1 apagarlo, encender LED 2 y ^; apagarlo, sigue hasta LED 8. La secuencia se invierte y sigue ^; desde LED 8 hasta LED 1 ^;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^;--------------- Encabezado -------------;********************************************************************; LIST p=PIC16F84A ; Directiva para definir micro. #include <p16f84a.inc> ; Fichero estandard de cabezera.; ;******************** DEFINICIONES **********************************; Todas las definiciones estan en 'include ', por tanto; solo se definen las localesporta equ h'0005' ; define puerto Aportb equ h'0006' ; define puerto B

con1 equ 0x0C ; Variable de temporizacion.con2 equ 0x0D ; Variable de temporizacion.

;******************** COMIENZO DEL PROGRAMA ********************; SE DEFINEN BANCOS #define banco1 bsf STATUS,RP0 ;Macro para abreviar el BANCO 1

;pone a 1 el bit5 del registro status#define banco0 bcf STATUS,RP0 ;Macro para abreviar el BANCO 0

;pone a 0 el bit5 del registro status

Page 151: Programador PIC Pablin II

ORG 0x00 ; Vector de Reset. GOTO inicio ; Programa Principal.

;************************************************************delay: CLRF con1 ;lazo exterior

MOVLW 0xF0MOVWF con2

; RETURN ;esta linea es de pruebaloop: DECFSZ con1,F ;lazo interior

GOTO loopDECFSZ con2,FGOTO loopRETURN

;;******************** PROGRAMA PRINCIPAL ********************

inicio: banco1 ; Banco 1.CLRF TRISB ; aclara puerto B, pone a 0 , todo salidas banco0 ; Banco 0.

MOVLW 0xff ; PORTB 11111111.MOVWF portb ;BCF STATUS,C ;Preparado para rotar, pone a 0 el bit C

; Desplazar portB a la izquierda, usamos la instruccion ROTAR

gira_i:BTFSS portb,7 ;si el bit 7 = 1 salta y rota a derechaANDLW 01 ;si no, AND entre literal y W

sigue_i: BTFSC portb,7 ; portb = 00?goto $+3 ; no, salta 2 lineasmovlw 0xff ; si, pon 255 enmovwf portb ; portbBCF STATUS,C ;Asegura que en primera

; rotacion ingrese 0 en PORTBRLF portb,F ;rota archivo F a izq. (F = '1111 1110')CALL delay ;salta a retardoGOTO gira_i ;vuele a girar.

; END ; Fin de programa.

Qué hace el programa.

Se definen los parámetros en las primeras líneas, registros, puertos y variables. Además en este caso he querido plasmar otra forma posible de definir las variables para manejar los bancos (banco0 y banco1). Para ello he definido las macros banco1 y banco0, mediante las cuales se realiza la configuración de los mismos. El tema de macros no se describirá aquí.

Seguidamente en Inicio, se ve como se aplican. En este punto recalco el modo de poner a cero todos los bits de un puerto, en este caso el puerto B (TRISB) mediante la instrucción CLRF (aclarar registro f). En las líneas siguientes, se carga el puerto B con el literal FF y con BCF (Bit Clear File) se pone a 0 el bit C, con lo que estamos listos para empezar a desplazar el LED encendido, por la barra de LEDs.

Sigue la subrutina de retardo y ahora empieza la rutina principal gira_i el primer paso

Page 152: Programador PIC Pablin II

comprueba el estado del bit7 =1 del puerto b, luego comprueba si es 0 y mediante la instrucción RLF (Rota Left File) nos desplaza a la izquierda una

posición (rotación del bit), en cada iteración del lazo de la subrutina, encendiendo, apagando y desplazando el LED en cada momento. Si en BTFSC portb,7 es 0, se carga el puerto b con 255 para podar seguir desplazando el LED.

Se puede observar un RETURN inhabilitado en la rutina de retardo, esto lo uso para comprobar el buen funcionamiento de las subrutinas, una vez comprobada, pongo el consabido punto y coma delante y a seguir. El listado en hex que sigue, por si no lo quiere ensamblar, lo puede copiar, pegar y guardar como ejem03.hex en un archivo con el que puede quemar el '84A para probar su funcionamiento.

:020000000528D1 :06000A008316860183123B:10001000FF3086000310861F0139860D10200B2843:100020008C01F0308D008C0B13288D0B13280800E9:00000001FF

Como siempre el circuito y esquema electrónico es el mismo mostrado en la figura anterior.

EXPERIMENTO 4. 

  En este caso, propongo producir un programa que encienda un LED y lo desplace en un sentido por la barra, cuando llegue al final regrese y repita esta secuencia en el otro sentido. Digamos que, con este programa obtendremos la clásica barra de LEDs del famoso coche 'Fantástico'. A tenor de lo visto en los ejemplos anteriores parece sencillo y así lo voy a demostrar. El listado sería el siguiente: 

;******************************************************************^ ; Título: ejem04.asm ^ ;  Autor: V. Garcia ^ ;  Fecha: 20-01-2006 ^ ; Version: 0.2 ^ ; Codigo para: PIC16C84 y PIC16F84 ^ ; Clock: 4MHz , XT. -> Ciclo = 1 uS. ^ ; Reset: Power On Reset. ^ ; Watch Dog: Inhabilitado. ^ ; Inhabilitado. ^ ; Ficheros requeridos: H16f84a.inc ^ ; Placa uControladora: Circuito de cátodos de LEDs a +Vcc. ^ ; ^ ; (Las tildes estan omitidas de manera intencionada) ^ ;_________________________________________________________________ ^ ; Recordar que con: 0 se designa al registro W  y con ^ ; 1 se designa al archivo f    ^ ; Pulsador sin rebotes enciende un LED   ^ ; Que hace => A de encender el LED 1 apagarlo, encender LED 2 y    ^ ; apagarlo, sigue hasta LED 8. La secuencia se invierte y sigue   

Page 153: Programador PIC Pablin II

^ ; desde LED 8 hasta LED 1 ^ ;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ;--------------- Encabezado ------------- ;******************************************************************* ; LIST p=PIC16F84A ; Directiva para definir micro. include "p16f84a.inc" ; Fichero estandard de cabezera. ;******************** DEFINICIONES *********************************

con1 equ 0x0C ; Variable de temporizacion. con2 equ 0x0D ; Variable de temporizacion.

;******************** COMIENZO DEL PROGRAMA  ******************** ; SE DEFINEN BANCOS#define banco1 BSF STATUS,RP0 ;Macro para abreviar el BANCO 1

;pone a 1 el bit5 del registro status#define banco0 BCF STATUS,RP0 ;Macro para abreviar el BANCO 0

;pone a 0 el bit5 del registro status ORG 0x00 ; Vector de Reset. GOTO inicio ; Programa Principal.

;****************** SUBRUTINA DE TIEMPO ************* delay: CLRF con1 MOVLW 0xF0 MOVWF con2 ; return ;es de prb loop: DECFSZ con1,F GOTO loop DECFSZ con2,F GOTO loop RETURN ;************************************************************ ;******************** PROGRAMA PRINCIPAL ******************** inicio: banco1 ; Banco 1. CLRF TRISB ; aclara   banco0 ; Banco 0. MOVLW 0xff ; PORTB 11111111. MOVWF PORTB ; BCF STATUS,C ;Preparado para rotar ; PORTB Rota hacia la izquierda, usamos la instruccion ROTAR

gira_i: BTFSC PORTB,7 ;si el bit7 = 0 salta y rota a derecha GOTO sigue_i ;no, sigue izquierda. GOTO gira_d ;sigue_i: RLF PORTB,F ;rota archivo F a izq. (F = '1110') CALL delay ;

BTFSC PORTB,0 ;salta y rota si bit0 = 0 GOTO gira_i

BSF PORTB,7 ; PORTB Rota hacia la derechagira_d: BTFSC PORTB,0 ;salta y rota si bit0 = 0

Page 154: Programador PIC Pablin II

GOTO sigue_d GOTO gira_isigue_d: RRF PORTB,F CALL delay GOTO gira_d ; END ; Fin de programa.

Qué hace el programa.

Si el lector sigue el flujo del programa puede comprender que, he recurrido a dos rutinas encadenadas idénticas en la forma: gira_i y gira_d ambas están entrelazadas, trataré de describir como funcionan.

Al llegar el programa a gira_i, encuentra la instrucción BTFSC portb,7 que comprueba si el bit7 del puerto B está a 0, como dicho bit7 es 0, el programa sigue y salta a la etiqueta sigue_i, en ese momento rota izquierda con RLF seguido de un salto al retardo para que el LED se vea encendido, al regresar comprueba si está a 0 el bit0, si no lo está vuelve a gira_i, repitiendo estos pasos hasta que el bit0 es 0, en cuyo caso salta hasta BSF PORTB,7 para poner a 1 el bit7, luego sigue con gira_d donde comprueba el estado del bit0 que, estará a 1 y saltará a sigue_d para rotar a derecha seguido de un CALL a pausa, al volver hará un GOTO gira_d, repitiendo estos pasos.

Al llegar el programa a la instrucción CALL delay saltará a la posición de la etiqueta (subrutina de retardo) delay, limpia el registro cont1 y carga el registro cont2 con el valor F0h, decrementa el registro cont1 que esta a 00 y por tanto ahora esta a FFh (GOTO loop) hasta que es 0 y en ese momento decrementa el registro cont2 (GOTO loop) hasta que es 0 cerrando el lazo por segunda vez. Cuando termine esta subrutina (pausa), volverá a la instrucción siguiente a la que le hizo saltar. Espero haber aclarado el flujo del programa.

Sigue está el listado en hex del archivo un vez ensamblado, como siempre, puede copiar y pegar en un editor de texto y guardarlo como ejem04.hex para posteriormente quemar un PIC17F84A y comprobar su eficacia.

:020000040000FA:1000000009288C01F0308D008C0B04288D0B0428FE:100010000800831686018312FF3086000310861BBA:1000200012281728860D012006180F288617061893:0A0030001A280F28860C012017285B:00000001FF

Con este ejercicio ponemos el punto y aparte por esta vez, seguiremos con estos ejemplos en la segunda parte. 

Volver al índice de artículos PIC.

Creada el: 03-06-2005 Actualizada el: 12-09-2005      © Copyright 2007, Hispavila.com. Reservados todos los derechos

Page 155: Programador PIC Pablin II
Page 156: Programador PIC Pablin II

Hoy: 3 Octubre 2009,              Incluir en favoritos, para volver a visitarnos.  Creado por: V. García.

Introducción.

Este artículo, basado en información adquirida de la red es, una aproximación a los conversores AD, en el que se muestra que hacer para conectar una señal analógica a un PIC. Una señal analógica es similar a una onda senoidal y generalmente de amplitud inferior a 5V (5.000mV). Las señales de bajo nivel, generalmente se expresan en mV, para hacerlas reconocibles instantáneamente y facilitar el comentar o referirse sobre ellas.

Análisis de una señal

La figura de la derecha muestra una señal analógica, esta señal puede ser tan baja como de unos pocos milivoltios o cientos de milivoltios. En general este tipo de señal será demasiado pequeño para ser detectado por la entrada de un microcontrolador. El micro necesita una señal mayor, sobre 3.500mV para que la forma de onda se presente sobre la línea de entrada como un nivel H (ALTO), durante el pico de su excursión. Este debería ser tan alto como sea posible, sobre 5.000mV para una detección fiable de la señal. La instrucción para leer un nivel H (Alto) es:

BTFSS 06,3 ;Comprueba si es H la línea de entrada RB3 (bit 3)

Esta instrucción comprueba la línea RB3 y si el bit es ALTO (la línea está Activa - la instrucción verá un ALTO) el micro saltará la siguiente línea del programa y ejecutará la línea que sigue en el programa, para su tratamiento. La forma de la onda no es del todo importante, ésta puede consistir en grandes y pequeños picos como muestra la figura de abajo.

En estos casos sólo los grandes picos serán detectados por el micro, los demás pueden ser demasiado pequeños para ser detectados y se despreciaran. Para aumentar en lo posible la señal analógica cerca de 5.000mV, como se muestra debajo, es necesario un amplificador.

Page 157: Programador PIC Pablin II

Un amplificador de tal vez una o dos etapas, según la amplitud de la señal original. Cada etapa del amplificador aumentará el tamaño de la señal aproximadamente 70 veces. Si tenemos mucha suerte, se puede conseguir una amplificación de 100 veces. Así, una señal de 5mV con una etapa amplificadora puede que produzca una señal de 350mV. Esto no es suficiente para que pueda ser detectado por el micro, otra etapa elevará fácilmente la señal a 5.000mV y el micro sí detectará su presencia.

La segunda etapa sólo tiene que amplificar la señal aproximadamente entre 10 y 12 veces, será suficiente para el micro y la ganancia proporcionada por la etapa añadida, simplemente recorta la forma de onda del "bajo" y el "alto" como muestra la imagen.

Qué significa que la forma de onda estará "recortada" en lo alto y bajo, que será convertida a una forma "limpiamente cuadrada". Normalmente a esto se le llama distorsión pero, en términos digitales aquí, no nos preocupamos sobre este estado deformado y simplemente lo usaremos por sus propiedades de "disparo" que es lo que interesa.

Supóngase que tenemos una forma de onda que es más alta de 5mV (es decir 30 o 50mV) y queremos saber si esto disparará el micro con una única etapa de amplificación. Conectaremos el circuito de la imagen de abajo al micro con un LED en serie con la resistencia 270R al pin GP0, grabemos la siguiente rutina en un '84A y el LED se iluminará cuando la forma de onda sea detectada como un estado ALTO.

Programa para un '84A:

BSF STATUS,5 ; Selecciona pagina1

MOVLW 08 ; GP3 b'0000 1000, entrada

Page 158: Programador PIC Pablin II

TRIS 06 ; carga TRIS

BCF STATUS,5 ; devuelve a pagina0

Test1 BTFSS 06,3 ; Forma de probar el bit 3 en el archivo 06

; salta la próxima instrucción si el bit 3 es 1.

GOTO Test2 ; si la entrada (RA1) es "1" va a Test2

BSF 06,0 ; si no

GOTO Test1 ; vuelve a comprobar el bit 3

Test2 BCF 06,0 ;

GOTO Test1 ; comprueba otro estado de entrada.

End

Sólo hay un problema con el circuito de la imagen de la derecha. Al finalizar la señal de una palabra o sonido, la señal de salida puede quedar en H o en L, esto aplicado a un LED, este puede quedar iluminado o apagado. Esto depende de la forma de onda del último ciclo. El circuito se detiene con la salida a mitad de tensión aproximadamente y un microprocesador no sabe si esto es un alto (H) o bajo (L) y tomará la lectura por la dirección del último ciclo. Algunas entradas de los micros son disparadores Schmitt, con lo que se evita este defecto. 

Esto significa que para poder ver un nivel alto, como un nivel lógico alto (H) tiene que ser del 85 % al 100 % de la tensión de suministro y entre el 20 % y el 0 %, para  ver como un nivel bajo (L). Las entradas sin disparador Schmitt ven un bajo (L) del 20 % al 0 % y un alto (H) por encima de 2V hasta 5'5V. 

Si el último ciclo fue de cero a mitad de la tensión, el micro con entradas disparador Schmitt verá la forma de onda como un bajo y sobre otro tipo de entrada un alto. Si el ciclo viene de un alto sobre la tensión media, la forma de onda será vista como un alto. Este problema puede ser superado mediante unas instrucciones en el programa, mirando la entrada y si esta no cambia, no se hace caso. Supongamos que el circuito apenas activa el micro con un fuerte silbido. Para mejorar la sensibilidad de la entrada será necesaria otra etapa.

Page 159: Programador PIC Pablin II

Esta como se muestra en la imagen anterior puede ser una etapa digital o como se muestra en la imagen siguiente una etapa analógica.

Una etapa digital, simplemente significa que la resistencia de influencia (realimentación) está separada de la base del segundo transistor, entonces el transistor conectará totalmente (saturación) cuando es detectada una señal mayor que 650mV y estará en corte totalmente en otras ocasiones. Esta etapa es conveniente sólo si se está seguro que tenemos mucha "sobre tensión" para poner el transistor en saturación. Por esto pensamos, debe tener al menos 1v (1,000mV) entonces se puede estar seguro que la señal de paso saturará el transistor.

Esta etapa es ideal para el micro, ya que sólo entregará dos niveles de tensión. Tan bajo como 0v o el máximo voltaje (5v), otra ventaja es que la etapa no consume ninguna corriente. La subida y a veces caída rápida, significa que se tiene un período de tiempo "limpio" para operaciones de corte durante un ALTO o BAJO. Un micro determina la frecuencia de una señal de entrada, contando el tiempo para el ALTO o BAJO (entre una subida y bajada) y tomando una decisión determinada según el programa.

Si los anchos de los ALTOS y BAJOS son muy regulares, el micro puede tomar una decisión exacta muy rápidamente. Esto es muy importante si se detecta una frecuencia particular fuera de la gama posible de frecuencias, como el programa comparará la frecuencia entrante con un valor de una tabla, puede seguir probando hasta que se produzca un máximo exacto. La imagen anterior muestra que dos etapas análogas darán "sobre carga", el circuito produce una señal que es mayor de lo necesario para el micro y

Page 160: Programador PIC Pablin II

aún cuando la forma de onda de entrada es muy baja, la salida todavía será suficientemente alta para disparar el micro.

Este circuito (analógico) es más sensible que el de la imagen anterior para digital y debería usarse si queremos recoger susurros débiles o conectar el equipo a un magnetófono. Esto también debería usarse con detectores magnéticos (detector de metales, clavos, tubos) este tipo de detectores tienen una salida muy baja (puede ser de 1 a 5mV).

EL DIAGRAMA CON PIEZO

También pueden usarse, transductores como diafragmas piezo como micrófonos. Estos producen un sonido muy de "lata" (como hablar en una lata) pero esto no es importante en nuestro caso. La salida del mismo es como un micrófono electret (aproximadamente 10 a 30mV para el habla de nivel bajo y hasta 50mV para el habla fuerte).

Algunos diafragmas son muy sensibles mientras otros son muy insensibles. Se puede comprobar la sensibilidad con un PIEZO, simplemente silbando y viendo la forma de onda.

El diagrama de la imagen de la derecha muestra como conectarlo a un amplificador de transistor. Usando el programa anterior, silbar en el piezo y determinar si es suficiente con una sola etapa. Si no, puede agregarse una segunda etapa, exactamente como la etapa del micrófono. Los diafragmas que funcionan con tensiones bajas, como los de las tarjetas de música parecen muy sensibles. Otro modo de determinar si un piezo-eléctrico es sensible, es conectarlo a un CI de música, la salida que entrega, refleja su sensibilidad como un micrófono. El piezo tiene una ventaja sobre el electret, no necesita fuente de tensión. 

La siguiente imagen muestra un circuito muy simple de interfase de un piezo con la entrada de un micro. El primer transistor se mantiene en "bajo" (saturación) y el segundo en "corte". Esto ofrece un consumo en corriente más bajo y produce una salida mayor. El segundo transistor permanece "apagado" mientras el primer transistor esté "conectado", el voltaje a través de sus terminales de emisor-colector estará sobre 0.35V, esto es una tensión baja para conectar la base del segundo transistor que ha de ser de 0.65V.

Page 161: Programador PIC Pablin II

El primer transistor se conectará totalmente pero la corriente absorbida es muy baja y esto permite la forma de onda máxima que producirá el piezo para una baja intensidad dada. En otras palabras, el circuito pone sobre el piezo una ligera carga, cuando no hay señal presente y la salida del circuito es ALTA.

La señal del piezo, produce un tren impulsos de tensión máxima para igualar exactamente la forma de onda del piezo. Si se supervisa la salida del circuito se será capaz de detectar al instante la forma de onda que produce un BAJO. Las instrucciones del bucle (loop) hasta detectar un bajo se muestra debajo:

Lazo1 NOP

BTFSC 06,0 ;probar GP0 para un Bajo

GOTO Lazo1

El único problema es que con lazo1 se mantiene ocupado el micro para hacer otras operaciones. La solución es "saltar" la línea de entrada produciendo un programa que "vea" en la entrada sobre una base regular y si se detecta un bajo, se coloca un bit en el

registro flag (bandera), la rutina principal mira constantemente la bandera del registro flag y se activará con un bit, esto requiere a cambio una operación de cancelar la bandera.

CÁPSULA MAGNÉTICA.

Una bobina (choke) de 10mH (con ambos cables que salen del mismo lado

del imán, puede pasar tan cerca como sea posible del núcleo), puede ser usado como una sonda magnética para detectar ejes rotativos, etc. el circuito del diagrama de abajo se conectará a un micro. Atar un imán fuerte a un eje rotatorio y poner el sensor magnético lo mas cerca posible del imán sin que toque, la amplitud de la forma de onda producida por la bobina va a depender del imán, la distancia entre el imán y la bobina, la

Page 162: Programador PIC Pablin II

velocidad del eje rotativo y el número de espiras de la bobina.

En la figura anterior, el acoplo de corriente alterna de la bobina al circuito de amplificación para que pueda ser determinada la zona de equilibrio del primer transistor por el valor de la resistencia de equilibrio de base. La bobina no se puede conectar directamente al transistor por la baja impedancia (resistencia) de la bobina que trastornará el equilibrio en la base. Si la bobina es conectada directamente a la base, el voltaje a través de  la bobina será sólo de unos milivoltios y  la bobina tendrá que producir 600mV o mas para activar el transistor.

Con este montaje 100mV o menos cortará el transistor (la forma de onda (mayor de 100mV) saturará el transistor durante "la mitad positiva" de la onda y lo cortará durante la otra mitad de la onda). Cualquier bobina de cable de cualquier tamaño, será conveniente hacer un colector de flujo magnético eficaz, este debería tener un campo magnético como una ferrita. Simplemente haga girar el eje a la mitad las RPM  vueltas requeridas y si el circuito detecta el imán, la bobina es adecuada. Ninguna otra medida de impedancia o resistencia es necesaria. La salida del circuito es exactamente la misma en cuanto al diafragma piezo excepto que la frecuencia será bastante menos.

UNA LDR

El sensor de luz más económico es la LDR, ésta tiene una resistencia de aproximadamente 100 ohmios en la luz brillante y más de 1M en la oscuridad, esto hace que pueda ser conectada a un amplificador de transistor como muestra la imagen.

El potenciómetro cambiará la sensibilidad del LDR para que la salida cambie con la intensidad de luz deseada. Este circuito es sólo conveniente para grandes cambios de intensidad. Si se tiene que detectar un cambio muy tenue de la iluminación necesita un detector muy sensible.

FOTO TRANSISTOR DARLINGTON.

Un dispositivo más sensible es un foto transistor darlington, como el MEL-12. Seguido de una etapa de amplificación y un potenciómetro ajustará el nivel de sensibilidad, como se muestra en la siguiente imagen.

Page 163: Programador PIC Pablin II

NIVELES DE TENSIÓN

Algunas formas de onda cambian muy lentamente, tanto que pueden tardar un día o más en crecer y decrecer. Estos niveles son clasificados como niveles de tensión y pueden ser producidos por termopares (un termopar produce una tensión debido a la temperatura en la unión (soldadura) entre dos metales diferentes en contacto el uno con el otro). Otros dispositivos entregan una tensión, por la existencia un voltaje y la resistencia del dispositivo, causando que cierto voltaje aparezca a través de él. Puede llamarse un principio de divisor de tensión. Entre los dispositivos que entregan un voltaje y la medida de tensión incluyen al termistor, el diodo (y el transistor). Esto es muy importante para determinar como es unido el dispositivo a un amplificador o a la entrada del micro.

LA FRECUENCIA DE UNA SEÑAL

Una vez que se tiene una forma de onda que dispara al micro (usar el programa de prueba dado al principio de este artículo para asegurarse que es detectado por el micro), puede conseguir el programa simplemente para detectar su presencia o determinar la frecuencia. La frecuencia puede ser determinada de dos modos:

1. Contar del número de altos [H] y bajos [L] en un segundo. 2. Contar del tiempo tomado para una transición H-a-L - medio ciclo.

El método 1 es un modo muy lento de obtener una frecuencia en ciclos por segundo. Un micro trabaja tan rápido que puede determinar cosas en una fracción de segundo.

El método 2 es mucho más rápido pero puede ser muy inexacto como el semiciclo es multiplicado, hasta conseguir el valor en Hertz. Para reducir la inexactitud se puede hacer cuentas de 10 o 100 ciclos y realizar una multiplicación. Una cuenta ciclos más alta reduce la inexactitud. Se requieren los pasos siguientes para producir el valor de una frecuencia (en Hertz). Refiérase al figura de abajo para la definición de un alto y bajo.

A. La entrada será reiniciada (loop) hasta detectar un ALTO.B. El programa entonces salta a un retardo corto e incremento de "cuenta". C. El micro vuelve del retardo e incremento de "cuenta".D. El programa revisa la entrada para detectar un BAJO. Si no es detectado un BAJO el programa va a pasar a la B. E. Cuando un BAJO es detectado el programa tiene un valor en el archivo de "cuenta" -

Page 164: Programador PIC Pablin II

esto es medio ciclo.

Por el aumento del número de instrucciones realizadas durante el incremento de "cuenta", el programa puede calcular la frecuencia de la forma de onda. A veces no se requiere una frecuencia en ciclos por segundo, se puede querer comparar una frecuencia con un valor en una tabla. Esto se llama detección de tono.

DETECCIÓN DE TONO

También llamado descifrado de tono. La frecuencia de un tono entrante puede ser detectada y "señalada" cuando ésta es exactamente el tono correcto. Esto es práctico para detectar tonos de DTMF en la línea telefónica. De este modo DTMF tonos puede ser usado para conectar el equipo (como la iluminación, la calefacción, alarmas etc.). La exactitud del tono puede ser ajustada según el programa, lo es mejor permitir un margen de error entonces se puede garantizar que el tono será reconocido. 

Para la mejor detección, el tono entrante debería ser de "buena calidad" es decir la amplitud completa y libre de ruido, entonces la determinación puede ser rápida. La figura muestra una forma de onda típica.

¿Que hemos cubierto?

Hemos descrito cómo tratar la señal de audio de una charla, un silbido, el tono de un micrófono, del piezo y la detección magnética. Por otra parte, el microcontrolador también puede medir la resistencia de un resistor, el potenciómetro, LDR (Resistencia Dependiente de la Luz) el foto transistor, termistor y la capacitancia de un condensador. Pero todo lo que no se ha visto, talvez pronto lo abordemos. Capítulos sobre los siguientes temas, están siendo considerados y quizás estén disponibles pronto:

Medir temperatura.  Resistencia de un potenciómetro.  Capacitancia de a condensador.