¡Descarga TUTORIAL PRACTICO PIC 16F84A y más Guías, Proyectos, Investigaciones en PDF de Electrónica Digital y Analógica solo en Docsity!
Introducción
Bienvenidos al inicio del Tutorial sobre PICs. Estas páginas te llevaran desde la estructura
básica del dispositivo, hasta los métodos y técnicas de programación. También habrá
sugerencias de como modificar el código 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.
Para empezar, echemos un vistazo al PIC.
Microcontrolador Microchip PIC 16F
Microchip fabrica una serie de microcontroladores llamados PIC. Puedes ver toda la gama
de sus microcontroladores aquí. Los hay disponibles de distintas capacidades, desde
algunos tipos básicos con poca memoria, hasta los que tienen convertidores Analógico 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á fácil.
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 más económica de programar los PICs, ya que no necesitas ningún
otro software extra que no sea de los gratuitos.
Los pines del 16F
Mas abajo verás el diagrama de patillas(pines en adelante) del PIC 16F84. Pasaré por cada
pin, explicando para que se utiliza cada uno.
RA0 a RA
RA es un puerto bidireccional. Eso quiere decir que puede ser configurado como entrada o
como salida. El número que hay después 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 RB
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 alimentación. VDD es la alimentación positiva, y VSS es el negativo
de la alimentación, o 0 Voltios. La tensión máxima de alimentación que puedes utilizar son
6 Voltios, y el mínimo son 2 Voltios.
OSC1/CLK IN y OSC2/CLKOUT
Estos pines son donde conectaremos el reloj externo, para que el microcontrolador
disponga de algún tipo de temporización.
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 alimentación
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 función de deseemos.
No lo utilizaremos mucho.
TOCK
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 PIC
Bien, espero que no te hayas asustado mucho. Ahora, querrás conocer como programar el
PIC, pero además de aprender las instrucciones de código de ensamble, ¿como programas
Una placa de entrenamiento sencilla
Bien, ahora ya tienes tu programador, y uno o dos PICs. Es muy simple conocer la teoría
para saber como programar el PIC, pero el verdadero aprendizaje viene cuando intentas
probar tu código 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 básica y económica.
Por supuesto, le puedes añadir 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 encenderán cuando los pines se pongan a nivel alto. También, puedes añadir switches a
los pines, para poder seleccionar que pines poner a nivel alto, y cuales a nivel bajo.
Básicamente, lo que estoy diciendo es que si comienzas con este circuito, puedes añadir lo
que creas necesario.
La linea de alimentación está puesta a 6 Voltios, que es el máximo voltaje para el PIC.
Puedes utilizar cualquier voltaje inferior, hasta un mínimo 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
alimentación. X1 es un cristal de 4 MHz. Puedes utilizar un circuito RC (resistencia y
condensador) ( Nota de edición: crear enlace aquí ), pero el precio del cristal es
insignificante, y es mas estable. C1 y C2 ayudan a reducir cualquier desviación en la
oscilación cristal, y a eliminar cualquier ruido no deseado antes de que la señal llegue al
PIC.
Buenas técnicas para programar
Antes de meternos en harina con la programación del PIC, creo que ahora es un buen
momento para explicar algunas técnicas para programar bien.
Si escribes un ; (punto y coma) en cualquier punto de tu programa, el compilador ignorará
cualquier cosa que haya detrás de él, hasta llegar al retorno de carro. Esto significa que
podemos añadir comentarios a nuestro programa que nos recuerden que estábamos
haciendo en ese punto. Esta es una buena práctica incluso para los programas más 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 límites.
Segundo, puedes asignar nombres a las constantes vía los registros (hablaremos de estos
más adelante). Hace lo que estás escribiendo mucho más sencillo de leer, para saber de que
valor se trata, mas que intentar entender que significan todos esos números. Así que utiliza
nombres reales como CONTADOR. Date cuenta de que hemos puesto el nombre en letras
mayúsculas. Esto lo hace destacar, y también significa (por convención) que se trata de una
constante.
Tercero, añade algún tipo de cabecera en tus programas utilizando los punto y coma. Un
ejemplo sería algo así:
; Autor: ; ; Fecha: ; ; Versión: ; ; Titulo: ; ; ; ; Descripción: ; ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Date cuenta de que hemos hecho una especie de caja utilizando puntos y comas. Esto es
simplemente para hacerlo más pulcro.
La primera cosa que notarás 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. Después volvemos al Banco 0 y enviamos
un 1 lógico a ese pin.
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
serán entradas y los que serán salidas del Puerto A, TRISB nos permite establecer los pines
que serán entradas y los que serán salidas del puerto B.
Vamos a ver con más 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 dirección 03h (la 'h'
significa que el número es hexadecimal).
TRISA y TRISB
Están 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 cuestión 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 estás familiarizado con
el paso de binario a hexadecimal y viceversa, utiliza una calculadora científica.
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 cuestión. Si deseamos poner uno de los pines
como salida, ponemos un 0 en ese bit. Los bits están 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 RA
Numero de bit 4 3 2 1 0
Valor Binario 0 0 1 1 0
Lo mismo se aplica para TRISB.
PORTA y PORTB
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).
Nuestro registro TRISA ahora tiene el valor 00110 o mostrado gráficamente :
Pin del Puerto A RA4 RA3 RA2 RA1 RA
Valor Binario 0 0 1 1 0
Entrada/Salida S S E E 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 instrucción hace lo contrario a BSF. Significa en ingles "Bit Clear F" (en castellano,
poner a 0 un bit de la memoria). Los dos números que le siguen son la dirección del
registro, en este caso del registro STATUS, y el número 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 código en un solo bloque:
BSF 03h, 5 ; Ve al banco 1 MOVLW 06h ; Pon 00110 en W MOVWF 85h ; Mueve 00110 a TRISA BCF 03h, 5 ; Vuelve al Banco 0
Léelo hasta que las entiendas. De momento ya hemos visto 4 instrucciones. ¡Solo nos
quedan 31 para terminar!
Cómo escribir en los puertos
En 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 03h, 5 ;Ir al Banco 1 movlw 00h ;Poner 00000 en W movwf 85h ;Mover 00000 al TRISA – todos los pines como salidas. bcf 03h, 5 ;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 02h ; 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. movwf 05h ; Ahora mueve los contenidos de W (02h) al puerto A, cuya dirección es 05h.
Por tanto, ahora tu LED está encendido, y ahora queremos apagarlo:
movlw 00h ; Escribe 00h en el registro W. Esto pone a 0 todos los pines. movwf 05h ; Ahora mueve todos los contenidos de W (0h) al puerto A, cuya dirección 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 diciéndole al programa que vaya
a ese punto constantemente.
Definimos una etiqueta muy simple. Escribimos un nombre, digamos INICIO, entonces el
código queda:
Inicio movlw 02h ; 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. movwf 05h ; Ahora mueve los contenidos de W (02h) al puerto A, cuya dirección es 05h. movlw 00h ; Escribe 00h en el registro W. Esto pone a 0 todos los pines. movwf 05h ; Ahora mueve todos los contenidos de W (0h) al puerto A, cuya dirección es 05h. goto Inicio ; ve donde esté Inicio.
Como puedes ver, primer decimos la palabra 'Inicio' justo al comienzo del programa.
Después, justo al final del programa decimos simplemente 'goto Inicio', ves a Inicio. La
instrucción '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 alimentación al circuito, y se detendrá cuando le quitemos la alimentación.
Creo que deberíamos echar un vistazo de nuevo a nuestro programa:
Seguro que ahora puedes ver que las constantes hacen el programa un poco más sencillo,
aunque todavía no hemos puesto los comentarios. Sin embargo, no hemos terminado
todavía.
Bucles de Retardo
Existe un ligero inconveniente en nuestro programa del LED parpadeante. Cada instrucción
necesita un ciclo de reloj para ser completada. Si utilizamos un cristal de 4 Mhz, cada
instrucción 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 rápido 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 atrás desde un número previamente
establecido y cuando llegue a cero, paramos de contar. El valor cero indica el fin del retardo
y continuamos nuestro camino a través 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 tamaño del
número desde el que contar. Bien, el número mayor que podemos tener es 255 o FFh en
hexadecimal. Ahora, como hemos mencionado en el apartado anterior, la instrucción equ
asigna una palabra a una localización de un registro. Esto significa que cualquiera que sea
el número que asignemos a CONTADOR, será igual al contenido de un registro.
Si lo probamos y asignamos el valor FFh, el compilador entenderá que estamos asignando
la dirección de memoria FFh a la constante, y obtendremos un error cuando vayamos a
compilar el programa. Esto es debido a que la localización FFh está reservada, y por tanto
no podemos acceder a ella. Así que, ¿ como hacemos para asignar un número real? Bien,
se requiere hacer un poco de "pensamiento lateral". Si asignamos a nuestro CONTADOR,
por ejemplo, a la dirección 08h, este apuntará a un registro de propósito 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, ¿ cómo ponemos un valor distinto en CONTADOR? Bien, todo lo que
tenemos que hacer es primero 'mover' un valor a esta posición. Por ejemplo, si queremos
que CONTADOR tenga un valor de 85h, no podemos decir 'CONTADOR equ 85h' porque
esta es la localización del registro tri-estado del puerto A (TRISA). Lo que hacemos es esto:
movlw 85h ; Primero, ponemos el valor 85h en el registro W. movwf 08h ; 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 continuación necesitamos disminuir este CONTADOR en 1 hasta que alcance cero. Da la
casualidad de que hay una sola instrucción que hace esto por nosotros, con la ayuda de un
'goto' y una etiqueta. La instrucción que usaremos es:
decfsz CONTADOR, 1
Esta instrucción dice "resta 1 al registro (en esta caso CONTADOR). Si llegamos a cero,
salta 2 lugares hacia delante"[ Nota de la traducción: El valor que le sigue a la coma, indica
donde debe almacenarse el resultado de la operación. Si es 1, como en el ejemplo anterior,
el resultado se almacena en el mismo registro indicado en la instrucción, y si es 0 el
resultado se almacena en el registro w. ]. Un montón de palabras para una sola instrucción.
Veamosla en acción antes, después la pondremos en nuestro programa.
CONTADOR equ 08h ETIQUETA decfsz CONTADOR, 1 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 instrucción decfsz. La
instrucción decfsz CONTADOR,1 disminuye el valor de CONTADOR en 1, y almacena el
resultado de vuelta en CONTADOR. También comprueba si CONTADOR tiene un valor
de 0. Si no lo tiene, hace que el programa salte a la siguiente linea. Aquí tenemos una
instrucción de 'goto' que nos envía de vuelta a nuestra instrucción decfsz. Si el valor de
CONTADOR es igual a cero, entonces la instrucción decfsz hace que el programa salte dos
lugares hacia adelante, y se sitúe 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 detrás 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 añadiendo los comentarios:
;*****Establecimiento constantes **** STATUS equ 03h ; Dirección del registro STATUS TRISA equ 85h ; Dirección del registro triestado para el Puerto A. PORTA equ 05h ; Dirección del Puerto A. CONTADOR1 equ 08h ; Primer contador para nuestros bucles de retardo. CONTADOR2 equ 09h ; Segundo contador para nuestros bucles de retardo. ;
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
rápido? Cual es el valor mínimo de CONTADOR para poder ver el LED parpadear? ¿ Por
qué no añades un tercer bucle o incluso más bucles de retardo después del primero para
hacer más lento el apagado mas lento? Necesitarás una constante para cada bucle de
retardo. Podrías 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 sección veremos como podemos usar una cosa llamada sub-rutina para
ayudar a mantener el programa simple y pequeño.
Subrutinas
Una subrutina es una sección de código o programa, que puede ser llamada como y cuando
la necesites. Las subrutinas se usan si vas a ejecutar la misma función función más de una
vez, por ejemplo para crear un retardo. Las ventajas de utilizar una subrutina son que hará
más sencillo modificar el valor una vez dentro de la subrutina antes que, digamos, hacerlo
diez veces a través de tu programa. Y también te ayudará a reducir el total de memoria que
ocupa tu programa dentro del PIC.
Miremos una subrutina:
RUTINA CONTADOR equ 255 ETIQUETA decfsz CONTADOR, 1 goto ETIQUETA return
Primero tenemos que dar un nombre a la subrutina, y en este caso hemos elegido RUTINA.
Después escribimos el código que queramos como hacemos normalmente. En este caso,
hemos elegido el código del retardo para el programa de parpadeo de nuestro LED.
Finalmente, terminamos la subrutina tecleando la instrucción RETURN.
Para arrancar la subrutina desde cualquier punto de nuestro programa, simplemente
escribimos la instrucción CALL seguida por el nombre de la subrutina.
Vamos a ver esto con algo más 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 instrucción RETURN, el programa salta de vuelta a nuestro
programa principal, justo a la instrucción que va inmediatamente después de nuestra
instrucción CALL xxx.
Puedes llamar a la misma subrutina tantas veces como quieras, esa es la razón por la que
utilizar subrutinas reduce el tamaño 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. Recomendaríamos 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 instrucción '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.
Vamos a verlo en nuestro programa de parpadeo de LED, pero esta vez utilizaremos una
subrutina para el bucle de retardo. Con suerte verás que sencillo se queda el programa, y
también veras como funciona la subrutina en la realidad:
;***** Establecimiento constantes **** STATUS equ 03h ; Dirección del registro STATUS TRISA equ 85h ; Dirección del registro tri- estado para el Puerto A. PORTA equ 05h ; Dirección del Puerto A. CONTADOR1 equ 08h ; Primer contador para nuestros bucles de retardo. CONTADOR2 equ 09h ; Segundo contador para nuestros bucles de retardo. ; ;**** Configuración del Puerto **** bsf STATUS, 5 ; Cambiamos al Banco 1 movlw 00h ; Ponemos los pines del puerto A ...
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 pequeño bit ayuda.
[ Nota de la traducción: Cuando el autor dice que el 16F84 tiene 1024 bytes, se esta
refiriendo al área de memoria para el almacenamiento del código 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 más de un byte). De
modo, que lo que sería correcto decir es, que el área de memoria de programa en el 16F
tiene un tamaño 1024 x 14 bit words, o 1K x 14 bit words, o 1024 posiciones de 14 bits
cada una. Como dato adicional, cada instrucción del conjunto de instrucciones del 16F
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 páginas de Microchip. ]
En el próximo capitulo, veremos cómo leer de los puertos.
Cómo leer de los puertos E/S
Hasta 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 capítulos previos, para configurar los puertos de E/S, tenemos que
cambiarnos del Banco 0 al Banco 1. Hagamos eso primero:
STATUS equ 03h ; Dirección del registro STATUS TRISA equ 85h ; Dirección del registro tri- estado para el Puerto A. PORTA equ 05h ; Dirección del Puerto A. bsf STATUS, 5 ; Cambia al 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 01h ; Para configurar el pin 0 del Puerto A... movwf TRISA ; ... como entrada. bcf STATUS, 5 ; Vuelve al Banco 0.
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 instrucción BTFSC significa "Haz una comprobación de bit en el registro y bit que
especificamos. Si es un 0, entonces sáltate la siguiente instrucción".
La instrucción BTFSS significa "Haz una comprobación de bit en el registro y bit que
especificamos. Si es un 1, entonces sáltate la siguiente instrucción".
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
podríamos utilizar la instrucción BTFSS de este modo:
;Aquí el código : BTFSS PortA, 0 Goto Inicio ;Continua por aquí : :
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 traducción: en ingles el término 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. Podrías probar a escribir el programa
completo, solo para ver si has comprendido los conceptos. Estamos usando el mismo
circuito que antes, con un conmutador añadido al pin RA0 del PIC y a la linea de
alimentación positiva.
;***** Establecimiento constantes **** STATUS equ 03h ; Dirección del registro STATUS TRISA equ 85h ; Dirección del registro tri- estado para el Puerto A. PORTA equ 05h ; Dirección del Puerto A. CONTADOR1 equ 08h ; Primer contador para nuestros bucles de retardo. CONTADOR2 equ 09h ; Segundo contador para nuestros bucles de retardo. ; ;**** Configuración 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 después 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, sáltate la siguiente instrucción y continua normalmente. call Retardo ; Si es 1, ejecuta esta instrucción añadiendo un retardo extra. ;