6. Programación en lenguaje ensamblador

Ya entramos al corazón de la creación de proyectos con microcontroladores. Lo primero que necesitaremos es un software para escribir los programas, en este caso basta con un editor de textos básico como el famoso bloc de notas de Windows, o el gedit de GNU/Linux.

Para escribir un programa en lenguaje ensamblador, en cada renglón se deben diferenciar tres columnas separadas por un espacio en blanco, en la primera columna se escriben etiquetas que asignamos a determinada línea del código, la segunda columna es la instrucción y la tercera columna es el registro, bit o dato al que se le aplica la instrucción. La estructura de cada renglón escrito quedaría así:

Etiqueta    Instrucción    Registro/Bit/Dato

No siempre se ponen etiquetas a cada renglón, en ese caso habrá que dejar la columna vacía pero se debe respetar el espacio en blanco antes de escribir la instrucción así:

                   Instrucción    Registro/Bit/Dato

Cuando escribimos un programa es muy importante agregar comentarios que nos guíen cada vez que queremos estudiar o modificar el código, en ellos también podemos agregar información adicional, por ejemplo, la conexión de los pines del microcontrolador. Los comentarios se escriben precedidos de un punto y coma (;) así:

Etiqueta    Instrucción    Registro/Bit/Dato     ; Comentario

Nota: A lo largo de un programa en ensamblador se hace uso frecuente del registro W, el cual se encarga de almacenar momentáneamente los datos que van a procesarse.

La estructura de un programa en ensamblador es la siguiente:

1. Biblioteca

2. Configuración de fusibles

3. Mapa de memoria

4. Configuración de inicio

5. Cuerpo del programa

6. Fin

1. Biblioteca: Esta es la parte del código donde se indica el microcontrolador que se va a programar, para el PIC 16F84A se escribe lo siguiente:

LIST P=PIC16F84A

#INCLUDE <P16F84A.INC>
2. Configuración de fusibles: Indica qué fusibles se usarán, por ahora vamos a usar la siguiente palabra de configuración:

__CONFIG        _XT_OSC  &  _WDT_OFF  &  _PWRTE_ON  &  _CP_OFF

La cual indica que se usará un oscilador XT (4MHz) y se activará el temporizador de encendido; no se usará perro guardián ni protección de código.

3. Mapa de memoria: Recordemos que producto de su arquitectura Harvard, el microcontrolador posee dos memorias (de datos y de programa). El mapa de memoria es la parte del código que le asigna nombres a los registros de la memoria de datos que serán usados, no es obligatorio hacer esto pero sí es aconsejable pues facilita la elaboración de programas.  Para asignar un nombre a un registro se debe conocer su dirección, por el momento nos interesan las direcciones de los registros de configuración y manejo de los puertos del PIC (0X05 y 0X06); también nos interesa la dirección de un registro muy importante llamado STATUS (0X03):

PORTA    EQU      0X05; Registro de configuración y manejo del puerto A

PORTB    EQU      0X06; Registro de configuración y manejo del puerto B

STATUS   EQU      0X03; Registro de estado

La instrucción “EQU” sirve para asignarle un nombre al registro especificado, el cual tiene una dirección en formato hexadecimal. Para saber con qué registros cuenta la memoria de datos véase la figura 2.10.

fig 2.10
fig 2.10 Memoria de datos del PIC 16F84A

Nótese que la memoria de datos del PIC 16F84A está dividida en dos partes llamadas banco 0 y banco 1. Para elegir el banco que se va a acceder, el registro STATUS tiene un bit encargado de esta función.

Ejemplo:

Si estoy en el banco 0 y modifico el registro de dirección 0X05, estaría modificando el registro PORTA; pero si estoy en el banco 1 y modifico también el registro de dirección 0X05 ahora estaría modificando el registro TRISA.

4. Configuración de inicio: En esta parte del código se indica el inicio del programa y se configuran la salidas y las entradas. El programa iniciará a partir de donde pongamos la siguiente línea:

        ORG     0X00  ; Indica que aquí inicia el programa

Ya se puede configurar los puertos, si observamos la distribución de la memoria de datos veremos que los registros de configuración TRISA y TRISB se encuentran en el banco 1, por eso se hace necesario direccionarnos hacia ese banco usando el registro STATUS de la siguiente manera:

BSF     STATUS,5  ; Esta sentencia nos dirige hacia el banco 1 de la memoria.

La función BSF significa poner un “1” en el bit indicado, en este caso, el bit 5 del registro STATUS. Cuando este bit, llamado RP0, se encuentra en “1” se activa el banco 1 y cuando está en “0” se activa el banco 0.

Estando en el banco 1 procedemos a acceder a los registros TRISA y TRISB; para configurar al puerto A como salida escribimos:

MOVLW     b’00000′  ; Con esto cargamos en W el número 0 en formato binario

MOVWF    0X05        ; Y con esto lo transferimos hacia el registro TRISA

Cuando ponemos TRISA en cero estamos configurando al puerto A como salida.

Para configurar el puerto B el procedimiento es similar:

MOVLW     b’00000000′  ; Con esto cargamos en W el número 0 en formato binario

MOVWF    0X06               ; Y con esto lo transferimos hacia el registro TRISB

Nótese que para configurar TRISA utilizamos en formato binario 5 ceros porque el puerto A tiene 5 líneas mientras que para configurar TRISB utilizamos 8 ceros porque el puerto B tiene 8 líneas.

Ya habiendo configurado los puertos deberíamos regresar al banco 0 que es desde donde se manejan, esto se hace con la siguiente instrucción:

BCF     STATUS,5  ; Esta sentencia nos dirige hacia el banco 0 de la memoria.

5. Cuerpo del programa: Aquí escribiremos las instrucciones que hemos diseñado para hacer funcionar al microcontrolador de la forma deseada. Con lo visto hasta ahora ya aprendimos dos instrucciones de manejo muy importantes: BSF (función para poner un “1” en determinado bit) y BCF (función para poner un “0” en determinado bit).

6. Fin: Para que el código en lenguaje ensamblador esté completo es necesario escribir una línea que indica la finalización de dicho código:

END      ; Con esta sencilla palabra culminaremos el programa.

Para guardar el código debemos hacerlo en formato *.asm, en Windows lo hacemos de la siguiente manera: damos clic en Archivo>>Guardar como y le damos un nombre al archivo seguido de la terminación “.asm” (ver fig 2.11), con esto, el texto queda automáticamente guardado en formato ensamblador con extensión *.asm.

fig 2.11
fig 2.11 Forma de guardar un código en lenguaje ensamblador