gentoo linux, java, software libre y otras hierbas
Nov, 27 2006 - 10:17 am

Grabando nuestros programas en ASM y C en los PIC’s

Bueno, ya he posteado sobre los microcontroladores y sobre los circuitos que se pueden montar y eso; ahora que ya sabemos qué es un microcontrolador (exactamente los PIC 16C84 y 16F84), cómo probar programas simples en ASM y C, y tenemos los esquemas de los mismos para implementarlos en circuitos. Es hora de probar una tool que nos permitirá grabar los programas en nuestros PIC’s y probar nuestros circuitos…

La tool que vamos a manejar es el ICProg (descarga directa) y las pruebas las he realizado con el grabador (o quemador) Te21se:

La puedes comprar en AP-ELEctronics wink

En esta ocación vamos a configurar nuestra tool para que quede al pelo xD; lo primero descargarla, ahora copiamos la carpeta en algún lugar donde te quede cómodo abrir (c:\ por ejemplo). Ejecutamos el icprog.exe y posiblemente nos saldrá algo como esto (si es nuestra primera vez… eso se escuchó muy virginal xD):

Le damos ok, y tendremos lo siguiente (en algunos pc’s da unos errores extraños, basta con cerrar la aplicación y volverla a lanzar):

Lo primero que haremos será configurar el idioma de la tool en “Español”. Vamos al menu Settings->Options y picamos la pestaña Language.

Le damos ok, y ahora vamos al menú Ajustes->Tipo Hardware con lo que nos saldrá algo como esto:

MUY IMPORTANTE: Deberemos indicar correctamente el puerto COM al que vamos a conectar el cable. Ten en cuenta que si indicamos COM1 en ICPROG y conectamos el cable al COM2 no funcionará. En algunos ordenadores con módem interno, puede darse el caso que esté ocupando el COM1, y los puertos del ordenador sean el COM2 y el COM3.

En caso de errores en la grabación, se puede ir probando, bajando el valor de Retardo I/O. Aconsejo entre 4 – 7.

Ahora vamos a hacer una configuración general de nuestra aplicación; vamos a Ajustes->Opciones y colocamos todo como lo veremos a continuación:

Le damos OK y ya tenemos nuestro Icprog configurado wink

Pasos a seguir para quemar nuestros PIC’s

Voy a indicar algunas cosas que han de ser obvias para muchos de uds. que sí saben de electrónica… necesitas tener una tarjeta Piccard-1 (PIC16F84) o Piccard-2 (PIC16C84), junto con sus correspondientes circuitos integrados, un programador, el programa ICPROG y:

  • En el caso de PICCARD-1, dos archivos: uno .HEX para programar la PIC y el otro .BIN (en ocasiones también .HEX) para programar la EEPROM
  • En el caso de PICCARD-2, un solo archivo para la PIC.

Nota: si no entiendes que es eso de la EEPROM, puedes hecharle un vistazo a este post wink

