Está en la página 1de 13

Introduccin al lenguaje ensamblador - parte 1

En la primera parte de este curso aprendiste los conceptos bsicos sobre microcontroladores. En esta ocasin te ensear
los conceptos bsicos sobre programacin en lenguaje Assembler y analizaremos nuestro primer programa El
encendido

apagado

El

de

un

cdigo

LED.
fuente

El cdigo fuente est constituido por una sujecin de lneas de programa. Cada lnea suele estar compuesta por cuatro
campos diferentes los cuales estn separados por una o ms tabulaciones. Estos campos son los siguientes:
-

Campo

de

Campo

Campo

etiquetas.

de
de

instrucciones.

operandos

Campo

datos.

de

comentarios.

A continuacin podemos ver un ejemplo:

La siguiente tabla nos explica mejor la imagen de arriba para poder entender mejor el asunto:

Etiquetas: Las etiquetas (tambin denominadas label) son expresiones alfanumricas escogidas por el usuario, su funcin
principal es identificar a una instruccin dentro del programa. Sin embargo, a pesar de que el nombre de las etiquetas lo
determina el usuario, estas no pueden llevar el nombre de una instruccin del assembler o de un operando. Por ejemplo
sera errneo ponerle el nombre bsf a una etiqueta. Tampoco es admitido que el primer caracter de una etiqueta sea un
nmero

un

espacio,

siendo

incorrecto

por

ejemplo

ponerle

10inicio.

Las etiquetas suelen utilizase para realizar saltos. Por ejemplo:

En este ejemplo, le estamos diciendo al programa (con la instruccin goto) que salte hasta donde se encuentra la etiqueta
inicio.
Instrucciones: El segundo campo es para las instrucciones, las cuales le indican al microcontrolador la tarea que debe
realizar. Suele ser una instruccin del microcontrolador que es directamente traducida a cdigo mquina por el ensamblador.

Operandos y Datos: Esta columna contiene los operandos para las instrucciones. Este campo puede tener uno o ms
operandos

separados

por

comas.

Es

importante

destacar

que

algunos

operandos

no

llevan

dato.

Comentarios: Los comentarios se escriben generalmente en el ltimo campo, pero solo es por una cuestin de orden y
estilo, puesto que pueden ir escritos en cualquier parte (excepto entremedio de una etiqueta, instruccin u operando).
Los comentarios son palabras, frases o textos escritos por el programador, con el fin de explicar o hacer una breve
descripcin de lo que se est realizando, de manera tal que posteriormente no sea dificultoso entender el programa o
modificarlo.
Los comentarios se escriben siempre anteponiendo punto y coma (;) y no son traducidos a cdigo mquina por el
ensamblador.

En

otras

palabras,

los

comentarios

no

son

parte

del

programa

propiamente

tal.

Importante
Un detalle importante y de inters, es que, no todas las lneas de programa estn conformadas por los cuatro campos
descritos anteriormente. Por ejemplo, las etiquetas solo se usan de vez en cuando. Tambin hay instrucciones que no llevan
operando, y hay operandos que no llevan dato. Pero nunca encontraremos un operando que no lleve instruccin, ni tampoco
un

dato

que

El

no

lleve

repertorio

operando.

de

instrucciones

El PIC 16F628A posee un repertorio de 35 instrucciones que pueden ser agrupadas de la siguiente manera:
-

Instrucciones

de

carga.

Instrucciones

de

salto.

Instrucciones

Instrucciones

para

lgicas.
especiales.

Instrucciones

Las

subrutinas.

Instrucciones

manejar

Instrucciones

aritmticas.

caractersticas
Es
La

un

juego

mayora
Son

Todas

principales
de

ortogonales
tienen

una

de
de

de

este

instrucciones

las

instrucciones
(casi

longitud

He aqu el set de instrucciones del PIC 16F628A:

todas
de

14

bit.

repertorio
reducido

se

pueden
y

instrucciones

(RISC)

ejecutan

bits,

de
en
usar

los

datos

rpido
4

ciclos

sencillo.
de

cualquier
son

son:
reloj.

operando).
de

bits.

Las

directivas

Para el correcto ensamblado del programa, es necesario escribir directivas. Estas no son parte del programa ya que no son
traducidas

lenguaje

mquina,

por

eso

se

les

suele

llamar

pseudoinstrucciones.

END: Esta directiva indica el fin del programa. Es la nica directiva obligatoria, y se utiliza siempre al final del programa para
indicar

en

donde

se

termina

el

proceso.

