66
Tutorial: Programación de PICs en Ensamblador De Asociación de Robotica y Domótica de E spaña (A.R.D.E.) Nota Inicial  Este tutorial fue escrito originalmente en ingles por Michael Stracey, y lo puedes encontrar en su sitio web (http://www.mstracey.btinternet.co.uk/pictutorial/picmain.htm)  . Ese texto está dividido en una introducción mas 13 tutoriales, que aquí se han asimilado todos como capítulos. La traducción intenta ser lo más fiel posible al texto original, pero hay expresiones coloquiales que utiliza el autor que han sido adaptadas a versiones m ás comunes del castellano. Otras expresiones o notas añadidas al texto original están indicadas convenientemente y marcadas como " notas de la traducción". El nivel del tutorial  puede considerarse básico, pero cubre bastante b ien la mayoría de los tópicos de la  programación en ens amblador para PICs Microchip. Contenido 1 Introducción al PIC 1.1 Introducción 1.2 Microcontrolador Microchip PIC 16F84 1.3 Los pines del 16F84 1.4 Como Programar el PIC 2 Conectarse al microcontrolador PIC 2.1 Una placa de en trenamiento sencilla 3 Buenas técnicas para programar 4 Los Registros 4.1 Un ejemplo de có digo 5 Cómo escribir en los puertos 6 Bucles de Retardo 7 Subrutinas 8 Cómo leer de los puertos E/S 9 Operadores Lógicos y Aritméticos 9.1 Operadores Lógicos 9.2 Operadores Aritméticos 10 Operaciones con Bits Page 1 of 66 Tutorial: Programación de PICs en Ensamblador - Asociación de Robotica ... 13/05/2012 htt  p://wiki.webdearde.com /index.php?title=Tu tor ial:_Programaci%C3%B3... Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com )

Tutorial Programacionde PICs en Ensamblador.pdf

Embed Size (px)

Citation preview

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Robotica ... Page 1 of 66

Tutorial: Programacin de PICs en EnsambladorDe Asociacin de Robotica y Domtica de Espaa (A.R.D.E.) Nota Inicial Este tutorial fue escrito originalmente en ingles por Michael Stracey, y lo puedes encontrar en su sitio web (http://www.mstracey.btinternet.co.uk/pictutorial/picmain.htm) . Ese texto est dividido en una introduccin mas 13 tutoriales, que aqu se han asimilado todos como captulos. La traduccin intenta ser lo ms fiel posible al texto original, pero hay expresiones coloquiales que utiliza el autor que han sido adaptadas a versiones ms comunes del castellano. Otras expresiones o notas aadidas al texto original estn indicadas convenientemente y marcadas como "notas de la traduccin". El nivel del tutorial puede considerarse bsico, pero cubre bastante bien la mayora de los tpicos de la programacin en ensamblador para PICs Microchip.

Contenido 1 Introduccin al PIC 1.1 Introduccin 1.2 Microcontrolador Microchip PIC 16F84 1.3 Los pines del 16F84 1.4 Como Programar el PIC 2 Conectarse al microcontrolador PIC 2.1 Una placa de entrenamiento sencilla 3 Buenas tcnicas para programar 4 Los Registros 4.1 Un ejemplo de cdigo 5 Cmo escribir en los puertos 6 Bucles de Retardo 7 Subrutinas 8 Cmo leer de los puertos E/S 9 Operadores Lgicos y Aritmticos 9.1 Operadores Lgicos 9.2 Operadores Aritmticos 10 Operaciones con Bits

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Robotica ... Page 2 of 66

11 Tablas de Datos 12 Interrupciones:una introduccin 12.1 El Flag de Interrupcin 12.2 La Posicin de Memoria 13 Interrupciones:Cmo escribir el cdigo 14 El Watchdog Timer 14.1 Tiempos de WDT 14.2 Temporizacin de las instrucciones 14.3 Software Programador 14.4 Programa de ejemplo 15 Referencias

Introduccin al PICIntroduccinBienvenidos al inicio del Tutorial sobre PICs. Estas pginas te llevaran desde la estructura bsica del dispositivo, hasta los mtodos y tcnicas de programacin. Tambin habr sugerencias de como modificar el cdigo para que lo puedas adaptar el PIC a tus propias aplicaciones. No incluir diagramas de arquitectura interna, ya que esto puede llevar a confusiones. Si quieres echar un vistazo a la 'datasheet', la puedes bajar del sitio de Microchip (http://www.microchip.com/) . Para empezar, echemos un vistazo al PIC.

Microcontrolador Microchip PIC 16F84Microchip fabrica una serie de microcontroladores llamados PIC. Puedes ver toda la gama de sus microcontroladores aqu (http://www.microchip.com/stellent/idcplg? IdcService=SS_GET_PAGE&nodeId=2551) . Los hay disponibles de distintas capacidades, desde algunos tipos bsicos con poca memoria, hasta los que tienen convertidores Analgico a Digital (ADC) incluidos o incluso los que llevan dentro PWMs (Pulse Width Modulators = Moduladores de Ancho de Pulso). Voy a concentrarme en el PIC 16F84. Una vez que aprendas como programar un tipo de PIC, aprender el resto ser fcil.

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Robotica ... Page 3 of 66

Hay diversas formas de programar el PIC, - usando BASIC, C, o Lenguaje Ensamblador. Voy a mostrarte el Lenguaje Ensamblador. No te asustes. Solo hay 35 instrucciones que aprender, y es la manera ms econmica de programar los PICs, ya que no necesitas ningn otro software extra que no sea de los gratuitos.

Los pines del 16F84Mas abajo vers el diagrama de patillas(pines en adelante) del PIC 16F84. Pasar por cada pin, explicando para que se utiliza cada uno.

RA0 a RA4 RA es un puerto bidireccional. Eso quiere decir que puede ser configurado como entrada o como salida. El nmero que hay despus de RA indica el numero de bit (0 a 4). Por tanto, tenemos un puerto bidireccional de 5 bits donde cada bit puede ser configurado como entrada o como salida. RB0 a RB7 RB es un segundo puerto bidireccional. Se comporta exactamente de la misma manera que RA, excepto que este tiene 8 bits. VSS y VDD Estos son los pins de alimentacin. VDD es la alimentacin positiva, y VSS es el negativo de la alimentacin, o 0 Voltios. La tensin mxima de alimentacin que puedes utilizar son 6 Voltios, y el mnimo son 2 Voltios. OSC1/CLK IN y OSC2/CLKOUT

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Robotica ... Page 4 of 66

Estos pines son donde conectaremos el reloj externo, para que el microcontrolador disponga de algn tipo de temporizacin. MCLR Este pin se utiliza para borrar las posiciones de memoria dentro del PIC (p.ej. cuando quiero reprogramarlo). Durante el funcionamiento normal est conectado a la alimentacin positiva. INT Este es un pin de entrada que puede ser monitorizado. Si el pin se pone a nivel alto, podemos hacer que el programa se reinicie, se pare o cualquier otra funcin de deseemos. No lo utilizaremos mucho. TOCK1 Esta es otra entrada de reloj, que opera con un temporizador interno. Opera aisladamente del reloj principal. De nuevo, este tampoco lo utilizaremos mucho.

Como Programar el PICBien, espero que no te hayas asustado mucho. Ahora, querrs conocer como programar el PIC, pero adems de aprender las instrucciones de cdigo de ensamble, como programas realmente ese cdigo y lo metes en el PIC? Pues hay dos maneras, la sencilla y la "Hazlo tu mismo". La manera sencilla es comprar un programador de PIC, que se conecte a tu PC, que trae un software con el que puedes programar el PIC. La "Hazlo t mismo" se trata de que construyas tu propio programador y utilices software gratuito de Internet y lo programes de ese modo. Si prefieres el mtodo "hazlo tu mismo", te recomendara este sitio (http://www.icprog.com/index1.htm) . Pulsa sobre "Supported Programmers" para ver los circuitos. El ms econmico es el "TAIT Classic Programmer". El software para programar el PIC tambin lo puedes bajar de esa pgina, ves a "Download". Si quieres ir por la va fcil, echa un vistazo a este sitio: (falta el sitio, el del texto original no funciona). Otro buen sitio de software gratuito es este (http://www.picallw.com/) . Este permite utilizar cualquier programador, puesto que el software es completamente configurable.

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Robotica ... Page 5 of 66

Cualquier mtodo funcionar, ya que ambos darn el mismo resultado, programar el PIC. Lo siguiente que necesitas es un ensamblador. Este convertir el programa que escribas en un formato que el PIC comprende. El mejor es del propio Microchip, llamado MPLAB. Es un programa de ventanas, que incluye un editor, un simulador y el ensamblador. Este es un software escrito por los propios fabricantes del PIC, y por encima de todo es gratuito !!! La siguiente imagen ilustra el proceso de programacin de un PIC.

Tambin recomiendo utilizar una placa de insercin para hacer tus circuitos, mientras juegas con el PIC. Hay varios tamaos disponibles. A continuacin veremos como conectar un circuito simple para el desarrollo con el PIC.

Conectarse al microcontrolador PICUna placa de entrenamiento sencillaBien, ahora ya tienes tu programador, y uno o dos PICs. Es muy simple conocer la teora para saber como programar el PIC, pero el verdadero aprendizaje viene cuando intentas probar tu cdigo en un PIC y ves los resultados en tu propio circuito. He incluido el diagrama de un circuito que muestra una placa de entrenamiento muy bsica y econmica. Por supuesto, le puedes aadir LEDs y switches, pero yo he dejado las patillas sin conectar. Puedes monitorizar los pines de entrada/salida conectando LEDs directamente a los pines, y se encendern cuando los pines se pongan a nivel alto.

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Robotica ... Page 6 of 66

Tambin, puedes aadir switches a los pines, para poder seleccionar que pines poner a nivel alto, y cuales a nivel bajo. Bsicamente, lo que estoy diciendo es que si comienzas con este circuito, puedes aadir lo que creas necesario.

La linea de alimentacin est puesta a 6 Voltios, que es el mximo voltaje para el PIC. Puedes utilizar cualquier voltaje inferior, hasta un mnimo de 2 Voltios. C3 es conocido como un condensador de 'bypass'. Todo lo que se hace C3 es reducir el ruido de la linea de alimentacin. X1 es un cristal de 4 MHz. Puedes utilizar un circuito RC (resistencia y condensador) (Nota de edicin: crear enlace aqu), pero el precio del cristal es insignificante, y es mas estable. C1 y C2 ayudan a reducir cualquier desviacin en la oscilacin cristal, y a eliminar cualquier ruido no deseado antes de que la seal llegue al PIC.

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Robotica ... Page 7 of 66

Buenas tcnicas para programarAntes de meternos en harina con la programacin del PIC, creo que ahora es un buen momento para explicar algunas tcnicas para programar bien. Si escribes un;(puntoycoma)encualquierpuntodetuprograma,elcompilador ignorar cualquier cosa que haya detrs de l, hasta llegar al retorno de carro. Esto significa que podemos aadir comentarios a nuestro programa que nos recuerden que estbamos haciendo en ese punto. Esta es una buena prctica incluso para los programas ms sencillos. Ahora mismo puede que entiendas completamente qu es lo que hace tu programa, pero dentro de unos meses, puede que te acabes tirando de los pelos. Por tanto, utiliza comentarios donde puedas , no hay lmites. Segundo, puedes asignar nombres a las constantes va los registros (hablaremos de estos ms adelante). Hace lo que ests escribiendo mucho ms sencillo de leer, para saber de que valor se trata, mas que intentar entender que significan todos esos nmeros. As que utiliza nombres reales como CONTADOR. Date cuenta de que hemos puesto el nombre en letras maysculas. Esto lo hace destacar, y tambin significa (por convencin) que se trata de una constante. Tercero, aade algn tipo de cabecera en tus programas utilizando los punto y coma. Un ejemplo sera algo as:;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Autor: ; ; Fecha: ; ; Versin: ; ; Titulo: ; ; ; ; Descripcin: ; ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Date cuenta de que hemos hecho una especie de caja utilizando puntos y comas. Esto es simplemente para hacerlo ms pulcro. Finalmente, prueba y documenta el programa sobre papel tambin. Puedes usar o bien diagramas de flujo o bien algoritmos o lo que tu quieras. Esto te ayudar a escribir tu programa paso a paso.

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Robotica ... Page 8 of 66

Bien, eso es todo al respecto, vamos a entrar en materia.

Los RegistrosUn registro es un lugar dentro del PIC que puede ser escrito, ledo o ambas cosas. Piensa en un registro como si fuese un trozo de papel donde tu puedes ver la informacin o escribirla. La figura de ms abajo muestra el mapa de registros del interior del PIC16F84. No te preocupes si no has visto nada parecido antes, es solo para mostrar donde estn los diferentes bits y piezas dentro del PIC, y nos ayudar a explicar unos cuantos comandos.

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Robotica ... Page 9 of 66

La primera cosa que notars es que est dividido en dos - Banco 0 y Banco 1. El Banco 1 es utilizado para controlar las propias operaciones del PIC, por ejemplo para decirle al PIC cuales bits del Puerto A son entradas y cuales son salidas. El Banco 0 se utiliza para manipular los datos. Un ejemplo es el siguiente: Digamos que queremos poner un bit del puerto A a nivel alto. Lo primero que necesitamos hacer es ir al Banco 1 para poner ese bit o pin en particular en el puerto A como salida. Despus volvemos al Banco 0 y enviamos un 1 lgico a ese pin.

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 10 of 66

Los registros que vamos a usar mas comunes en el Banco 1 son STATUS, TRISA y TRISB. El primero permite volver al Banco 0, TRISA nos permite establecer los pines que sern entradas y los que sern salidas del Puerto A, TRISB nos permite establecer los pines que sern entradas y los que sern salidas del puerto B. Vamos a ver con ms detenimiento estos tres registros. STATUS Para cambiar del Banco 0 al Banco 1 utilizamos el registro STATUS. Hacemos esto poniendo el bit 5 del registro STATUS a 1. Para cambiar de nuevo al Banco 0, ponemos el bit 5 del registro STATUS a 0. El registro STATUS se localiza en la direccin 03h (la 'h' significa que el nmero es hexadecimal). TRISA y TRISB Estn localizados en las direcciones 85h y 86h respectivamente. Para programar que un pin sea una salida o una entrada, simplemente enviamos un 0 o un 1 al bit en cuestin en el registro. Ahora, podemos hacer esto ya sea en binario o en hexadecimal. Personalmente uso ambos, ya que el binario ayuda mucho a visualizar el puerto. Si no ests familiarizado con el paso de binario a hexadecimal y viceversa, utiliza una calculadora cientfica. Entonces en el puerto A tenemos 5 pines, por tanto 5 bits. Si deseamos poner uno de los pines como entrada, enviamos un 1 al bit en cuestin. Si deseamos poner uno de los pines como salida, ponemos un 0 en ese bit. Los bits estn definidos de manera correspondiente con los pines, en otras palabras el bit 0 es el RA0, el bit 1 es el RA1, el bit 2 es el RA2, y as sucesivamente. Vamos a tomar un ejemplo. Si queremos poner RA0, RA3 y RA4 como salidas, y RA1 y RA2 como entradas, enviamos esto: 00110 (06h). Date cuenta de que el bit cero est a la derecha, como se muestra aqu: Pin del Puerto A RA4 RA3 RA2 RA1 RA0 Numero de bit Valor Binario 4 0 3 0 2 1 1 1 0 0

Lo mismo se aplica para TRISB.

PORTA y PORTB

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 11 of 66

Para poner uno de nuestros pines de salida a nivel alto, simplemente ponemos un 1 el bit correspondiente en nuestro registro PORTA o PORTB. El formato es el mismo que para los registros TRISA y TRISB. Para leer si un pin est a nivel alto o nivel bajo en los pines de nuestro puerto, podemos ejecutar un chequeo para ver si el bit en particular correspondiente esta puesto a nivel alto (1) o est puesto a nivel bajo (0). Antes de dar un ejemplo de cdigo, tenemos que explicar dos registros mas - W y F. W El registro W es un registro de propsito general al cual le puedes asignar cualquier valor que desees. Una vez que has asignado un valor a ese registro, puedes sumarle cualquier otro valor, o moverlo. Si le asignas otro valor a W, su contenido es sobrescrito. Un ejemplo de cdigo Vamos a darte un ejemplo de cdigo sobre lo que acabamos de aprender. No intentes compilar esto todava, lo haremos cuando hagamos nuestro primer programa. Simplemente estamos intentado mostrar como se hace la programacin de lo anterior y de paso presentando un par de instrucciones. Vamos a poner el Puerto A como en el ejemplo anterior. Lo primero, necesitamos cambiar del banco 0 al banco 1. Hacemos esto modificando el registro STATUS, que est en la direccin 03h, poniendo el bit 5 a 1.BSF 03h,5

La instruccin BSF significa en ingles "Bit Set F" (Poner a 1 un bit de la Memoria). La letra F significa que vamos a utilizar una posicin de memoria, o un registro en memoria. Vamos a utilizar dos nmeros despus de esta instruccin - 03h, el cual se refiere a la direccin del registro STATUS, y el nmero 5 que corresponde al nmero de bit. Por tanto, lo que estamos diciendo es "pon a 1 el bit 5 de la direccin de memoria 03h". Ahora ya estamos en el banco 1.MOVLW b'00110'

Estamos poniendo el valor binario 00110 (la letra 'b' significa que el nmero est en binario) en nuestro registro de propsito general W. Podramos haber hecho esto en hexadecimal, en cuyo caso nuestra instruccin hubiese sido:

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 12 of 66

MOVLW 06h

Cualquiera de las dos funcionar. La instruccin MOVLW significa en ingles "Move Literal Value into W", en castellano, mover un valor literal directamente al registro W. Ahora necesitamos poner este valor en el registro TRISA para configurar el puerto:MOVWF 85h

Esta instruccin significa "poner los contenidos de W en el registro cuya direccin viene a continuacin", en este caso la direccin 85h, que apunta a TRISA. Nuestro registro TRISA ahora tiene el valor 00110 o mostrado grficamente: Pin del Puerto A RA4 RA3 RA2 RA1 RA0 Valor Binario Entrada/Salida 0 S 0 S 1 E 1 E 0 S

Ahora tenemos que configurar los pines del Puerto A, y para ello necesitamos volver al banco 0 para manipular cualquier dato.BCF 03h,5

Esta instruccin hace lo contrario a BSF. Significa en ingles "Bit Clear F" (en castellano, poner a 0 un bit de la memoria). Los dos nmeros que le siguen son la direccin del registro, en este caso del registro STATUS, y el nmero de bit, es este caso el 5. As que lo que hemos hecho ahora es poner a 0 el bit 5 del registro STATUS. Ya estamos de vuelta en el Banco 0. Aqu est el cdigo en un solo bloque:BSF MOVLW MOVWF BCF 03h,5 06h 85h 03h,5 ; ; ; ; Ve al banco 1 Pon 00110 en W Mueve 00110 a TRISA Vuelve al Banco 0

Lelo hasta que las entiendas. De momento ya hemos visto 4 instrucciones. Solo nos quedan 31 para terminar!

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 13 of 66

Cmo escribir en los puertosEn el apartado anterior, hemos mostrado como configurar los pines de un puerto del PIC como entradas o como salidas. En este apartado, vamos a mostrar como enviar datos a los puertos. En el siguiente apartado terminaremos haciendo que un LED parpadee incluyendo el listado completo del programa y un diagrama de un circuito simple para que puedas ver al PIC haciendo exactamente lo que esperamos que haga. No intentes compilar o programar tu PIC con estos listados de aqu, ya que son solo ejemplos. Primero, pongamos el bit 2 del puerto A como salida:bsf movlw movwf bcf 03h,5 00h 85h 03h,5 ;Ir al Banco 1 ;Poner 00000 en W ;Mover 00000 al TRISA todos los pines como salidas. ;volver al Banco 1

Esto te sonar del apartado anterior. La nica diferencia es que hemos puesto todos los pines del Puerto A como salidas, poniendo 0h en el registro tri-estado (TRISA). Ahora lo que tenemos que hacer es encender el LED. Hacemos esto poniendo uno de los pines (aquel que tenga el LED conectado) a nivel alto. En otras palabras, enviamos un 1 al pin. As es como se hace (Mira los comentarios de cada linea):movlw movwf 02h 05h ; Escribe 02h en el registro W. En binario es 00010, ; ...lo cual pone a 1 el bit 2 (pin 18) mientras mantiene los otros pines a 0. ; Ahora mueve los contenidos de W (02h) al puerto A, cuya direccin es 05h.

Por tanto, ahora tu LED est encendido, y ahora queremos apagarlo:movlw movwf 00h 05h ; Escribe 00h en el registro W. Esto pone a 0 todos los pines. ; Ahora mueve todos los contenidos de W (0h) al puerto A, cuya direccin es 05h.

As que lo que hemos hecho ha sido encender y apagar el LED una vez. Lo que queremos es que el LED se encienda y se apague continuamente. Para hacer esto tenemos que volver al principio del programa. Para conseguir esto lo primero que hacemos es poner una etiqueta al comienzo de nuestro programa, y dicindole al programa que vaya a ese punto constantemente. Definimos una etiqueta muy simple. Escribimos un nombre, digamos INICIO, entonces el cdigo queda:

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 14 of 66

Inicio

movlw movwf movlw movwf goto

02h 05h 00h 05h Inicio

; ; ; ; ; ;

Escribe 02h en el registro W. En binario es 00010, ...lo cual pone a 1 el bit 2 (pin 18) mientras mantiene los otros pines a 0. Ahora mueve los contenidos de W (02h) al puerto A, cuya direccin es 05h. Escribe 00h en el registro W. Esto pone a 0 todos los pines. Ahora mueve todos los contenidos de W (0h) al puerto A, cuya direccin es 05h. ve donde est Inicio.

Como puedes ver, primer decimos la palabra 'Inicio' justo al comienzo del programa. Despus, justo al final del programa decimos simplemente 'goto Inicio', ves a Inicio. La instruccin 'goto' significa en ingles 'ir a', y eso es lo que hace. Este programa encender y apagar el LED constantemente, desde el momento que le demos alimentacin al circuito, y se detendr cuando le quitemos la alimentacin. Creo que deberamos echar un vistazo de nuevo a nuestro programa:; bsf movlw movwf bcf movlw movwf movlw movwf goto 03h,5 00h 85h 03h,5 02h 05h 00h 05h Inicio

Inicio

Bien, he quitado los comentarios. Pero, te das cuenta de que todo lo que vemos son instrucciones y nmeros ? Esto puede ser algo confuso si mas tarde intentas depurar el programa, y tambin cuando escribes cdigo que te tengas que acordar de todas las direcciones de memoria. Incluso con los comentarios puestos, puede ser un poco lioso. Lo que necesitamos es dar nombres a estos nmeros. Esto se consigue con otra instruccin: "equ" La instruccin "equ" simplemente significa que algo equivale a algo [Nota de la traduccin: "equ" viene del termino ingles "equivalence", en castellano "equivalencia"]. No es una instruccin del PIC, sino para el ensamblador. Con esta instruccin podemos asignar un nombre a la direccin de localizacin de un registro, o en trminos de programacin asignar una constante. Vamos a establecer algunas constantes para nuestro programa, y vers que sencillo es de leer.STATUS TRISA PORTA equ equ equ 03h 85h 05h ; Este asigna a la palabra STATUS el valor 03h, que es la direccin del registro S ; Este asigna a la palabra TRISA el valor 85h, que es la direccin del registro tr ; Este asigna a la palabra PORTA el valor 05h, que es la direccin del Puerto A.

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 15 of 66

As que ahora que hemos establecido nuestro valores constantes, vamos a ponerlos en nuestro programa. Los valores constantes deben ser definidos antes de que los usemos. Para estar seguros de ello los ponemos siempre al comienzo del programa. Reescribiremos de nuevo el programa sin comentarios, para que puedas comparar el listado anterior con este:STATUS TRISA PORTA ; equ equ equ bsf movlw movwf bcf movlw movwf movlw movwf goto 03h 85h 05h STATUS,5 00h TRISA STATUS,5 02h PORTA 00h PORTA Inicio

Inicio

Seguro que ahora puedes ver que las constantes hacen el programa un poco ms sencillo, aunque todava no hemos puesto los comentarios. Sin embargo, no hemos terminado todava.

Bucles de RetardoExiste un ligero inconveniente en nuestro programa del LED parpadeante. Cada instruccin necesita un ciclo de reloj para ser completada. Si utilizamos un cristal de 4 Mhz, cada instruccin tardar 1/4 Mhz o 1 microsegundo en ser completada. Como solo estamos usando 5 instrucciones, el LED se encender y apagar en 5 microsegundos. Esto es demasiado rpido para que lo podamos ver, y parecer que el LED est permanentemente encendido. Lo que necesitamos hacer es introducir un retardo entre el momento de encendido y apagado y viceversa. El principio para retardo es el de contar hacia atrs desde un nmero previamente establecido y cuando llegue a cero, paramos de contar. El valor cero indica el fin del retardo y continuamos nuestro camino a travs del programa. As que lo primero que necesitamos hacer es definir una constante que usaremos como contado. La llamaremos CONTADOR. Lo siguiente, necesitamos decidir el tamao del nmero desde el que contar. Bien, el nmero mayor que podemos tener es 255 o FFh en hexadecimal. Ahora, como hemos mencionado en el apartado anterior, la instruccin equ asigna una palabra a una localizacin de un registro. Esto significa que cualquiera que sea el nmero que asignemos a CONTADOR, ser igual al contenido de un registro.

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 16 of 66

Si lo probamos y asignamos el valor FFh, el compilador entender que estamos asignando la direccin de memoria FFh a la constante, y obtendremos un error cuando vayamos a compilar el programa. Esto es debido a que la localizacin FFh est reservada, y por tanto no podemos acceder a ella. As que, como hacemos para asignar un nmero real?Bien,serequierehacerunpocode"pensamiento lateral". Si asignamos a nuestro CONTADOR, por ejemplo, a la direccin 08h, este apuntar a un registro de propsito general. Las posiciones de memoria tienen un valor por defecto de FFh. De este modo, si CONTADOR apunta a 08h, tendr un valor de FFh la primera vez que lo pongamos en marcha. Pero, s, no llores, cmo ponemos un valor distinto en CONTADOR ? Bien, todo lo que tenemos que hacer es primero 'mover' un valor a esta posicin. Por ejemplo, si queremos que CONTADOR tenga un valor de 85h, no podemos decir 'CONTADOR equ 85h' porque esta es la localizacin del registro tri-estado del puerto A (TRISA). Lo que hacemos es esto:movlw movwf 85h 08h ; Primero, ponemos el valor 85h en el registro W. ; Ahora lo movemos a nuestro registro 08h.

Ahora, podemos decir 'CONTADOR equ 08h', CONTADOR ser igual al valor 85h. Sutil, verdad? As que lo primero definimos nuestra constante:CONTADOR equ 08h

A continuacin necesitamos disminuir este CONTADOR en 1 hasta que alcance cero. Da la casualidad de que hay una sola instruccin que hace esto por nosotros, con la ayuda de un 'goto' y una etiqueta. La instruccin que usaremos es:decfsz CONTADOR,1

Esta instruccin dice "resta 1 al registro (en esta caso CONTADOR). Si llegamos a cero, salta 2 lugares hacia delante"[Nota de la traduccin: El valor que le sigue a la coma, indica donde debe almacenarse el resultado de la operacin. Si es 1, como en el ejemplo anterior, el resultado se almacena en el mismo registro indicado en la instruccin, y si es 0 el resultado se almacena en el registro w.] . Un montn de palabras para una sola instruccin. Veamosla en accin antes, despus la pondremos en nuestro programa.CONTADOR ETIQUETA equ 08h decfsz CONTADOR,1

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 17 of 66

goto ETIQUETA ;Continua por aqu. : : :

Lo que hemos hecho es primero poner nuestra constante CONTADOR a 255. La siguiente linea pone una etiqueta, llamada ETIQUETA seguida de nuestra instruccin decfsz. La instruccin decfsz CONTADOR,1 disminuye el valor de CONTADOR en 1, y almacena el resultado de vuelta en CONTADOR. Tambin comprueba si CONTADOR tiene un valor de 0. Si no lo tiene, hace que el programa salte a la siguiente linea. Aqu tenemos una instruccin de 'goto' que nos enva de vuelta a nuestra instruccin decfsz. Si el valor de CONTADOR es igual a cero, entonces la instruccin decfsz hace que el programa salte dos lugares hacia adelante, y se site donde hemos escrito "Continua por aqu". As que, como puedes ver, hemos hecho que el programa permanezca en un lugar durante un tiempo predeterminado antes de seguir adelante. Esto se llama bucle de retardo. Si necesitamos un retardo mayor, podemos poner un bucle detrs de otro. Cuantos mas bucles pongamos, mayor ser el retardo. Nosotros vamos a necesitar por lo menos dos, si queremos ver parpadear al LED. Vamos a poner estos bucles de retardo en nuestro programa, y terminaremos haciendo un programa real aadiendo los comentarios:;*****Establecimiento constantes **** STATUS equ 03h TRISA equ 85h PORTA equ 05h CONTADOR1 equ 08h CONTADOR2 equ 09h ; ;****Configuracin del Puerto**** bsf STATUS,5 movlw 00h movwf TRISA bcf STATUS,5 ; ;****Encendido del LED **** Inicio movlw 02h movwf PORTA ; ;****Inicio del buble de retardo 1**** Bucle1 decfsz CONTADOR1,1 goto Bucle1 decfsz CONTADOR2,1 goto Bucle1 ; ; ; ; ; Direccin del registro STATUS Direccin del registro triestado para el Puerto A. Direccin del Puerto A. Primer contador para nuestros bucles de retardo. Segundo contador para nuestros bucles de retardo.

; ; ; ;

Cambiamos al banco 1Switch to Bank 1 Ponemos los pines del puerto A ... ...como salidas. Volvemos al Banco 0.

; Encendemos el LED poniendo primero el valor... ; ... en el registro w y despus al puerto

; ; ; ; ; ;

Restamos 1 a 255. Si CONTADOR es cero, continuamos. Restamos 1 a 255 Volvemos al inicio de nuestro bucle Este retardo cuenta hacia atrs ... ...desde 255 a 0, 255 veces.

; ;****Retardo terminado, ahora apagamos el LED **** movlw 00h ; Apaga el LED poniendo primero el valor ... movwf PORTA ; ... en el registro w y despus al puerto ; ;****Aadimos otro retardo**** Bucle2 decfsz CONTADOR1,1 ; Este segundo bucle mantiene el LED... goto Bucle2 ; ...apagado el tiempo suficiente... decfsz CONTADOR2,1 ; ...para que lo veamos goto Bucle2 ; ; ;****Ahora volvemos al inicio del programa

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 18 of 66

goto

Inicio

; Vuelve al principio y enciende el LED... ; ...de nuevo. ; Algunos compiladores necesitan esta instruccin. ; y tambin por si acaso olvidamos poner... ; ... la instruccin 'goto'.

;****Termina el Programa**** end

Puedes compilar este programa y programar el PIC con l. Por su puesto, querrs probar el circuito para ver si funciona realmente. Aqu est el diagrama del circuito para que lo construyas una vez que hayas programado tu PIC:

Felicidades, acabas de escribir tu primer programa para PIC, y construido un circuito para hacer parpadear un LED. As que, si has seguido este tutorial hasta aqu, has aprendido 7 instrucciones de 35, y ya controlas los puertos de entrada/salida ! Por qu no intentas modificar los bucles de retardo para hacer que el LED parpadee mas rpido?CualeselvalormnimodeCONTADORparapoderverelLED parpadear? Por qu no aades un tercer bucle o incluso ms bucles de retardo despus del primero para hacer ms lento el apagado mas lento ? Necesitars una constante para cada bucle de retardo. Podras incluso ajustar tus bucles de retardo para hacer que el LED parpadease con un ritmo definido, por ejemplo una vez por segundo. En la siguiente seccin veremos como podemos usar una cosa llamada sub-rutina para ayudar a mantener el programa simple y pequeo.

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 19 of 66

SubrutinasUna subrutina es una seccin de cdigo o programa, que puede ser llamada como y cuando la necesites. Las subrutinas se usan si vas a ejecutar la misma funcin funcin ms de una vez, por ejemplo para crear un retardo. Las ventajas de utilizar una subrutina son que har ms sencillo modificar el valor una vez dentro de la subrutina antes que, digamos, hacerlo diez veces a travs de tu programa. Y tambin te ayudar a reducir el total de memoria que ocupa tu programa dentro del PIC. Miremos una subrutina:RUTINA ETIQUETA CONTADOR decfsz goto return equ 255 CONTADOR,1 ETIQUETA

Primero tenemos que dar un nombre a la subrutina, y en este caso hemos elegido RUTINA. Despus escribimos el cdigo que queramos como hacemos normalmente. En este caso, hemos elegido el cdigo del retardo para el programa de parpadeo de nuestro LED. Finalmente, terminamos la subrutina tecleando la instruccin RETURN. Para arrancar la subrutina desde cualquier punto de nuestro programa, simplemente escribimos la instruccin CALL seguida por el nombre de la subrutina. Vamos a ver esto con algo ms de detalle. Cuando alcanzamos la parte de nuestro programa que dice CALL xxx, donde xxx es el nombre de nuestra subrutina, el programa salta a donde quiera que resida la subrutina xxx. Las instrucciones dentro de la subrutina se ejecutan. Cuando se alcanza la instruccin RETURN, el programa salta de vuelta a nuestro programa principal, justo a la instruccin que va inmediatamente despus de nuestra instruccin CALL xxx. Puedes llamar a la misma subrutina tantas veces como quieras, esa es la razn por la que utilizar subrutinas reduce el tamao total de nuestro programa. Sin embargo, hay dos cosas que debes tener en cuenta. La primera, igual que en tu programa principal, cualquier constante debe ser declarada antes de utilizarla. Pueden ser declaradas dentro de la subrutina misma, o justo al comienzo del programa principal. Recomendaramos que declarases todo al comienzo del programa principal, para que as sepas que todo se encuentra en el mismo sitio. Lo segundo, te debes asegurar de que el programa principal pasa por alto la subrutina. Lo que queremos decir con esto es que si pones la subrutina justo al final del programa principal, a menos que uses una instruccin 'goto' para saltar la subrutina, el programa seguir y ejecutar la subrutina tanto si quieres como si no. El PIC no diferencia entre una subrutina y el programa principal.

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 20 of 66

Vamos a verlo en nuestro programa de parpadeo de LED, pero esta vez utilizaremos una subrutina para el bucle de retardo. Con suerte vers que sencillo se queda el programa, y tambin veras como funciona la subrutina en la realidad:;***** Establecimiento constantes **** STATUS equ 03h ; Direccin del registro STATUS TRISA equ 85h ; Direccin del registro tri-estado para el Puerto A. PORTA equ 05h ; Direccin del Puerto A. CONTADOR1 equ 08h ; Primer contador para nuestros bucles de retardo. CONTADOR2 equ 09h ; Segundo contador para nuestros bucles de retardo. ; ;**** Configuracin del Puerto **** bsf STATUS,5 ; Cambiamos al Banco 1 movlw 00h ; Ponemos los pines del puerto A ... movwf TRISA ; ...como salidas. bcf STATUS,5 ; Volvemos al Banco 0. ; ;**** Encendido del LED **** Inicio movlw 02h ; Encendemos el LED poniendo primero el valor... movwf PORTA ; ... en el registro w y despus al puerto ; ;**** Aadimos un retardo **** call Retardo ; ;**** Retardo terminado, ahora apagamos el LED **** movlw 00h ; Apaga el LED poniendo primero el valor ... movwf PORTA ; ... en el registro w y despus al puerto ; ;**** Aadimos otro retardo **** call Retardo ; ;**** Ahora volvemos al inicio del programa goto Inicio ; Vuelve al principio y enciende el LED... ; ...de nuevo. ; ;**** Aqu est nuestra Subrutina Retardo Bucle1 decfsz CONTADOR1,1 ; Este segundo bucle mantiene el LED... goto Bucle1 ; ...apagado el tiempo suficiente... decfsz CONTADOR2,1 ; ...para que lo veamos goto Bucle1 ; return ; ;**** Fin del Programa**** end ; Algunos compiladores necesitan esta instruccin, ; y tambin por si acaso olvidamos poner... ; ... la instruccin 'goto'.

Puedes ver que utilizando una subrutina para nuestro bucle de retardo, hemos reducido el tamao del programa. Cada vez que queramos hacer un retardo, ya sea cuando el LED est apagado o cuando est encendido, simplemente llamamos a la subrutina de retardo. Al final de la subrutina, el programa retorna a la linea siguiente a la instruccin 'call'. En el ejemplo anterior, encendemos el LED. Despus llamamos a la subrutina. Entonces el programa retorna para que podamos apagar el LED. Llamamos a la subrutina de nuevo, y cuando la surutina termina, el programa retorna a la siguiente instruccin que ve, que es 'goto Inicio'.

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 21 of 66

Para aquellos de vosotros que estis interesados, nuestro programa original tenia 120 bytes de tamao. Mediante el uso de la subrutina, hemos reducido el programa a 103 bytes.[Nota de la traduccin: Estos tamaos en bytes a los que se refiere el autor, son los tamaos de los ficheros .HEX que resultan de compilar estos listados con el compilador de Microhip MPASM.] Puede que no parezca gran cosa, pero teniendo en cuenta que solo tenemos 1024 bytes en total dentro del PIC , cada pequeo bit ayuda. [Nota de la traduccin: Cuando el autor dice que el 16F84 tiene 1024 bytes, se esta refiriendo al rea de memoria para el almacenamiento del cdigo o programas. Y, aunque utiliza la palabra bytes aqu, en realidad no se trata de bytes(los cuales tienen 8 bits), sino que se trata 14-bit words(en castellano, palabras de 14-bits, un poco ms de un byte). De modo, que lo que sera correcto decir es, que el rea de memoria de programa en el 16F84 tiene un tamao 1024 x 14 bit words, o 1K x 14 bit words, o 1024 posiciones de 14 bits cada una. Como dato adicional, cada instruccin del conjunto de instrucciones del 16F84 ocupa una palabra de 14 bits. Es decir, cada una ocupa una de esas 1024 posiciones de memoria disponible. Microchip fabrica otros PICs con mayor espacio de memoria interna. Estos se pueden ver en las pginas de Microchip (http://www.microchip.com/stellent/idcplg? IdcService=SS_GET_PAGE&nodeId=2551) . ] En el prximo capitulo, veremos cmo leer de los puertos.

Cmo leer de los puertos E/SHasta este punto, hemos estado escribiendo en el Puerto A para poder encender y apagar el LED. Ahora vamos a ver como podemos leer los pines de E/S de los puertos. Esto es para que podamos conectar un circuito externo y actuar sobre cualquier salida que este nos d. Si recuerdas de los captulos previos, para configurar los puertos de E/S, tenemos que cambiarnos del Banco 0 al Banco 1. Hagamos eso primero:STATUS TRISA PORTA equ equ equ bsf 03h 85h 05h STATUS,5 ; ; ; ; Direccin Direccin Direccin Cambia al del registro STATUS del registro tri-estado para el Puerto A. del Puerto A. Banco 1.

Ahora, para configurar el pin de un puerto para que sea una salida, enviamos un 0 al registro TRISA. Para poner el pin como entrada, ponemos un 1 en el registro TRISA.movlw movwf bcf 01h TRISA STATUS,5 ; Para configurar el pin 0 del Puerto A... ; ... como entrada. ; Vuelve al Banco 0.

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 22 of 66

Ahora hemos puesto el bit 0 del puerto A como entrada. Lo que necesitamos hacer ahora es comprobar si el pin est a nivel alto o a nivel bajo. Para ello, podemos usar una de estas dos instrucciones: BTFSC y BTFSS. La instruccin BTFSC significa "Haz una comprobacin de bit en el registro y bit que especificamos. Si es un 0, entonces sltate la siguiente instruccin". La instruccin BTFSS significa "Haz una comprobacin de bit en el registro y bit que especificamos. Si es un 1, entonces sltate la siguiente instruccin". La que usemos depender de como queramos que nuestro programa reaccione cuando lea la entrada. Por ejemplo, si simplemente estamos esperando que la entrada sea 1, entonces podramos utilizar la instruccin BTFSS de este modo:;Aqu el cdigo : BTFSS PortA,0 Goto ;Continua por aqu : :

Inicio

El programa solo se mover hacia 'Continua por aqu' si el bit 0 del puerto A se pone a 1. Vamos ahora a escribir un programa con el que el LED parpadear a una velocidad, pero si un conmutador[Nota de la traduccin: en ingles el trmino original es "switch"] se cierra, parpadear a la mitad de velocidad. Seguramente puedas hacer el programa por ti mismo, pero hemos incluido el listado de todos modos. Podras probar a escribir el programa completo, solo para ver si has comprendido los conceptos. Estamos usando el mismo circuito que antes, con un conmutador aadido al pin RA0 del PIC y a la linea de alimentacin positiva.;***** Establecimiento constantes **** STATUS equ 03h ; Direccin del registro STATUS TRISA equ 85h ; Direccin del registro tri-estado para el Puerto A. PORTA equ 05h ; Direccin del Puerto A. CONTADOR1 equ 08h ; Primer contador para nuestros bucles de retardo. CONTADOR2 equ 09h ; Segundo contador para nuestros bucles de retardo. ; ;**** Configuracin del Puerto **** bsf STATUS,5 ; Cambiamos al Banco 1 movlw 01h ; Ponemos los pines del puerto A ... movwf TRISA ; ...el bit 1 como salida, el bit 0 como entrada. bcf STATUS,5 ; Volvemos al Banco 0. ; ;**** Encendemos del LED **** Inicio movlw 02h ; Encendemos el LED poniendo primero el valor... movwf PORTA ; ... en el registro w y despus al puerto ; ;**** Comprobamos si el conmutador est cerrado **** btfsc PORTA,0 ; Tomamos el valor del bit 0 del puerto A y comprobamos si es 0. ; Si es 0, sltate la siguiente instruccin y continua normalmente. call Retardo ; Si es 1, ejecuta esta instruccin aadiendo un retardo extra.

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 23 of 66

; ;**** Aade un retardo call Retardo ; ;**** Retardo terminado, ahora apagamos el LED **** movlw 00h ; Apaga el LED poniendo primero el valor ... movwf PORTA ; ... en el registro w y despus al puerto ; ;**** Comprobamos si el conmutador est todava cerrado **** btfsc PORTA,0 ; Tomamos el valor del bit 0 del puerto A y comprobamos si es 0. ; Si es 0, saltate la siguiente instruccin y continua normalmente. call Retardo ; Si es 1, ejecuta esta instruccin aadiendo un retardo extra. ; ;**** Aadimos otro retardo **** call Retardo ; ;**** Ahora volvemos al inicio del programa goto Inicio ; Vuelve al principio y enciende el LED... ; ...de nuevo. ; ;**** Aqu est nuestra Subrutina Retardo Bucle1 decfsz CONTADOR1,1 ; Este segundo bucle mantiene el LED... goto Bucle1 ; ...apagado el tiempo suficiente... decfsz CONTADOR2,1 ; ...para que lo veamos goto Bucle1 ; return ; ;**** Fin del Programa**** end ; Algunos compiladores necesitan esta instruccin, ; y tambin por si acaso olvidamos poner... ; ... la instruccin 'goto'.

Lo que hemos hecho aqu es encender el LED. Despus comprobar si el conmutador est cerrado. Si est cerrado, entonces hacemos una llamada a nuestra subrutina de retardo. Esto nos da el mismo retardo que anteriormente, pero ahora la estamos llamando dos veces. Lo mismo pasa cuando el LED est apagado. Si el conmutador no est cerrado, entonces tenemos nuestros tiempos de encendido y apagado como antes. Puedes compilar y ejecutar este programa. Sin embargo, una nota de advertencia: El circuito final y el cdigo puede resultar irrelevante para alguien que no le interese programar microcontroladores. Por tanto, no te enfades si cuando ensees el circuito a tu familia y amigos sobre como puedes cambiar la velocidad de parpadeo de un LED, ves que no muestran ni el mas mnimo inters Hablamos desde nuestra experiencia personal! Si has ido siguiendo estos captulos desde el comienzo, puede que te interese saber que ahora llevas aprendidas 10 de 35 instrucciones para el PIC 16F84 ! Y todas ellas las has aprendido simplemente con el encendiendo y apagando de un LED. Hasta ahora hemos hecho que el PIC haga parpadear un LED. Despus fuimos capaces de interactuar con nuestro PIC aadiendo un conmutador, para modificar el ritmo de parpadeo. El nico problema es que el programa es muy largo y desperdicia mucha memoria. Era aceptable ya que introducamos comandos por primera vez, pero debe existir una manera mejor de hacerlo. Bueno, la hay (sabias que la haba, verdad? ).

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 24 of 66

Vamos a examinar como estbamos haciendo el parpadeo del LED realmente.movlw movwf movlw movlw 02h PORTA 00h PORTA

Primero cargamos nuestro registro w con 02h, despus lo pusimos en nuestro registro del puerto A para encender el LED. Para apagarlo, cargamos w con 00h y despus lo pusimos en nuestro registro del puerto A. Entremedias de estas rutinas tenamos que llamar a una subrutina para que pudiramos ver el LED parpadear. As que hemos tenido que mover dos conjuntos de datos dos veces (una vez al registro w y despus al PORTA) y llamar a la subrutina dos veces (una vez para el encendido y otra para el apagado). As que, cmo podemos hacer esto de una manera mas eficiente ? Sencillo. Utilizamos otra instruccin llamada XORWF. La instruccin XORWF ejecuta una funcin OR Exclusiva entre el registro w y el registro que le pasamos como dato. Ser mejor que expliquemos que narices es una OR Exclusiva antes de continuar. [Nota de la traduccin: Tambin llamada funcin XOR simplemente] Si tenemos dos entradas, y una salida, la salida solo ser 1 si, y solo si, las dos entradas son diferentes. Si son iguales, la salida ser 0. Aqu est la tabla de verdad, para aquellos que prefieran verlo en una tabla: A B Salida 0 0 0 0 1 1 1 0 1 1 1 0 Vamos a ver que ocurre si hacemos que B tome el valor de salida anterior, y simplemente cambiamos el valor de A: A B Salida 0 0 0 1 0 1

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 25 of 66

1 1 0 1 0 1 Si mantenemos el valor de A igual a 1, y hacemos OR exclusiva entre l y el valor de la salida anterior, la salida resultante conmuta. Para los que no lo vean de este modo en la tabla de verdad, aqu est utilizando binario: Valor de salida actual => 0 OR-Ex con l y con 1 => 1 ; 1 es el nuevo valor de salida. OR-EX con l y con 1 => 0 ;0eselnuevovalordesalida. OR-Ex con l y con 1 => 1 ; 1 es el nuevo valor de salida. .... as sucesivamente. Espero que puedas entender que haciendo OR exclusiva de una salida con un 1, lo que estamos haciendo ahora es conmutar de 0 a 1 a 0, etc... As que ahora, para encender y apagar nuestro LED, necesitamos solo dos lineas:MOVLW XORWF 02h PORTA,1

Lo que estamos haciendo aqu es cargar nuestro registro w con 02h. Despus le hacemos una OR exclusiva a este nmero que hay en w con lo que quiera que est en nuestro registro del puerto A. Si el bit 1 es 1, cambiar a 0. Si el bit 1 es 0, cambiar a 1. [Nota de la traduccin: El nmero que va despus del registro especificado en la instruccin XORWF, indica donde debe de ser almacenado el resultado de dicha operacin OR exclusiva. Si, como ocurre en este ejemplo anterior, ponemos un 1, el resultado se almacenar de vuelta en el registro de memoria especificado. Si pusisemos 0, el resultado de la operacin OR exclusiva se almacenara en el registro w] Vamos a ejecutar este cdigo un par de veces, para mostrar como funciona en binario: PORTA 00010 xorwf 00000 xorwf 00010 xorwf 00000 xorwf 00010

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 26 of 66

Incluso no necesitamos cargar el mismo valor en nuestro registro w cada vez, lo podemos hacer una sola vez al principio, y simplemente saltar hacia atrs a nuestro comando de conmutacin. Adems, no tenemos que establecer una valor al registro de nuestro puerto A. Por qu?Bien,siduranteelencendidoesun1,loharemosconmutar.Siporel contrario es un 0 durante el arranque, tambin lo conmutaremos. As que, vamos a ver nuestro nuevo cdigo. El primero es nuestro cdigo original de parpadeo del LED, y el segundo es donde hemos aadido el conmutador externo: LED Parpadeante:;***** Establecerlas constantes **** STATUS equ 03h ; Direccin del registro STATUS TRISA equ 85h ; Direccin del registro tri-estado del puerto A. PORTA equ 05h ; Direccion del puerto A CONTADOR1 equ 08h ; Primer contador para nuestros bucles de retardo. CONTADOR2 equ 09h ; Segundo contador para nuestros bucles de retardo. ;**** Configurar el puerto**** bsf STATUS,5 ; Cambia al Banco 1 movlw 00h ; Configura las pines del puerto A ... movwf TRISA ; ...como salidas. bcf STATUS,5 ; Vuelve al Banco 0 movlw 02h ; Configura nuestro registro w con 02h ;**** Enciende y apaga el LED **** Inicio xorwf PORTA,1 ; Conmuta el LED ;**** Aade un retardo call Retardo ; El retardo mnimo necesario ;**** Ahora vuelve al inicio del programa goto Inicio ; Vuelve al inicio para conmutar el LED de nuevo. ; ;**** Aqu est nuestra subrutina Retardo Bucle1 decfsz CONTADOR1,1 ; Este bucle mantiene el LED apagado o encendido... goto Bucle1 ; ... el tiempo suficiente ... decfsz CONTADOR2,1 ; ... para que lo podamos ver. goto Bucle1 ; return ;**** Final del programa **** end ; Algunos compiladores necesitan esta instruccin, ; y tambin por si acaso olvidamos poner... ; ... la instruccin 'goto'.

LED parpadeante con el conmutador externo:;***** Establecerlas constantes **** STATUS equ 03h ; Direccin del registro STATUS TRISA equ 85h ; Direccin del registro tri-estado del puerto A. PORTA equ 05h ; Direccion del puerto A CONTADOR1 equ 08h ; Primer contador para nuestros bucles de retardo. CONTADOR2 equ 09h ; Segundo contador para nuestros bucles de retardo. ; ;**** Configurar el puerto**** bsf STATUS,5 ; Cambia al Banco 1 movlw 00h ; Configura las pines del puerto A ... movwf TRISA ; ...como salidas. bcf STATUS,5 ; Vuelve al Banco 0 movlw 02h ; Configura nuestro registro w con 02h ; ;**** Enciende y apaga el LED **** Inicio xorwf PORTA,1 ; Conmuta el LED ; ;**** Comprobamos si el conmutador est cerrado ****

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 27 of 66

btfsc

PORTA,0

call Retardo ; ;**** Aade un retardo call Retardo ; El retardo mnimo necesario ; ;**** Ahora vuelve al inicio del programa goto Inicio ; Vuelve al inicio para conmutar el LED de nuevo. ; ;**** Aqu est nuestra subrutina Retardo Bucle1 decfsz CONTADOR1,1 ; Este bucle mantiene el LED apagado o encendido... goto Bucle1 ; ... el tiempo suficiente ... decfsz CONTADOR2,1 ; ... para que lo podamos ver. goto Bucle1 ; return ; ;**** Final del programa **** end ; Algunos compiladores necesitan esta instruccin, ; y tambin por si acaso olvidamos poner... ; ... la instruccin 'goto'.

; Tomamos el valor del bit 0 del puerto A y comprobamos si es 0. ; Si es 0, sltate la siguiente instruccin y continua normalmente. ; Si es 1, ejecuta esta instruccin aadiendo un retardo extra.

Esperamos que hayas podido comprender cmo con el uso de una simple instruccin, hemos reducido el tamao de nuestro programa. De hecho, simplemente para mostrar en cuanto se han reducido nuestros programas, hemos mostrado los dos programas, los cambios que hicimos, y sus tamaos en la siguiente tabla:

Programa LED parpadeante LED Parpadeante LED Parpadeante

Cambio Original Aadiendo subrutina

Tamao (en bytes) 120 103

Utilizando funcin XOR 91 132

LED con conmutador Original

LED con conmutador Utilizando funcin XOR 99 [Nota de la traduccin: Estos tamaos en bytes a los que se refiere el autor, son los tamaos de los ficheros .HEX que resultan de compilar estos listados con el compilador de Microhip MPASM.] As que no solo hemos aprendido nuevas instrucciones, tambin hemos reducido el tamao de nuestro cdigo!

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 28 of 66

Operadores Lgicos y AritmticosOperadores Lgicos

En el ltimo captulo presentamos la funcin OR exclusiva. La funcin ExOR (o XOR) es conocida como un operador lgico. En este captulo vamos a explicar otros operadores lgicos que soporta el PIC. No habr ningn programa de ejemplo, pero explicaremos como usar los operadores utilizando pequeas secciones de cdigo.

AND La funcin AND simplemente compara dos bits y produce un 1 si son iguales, y 0 si son diferentes. Por ejemplo, si decimos 1 AND 1, el resultado es 1, mientras que si decimos 1 AND 0 el resultado ser 0. Por supuesto, podemos comparar palabras (o bytes) tambin, y la funcin AND hace esta comparacin de ambas bit a bit. El ejemplo de ms abajo muestra dos palabras de 8 bits a las que se aplica AND con el siguiente resultado: 11001011 AND 10110011 Igual a 10000011 Como puedes ver, el resultado solo tiene un 1 cuando dos 1s coinciden en ambas palabras. Podemos utilizar la funcin AND para hacer comprobaciones de puertos, por ejemplo. Si estamos monitorizando pines E/S que estn conectados a un circuito, y tenemos que monitorizar una condicin en concreto donde solo algunos pines estn a nivel alto, entonces simplemente podemos leer el puerto, y aplicar a ese valor la funcin AND con la condicin que estamos buscando, simplemente como en el ejemplo anterior. [Nota de la Traduccin: Incluimos aqu la tabla de verdad de esta funcin que no estaba en el texto original por homogeneizar:] A B Resultado de AND 0 0 1 0 1 0 1 0 0

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 29 of 66

1 1 1 El PIC nos da dos modalidades para AND. Estas son ANDLW y ANDWF.

ANDLW nos permite hace una funcin AND con los contenidos del registro W, y un nmero que nosotros especifiquemos. Las sintaxis es: ANDLW ; donde es con el que haremos AND a los contenidos de W. El resultado de la funcin AND sern almacenamos de vuelta en el registro W. [Nota de la traduccin: El valor de tiene que estar comprendido entre 0 y 255]]

ANDWF nos permite hacer una funcin AND con los contenidos del registro W y otro registro, como por ejemplo un puerto. Las sintaxis es: ANDWF ,d ; donde es el registro en el que estamos interesados, por ejemplo PORTA, y d dice al PIC donde almacenar el resultado. Si d=0, el resultado se almacena en el registro W, y si d=1 el resultado se almacena en ese registro especificado.

Las dos secciones de cdigo de ms abajo muestran un ejemplo de cada instruccin AND. La primera comprueba el estado del PORTA, donde necesitamos ver si las entradas son 1100. Pondremos el resultado de vuelta en el registro W:movlw ANDWF 1100 05h,0

El segundo ejemplo comprobar ahora los contenidos del registro W:ANDLW 1100

OR Ya hemos visto una funcin OR, llamada XOR. Esta produce un 1 si dos bits son diferentes, pero no si son iguales. Hay una segunda funcin OR llamada IOR, la cual es OR inclusiva. La funcin produce un 1 si cualquiera de los dos bits es 1, pero tambin si ambos bits son 1. Aqu est la tabla de verdad para demostrar esto:

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 30 of 66

A B Resultado de OR 0 0 0 0 1 1 1 0 1 1 1 1

Operadores Aritmticos

ADD Esta funcin exactamente lo que dice [Nota de la traduccin: "Add" en ingles significa sumar] Suma dos nmeros! Si el resultado de sumar dos nmeros excede de 8 bits [Nota de la traduccin: 8 bits pueden contener un valor mximo de 255 en decimal], entonces se activar un flag llamado CARRY [Nota de la traduccin: "flag" en castellano se podra traducir por bandern, y normalmente se trata de 1 bit que se ubica en un registro en concreto de la memoria del PIC. "CARRY" en castellano puede traducirse como "llevar", podra ser como cuando hacemos una cuenta a mano y utilizamos la expresin "me llevo una".]. El flag de CARRY est localizado en el bit 0 de la direccin de memoria 03h. Si este bit se activa, quiere decir que la suma de esos 2 nmeros excedi de 8 bits. Si es 0, entonces el resultado queda dentro de los 8 bits. De nuevo, el PIC nos da dos modalidades de ADD, que son ADDLW y ADDWF. Como puedes suponer, es muy similar a la funcin anterior.

ADDLW aade los contenidos del registro W con un nmero que le especifiquemos. La sintaxis es: ADDLW

ADDWF aadir los contenidos del registro W y cualquier otro registro que le especifiquemos. La sintaxis es:

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 31 of 66

ADDWF ,d ; donde es el registro que queremos especificar, y d le dice al PIC donde almacenar el resultado. Si d=0, el resultado se almacena en el registro W, y si d=1 el resultado se almacena en ese registro especificado.

SUB Ahora, apuesto a que sabes que hace esta funcin! S, lo que suponas, esta funcin sustrae(o resta) un bit a otro ['Nota de la traduccin: SUB, viene del ingles "substract" que significa "sustraer" en castellano]]. Una vez ms el PIC da dos modalidades: SUBLW y SUBWF. La sintaxis es exactamente la misma que para la funcin ADD, excepto por supuesto que tienes que escribir SUB en lugar de ADD!

Incremento Si queremos aadir 1 a un nmero en el PIC, podramos simplemente utilizar la funcin ADD, y usar el nmero 1. El problema con esto es que primero tenemos que poner el nmero 1 en el registro w, y despus utilizar el comando "ADDLW 1" para incrementarlo. Si queremos aadir 1 a cualquier otro registro, la cosa se pone peor. Primero tenemos que poner el nmero 1 en el registro W, y despus utilizar "ADDWF ,1". As que por ejemplo, para aadir 1 a la posicin 0Ch, tendramos que tener la siguiente seccin de cdigo:movlw addwf 01 0Ch,1

Hay una manera mejor de hacer esto. Podemos utilizar la instruccin INCF. La sintaxis es: INCF ,d ; donde es un registro, o posicin de memoria en la que estemos interesados, y d le dice al PIC donde almacenar el resultado. Si d=0, el resultado se almacena en el registro W, y si d=1 el resultado se almacena en ese registro especificado. Mediante el uso de esta simple instruccin podemos literalmente hacer la mitad de cdigo. Si queremos que el resultado vaya de vuelta al registro W, usando el ejemplo anterior, hubisemos tenido que aadir otro comando para mover el contenido de la posicin 0Ch de vuelta al registro W, y despus poner en el registro 0Ch lo que quiera que tuviese al principio.

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 32 of 66

Existe otro comando de incremento. Es el INCFSZ. Este comando incrementar el registro que nosotros le especifiquemos, pero si el registro es igual a 0 despus del incremento (esto ocurrir cuando aadamos 1 a 255) entonces el PIC se saltar la siguiente instruccin. La seccin de cdigo de ms abajo lo demuestra:Bucle incfsz 0Ch goto Bucle : : ;Resto del programa.

En la seccin de cdigo anterior, el registro de la posicin de memoria OCh ser incrementado en 1. Despus tenemos una instruccin que le dice al PIC que vaya de vuelta a nuestra etiqueta llamada "Bucle", e incremente OC en 1 de nuevo. Esto ocurrir constantemente hasta que 0Ch sea igual a 255. En este momento, cuando incrementemos OCh en 1, 0Ch ser igual a 0. Nuestra instruccin le dir al PIC que se salte la siguiente instruccin, la cual es en este caso "goto", y por tanto que el PIC contine con el resto del programa.

Decremento [Nota de la traduccin: La palabra "decremento" no existe en castellano. Surge de traducir un poco a la ligera la palabra inglesa "decrement". As que nos permitimos una pequea licencia, por comodidad y claridad.] Ya hemos cubierto la funcin de decremento (o disminucin en 1) en el capitulo Bucles de Retardo, as que no me voy a repetir aqu.

Complemento La ltima instruccin de este grupo invierte todos los bits de un registro que le especifiquemos. La sintaxis es: COMF ,d ; donde es el registro que deseamos invertir, y d le dice al PIC donde almacenar el resultado. Si d=0, el resultado se almacena en el registro W, y si d=1 el resultado se almacena en ese registro especificado. El siguiente ejemplo muestra la instruccin en accin:

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 33 of 66

0Ch = 11001100 COMF 0Ch,1 0Ch = 00110011 Esto se puede usar, por ejemplo, para cambiar rpidamente todos los bits de un puerto de salida a entra y viceversa.

Operaciones con BitsLas operaciones con bits nos permite manipular un solo bit dentro de una palabra (word). Nos permiten, mover, activar o desactivar bits individualmente en registros o nmeros que especifiquemos. Al final de este captulo te mostraremos un programa que producir un conjunto de luces que se desplazan en un sentido, y despus en el sentido contrario. Vimos esto cuando revisamos la funcin OR, donde hacamos OR exclusiva con una palabra. Ya hemos visto un par de operaciones con un bits, cuando configurbamos los puertos del PIC, y voy a repetir aqu su uso.

BCF Esta instruccin pone a cero un bit que especifiquemos en el registro que especifiquemos. La sintaxis es la siguiente:

BCF ,

La hemos utilizado previamente para cambiar del Banco 1 al Banco 0 cuando ponamos a 0 el bit 5 del registro STATUS. Tambin podemos utilizarla para poner a 0 cualquier bit de cualquier otro registro/posicin de memoria. Por ejemplo, si queremos poner a 0 el tercer bit de 11001101 que est almacenado en la posicin de memoria 0Ch, introduciramos:BCF 0Ch,2

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 34 of 66

[Nota de la Traduccin: el valor que puede tomar el parmetro va de 0 a 7, donde 0 es el bit mas a la derecha de nuestro nmero binario. La siguiente tabla clarifica un poco ms la disposicin de los bits en un byte (o palabra de 8 bits) y sus posiciones: Posicin Nmero de bit Nuestro ejemplo ] 8 bit 7 bit 6 bit 5 bit 4 bit 3er bit 2 bit 1er bit 7 1 6 1 1 5 0 1 4 0 0 3 1 0 2 1 0 1 0 0 0 1 1

Despus de "BCF 0Ch,2" 1

BSF Esta instruccin pondr a 1 el bit que especifiquemos en cualquier registro que especifiquemos. Hemos utilizado esta operacin antes para cambiar del Banco 0 al Banco 1. La sintaxis es:

BSF , , y se utiliza exactamente de la misma forma que la BCF de ms arriba.

BTFSC Hasta ahora hemos puesto a 1 o a 0 un bit en un registro. Pero qu pasa si queremos simplemente comprobar si un bit es 0 1 en un registro? Bien, podemos utilizar BTFCS. Esta dice "Comprueba un bit en el registro o posicin de memoria (F), y salta si es 0". Esta instruccin comprobar el bit que le especifiquemos en el registro. Si el bit es 0, la instruccin le dice al PIC que se salte la instruccin que viene a continuacin. Podramos utilizar esta instruccin si queremos comprobar un flag, como por ejemplo en flag de CARRY. Esto nos ahorra tener que leer el registro STATUS y mirar los bits individualmente para ver que flags estn a 1. Por ejemplo, si queremos comprobar si el flag de CARRY ha sido puesto a 1 cuando hayamos sumado dos nmeros, haremos lo siguiente:

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 35 of 66

; BTFSC 03h,0 ; continua por aqu si CARRY est a 1. ; o por aqu si est a 0.

Si el valor del bit es 1, entonces BTFSC continuar por la instruccin inmediatamente siguiente. Si est a 0, entonces se salta esa instruccin. La siguiente seccin de cdigo muestra donde podra ser utilizada:Bucle : : : BTFSC 03,0 Goto Bucle

En el cdigo anterior, el PIC solo saldr de bucle si el bit 0 del registro STATUS (o el flag de CARRY) est puesto a 0. De otro modo, el comando 'goto' ser ejecutado.

BTFSS Esta instruccin dice "Comprueba el bit del registro o posicin de memoria(F), y salta si est a 1". Esta es similar a la instruccin BTFSC, excepto que el PIC se saltar la siguiente instruccin si el bit que estamos comprobando est a 1, en lugar de a 0.

CLRF Esta instruccin pondr todos los bits del contenido de un registro a 0. La sintaxis es:

CLRF

La hemos usado anteriormente para poner todos los pines de un puerto como salidas, haciendo "CLRF 85h". Tambin lo usamos para poner los pines de un puerto que estaban como salidas todos a 0, haciendo "CLRF 05h".

CLRW

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 36 of 66

Es similar a la instruccin CLRF, excepto en que solo pone a 0 el registro W. La sintaxis es bastante sencilla:

CLRW

RLF y RRF Estas instrucciones desplazan los bits del contenido de un registro un lugar hacia la izquierda (RLF), o un lugar hacia la derecha (RRF). Por ejemplo, si tenemos 00000001 y utilizamos la instruccin RLF, tendramos 00000010. Ahora, qu ocurre si tenemos 10000000 y empleamos RLF? Bien, el bit 1 ser desplazado al flag CARRY. y si empleamos RLF una vez ms, el 1 reaparecer justo al principio [Nota de la traduccin: es decir, por el lado derecho del byte, o dicho de otro modo en el bit0]. Lo mismo ocurre con la instruccin RRF pero de manera inversa. El ejemplo de ms abajo ilustra esto para la instruccin RLF, donde mostramos los 8 bits del contenido de un registro, y el flag de CARRY:

C 76543210 0 00000001 RLF 0 00000010 RLF 0 00000100 RLF 0 00001000 RLF 0 00010000 RLF 0 00100000 RLF 0 01000000 RLF 0 10000000 RLF 1 00000000 RLF 0 00000001

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 37 of 66

[Nota de la traduccin: La sintaxis para estas dos instrucciones es:

RLF ,d RRF ,d

Donde d le dice al PIC donde almacenar el resultado. Si d=0, el resultado se almacena en el registro W, y si d=1 el resultado se almacena en ese registro especificado.]

Programa de ejemplo

Ahora vamos a darte un ejemplo de cdigo que puedes compilar y ejecutar. Este har que una luz que se desplace, comenzando en el bit 0 del puerto B hasta el bit 8 del mismo, siguiendo al bit 0 del puerto A hasta el bit 5, y despus haciendo todo el camino inverso hasta al principio. Conecta LEDs a todos los pines de los puertos A y B. Aqu comprenders algunas de las operaciones de bit mencionadas en este captulo:TIEMPO PORTB TRISB PORTA TRISA STATUS CONTADOR1 CONTADOR2 equ equ equ equ equ equ equ equ bsf movlw movwf movlw movwf bcf movlw movwf 9Fh 06h 86h 05h 85h 03h 0Ch 0Dh STATUS,5 00h TRISB 00h TRISA STATUS,5 00h PORTA ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; Variable para Direccin del Direccin del Direccin del Direccin del Registro para Registro para Registro para el bucle de retardo. Port B. registro tri-estado del Port B. Port A. registro tri-estado del Port A. seleccionar el banco. el bucle. el bucle.

Va al Banco 1 y configura ambos puertos A y B como salidas, despus vuelve al Banco 0. Pon a 0 el Puerto A.

; ; Comienzo del programa ; CorreLuz movlw 01h ; Pon a 1 el primer bit movwf PORTB ; del Puerto B. PORTB = 00000001 call Retardo ; Espera un momento. call Retardo ; ; ; Desplaza el bit a la izquierda, y despus pausa. ; rlf PORTB,1 ; PORTB = 00000010, C = 0 ; call Retardo call Retardo ; rlf PORTB,1 ; PORTB = 00000100, C = 0 ; call Retardo call Retardo ;

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 38 of 66

rlf ; call call ; rlf ; call call ; rlf ; call call ; rlf ; call call ; rlf ; call call ; rlf

PORTB,1 Retardo Retardo PORTB,1 Retardo Retardo PORTB,1 Retardo Retardo PORTB,1 Retardo Retardo PORTB,1 Retardo Retardo PORTB,1

; PORTB = 00001000, C = 0

; PORTB = 00010000, C = 0

; PORTB = 00100000, C = 0

; PORTB = 01000000, C = 0

; PORTB = 10000000, C = 0

; Este desplaza el bit al ''flag'' CARRY. ; PORTB = 00000000, C = 1

; ; Ahora se mover al puerto A, desplazando el bit hacia la izquierda. ; rlf PORTA,1 ; Esto mueve el bit desde el ''flag'' CARRY al puerto A. ; PORTA = 00001, C = 0 ; call Retardo call Retardo ; rlf PORTA,1 ; PORTA = 00010, C = 0 ; call Retardo call Retardo ; rlf PORTA,1 ; PORTA = 00100, C = 0 ; call Retardo call Retardo ; rlf PORTA,1 ; PORTA = 01000, C = 0 ; call Retardo call Retardo ; rlf PORTA,1 ; PORTA = 10000, C = 0; ; call Retardo call Retardo ; ; Desplaza el bit de vuelta por el puerto A ; rrf PORTA,1 ; PORTA = 01000, C = 0; call Retardo call Retardo rrf PORTA,1 ; PORTA = 00100, C = 0; call Retardo call Retardo rrf PORTA,1 ; PORTA = 00010, C = 0; call Retardo call Retardo rrf PORTA,1 ; PORTA = 00001, C = 0; call Retardo call Retardo rrf PORTA,1 ; Esta desplaza el bit al ''flag'' CARRY ; PORTA = 00000, C = 1; ; ; Ahora desplaza el bit de vuela al Puerto B ;

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 39 of 66

rrf call call rrf call call rrf call call rrf call call rrf call call rrf call call rrf call call rrf call call goto ; ; La subrutina para ; Retardo movlw movwf Bucle1 decfsz goto movwf Bucle2 decfsz goto return ; end

PORTB,1 Retardo Retardo PORTB,1 Retardo Retardo PORTB,1 Retardo Retardo PORTB,1 Retardo Retardo PORTB,1 Retardo Retardo PORTB,1 Retardo Retardo PORTB,1 Retardo Retardo PORTB,1 Retardo Retardo CorreLuz

; PORTB = 10000000, C = 0

; PORTB = 01000000, C = 0

; PORTB = 00100000, C = 0

; PORTB = 00010000, C = 0

; PORTB = 00001000, C = 0

; PORTB = 00000100, C = 0

; PORTB = 00000010, C = 0

; PORTB = 00000001, C = 0 ; Ahora hemos vuelto a donde empezamos, ; ; Vamos a hacerlo de nuevo.

hacer el retardo entre los movimientos de bits.

TIEMPO CONTADOR1 CONTADOR1 Bucle1 CONTADOR1 CONTADOR1 Bucle2

; ; ; ; ; ; ; ; ; ; ;

Cogemos el tiempo de retardo, y lo ponemos en una variable. Decrementa el tiempo de retardo hasta que alcance cero. Cogemos el tiempo de retardo de nuevo, y repetimos la cuenta atrs.

Fin de la subrutina.

Tablas de DatosHay una propiedad interesante en el conjunto de instrucciones del PIC, que nos va a permitir realizar tablas de datos. Una tabla de datos es una lista simple de valores de datos, donde cada uno de ellos puede ser ledo(solo ledo) dependiendo de algn criterio. [Nota de la traduccin: El ejemplo dado en el texto original, se ha sustituido por este que mostramos a continuacin para hacer ms comprensible el concepto de tabla de datos. Al final del captulo se incluye un programa para realizar el ejemplo:

Por ejemplo, podras hacer un circuito con el PIC, que cuente de 0 a 9 y represente este nmero en un display de 7 segmentos. El display de 7 segmentos lo vamos a conectar al puerto B. De manera que cada pin encienda un LED del display (como tenemos 8 pines en el puerto B, uno de ellos no sera utilizado). Para ello, podemos utilizar el siguiente esquema de conexiones entre el PIC y el display:

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 40 of 66

Es decir, el pin RB7 no lo conectaramos al display. De este modo tendremos la siguiente tabla de correspondencias entre los nmeros a representar y el valor binario que debe de tomar el puerto B para que se enciendan los diodos LED correspondientes: Nmero Valor para puerto B Imagen en el display

1

b'01000001' = 41h

2

b'00111011' = 3Bh

3

b'01101011' = 6Bh

4

b'01001101' = 4Dh

5

b'01101110' = 6Eh

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 41 of 66

6

b'01111110' = 7Eh

7

b'01000011' = 43h

8

b'01111111' = 7Fh

9

b'01101111' = 6Fh

0

b'01110111' = 77h

Bien, pues esta tabla de correspondencias la queremos tener almacenada en el PIC, y mediante el uso de una tabla de datos, vamos a poder hacerlo. Y as podremos representar el nmero adecuado en cada momento.]

Ahora, antes de continuar con la explicacin de como funciona la tabla de datos, tenemos que explicar como hace el PIC seguimiento de por donde va el programa mientras se est ejecutando. Si alguna vez has programado en BASIC esto te ayudar a comprenderlo. Si no, no te preocupes, aun as sers capaz de comprender el concepto.

Imagina que tenemos un programa BASIC como el que se muestra AQU:10 11 12 LET K=0 K=K+1 IF K>10 THEN GOTO 20 ELSE GOTO 11

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 42 of 66

20 21

PRINT K END

El programa comienza en la linea 10. Una vez que K vale 0, continua con la linea 11. Despus de que le hemos aadido 1 a K nos desplazamos a la linea 12. Aqu estamos preguntando si K es mayor que 10. Si lo es, entonces vamos a la linea 20, y si no, volvemos a la 11. La linea 20 muestra el valor de K en pantalla, y la linea 21 finaliza el programa. BASIC utiliza los nmeros de linea para ayudar al programador a hacer seguimiento de donde est cada cosa, ya que las etiquetas no estn permitidas.

El PIC utiliza etiquetas para saltar de unas posiciones a otras, si?. Utilizamos las etiquetas para que sepamos donde estn las cosas, y tambin para que podamos decirle al PIC de una manera sencilla donde tiene que ir. Lo que realmente ocurre es que el PIC utiliza un contador de lnea interno llamado Contador de Programa [Nota de la traduccin: en ingles "Program Counter", abreviado tambin como PC. ]. El Contador de Programa mantiene almacenada la direccin de la posicin de memoria donde se encuentra la instruccin actual. Cuando le decimos al PIC que vaya a una etiqueta en particular, sabe la posicin de memoria y por tanto modifica el PC hasta que alcanza esa posicin y la lee. Esto es exactamente el mismo modo en el que leemos nosotros el programa BASIC anterior.

Aqu hay una seccin de cdigo, con las posiciones de memoria, o contenidos del PC, junto a cada instruccin:PC Instruccin ----------------------------0000 movlw 03h 0001 movwf 0Ch 0002 Bucle decfsc 0Ch 0003 goto Bucle 0004 end

En este ejemplo anterior hemos puesto el PC a 0000. En esta posicin tenemos la instruccin "movlw 03h". Cuando el PIC ha ejecutado esta instruccin, incrementar PC para que la siguiente instruccin pueda ser leda. Aqu el PIC ve "movwf 0Ch". El PC se incrementa de nuevo. Ahora el PIC lee "decfsc 0Ch". Si el contenido del registro 0Ch no es 0, entonces el PC se incrementa en 1, y la siguiente instruccin, "goto Bucle", le dice al PC que vaya de vuelta a la posicin 0002, en la cual hemos escrito la palabra "Bucle". Si el contenido del 0Ch es 0, entonces el PC ser incrementado en 2, en otras palabras se saltar la siguiente instruccin. Esto colocar el PC en la posicin 0004, donde el programa termina. Las posiciones son asignadas por el programa ensamblador (p.ej. MPASM), y

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 43 of 66

normalmente no nos tenemos que preocupar de lo que hace el Contador de Programa (PC). Hasta que necesitemos controlarlo, como vamos a hacer cuando usemos tablas de datos. La mejor manera de explicar como funciona una tabla de datos es comenzar con un pequeo ejemplo.PC ; equ movlw call : : : addwf retlw retlw retlw retlw retlw retlw retlw return 02h 03h tabla

tabla

PC 0Ah 0Bh 0Ch 0Dh 0Eh 0Fh 10h

;

La primera instruccin esta asignando a la etiqueta PC la direccin del Contador de Programa (02h). Despus colocamos el valor 03h en el registro w. A continuacin hacemos una llamada a "tabla". La primera linea en la subrutina "tabla" aade los contenidos del registro W (03h) al Contador de Programa. Esto causa que el contador de programa se incremente en 3, o dicho de otro modo, causa que el contador de programa se mueva 3 lineas hacia abajo. Cuando el contador llega 3 lineas ms abajo el PIC ve la instruccin retlw. Este comando pasa el valor que viene con la instruccin, al registro W, y retorna desde la subrutina.

RETLW realmente significa "RETurn, y pon el Literal en W". Date cuenta de que hemos puesto una coma despus de la palabra "return" en la frase anterior. Como si estuvisemos en una subrutina normal, necesitamos una instruccin de "return" para salir de ella. Eso lo hace el RET en la instruccin. Despus de la instruccin RETLW hay un nmero, y este es el que colocaremos en el registro W. En este caso el nmero 0Ch. [Nota de la traduccin: En resumidas cuentas, el valor que ponemos en el registro W antes de llamar a la subrutina "tabla", indica qu posicin queremos mirar de la tabla. Es decir, acta de ndice o indicador de la posicin que queremos ver. Al pasarle un 3 a W antes de "call tabla", le estamos diciendo que queremos recuperar el valor que existe en la posicin 3 de la tabla. La primera instruccin de la subrutina "tabla" dice "sumarle el contenido de W a PC", es decir, le sumar 3 a PC. Lo cual va a trasladar el PC hasta la instruccin "retlw 0Ch". Entonces, este valor, 0Ch, ser copiado en el registro W, y se efectuar un "RETurn", que hace que el programa contine por la instruccin siguiente a

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 44 of 66

"call tabla". Ahora, estamos de vuelta al flujo principal del programa con W cargado con el dato que queramos recuperar de nuestra tabla. De este modo, hemos creado una tabla de datos, que la podremos consultar cuando queramos para ver un valor de una posicin concreta. En el ejemplo del display de 7 segmentos se ve de modo prctico para qu se podra utilizar una tabla de datos.]

(Antes de llamar a la subrutina) podemos asignar cualquier nmero a W, siempre y cuando este nmero al ser aadido a PC haga que PC se desplace aun elemento de la tabla de la subrutina, all donde hemos puesto una instruccin retlw. En el ejemplo anterior esto significa que podemos poner un nmero de 1 a 7. Si nos pasamos de largo de la subrutina, podramos terminar ejecutando otra parte del programa. Por esta razn, siempre es buena idea poner la tabla de datos al final del programa, as si nos pasamos de largo podemos llegar al final del programa en cualquier caso.

[Nota de la traduccin: Continuando con el ejemplo del display de 7 segmentos, ponemos aqu la tabla de datos que tendremos que crear. La hemos sacado de la tabla del principio de este captulo: Poscin Valor 1 2 3 4 5 6 7 8 9 10 Nmero para el display

b'01000001' = 41h 1 b'00111011' = 3Bh 2 b'01101011' = 6Bh 3 b'01001101' = 4Dh 4 b'01101110' = 6Eh 5 b'01111110' = 7Eh 6 b'01000011' = 43h 7 b'01111111' = 7Fh 8 b'01101111' = 6Fh 9 b'01110111' = 77h 0

Hemos puesto el 0 en la ltima posicin, para que el resto de los nmeros que hay que representar en el display, coincidan con la posicin que ocupan en la tabla. De este modo, la tabla se podra crear utilizando el siguiente cdigo:PC equ : : 02h

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 45 of 66

tabla

addwf retlw retlw retlw retlw retlw retlw retlw retlw retlw retlw return

PC 41h 3Bh 6Bh 4Dh 6Eh 7Eh 43h 7Fh 6Fh 77h

Hemos reutilizado parte del cdigo que hemos empleado anteriormente para crear este nuevo. As que habr partes que te sern familiares. Este es el cdigo completo para hacer que el PIC muestre en el display una cuenta ascendente de 0 a 9 y vuelta a empezar:PC equ 02h TIEMPO equ 9Fh PORTB equ 06h TRISB equ 86h STATUS equ 03h CONTADOR1 equ 0Ch CONTADOR2 equ 0Dh ; ; Configuramos el Puerto B ; bsf STATUS,5 movlw 00h movwf TRISB bcf STATUS,5 movlw 00h movwf PORTB ; ; Comienzo del programa ; Inicio movlw 0Ah call tabla movwf PORTB ; call Retardo call Retardo ; movlw 01h call tabla movwf PORTB ; call Retardo call Retardo ; movlw 02h call tabla movwf PORTB ; call Retardo call Retardo ; movlw 03h call tabla movwf PORTB ; call Retardo call Retardo ; movlw 04h call tabla ; ; ; ; ; ; ; Direccin del Variable para Direccin del Direccin del Registro para Registro para Registro para Contador de Programa(PC) el bucle de retardo. Port B. registro tri-estado del Port B. seleccionar el banco. el bucle. el bucle.

; ; ; ; ; ;

Va al Banco 1 y configura los pines del Puerto B todos como salidas. Vuelta al Banco 0. Pon a 0 el Puerto B. Es decir, el display totalmente apagado.

; Carga en W el valor 10 antes de llamar a la tabla ; para recuperar la configuracin de encendido del 0. ; Ahora W = 77h, lo pone en puerto B, para representar 0 en el display. ; Espera un momento. ; Para que se pueda ver el 0 ; Carga en W el valor 1 antes de llamar a la tabla ; para recuperar la configuracin de encendido del 1. ; De W lo pone en puerto B, para representar 1 en el display. ; ; ; Carga en W el valor 2 antes de llamar a la tabla ; para recuperar la configuracin de encendido del 2. ; De W lo pone en puerto B, para representar 2 en el display. ; ; ; Carga en W el valor 3 antes de llamar a la tabla ; para recuperar la configuracin de encendido del 3. ; De W lo pone en puerto B, para representar 3 en el display. ; ; ; Carga en W el valor 4 antes de llamar a la tabla ; para recuperar la configuracin de encendido del 4.

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.webdearde.com/index.php?title=Tutorial:_Programaci%C3%B3...

13/05/2012

Tutorial: Programacin de PICs en Ensamblador - Asociacin de Roboti... Page 46 of 66

movwf ; call call ; movlw call movwf ; call call ; movlw call movwf ; call call ; movlw call movwf ; call call ; movlw call movwf ; call call ; movlw call movwf ; call call ;

PORTB Retardo Retardo 05h tabla PORTB Retardo Retardo 06h tabla PORTB Retardo Retardo 07h tabla PORTB Retardo Retardo 08h tabla PORTB Retardo Retardo 09h tabla PORTB Retardo Retardo

; De W lo pone en puerto B, para representar 4 en el display. ; ; ; Carga en W el valor 5 antes de llamar a la tabla ; para recuperar la configuracin de encendido del 5. ; De W lo pone en puerto B, para representar 5 en el display. ; ; ; Carga en W el valor 6 antes de llamar a la tabla ; para recuperar la configuracin de encendido del 6. ; De W lo pone en puerto B, para representar 6 en el display. ; ; ; Carga en W el valor 7 antes de llamar a la tabla ; para recuperar la configuracin de encendido del 7. ; De W lo pone en puerto B, para representar 7 en el display. ; ; ; Carga en W el valor 8 antes de llamar a la tabla ; para recuperar la configuracin de encendido del 8. ; De W lo pone en puerto B, para representar 8 en el display. ; ; ; Carga en W el valor 9 antes de llamar a la tabla ; para recuperar la configuracin de encendido del 9. ; De W lo pone en puerto B, para representar 9 en el display. ; ;

goto Inicio ; Vamos a hacerlo de nuevo. ; ; La subrutina para hacer el retardo entre los nmeros. ; Retardo movlw TIEMPO ; Cogemos el tiempo de retardo, movwf CONTADOR1 ; y lo ponemos en una variable. Bucle1 ; decfsz CONTADOR1 ; Decrementa el tiempo de retardo hasta goto Bucle1 ; que alcance cero. movwf CONTADOR2 ; Cogemos el tiempo de retardo de nuevo, Bucle2 ; y repetimos la cuenta atrs. decfsz CONTADOR2 ; goto Bucle2 ; return ; Fin de la subrutina. ; ; Y aqu la tabla de configuraciones para representar los nmeros ; en el display de 7 segmentos, de acuerdo a nuestro esquema de conexiones. ; tabla addwf PC retlw 41h ; Carga 41h (representacin de 1) en W y retorna. retlw 3Bh ; Carga 3Bh (representacin de 2) en W y retorna. retlw 6Bh ; Carga 6Bh (representacin de 3) en W y retorna. retlw 4Dh ; Carga 4Dh (representacin de 4) en W y retorna. retlw 6Eh ; Carga 6Eh (representacin de 5) en W y retorna. retlw 7Eh ; Carga 7Eh (representacin de 6) en W y retorna. retlw 43h ; Carga 43h (representacin de 7) en W y retorna. retlw 7Fh ; Carga 7Fh (representacin de 8) en W y retorna. retlw 6Fh ; Carga 6Fh (representacin de 9) en W y retorna. retlw 77h ; Carga 77h (representacin de 0) en W y retorna. return ; ; end ; Fin del programa.

Create PDF files without this message by purchasing novaPDF printer (http://www.novapdf.com) http://wiki.we