La electrónica ha evolucionado mucho. Casi todo lo que hasta hace unos años se realizaba mediante un grupo (a veces muy numeroso) de circuitos integrados conectados entre sí, hoy se puede realizar utilizando un microcontrolador y unos pocos componentes adicionales.
Los microcontroladores mas utilizados hoy en día, son los del fabricante MICROCHIP, por la amplia variedad de microcontroladores que nos ofrece, y la información de cada uno de los microcontroladores que nos proporciona sin ningún costo alguno.
El lenguaje nativo de estos microcontroladores es el ASM, y en el caso de la familia “16F” solo posee 35 instrucciones. Pero el ASM es un lenguaje que está mucho más cerca del hardware que del programador, y gracias a la miniaturización que permite incorporar cada vez más memoria dentro de un microcontrolador sin aumentar prácticamente su costo, han surgido compiladores de lenguajes de alto nivel. Entre ellos se encuentran varios dialectos BASIC y C.
Un microcontrolador es como un ordenador en pequeño: dispone de una memoria donde se guardan los programas, una memoria para almacenar datos, dispone de puertos de entrada y salida, etc. A menudo se incluyen puertos seriales (RS-232), conversores analógico/digital, generadores de pulsos PWM para el control de motores, bus I2C, y muchas cosas más. Por supuesto, no tienen ni teclado ni monitor, aunque podemos ver el estado de teclas individuales o utilizar pantallas LCD o LED para mostrar información.
El pic16f628a es un microcontrolador de 8 bit, posee una arquitectura RISC avanzada así como un juego reducido de 35 instrucciones. Este microcontrolador es el remplazo del obsoleto pic16f84a, los pines del pic16f628a son compatibles con el pic16f84a, así se podrían actualizar proyectos que hemos utilizado con el pic16f84a.
Como habrán notado, muchos de los pines tienen más de una descripción. Esto se debe a que pueden utilizarse de varias maneras diferentes, seleccionables por programa. Por ejemplo, el pin 4 sirve como parte del PORTA, como RESET (MCLR = Máster Clear) y como tensión de programación (Vpp)
Diagramas de pines del PIC16F628A.
Mapa de memoria del PIC16F628A.
|
Como vemos en la figura 1.4 el mapa de memoria se encuentra dividida en 4 bancos en estos bancos se encuentra los registros de control así como también la memoria RAM.
Diagrama de bloques del PIC16F628A.
En la figura 1.5 se muestra el diagrama de bloques del pic16f628a como vemos los puertos a y b son direccionales, o sea se les puede configurara como entrada o salida digital.
¿COMO CARGAREMOS UN PROGRAMA AL MICROCONTROLADOR?
Utilizaremos la aplicación llamada MPLAB, en el cual cargaremos las instrucciones que deseemos, que nuestro Pic realice, esto se llevara a cabo con un lenguaje C.
PARA HACER DICHO PRIGRAMA SE REQUIEREN DE INSTRUCCIONES QUE SIN CONPATIBLES CON NUESTRO PIC 16F628:
INSTRUCCIONES DEL ENSAMBLADOR MPASM.
Estas 35 instrucciones son las mismas para toda la gama media de los microcontroladores pic así que si más adelante se quiere realizar un programa para un pic 16F877 se usaran las mismas instrucciones.
| |
|
Fig1.6 Proceso del ensamblador.
Antes de continuar es necesario definir algunos términos que se usaran para explicar las instrucciones:
f: cualquier registro del microcontrolador
W: registro de trabajo
b: posicion de un bit en el registro 'f'
d: destino, puede ser 'f' (d=1) o 'W' (d=0)
etiqueta: grupo de caracteres que marcan el inicio de una parte del programa
[]: Opcional
: Posicion de un bit dentro de un registro
Instrucciones orientadas a registros.
ADDWF: Suma W y f
Suma el contenido del registro 'W' y el registro 'f'. Si "d" es 0, el resultado se almacena en el registro W. Si 'd' es 1 el resultado se almacena en el registro 'f'.
Sintaxis: [etiqueta] ADDWF f,d
Operación: (W) + (f) --> (destino)
Flags afectados: C, DC, Z
Ejemplo: ADDWF REG,1
Antes de la instrucción: W=0x03, REG=0x04
Después de la instrucción: W=0x03, REG=0x07
ANDWF: (W AND f)
Realiza la operación lógica AND entre el registro W y el registro "f". Si "d" es 0 el resultado se almacena en el registro W. Si "d" es 1, el resultado se almacena en el registro "f".
Sintaxis: [etiqueta] ANDWF f,d
Operación: (W) AND (f) --> (destino)
Flags afectados: Z
Ejemplo: ANDWF REG,1
Antes de la instrucción: W=0x17, REG= 0xC2
Después de la instrucción: W=0x17, REG= 0x02
CLRF: (Borra un registro)
Borra el contenido del registro 'f' y se activa el flag Z.
Sintaxis: [etiqueta] CLRF f
Flags afectados: Z
Ejemplo: CLRF REG
Antes de la instrucción: REG=0x54
Después de la instrucción: REG=0x00, Z=1
CLRW: (Borra el registro de trabajo W)
Borra el contenido del registro 'W' y se activa el flag Z. Esta instrucción no tiene operandos.
Sintaxis: [etiqueta] CLRW
Flags afectados: Z
Ejemplo: CLRW
Antes de la instrucción: W=0x54
Después de la instrucción: W=0x00, Z=1
COMF (Complementa el registro f)
El contenido del registro 'f' se complementa. Si d=0 el resultado se almacena en el registro W. Si d=1 el resultado se almacena en el registro 'f'.
Sintaxis: [etiqueta] COMF f,d
Flags afectados: Z
Ejemplo: COMF REG,0
Antes de la instrucción: REG=0x13
Después de la instrucción: REG=0x13, W=0xEC
DECF: (Decrementa f en 1)
De decrementa en uno el contenido del registro 'f'. Si d=0, el resultado se almacena en W. Si d=1, el resultado se almacena en 'f'.
Sintaxis: [etiqueta] DECF f,d
Flags afectados: Z
Ejemplo: DEC CONT, 1
Antes de la instrucción: CONT=0x01, Z=0
Después de la instrucción: CONT=0x00, Z=1
DECFSZ: (Decrementa en 1 y salta si el resultado es 0)
El contenido del registro 'f' se decrementa. Si 'd=0, el resultado se coloca en el registro W. Si d=1, el resultado se coloca en el registro 'f'. Si el resultado es 0, se salta la siguiente instrucción y se continúa con la ejecución.
Sintaxis: [etiqueta] DECFSZ f,d
Flags afectados: Ninguno
INCF: (Incrementa el registro f)
Incrementa en uno el contenido del registro 'f'. Si d=0, el resultado se almacena en W. Si d=1, el resultado se almacena en 'f'.
Sintaxis: [label] INCF f,d
Flags afectados: Z
Ejemplo: INCF CONT,1
Antes de la instrucción: CONT=0xFF, Z=0
Después de la instrucción: CONT=0x00, Z=1
INCFSZ: (Incrementa en 1 y salta si el resultado es 0)
El contenido del registro 'f' se incrementa. Si d=0, el resultado se coloca en el registro W. Si d=1, el resultado se coloca en el registro 'f'. Si el resultado es 0, se salta la siguiente instrucción y se continúa con la ejecución.
Sintaxis: [etiqueta] DECFSZ f,d
Flags afectados: Ninguno
IORWF: (W OR f)
Realiza la operación lógica OR entre el registro W y el registro 'f'. Si d=0 el resultado se almacena en el registro W. Si d=1, el resultado se almacén en el registro 'f'.
Sintaxis: [etiqueta] IORWF f,d
Flags afectados: Z
Ejemplo: IORWF REG,0
Antes de la instrucción: REG=0x13, W=0x91
Después de la instrucción: REG=0x13, W=0x93
MOVF: ( Mover el registro f)
El contenido del registro 'f' se mueve al destino 'd'. Si d=0, el destino es el registro W. Si d=1, el destino es el propio registro 'f'.
Sintaxis: [etiqueta] MOVF f,d
Flags afectados: Z
Ejemplo: MOVF REG,0
Después de la instrucción: W=REG
RLF: (Rota el registro f a la izquierda)
El contenido del registro 'f' se rota una posición a la izquierda. El bit de más peso pasa al carry y el carry se introduce por el bit de menos peso de 'f'. Si d=0, el resultado se coloca en el registro W. Si d=1, el resultado queda en el registro 'f'.
Sintaxis: [etiqueta] RLF f,d
Flags afectados: C
Ejemplo: RLF REG,1
Antes de la instrucción: REG=b'11100110', C=0
Después de la instrucción: REG=b'11001100', C=1
RRF: ( Rota el registro f a la derecha)
El contenido del registro 'f' se rota una posición a la derecha. El bit de menos peso pasa al carry y el carry se introduce por el bit de más peso de 'f'. Si d=0, el resultado se coloca en el registro W. Si d=1, el resultado queda en el registro 'f'.
Sintaxis: [etiqueta] RLF f,d
Flags afectados: C
Ejemplo: RLF REG,1
Antes de la instrucción: REG=b'11100110', C=0
Después de la instrucción: REG=b'01110011', C=0
SUBWF: (Resta f – W)
Resta el contenido del registro 'f' menos el contenido del registro W. Si d=0, el resultado se almacena en el registro W. Si d=1, el resultado se almacena en el registro 'f'.
Sintaxis: [etiqueta] SUBWF f,d
Flags afectados: C, DC, Z
Ejemplo: SUBWF REG,1
Antes de la instrucción: REG=0x01, W=0x02
Después de la instrucción: REG=0xFF, W=0x02
SWAPF: (Intercambio de f)
El nibble bajo del registro 'f' se intercambia con el nibble alto del mismo. Si d=0, el resultado se coloca en el registro W. Si d=1, el resultado queda en el registro 'f'.
Sintaxis: [etiqueta] SWAPF f,d
Flags afectados: Ninguno
Ejemplo: SWAPF REG,1
Antes de la instrucción: REG=0x54
Después de la instrucción: REG=0x45
XORWF: (W XOR f)
Realiza la función lógica OR exclusiva entre el contenido del registro W y el registro 'f'. Si d=0, el resultado se almacena en el registro W. Si d=1 el resultado se almacena en el registro 'f'.
Sintaxis: [etiqueta] XORWF f,d
Flags afectados: Z
Ejemplo: XORWF REG,1
Antes de la instrucción: REG=0xAF, W=0xB5
Después de la instrucción: REG=0x1A, W=0xB5
NOP: (No operación)
No realiza ninguna operación, solo consume un ciclo de reloj
Sintaxis: [etiqueta] NOP
INSTRUCCIONES ORIENTADAS A BITS:
BCF: (Borra un bit)
Borra el bit 'b'del registro 'f'
Sintaxis: [etiqueta] BCF f,b
Ejemplo: BCF REG,0
Antes de la instrucción: REG=b'01101101'
Después de la instrucción: REG=b'01101100'
BSF: (Activa un bit)
Activa el bit 'b' del registro 'f'
Sintaxis: [etiqueta] BSF f,b
Ejemplo: BSF REG,2
Antes de la instrucción: REG=b'01001001'
Después de la instrucción: REG=b'01001011'
BTFSC: (Checa un bit y salta si es 0)
Si el bit "b" del registro "f" es 0, se salta una instrucción y se continúa con la ejecución.
Sintaxis: [etiqueta] BTFSC f,b
BTFSS: (Checa un bit y salta si es 1)
Si el bit "b" del registro "f" es 1, se salta una instrucción y se continúa con la ejecución.
Sintaxis: [etiqueta] BTFSS f,b
INSTRUCCIONES ORIENTADAS A CONSTANTES Y DE CONTROL
ANDLW: (W AND literal)
Realiza la operación lógica AND entre el registro W y la constante "k". El resultado se almacena en el registro W.
Sintaxis: [label] ANDWL k
Flags afectados: Z
Ejemplo: ANDLW 0x5F
Antes de la instrucción: W=0xA3
Después de la instrucción: W=0x03
CALL: (Llamada a subrutina)
Llamada y salto a subrutina. La dirección de retorno se guarda en el stack. La constante "k" de 8 bits forma la dirección de salto y se carga en los bits del PC. Los bits del PC se cargan con los bits del registro "STATUS". PC se pone a 0.
Sintaxis: [etiqueta] CALL k
Ejemplo: INICIO CALL DESTINO
Antes de la instrucción: PC=INICIO
Después de la instrucción: PC=DESTINO
CLRWDT: (Borra el watchdog timer)
Esta instrucción borra tanto el "watchdog" como el prescaler. Los bits TO y PD del registro de estado se ponen a "1".
Sintaxis: [label] CLRWDT
Flags afectados: TO, PD
GOTO: (Salto incondicional)
Se trata de un salto incondicional. Los 9 bits de la constante "k" que forman la instrucción, se cargan en los bits del PC y forman la dirección de salto. Los bits del PC se cargan con los bits del registro de estado.
Sintaxis: [etiqueta] GOTO k
Ejemplo: INICIO GOTO DESTINO
Antes de la instrucción: PC=0
Después de la instrucción: PC=DESTINO
IORLW: (W OR literal)
Se realiza la función lógica OR entre el registro W y la contante "k". El resultado se almacena en el registro W.
Sintaxis: [etiqueta] IORLW k
Flags afectados: Z
Ejemplo: IORLW Ox35
Antes de la instrucción: W=0x9A
Después de la instrucción: W=0xBF
MOVLW: (Carga un literal en W)
El registro W se carga con el valor de 8 bits expresado mediante la literal "k".
Sintaxis: [etiqueta] MOVLW k
Ejemplo: MOVLW 0x5A
Después de la instrucción: W=0x5A
RETURN: (Regresa de una subrutina)
El programa regresa de la subrutina y ejecuta la instrucción que sigue a CALL
Sintaxis: [etiqueta] RETURN
RETLW: Regresa de una subrutina y carga el valor K en W
El programa regresa de la subrutina y carga el valor de 8 bits del registro k en el registro W
Sintaxis: [etiqueta] RETLW, k
Ejemplo: RETLW, 0x45
Antes de la instrucción: W=xx
Después de la instrucción: W=0x45
RETFIE: (Regresa de la rutina de servicio)
Sintaxis: [etiqueta] RETFIE
SLEEP: (Entra en estado de reposo)
Al salir, activa el bit de estado TO y borra el PD. El WDT y el prescaler se borran. Al entrar en el modo SLEEP, se detiene el oscilador.
Sintaxis: [etiqueta] SLEEP
Flags afectados: TO, PD, GPWUF
XORLW: ( W XOR literal)
Realiza la función lógica OR exclusiva entre el contenido del registro W y la constante "k" de 8 bits. El resultado se almacena en el registro W.
Sintaxis: [etiqueta] XORLW k
Flags afectados: Z
Ejemplo: XORLW 0xAF
Antes de la instrucción: W = 0xB5
Después de la instrucción: W = 0x1A
SUBLW: (Resta L – W)
A una constante "k" de 8 bits se le resta el registro W. El resultado es guardado en el mismo registro W.
Sintaxis: [etiqueta] SUBLW k
Flags afectados: C,DC,Z
MOVWF: (Mover el valor del registro W al registro f)
El contenido del registro ‘W’ se mueve al registro ‘f’.
Sintaxis: [etiqueta] MOVWF f
Flags afectados: Ninguno
Ejemplo: MOVWF REG
Antes de la instrucción: REG=0x03, W=0xA4
Después de la instrucción: REG=0xA4, W=0xA4
Y estas son las 35 instrucciones que podemos utilizar para programar los microcontroladores PIC. La razón para que solo se utilicen 35 instrucciones en la programación es que los PIC son microcontroladores RISC, y estas instrucciones están bien optimizadas para tener una mayor velocidad de trabajo, una arquitectura más simple y un código más compacto.
PROGRAMADOR MPLAB UTILIZADO PARA ESTE TIPO DE PIC.
MPLAB es un editor IDE gratuito, destinado a productos de la marca Microchip. Este editor es modular, permite seleccionar los distintos microcontroladores soportados, además de permitir la grabación de estos circuitos integrados directamente al programador.
Es un programa que corre bajo windows y como tal, presenta las clásicas barras de programa, de menú, de herramientas de estado, etc. El ambiente MPLAB® posee editor de texto, compilador y simulación (no en tiempo real). Para comenzar un programa desde cero para luego grabarlo al μC en MPLAB® v7.XX los pasos a seguir son:
1. Crear un nuevo archivo con extensión .ASM y nombre cualquiera
2. Crear un Proyecto nuevo eligiendo un nombre y ubicación
3. Agregar el archivo .ASM como un SOURCE FILE
4. Elegir el microcontrolador a utilizar desde SELECT DEVICE del menú CONFIGURE
A continuación se muestra un programa hecho en el MLAB, utilizando las algunas instrucciones que acabamos de mencionar, dicho programa es para encender 10 luces (led) secuencialmente.
Fig.1.8 Ejemplo de diseño de programa de 10 Luces secuenciales.