ORG: Esta directiva le indica al programa la direccin desde la que deben ensamblarse las instrucciones escritas. Si las
instrucciones del programa son ensambladas sin especificar ORG, el ensamblador toma por defecto ORG 0x0.
__CONFIG: Esta directiva le indica al programa la configuracin elegida para la grabacin del programa. Se le denomina
tambin
Ejemplo:

Palabra

de

Configuracin

Esta directiva est formada por varios fusibles que se utilizan para definir una serie de parmetros que a continuacin
explicar.
La forma de escribir estos parmetros es tal como se ve en la imagen de arriba, se coloca un guin bajo entre cada fusible y
su

configuracin,

se

separa

cada

configuracin

con

la

letra

&.

WDT: Watch Dog Timer, o Temporizador Perro Guardin. Este temporizador resetea el PIC cada determinado tiempo para
evitar

enciclamientos

por

error

en

el

programa.

Preferentemente

hay

que

apagarlo

(OFF).

OSC: Define que tipo de oscilador se usara. RC es para Capacitor y resistencia, XT es para cristal de 4Mhz, HS para
cristales

mayores

BODEN:

Se

emplea

para

que

el

PIC

se

resetee

cuando

4Mhz.

exista

una

cada

de

tensin.

CP: Cdigo de Proteccin de programa, si lo habilitamos (ON) evita que otras personas puedan leer el programa contenido
en

el

PIC.

PWRT: Bit de Permiso para el Timer de conexin de alimentacin. Se usa para resetear el PIC cada vez que se conecta la
fuente

de

alimentacin

de

nuestra

aplicacin.

WRT: Permiso para escritura en Modo FLASH. Se usa cuando en nuestro programa accedemos a la memoria de datos
EEPROM.
CPD: Cdigo de Proteccin de Datos. Se usa para evitar que terceros lean lo que hemos escrito en la memoria EEPROM
del

PIC.

LVP: Voltaje de programacin bajo. Si esta en ON permite programar el PIC con 5V, si esta en OFF programa el PIC con
12V.
Hay un detalle muy importante con respecto al ltimo fusible llamado LVP. Una de las funciones del pin RB4 del
PIC16F628A es la de programacin en bajo voltaje, y por defecto es la funcin que viene habilitada de fbrica. Esto significa
que si queremos utilizar el pin RB4 como entrada o salida debemos poner el fusible LVP en OFF para desactivar la funcin
que
LIST:

trae
Esta

INCLUDE:

directiva

Esta

indica

directiva

se

de

el

modelo

de

utiliza

para

incluir

fbrica.

microcontrolador
una

librera

que
dentro

se
de

va

nuestro

utilizar.
programa.

CBLOCK y ENDC: Este par de directivas cumplen la funcin de asignar direcciones, generalmente de la memoria RAM de
datos.
#DEFINE:
Las

La

lista
Esta

queda
directiva

enmarcada
define

entremedio
una

de
cadena

las

directivas
de

CBLOCK

sustitucin

y
de

ENDC.
texto.
subrutinas

Una subrutina es un trozo de cdigo fuente que suele estar apartado del resto del programa para hacer ms sencilla la
revisin y lectura del programa. Para llamar a una subrutina se utiliza la instruccin call, y para salir de una subrutina se
utiliza

la

instruccin

return.

Al llamar a una subrutina, el programa ejecuta las instrucciones que forman parte de ella, y luego retorna una posicin ms
abajo desde donde fue llamada la subrutina. Mira esta representacin:

Las subrutinas generalmente se utilizan cuando un mismo trozo de cdigo fuente se debe repetir demasiadas veces,
entonces se escribe ese trozo de cdigo a modo de subrutina, y posteriormente se le llama cada vez que se necesite.
La

memoria

del

microcontrolador

Para poder realizar las acciones que ejecuta el microcontrolador, es necesario escribir y leer datos en alguna parte Para
eso est la memoria del PIC, la cul est dividida en cuatro bancos (del 0 al 3), en cada banco hay una cierta cantidad de
registros, y cada registro est dividido en 8 bits (1 byte). Veamos el mapa de memoria del PIC 16F628A:

Introduccin al lenguaje ensamblador - parte 2


Programa

de

ejemplo

Probablemente, el encendido y apagado de un LED es lo primero que todos intentan conseguir cuando se inician en la
programacin en Assembler, por esa razn decid comenzar la segunda parte de mi curso explicando precisamente un
programa

que

realice

tal

accin.

Comencemos:

La primera lnea se utiliza simplemente para indicarle al programa el modelo de PIC que vamos a utilizar.
La segunda lnea es para agregar a nuestro programa la librera del PIC 16F628A que contiene datos de direccionamiento
para

que

no

tengamos

que

escribirlos

manualmente.