Lo primero es insertar nuestro PIC en el zócalo adecuado del Te21se y en su posición correspondiente. Observa los chips de cerca, tienen una pequeña muesca en forma de media luna o de punto, que debe coincidir con la muesca de la misma forma de los zócalos del grabador, si los inviertes quemarás los put0s PIC’s (no saldrá humo como en las películas xD, pero ya no funcionará más ;( ).

Una vez están correctamente insertados, conectamos el cable serie, por un lado al programador y por el otro a un puerto COM libre del ordenador. Ahora ejecutamos el programa ICPROG que ya deberemos tener bien configurado.

Indicamos que vamos a grabar el primero de los dos chips, el PIC16F84, con los siguientes pasos:

Ajustes -> Dispositivo -> Microchip Pic -> Mas -> PIC16F84

Ahora cargaremos el archivo que se va a grabar en el PIC, estos son los pasos:

Archivo -> Abrir Datos -> *.hex, (de los dos archivos hay que abrir el que tiene extensión .HEX puesto que el .BIN es para grabar el otro chip).

Esto se puede parecer a un editor hexadecimal, herramienta común entre los crackers. Una vez abierto, deberemos colocar las opciones Oscilador en XT y desactivar las opciones Bits configuración.

Listo!!!! Ahora solo no queda grabar la información del HEX en nuestros PIC’s: Menu “Comando” -> “Programar todo”:

Solución de Problemas

Este pequeño articulo de Solución de problemas frecuentes lo he pillado en un libro de Ap-Electronics. Dice así:

Si usando el programador no lee, no programa o genera errores de verificación (error de verificación en 0000H), se puede solucionar el problema en la mayoría de las ocasiones revisando los siguientes puntos:

  • El programador debe utilizarse desde un ordenador con Windows ME – 98 – 95. La familia Windows 2000 no soporta ICPROG.
  • Probar con un sólo elemento a programar o leer, en el zócalo correspondiente, es decir un PIC ó una EEPROM.
  • Probar con un sólo elemento a programar o leer, en el zócalo correspondiente, es decir un PIC ó una EEPROM.
  • Comprobar que la PIC y la EEPROM son los correctos, y han sido insertados con su muesca coincidiendo con la muesca del zócalo de programación, y que a su vez coincide con el PIN 1 en la serigrafía de la placa, marcado con un 1.
  • Comprobar que la PIC o la EEPROM se encuentra completamente insertado en su zócalo.
  • Comprobar que ha sido seleccionado en el menú el elemento que está programando en ese momento, es decir si se procede a programar un PIC16F876, el elemento seleccionado deberá ser el PIC16F876. En los anteriores pasos hemos indicado como seleccionarlo.
  • Comprobar que el menú Ajustes/Tipo Hardware (F3) se encuentra bien configurado.
  • La PIC y la EEPROM necesitan ser programados despacio, si su puerto está configurado a mucha velocidad esto puede originar fallos en la programación y verificación del mismo. Para reducir la velocidad de su puerto siga la siguiente secuencia de comandos con el ratón: Mi PC – Panel de control – Sistema – Administrador de dispositivos – Puertos COM y LPT – Puertos de comunicación COM1 ó COM2 – Configuración del puerto.

    El puerto puerto debe estar configurado de la siguiente manera:

    Bits por segundo: 9600 (ó menos en caso de errores)
    Bits de datos: 8 Paridad:
    Ninguna Bits de paridad: 1
    Control de flujo: Xon/Xoff

  • Al programar la PIC o la EEPROM, comprobar que el programa cargado y que se pretende programar en el integrado, tiene la extensión correcta, siendo generalmente *.HEX o *.BIN. Comprobar que el programa a programar en la PIC es el correcto y es el correspondiente al mismo, si intenta programar un programa de mayor tamaño a la capacidad del PIC, se producirá un mensaje de error.
  • Probar a utilizar en otro ordenador, ya que los programadores que se alimentan del puerto serie, son muy sensibles a la tensión que reciben desde el mismo y no todos los ordenadores son capaces de mantener la misma tensión durante el proceso de grabación.

Saludos!!!

2 Comentarios | deja el tuyo

Nov, 25 2006 - 5:57 pm

Revista Essential Libre – Edición 4

Contenido:

  • Llevando la belleza al escritorio GNU/Linux
  • Entornos de escritorio 3D
  • Pyragua, Un editor colombiano para Python
  • Drupal; Casos de éxito, com unidad, diseño y estandares
  • Estilo libre y propietario, con aumento; El diablo, la manzana y el desconocido
  • El proyecto Maxima
  • Desde el sur… Entre mates y pingüinos Argentina y el Software Libre
  • Tips y curiosidades: Pyslide para principiantes
  • Humor Tiras cómicas
  • Informe especial: IV Foro Mundial de Conocimiento Libre

Versión en PDF

Sin comentarios | deja el tuyo

Nov, 21 2006 - 2:43 pm

Introducción a microcontroladores PIC [simulando nuestro programas en ASM y C]

EL PRIMER CONTACTO CON EL PIC16X84

De antemano disculpas por cualquier fallo en este escrito, ya que no es hecho por un “electrónico”, sino por un aficionado que pretende ser algún día un programador. Y a todas estas, lo bonito del los microcontroladores no está (para mi) en el hardware sino en la programación.

Los temas a tratar son los siguientes:

    •Introducción al PIC16X84 (Pequeño, pobre, pero resultón)
    •Variantes del PIC16X8X
    •Diferencias entre el PIC16C84 con lo demás modelos PIC16X8X
    •La frecuencia de funcionamiento, el reloj
    •¿Para qué y cómo programar PIC’s?
    •Primer ejemplo… Aprendiendo a Sumar (ASM)
    •Ejecutar nuestro programa (simulando con el Simupic’84)
    • ASM vs. C/C++; Eficiencia vs. Comodidad

Importante: es recomendado que la gente que esté interesada en la parte de electrónica revise todos los puntos… los que solo se interesan en la programación (que es en ASM y C), se pueden saltar a la parte de ¿Para qué y cómo programar PIC’s?

Bueno… he aquí mi granito de arena. Considerando que mucha gente no conoce o quisiera conocer acerca de los microcontroladores, me veo en la obligación de aportar un poco acerca de, en mi opinión, el microcontrolador más fácil de manejar y programar (la familia PIC16X84, es decir PIC16C84 y PIC16F84).
Mucha gente, me incluyo, cuando está comenzando en este mundillo ve a los microcontroladores y a la programación en ASM como algo raro y de otro mundo… cuando en verdad es algo realmente sencillo. Así que si estás interesado en aprender un poco de “electrónica” o “Programación en ASM” esto te puede ayudar a aclarar muchas dudas.

Menos charla, más acción:

Pequeño, pobre, pero resultón
Este “maravilloso” PIC pertenece a la familia de la gama media y dentro de ella es uno de los más pequeños; solo tiene 18 patitas. Además es el que dispone de menos recursos.

El resto de sus parientes tiene conversores AD y DA, comparadores analógicos, tensión interna de referencia, más líneas de E/S, más capacidad en sus memorias, varios temporizadores y un largo etcétera de dispositivos de los que el PIC16X84 carece.

Es “pobre” de mantenimiento… pero he escogido este PIC, en sus dos versiones C y F, porque cumple con los requisitos esenciales para enseñar a manejar los microcontroladores y para comenzar para diseñar proyectos. Es práctico, es sencillo y es económico, pudiéndolo considerar como el paradigma para su empleo en todos los pequeños proyectos que realizan los aficionados, los estudiantes y los que quieren progresar en sus conocimientos de lo fácil a lo difícil. Además si aprendes a manejar este PIC, migrar hacia los demás es muy sencillo.

La razón exclusiva por la que este PIC es tan “requerido”, es por el tipo de memoria de programa que posee. El PIC16C84 posee una EEPROM de 1K palabras de 14 bits cada una. El PIC16F84 tiene la misma capacidad de memoria de instrucciones pero de tipo Flash. Ambos poseen una capacidad de 64 bytes EEPROM como memoria de datos auxiliar y opcional.

La memoria EEPROM y la Flash son eléctricamente grabables y borrables, lo que permite escribir y borrar el programa bajo prueba manteniendo el microcontrolador bajo el mismo dispositivo grabar y borrar. Esta característica supone una gran ventaja con la mayoría de los microcontroladores, que tienen como memoria de programa reescribible una tipo EPROM. Se graban eléctricamente, pero para borrarlas hay que exponerlas cierto tiempo a rayos ultravioleta, lo que implica tener que sacar el chip del zócalo para poderlo borrar.

Microchip ha introducido la memoria Flash porque tiene mayores posibilidades de aumentar su capacidad con relación a la EEPROM. Pero sin embargo la EEPROM soporta 1.000.000 ciclos de escritura/borrado frente a los 1.000 de la Flash.

Otra de las grandes ventajas del PIC16X84 (en cuanto a escritura, borrado y reescritura) es su sistema de grabación de datos, que se realiza en serie. Para escribir un programa en la memoria se manda la información en serie usando solo dos patitas: la RB6 para la señal de reloj y la RB7 para los bits de datos de serie. Bueno, no os asustéis con eso de los RB6 y RB7 que más adelante os lo explico.

A continuación la “Tarjeta de presentación de los PIC16X84” con sus datos personales más significativos:

Cita de: Ficha técnica de los PIC16X84
Memoria de programa: 1Kx14, EEPROM (PIC16C84) y Flash (PIC16F84)
Memoria de datos RAM: 36 bytes (PIC16C84) y 68 bytes (PIC16F84)
Memoria de datos EEPROM: 64 bytes para todos lo modelos
Pila (stack): De 8 Niveles
Interrupciones: 4 tipos diferentes
Encapsulado: Plástico DIP de 18 patitas
Frecuencia de trabajo: 10MHz máxima
Temporizadores: Sólo uno, el TMR0. También tienen “Perro guardián (WDT)”
Líneas de E/S Digitales: 13 (5 Puerta A y 8 Puesta B)
Corriente máxima absorbida: 80mA Puerta A y 150mA Puerta B
Corriente máxima suministrada: 50mA Puerta A y 100mA Puerta B
Corriente máxima absorbida por línea: 25mA
Corriente máxima suministrada por línea: 20mA
Voltaje de alimentación (VDD): De 2 a 6 V DC
Voltaje de grabación (VPP): De 12 a 14 V DC

Variantes del PIC16X8X
Se comercializan varios chips correspondientes a la familia de los PIC16X8X, que atienden diversas características.

    1. Frecuencia máxima de funcionamiento
    2. Tipo de oscilador externo usado para generar la frecuencia de reloj.
    3. Margen de voltaje de alimentación

Los modelos que tienen de intermedio la referencia C, F o CR admiten el rango de alimentación de voltaje estándar, que es el que oscila de 4 a 4,5 V DC como mínimo, hasta 5,5 a 6 V DC como máximo. Los modelos con las letras LC, LF o LCR intermedias admiten el rango de voltaje “extendido”, que abarca desde los 2 V hasta los 6 V DC.

La buena aceptación del PIC16C84 ha animado al fabricante Microchip a comercializar nuevas versiones. Ha diseñado cuatro nuevos modelos:

    •PIC16F84
    •PIC16CR84
    •PIC16F83
    •PIC16CR83

Dos de ellos intercalan la letra F indicando así que la memoria EEPROM se ha sustituido por otra de tipo Flash. Los otros modelos la sustituyen por memoria ROM con máscara, pero todos ellos mantienen los 64 bytes de EEPROM para datos.

Diferencias entre el PIC16C84 con lo demás modelos PIC16X8X

    1. La memoria de programa es de tipo Flash en los PIC16F8X y de tipo ROM en los PIC16CR8X
    2. El PIC16F84 y el PIC16CR84 tienen mayor capacidad de la RAM de datos. Disponen de 68 bytes en lugar de los 36 del PIC16C84.
    3. Se ha invertido la polaridad del bit de control PWRTE, que activa y desactiva un temporizador encargado de retrasar el funcionamiento del PIC al aplicarle la alimentación.
    4. Se ha incorporado un filtro a la entrada de la patita MCLR#, por lo que se requiere un pulso de mayor duración para generar el Reset.
    5. Se han mejorado muchas especificaciones eléctricas en los modelos F y CR.

El aspecto externo
Este PIC está desarrollado con tecnología CMOS de altas prestaciones y encapsulado en plástico con 18 patitas. Ok, ahora comento brevemente la misión de cada patita.

VDD: Patita por la que se aplica la tensión positiva de la alimentación.
VSS: Patita conectada a la tierra o negativo de la alimentación.
OSC1/CLKIN: Patita por la que se aplica la entrada del circuito oscilador externo que proporciona la frecuencia de trabajo del microcontrolador.
OSC2/CLKOUT: Patita auxiliar del circuito oscilador.
MCLR#: Esta patita es activa con nivel lógico bajo, lo que se representa con el símbolo #. En pocas palabras con esta reseteas el PIC.
RA0-RA4: Son las líneas de E/S digitales correspondientes a la puerta A. La línea RA4
RB0-RB7: estas 8 patitas corresponden a las 8 líneas de E/S digitales de la puerta B. La línea RB0 multiplexa otra función, que es la de servir como entrada a otra petición externa de interrupción, por eso se le denomina RB0/INT.

   

Los PIC16X8X tienen un encapsulado de 18 patitas, dos de ellas soportan la tensión de alimentación, otras dos reciben la señal de oscilador externo y otra se utiliza para generar un Reset. Las 13 patitas restantes funcionan como líneas de E/S para controlar las aplicaciones.

La frecuencia de funcionamiento, el reloj
La frecuencia de trabajo del microcontrolador es sumamente importante para establecer la velocidad en el proceso de instrucciones y el consumo de energía.

¿Qué coños significa esto?… bien, paso a explicar. Por ej., cuando un PIC16X8X funciona a 10 MHz le corresponde un ciclo de instrucción de 400 ns… ¿por qué? Pues porque cada instrucción tarda en ejecutarse cuatro periodos de reloj, o sea, 4×100 ns. Ahhh se me olvidaba: cada instrucción se ejecuta en un ciclo, menos las de salto que se demoran el doble.

Bueno muy bonito todo pero… ¿para qué y cómo programo microcontroladores?

Muchas veces cuando nos metemos en el mundillo de la programación, nos preguntamos si los resultados de nuestra programación podrían ser más palpables, y a veces (por lo menos yo) ni nos imaginamos que podemos crear software que manipule Chips directamente.

El para qué programar microcontroladores es muy sencillo. Por ejemplo, hoy en día, casi todos los aparatos funcionan con microcontroladores. Desde las puertas automáticas de un súper mercado, pasando por los controles de computadores, hasta la lavadora de mamá. Esto nos da a entender, a grosso modo, que el mercado de los microcontroladores es muy amplio y por ende apetecido; lo que se vuelve en una tentativa para comenzar conocer y manejar estos maravillosos dispositivos.

Para el cómo he aquí una breve explicación de cómo se modela software para microcontroladores, los pasos a seguir son más o menos los siguientes:

    • Crear el algoritmo
    • Codificar
    • Compilar
    • Ejecutar y Depurar
    • Grabar
    • Montar

Más o menos la explicación sería: diceñamos el algoritmo del programa que deseemos crear. En lo personal no me gustan los tales diagramas de flujo ni ninguna coñada de esas, si acaso el pseudo-código y listo.

Codificar (o codear como dicen algunos) es la parte que más me gusta, y consiste en crear el código fuente del programa con el Block de Notas, el Edit, el Vim, el Emacs o cualquier editor de texto plano. Este archivo lo deberéis guardar con la extensión .ASM, ya te estaréis imaginando que la programación será en Assembler ¿no?

Es muy común que uno oiga hablar del famoso Assembler… que ASM esto, que ASM lo otro, que ASM es difícil, que ahora es fácil, etc. Pero la verdad no le vemos mucho sentido utilizar este lenguaje (de bajo nivel) para programar (si acaso si nos interesamos un poco por él cuando sentimos curiosidad por el mundo del Cracking), ya que para eso está el C++, Java y los demás. Pues bien, llegó la hora de tratar de aprender un poco de este, y que deje de ser un bicho raro. Para ello desarrollaremos unos ejercicios, pero más adelante, ahora sigo explicando el modelado de software.

La fase de compilación es muy similar a la que hay en lenguajes como C o Java, y consiste pasar el código por un “compilador” (en mi caso MPASM) que determinará si existen errores de sintaxis, y de lo contrario crea un archivo .HEX (es como cuando se crean .exe a partir de un código en C). La extensión es .HEX porque lo que hace es pasar el código a instrucciones en Hexadecimal (no exactamente, pero quedaros con ello mientras tanto).

Bueno, después necesitamos verificar si en realidad nuestro software funciona. Pero NO resultaría muy viable pasar el software directamente a un Microcontrolador sin haberlo probado, por ello se han inventado los famosos “simuladores”. Como os podréis imaginar lo que hacen estos programas es simular la ejecución del programa en el chip, para poder depurar los posibles errores de lógica. Para que vayas averiguando uno de los mejores simuladores es el Simupic.

El proceso de grabación se hace a través de una quemadora de PIC’s (en Colombia se le dice quemadora, en otros lados le dicen grabadora, tostadora y que se yo), que es un hardware que se conecta a un puerto serial de vuestra PC, y en donde se “incrusta” el microcontrolador a “quemar”.

El proceso de grabación se lleva a cabo, obviamente, a través de un software especial. En mi caso utilizo de ICProg… más adelante tal vez explique su uso.

El montaje es en sí el proceso en el que colocamos nuestro chip en el circuito final, o en una protoboard de ensayos. Esto obviamente para que cumpla con las acciones que hemos programado.

Primer ejemplo… Aprendiendo a Sumar
Bueno, antes de codear tenemos que aprendernos algunos conceptos… no os desesperéis. Todos los computadores saben sumar y nuestro PIC16X84 también. Bueno, el caso es que solo saben sumar en binario, porque son máquinas electrónicas digitales. El sumador del PIC es capaz de sumar dos datos de 8 bits cada uno. Dicho sumador tiene un registro, llamado W (de trabajo), en donde aloja uno de los dos sumandos. El otro sumando debemos decir lo que vale o en que posición de memoria está.

Antes de poner el enunciado del problema, miraremos las instrucciones que vamos a usar:

Instrucción mov
Esta instrucción es típica en todos los procesadores y su misión es transferir el contenido de un registro “fuente” (f) a un “destino” (d). En los microcontroladores PIC todos los datos residen en posiciones de memoria de datos y sólo el registro de trabajo W se salva de esta regla. Esto significa que mov puede mover tres tipos de operandos fundamentales:

    1. El contenido del registro W
    2. El contenido de una posición de la memoria de datos o registro.
    3. Un literal o valor inmediato que se incluye en el código máquina de la propia instrucción.

Para gestionar los posibles operandos existen tres variantes de mov:

movf f,d: Mueve el contenido del operando fuente, que es una posición de la memoria de datos, al destino, que bien puede ser W cuando d=0, o el propio fuente cuando d=1.

movwf f: Mueve el contenido del registro W a la posición de la memoria de datos identificada por f. Realiza la transferencia W->f.

movlw k: Mueve el literal k incluido en el código de la instrucción al registro W, k->W.

Instrucción add

addwf f,d: Suma el contenido del registro W con el de f y deposita el resultado en W si el valor de d=0, mientras que si d=1 lo deposita en f.

addlw k: Suma al contenido del registro W el literal que acompaña a la instrucción y deposita el resultado en W (W+k->W).

Bien, hasta aquí todo bien, pero sé que con aún no os queda claro y la mejor forma de aclarar todo lo que he intentado explicar es con un ejemplo:

Enunciado del problema
El ejercicio debe manejar tres posiciones de memoria de datos. En la dirección 0×0c (recordemos que las posiciones de memoria se manejan con números hexadecimales) se depositará el primer operando; en la 0×0d el segundo y en la 0×0e el resultado de la suma de los primeros operandos. Como valor para el primer operando se va a usar 5 y como segundo operando el 12.

Nota: en muchas fuentes de información se manejan los números hexadecimales de otra forma… por ejemplo es lo mismo si ves: 0×0c, h’0c’, 0c ó 0Ch. Esto nos indica que hay varias formas de representar un numero hexadecimal, pero yo utilizo la forma en la que se antepone 0x porque es la más empleada, a demás de ser la que utiliza lenguajes como C/C++.

Edición del programa
Como ya lo había dicho, para editar un programa se puede usar cualquier editor de texto plano. Entonces creamos un archivo con el siguiente código, y lo guardamos como suma.asm:

LIST P=16C84 ; Indica el modelo de PIC que se usa
; Es una directiva del Ensamblador; Zona para etiquetas
OPERANDO1 EQU 0×0c ; Define la posición del operando 1
OPERANDO2 EQU 0×0d ; Define la posición del operando 2
RESULTADO EQU 0×0e ; Define la posición del resultado

ORG0 ; Comando que indica al Ensamblador
; la dirección de la memoria de
; programa donde se situará la
; siguiente instrucción

movlw 05 ; 5->W (primera instrucción)
movwf OPERANDO1 ; W->operando1
movlw 02 ; 2->W
movwf OPERANDO2 ; W->operando2
movfw OPERANDO1 ; opernado1 -> W
addwf OPERANDO2,0 ; W + operando2 ->W
movwf RESULTADO ; W->resultado

END ; Directiva de fin de programa

A tener en cuenta: el uso de mayúsculas y minúsculas en este fragmento de código obedece a una serie de reglas o normas de estilo, comunes entre los programadores en ensamblador, que aunque no son obligatorias, facilitan la lectura del código fuente. Un resumen de las reglas empleadas es el siguiente:

    • Directivas de compilador en mayúsculas
    • Nombre de variables en mayúsculas
    • Nemónicos en minúsculas
    • Programa bien tabulado

Solo por aclarar: los “punto y coma” ( ; ) después de cada instrucción se utilizan para comentariar el código. Es como el /* de C el # de Perl ó el // de C++ y Java. Finalmente guardamos nuestro archivo con la extensión .ASM y listo.

Bueno todo muy bonito, pero como coños pruebo mi maldito programa ¿ehh? Púes bien para eso tendremos que valernos de un software especial, que nos compile el programa (que lo pase a instrucciones en hexadecimal; .ASM -> .HEX). Recomiendo el MPSIM de Microchip y el SIMUPIC de Microsystems Engineering. Lo que me lleva al siguiente capitulo.

Manejando el Simulador SIMUPIC’84: el primer contacto
El simulador SIMUPIC’84 es una herramienta que trata de facilitar la labor del programador del PIC. Como sabemos para crear un programa en ensamblador tenemos que recurrir a distintos programas; un editor, un ensamblador y un simulador. El SIMUPIC’84 trata de integrar todos en una sola herramienta, y agrega otras herramientas más, que facilitan el proceso de depuración entre otras.

Para los que saben un poco del tema sabrán que este es un programa antiguo, pero es de los más fáciles de manejar por lo que lo he escogido. Lo primero que debemos hacer es bajarlo de Internet, entonces vas al google y lo buscas… ¿cómo, te da pereza? Ok, bájalo de aquí.

Bueno, lo primero es descomprimirlo. Guardas la carpeta donde te quede más cómodo y ejecutas el archivo sim84.exe. Con lo que verás lo siguiente:

Ok, ahora vamos a ver el funcionamiento básico del programa; primero hay que indicarle el nombre del fichero (.asm) con el que vamos a trabajar, esto lo hacemos dándole “enter” a la opción “Asignar Nombre”. Vamos a trabajar con nuestro primer programa (el que hicimos arriba), por lo tanto debemos guardar ese archivo (suma.asm) en la carpeta donde tengamos nuestro simupic.

Paso siguiente vamos a la opción “Llamar al editor”. Esta opción nos permite crear un fichero nuevo (llamando al edit del Windows), o cargar un archivo ya existente (en este caso suma.asm).

Hasta el momento solo hemos editado y cargado el código del programa en el simupic. Ahora debemos ensamblarlo (o compilarlo), por lo que vamos a la opción “Ensamblar”. Es de aclarar que el “ensamblaje” lo hace un programa externo llamado “MPASM”, pero nuestro simupic se encarga de llamarlo y utilizarlo por nosotros. Nos debe aparecer lo siguiente:

En esa consola nos aparecen los posibles errores de sintaxis, y los molestos warnings. De momento solo nos interesa que no tenga errores, por lo que presionamos cualquier tecla para salir de esa ventana, y la siguiente que vemos es el reporte de los Warnings, simplemente salimos del edit.

Recordemos que al ensamblar nuestro código fuente, lo que hacemos es crear un fichero .hex que contienes las instrucciones del fuente en hexadecimal. Por esto debemos cargar el fichero hexadecimal en el PIC (esta parte simula el momento en el que quemamos nuestro programa en un PIC de verdad). Vamos a la opción “Cargar fichero HEX” con lo que nos saldrá el siguiente dialogo:

Fijémonos que al cargar el archivo .hex la parte inferior izquierda cambia:

En esta parte podemos observar línea a línea el comportamiento de nuestro programa, y es de gran utilidad por que nos sirve como depurador.

Ahora vamos a “simular” el programa, para analizar su comportamiento. Para ello vamos a configurar nuestro simulador para que nos muestre el comportamiento de las variables, es decir, qué valores toman al transcurrir el programa. Para ello vamos a la opción “Visualizar Registros” y después “Añadir registros”:

Y después seleccionamos “W (Acumulador)”… recordemos que el registro W (registro de trabajo) es donde almacenamos los datos que necesitemos manipular.

Luego de esto nos aparecerá en la ventana superior derecha, el registro que hemos agregado y el valor que contiene:

Es de aclarar que las variables y registros de nuestro PIC almacenan un byte, es decir 8 bits, por lo que las variables y registros que pongamos en esa parte, constarán de 8 números binarios. Si te estás preguntando qué coños es el tal PCL, explico; el PCL es un “apuntador” que le indica al PIC la posición de memoria donde se encuentra la instrucción (en binario) que se debe efectuar. Esto no es así exactamente pero por ahora nos basta.

Pero en el programa tenemos tres variables (OPERANDO1, OPERANDO2, RESULTADO), que sería importante tener en cuenta para analizar el programa. Para añadirlas a la lista vamos a la opción “Visualizar Registros” y “Añadir registros”, y seleccionamos la opción “Mediante Dir. Hex.”:

Allí debemos indicarle la posición en memoria en donde se encuentra la variable… recordemos el fragmento de código donde inicializamos las variables:

OPERANDO1 EQU 0×0c ; Define la posición del operando 1
OPERANDO2 EQU 0×0d ; Define la posición del operando 2
RESULTADO EQU 0×0e ; Define la posición del resultado

A la variable OPERANDO1 se le asigno la posición 0×0c; a la variable OPERANDO2 se le asigno la posición 0×0d; a la variable RESULTADO se le asigno la posición 0×0e.

Por ello en el cuadro de dialogo que nos pide la dirección de memoria de las variables debemos digitar esas direcciones; pero no todas a la vez, sino “una por una”:

Observemos que no digitamos 0×0c sino 0c, ya que se asume que lo que vamos a digitar es un numero en sistema hexadecimal. Después le damos continuar y asignamos una referencia a esa variable, por ej. Op1:

Repetimos la misma operación con las variables OPERANDO2 y RESULTADO, y nos fijamos que en la parte superior derecha tengamos algo como:

Ahora sí vamos a “simular” nuestro programa, pero primero vamos a la opción “Opciones de simulación” y le damos “Reset en el PIC” (esto no creo tener que explicarlo); Ahora nos vamos a la opción “Trazar” para ver el comportamiento de nuestro programa. Analizamos un poco la primera instrucción a la que apunta PCL:

Esta instrucción equivale a la instrucción movlw 05 de nuestro código fuente. Y le indica al PIC que acumule el valor 5 en el registro de trabajo W. Fijémonos como esto se ve reflejado a nuestra derecha:

En el registro W tenemos 00000101 que es el equivalente de 5 en notación binaria. Ahora cada vez que demos un “enter” el programa va ir avanzando línea por línea (con el apuntador PCL). Ahora, analizaremos qué pasa cada vez que demos enter (cada item equivale a un enter):

    1. En el registro W tenemos 00000101 (5 en decimal); esto equivale a la instrucción movlw 05.
    2. (en el segundo enter) En el registro op1 tenemos 00000101 (5 en decimal), ya que almacenamos lo que tenía W en OPERANDO1 (referenciado por op1); esto equivale a la instrucción movwf OPERANDO1.
    3. En el registro W tenemos 00000010 (2 en decimal); esto equivale a la instrucción movlw 02.
    4. En el registro op2 tenemos 00000010 (2 en decimal), ya que almacenamos lo que tenía W en OPERANDO2 (referenciado por op2); esto equivale a la instrucción movwf OPERANDO2.
    5. En el registro W tenemos 00000101 (5 en decimal), ya que copiamos el contenido de OPERANDO1 a W; esto equivale a la instrucción movfw OPERANDO1.
    6. En el registro W tenemos 00000111 (7 en decimal), ya que sumamos el contenido de OPERANDO2 con W y el resultado lo almacenamos en W; esto equivale a la instrucción addwf OPERANDO2,0.
    7. En el registro res (que referencia la variable RESULTADO) tenemos 00000111 (7 en decimal), ya que le almacenamos lo que tenía W; esto equivale a la instrucción movwf RESULTADO.

Cuando ya hemos ejecutado todas las instrucciones nos aparecerá un mensaje indicándonos que el programa ha finalizado:

ASM vs. C/C++; Eficiencia vs. Comodidad

Parte importante de este tutorial es hacer un paralelo entre la programación en ASM y en C/C++, ya que cualquier programa para un microcontrolador, además de codificarse en ASM, también puede ser codificado en C. Obviamente en C, al ser un lenguaje de “alto nivel”, se dispone de una mayor comodidad a la hora de programar, pero ello conlleva un pequeño sacrificio en cuanto a tiempo de ejecución. Al grano, vamos a hacer el mismo programa que habíamos hecho en un principio (suma.asm) pero ahora en C (suma.c):

/* Programa que suma el contenido de dos variables en memoria y almacena */
/* el resultado en una tercera variable de resultado. Equivalente al */
/* ejercicio 1. */
#include <16c84.h>
void main( void )
{
int operando1 = 5, operando2 = 2, resultado;
resultado = operando1 + operando2;
}

El programa ha sido compilado con el PCM de la casa Custom Computer Services que comercializa Microsystems Engineering y se ha empleado el SIMUPIC’84 para desensamblar su código y traducirlo a ensamblador. El resultado es el siguiente:

00 movlw 00
01 movwf 0×0a
02 goto 05
03 nop
04 nop
05 clrf 0×04
06 clrf 0×03
07 movlw 0×0c
08 movwf 0×0e
09 movlw 0×0d
0A movwf 0×0f
0B movlw 0×0e
0C movwf 0×10
0D movf 0×0e,0
0E movwf 0×04
0F movlw 0×05
10 movwf 0×00
11 movf 0×0f,0
12 movwf 0×04
13 movlw 02
14 movwf 0×00
15 movf 0×00,0
16 movwf 0×11
17 movf 0×0e,0
18 movwf 0×04
19 movf 0×00,0
1A movwf 0×12
1B movf 0×0f,0
1C movwf 0×04
1D movf 0×00,0
1E addwf 0×12,0
1F movwf 0×12
20 movf 0×11,0
21 movwf 0×04
22 movf 0×12,0
23 movf 0×00
24 sleep
25

¡¡¡Demonios, el código resultante está compuesto por 37 instrucciones!!! Esto es casi cuatro veces el programa que habíamos hecho anteriormente en assembler. Esto ya os dará una idea de lo que implica programar en C microcontroladores: tamaño en el programa y por ende tiempo de ejecución.

8 Comentarios | deja el tuyo

« Entradas anteriores