*Entindase por librera como un programa escrito previamente, el cul agregamos a nuestros programas para que sean
ms manejables. Podramos decir entonces que cualquier programa que escribamos podra ser denominado librera si lo
agregramos a otro programa a futuro.

En esta lnea estamos configurando los fusibles. Esto fue explicado en la seccin de directivas.

Con esta lnea le estamos indicando al programa que ignore los posibles errores cuando almacene en banco. Cuando
compilamos, a veces aparecen mensajes que dice Warning o Message advirtiendo de posibles errores en nuestro
programa, cada uno de estos errores tiene un nmero (este nmero aparece junto al mensaje). El aviso 302 es el que indica
que un registro puede haber sido configurado en un banco equivocado. Al escribir errorlevel -302 estamos dicindole al
programa que ignore ese posible error.

Los registros o variables que se usarn se declaran entre estos dos reglones, el 0X20 indica que usaremos los espacios
disponibles
*Para

mayor

para

registros

informacin

puedes

partir
ver

la

de
seccin

la

posicin

Memory

Map

0x20
en

de
la

la

datasheet

Las variables que utilizaremos se declararn entre estos dos reglones, pero eso lo haremos ms adelante.

memoria.
del

PIC.

La lnea org 0x0 (origen 0) es el Vector de Reset, lo cual quiere decir que siempre que se resetee, o se encienda el PIC, el
programa

se

comenzar

ejecutar

partir

de

esta

posicin.

El goto es una instruccin que se utiliza para saltar a una parte especfica de nuestro programa, en este caso le decimos
que

vaya

la

etiqueta

reg,

que

obviamente

puede

tener

cualquier

otro

nombre.

Como ya debers saber, el PIC 16F628A tiene cuatro bancos, en cada uno de ellos hay registros, y en cada registro hay 2
Nibbles,

que

*Nibble:

es

lo

Conjunto

mismo

que

de

bits.

bits.

Para moverse de un banco a otro debemos utilizar el registro STATUS. En este registro tenemos RP0 y RP1, los cuales
deben tener un 0 o un 1 para poder posicionarnos en un determinado banco. La siguiente tabla (extrada de la datasheet)
muestra la configuracin que debe tener RP0 y RP1 para moverse a un determinado banco:

Vale decir que para movernos al banco 0, debemos poner en 0 el RP0 y el RP1, y para movernos por ejemplo al banco 3
debemos

poner

en

el

RP1

en

el

RP0.

Teniendo esto en cuenta, analicemos las siguientes lneas.

BCF es la instruccin para poner un 0 y BSF es para poner un 1. Lo dije de una manera poco tcnica pero se entiende la
idea.
Entonces, necesitamos configurar los registros TRIS ubicados en el banco 1, estos registros se utilizan para definir si los
puertos A y B sern entradas o salidas. Por lo tanto, y segn la tabla de arriba, para movernos al banco 1 debemos poner un
0

en

RP1

un

en

RP0.

La lnea org 0x5 se utiliza para saltarse el vector de interrupciones (esto ser analizado en la segunda parte de este curso).
Luego estamos poniendo en 1 el RP0, no hace falta poner en 0 el RP1 porque por defecto todo bit est en cero.
Ahora ya estamos ubicados en el Banco 1 de la memoria de nuestro PIC.

Ahora, en la tercera lnea dice clrf trisa. La instruccin clrf es para mandar puros ceros a un registro, en este caso estamos
mandando

puros

ceros

*TRISA

direcciona

al
al

registro

TRISA

lo

puerto

cual

configura

TRISB

al

puerto

direcciona

A
al

como
puerto

salida.
B.

La instruccin clrf nos ahorra espacio, ya que manda puros ceros, pero sera lo mismo escribir esto:

De esta forma cargamos puros ceros y luego los mandamos al registro TRISA. Es lo mismo.

Bueno, volvamos a este trozo de cdigo fuente. Luego de poner en 0 el TRISA estamos utilizando la instruccin movlw que
carga un valor literal en W, en este caso el valor literal es binario (por eso ponemos una b en minscula).
El nmero binario que estamos cargando es 10000000 lo que significa que RB7 est configurado como entrada, y de RB6 a
RB0

estn

siendo

configurados

como

salidas.

Pero hasta este momento solo hemos cargado el valor binario, pero ahora hace falta enviarlo a algn registro, para ello
utilizamos la instruccin movwf y escribimos TRISB, o sea que le estamos diciendo que mueva el valor binario cargado al
registro

TRISB.

En seguida, debemos regresar al Banco 0, puesto que el PIC debe mantenerse en este banco para poder trabajar. Para ello
nicamente ponemos en 0 el RP0 (como se explic ms arriba) y ya estamos en el Banco 0.

Las dos lneas que siguen clrf porta y clrf portb estn mandando puros ceros a los registros porta y portb para apagar
ambos puertos, por si alguno de ellos se encontrase con un nivel de voltaje alto a la hora de comenzar a funcionar el
programa.
Como los registros porta y portb se encuentran en el Banco 0, debemos estar posicionados en ese banco para poder
configurarlos.

Aqu ya entramos de lleno en el programa principal, la parte difcil era la configuracin de los registros, pero el programa
principal

propiamente

tal,

es

mucho

ms

fcil

aburrido,

porque

si

no

es

difcil

no

es

divertido.

Haremos un programa que encender un LED conectado en RB0 cuando presionemos un pulsador conectado en RB7.
Primeramente,

escribimos

una

etiqueta

la

que

yo

he

llamado

inicio.

Luego nos topamos con la instruccin btfss que es como una condicin if then en programacin con otros lenguajes que son
de alto nivel. Esta instruccin pregunta si se ha cumplido una determinada condicin, si esta condicin es falsa el programa
hace

una

cosa,

si

es

verdadera

entonces

hace

otra.

En este caso yo puse btfss portb,7 lo cual est preguntando si hay o no un nivel del voltaje alto en el pin RB7, si la condicin
es falsa se ejecuta la instruccin que le sigue al btfss, en este caso un goto que nos est enviando de regreso al inicio para
que vuelva a comprobar la condicin, y estar dando vueltas en este bucle hasta que la condicin sea verdadera.
*PORTB,7

hace

referencia

al

RB7,

as

como

por

ejemplo

PORTA,4

hara

referencia

al

pin

RA4.

Ahora bien, si la condicin es verdadera (o sea que hay un nivel alto en RB7), entonces el programa se salta la instruccin
goto y contina leyendo el resto de instrucciones.

Ahora que la condicin se hizo verdadera, la instruccin que sigue es bsf que se utiliza para poner un 1, en este caso yo
coloco

en

el

pin

RB0,

sea

que

se

encender

el

diodo

LED

conectado

en

dicho

pin.

Luego, llamo a una rutina de tiempo (que haremos ms adelante) para que el programa espere un tiempo antes de
continuar.

Para

esto

utilizamos

la

instruccin

call

nuestra

rutina

se

llama

PDelay.

Terminando la rutina de espera, utilizamos la instruccin bcf para poner en 0 el RB0 y as apagar el LED.
Despus, volvemos a llamar a la rutina y finalmente utilizamos la instruccin goto para regresar al inicio y realizar todo el
programa

nuevamente

infinitas

veces.

Eso es todo, ahora veamos la subrutina de tiempo. Esta se puede confeccionar manualmente empleando una formula, pero
ya son las 0:34, tengo sueo y no tengo ganas de explicar eso, as que haremos nuestra rutina con un lindo programa que
se llama PIC Delayer, ms conocido como PIC Delay o PIC Del.

Bueno, ejecuta el PIC Delayer y se ver est ventana:

En donde dice Frequency debes escribir la frecuencia del oscilador que ests utilizando, el programa trae por defecto 4MHz.
Luego, donde dice Delay Time debes escribir el tiempo que deseas (ponlo en milisegundos). Y presiona el botn Calculate
Cycles.
Yo puse 500mS. Luego presionas el botn Generate Code y espera a que el programa genere la rutina de tiempo solicitada.
Debers ver esto:

Ah ya est la subrutina creada, ahora cpiala y pgala en tu cdigo fuente. De esta manera:

No olvides escribir end al final del programa. Yo aqu arregl la rutina borrando los comentarios y alinendola con mi cdigo
fuente. Te sugiero que hagas lo mismo, no hay un programador ms mediocre que el que escribe desordenado. Si te fijas la
palabra PDelay aparece encerrada con rojo en nuestra rutina. Ese es el nombre de la etiqueta de nuestra rutina y a ella
debemos

llamar

para

que

el

programa

salte

hacia

all.

Call

PDelay.

Ojo con un detalle. Cuando creamos la rutina con el programa PIC Delayer, aparecieron unos requerimientos en la parte de
abajo:

Nuestra rutina necesita un lugar en el cual almacenarse, a estos lugares denominaremos variables. Estas variables se
llaman PDel0 y PDel1 y hay que declararlas entre los reglones cblock y endc.

De esta forma nuestra rutina funcionar de forma correcta. Si te fijas hay un tercer requerimiento, 1 stack level. El stack es
una cosa del PIC que no voy a explicar ahora, pero no te preocupes por eso ya que no es relevante saberlo para que la
rutina funcione. Por ahora ignora eso del stack