Está en la página 1de 560

PIC 18F2550: Programación con PicBasic

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 1


TUTORIAL: Programación de Microcontroladores
Parte I

Muchos lectores de NeoTeo se han mostrado interesados en la programación de microcontroladores. Desde


hoy tendrán en forma semanal una entrega de este tutorial que les mostrará como hacerlo. ¿Te apuntas?

La electrónica ha evolucionado mucho. Casi todo lo que hasta hace unos años se hacia mediante un grupo (a
veces muy numeroso) de circuitos integrados conectados entre si, hoy se puede realizar utilizando un
microcontrolador y unos pocos componentes adicionales.

De todos los fabricantes de microcontroladores que existen, los más elegidos por los hobbystas suelen ser los
modelos de Microchip, en gran parte debido a la excelente documentación gratuita que proporciona la
empresa para cada modelo.

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 esta 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. El BASIC resulta bastante más simple de aprender.

Antes de comenzar a ver los temas programación en si mismos, debemos aclarar algunos conceptos básicos
sobre los microcontroladores para poder entender lo que hace cada instrucción BASIC. Eso será muy útil
para los que vayan a comenzar a programar a partir de este artículo.

Lo más interesante de trabajar con microcontroladores es que se necesitan conocimientos tanto de electrónica
(hardware) como de programación (software) así que a lo largo de estos tutoriales iremos viendo temas de
ambas disciplinas, ya que íntimamente vinculadas.

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.

En general, por cada cuatro ciclos de reloj del microcontrolador se ejecuta una instrucción ASM (una
instrucción BASIC consta generalmente de mas de una instrucción ASM). Esto significa que un PIC
funcionando a 20MHz puede ejecutar 5 millones de instrucciones por segundo.

Los pines del PIC se dedican casi en su totalidad a los puertos que mencionábamos anteriormente. El resto (2
o mas) son los encargados de proporcionar la alimentación al chip, y a veces, un sistema de RESET. Desde
BASIC es posible saber si un pin esta en “estado alto” (conectado a 5V o a un “1” lógico) o en “estado bajo”
(puesto a 0V o a un “0” lógico”). También se puede poner un pin de un puerto a “1” o “0”. De esta manera, y
mediante un rele, por ejemplo, se puede encender o apagar una luz, motor, maquina, etc.

Uno de los microcontroladores más famosos de todos los tiempos ha sido, sin duda, el 16F84A, que ya es
considerado obsoleto. Un buen reemplazo es el 16F628A, y es el que utilizaremos en la mayoría de los

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 2


ejemplos y proyectos que veamos. La disposición de sus pines es la siguiente:

Como podemos ver, los pines 1, 2, 3, 4, 15, 16, 17 y 18 tienen el nombre de RAx. Esos pines conforman el
puerto A, “PORTA” de ahora en más. Los pines 6 al 13 forman parte del puerto B (“PORTB”). El pin 5 es el
que se conectara al negativo de la fuente de alimentación. El 14 irá conectado a 5V.

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 = Master Clear) y como tensión de programación (Vpp)

No es mala idea descargar desde la web de Microchip la hoja de datos de este microcontrolador (esta en
inglés) para tenerla siempre a mano.

Ahora bien ¿Cómo colocamos el programa dentro del PIC? Para ello necesitamos algunas herramientas. Por
un lado, es necesario un “quemador” de PICs, como el que publicamos en NeoTeo, o alguno de los varios
disponibles comercialmente. Uno que me gusta particularmente es el GTP-USB+, ya que al funcionar
conectado al puerto USB es muy veloz. Además, necesitaremos un software que envíe el programa al PIC.
Para ello usaremos el WinPIC800, que es un excelente soft gratuito.

Y también vamos a necesitar un compilador, para “traducir” nuestro programa en BASIC al ASM que es
capaz de entender el PIC. Después de mirar varios candidatos, en este momento parece una buena elección el
PIC SIMULATOR IDE, que no solo es un excelente compilador de BASIC, si no que además (y por solo 29
euros) ofrece un entorno de simulación de nuestros circuitos. Existe una versión de prueba que se puede bajar
gratuitamente desde aquí.

El GTP USB+, un excelente programador de micros y El WinPic800 enviara el programa al PIC.


memorias.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 3


El PIC SIMULATOR IDE, entorno de programacionPara comenzar, usaremos un PIC 16F628A.
BASIC.
El primer ejemplo que veremos, equivalente al “hola mundo” de cualquier otro entorno de programación,
consiste en encender y apagar continuamente un LED conectado a uno de los pines del micro. Utilizaremos
el circuito siguiente:

Nuestro primer ejemplo.


A diferencia de un programa de ordenador, donde uno escribe el programa, lo compila, lo ejecuta y ya, en el
mundo de los microcontroladores hay que, previamente, definir el tipo de microcontrolador que se va a
utilizar, cual va a ser su frecuencia de clock, como va a ser el circuito en que se va a utilizar el mismo, etc.

En primer lugar, vamos a aprovechar el oscilador interno del 16F628A y nos evitaremos el cristal y
condensadores asociados. El puerto B del micro tiene su pin 9 conectado a un LED mediante una resistencia
de 220ohms, que tienen como función limitar la corriente que circula por el LED. Esta será nuestra "salida".

El circuito debe alimentarse con 5v bien filtrados y regulados. Volviendo a nuestro programa, vamos a
escribir el "hola mundo" de los microcontroladores: encender un LED.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 4


El primer paso es elegir en PIC SIMULATOR IDE, desde el menú "Opciones" -> "Select Microcontroller", el
microcontrolador PIC16F628A. Luego, debemos configurar los bits correspondientes, como se ve en las
figuras de más abajo.

Lo destacable por ahora de esta configuración es que estamos dejando la memoria (FLASH y EEPROM) sin
protección, que el pin RESET se va a comportar como I/O y que usaremos como oscilador el oscilador
interno INTRC.

"Opciones" -> "Select Microcontroller" "Opciones" -> "Configuration Bits"

Una vez hecho esto, arrancamos el editor de BASIC (presionando CTRL-C, por ejemplo), y escribimos el
siguiente código:

AllDigital
TRISA = %11111111
TRISB = %00000000
loop:
PORTB.3 = 1
WaitMs 500
PORTB.3 = 0
WaitMs 500
Goto loop
Vamos a analizarlo línea por línea para entender su funcionamiento:

La línea 1 utiliza la sentencia AllDigital para convertir todos los pines del micro en pines de E/S. Esto
equivale a deshabilitar los comparadores, conversores A/D y todos los módulos que pudiese tener nuestro
microcontrolador. No es la única manera de hacer esto, pero si la mas sencilla.

Las líneas 3 y 4 convierten todos los pines del puerto A en entradas ( TRISA = %11111111 ) y los del
puerto B en salidas ( TRISB = %00000000 ). El "%" indica que el numero que viene a continuación esta
en binario. Se podría haber escrito, por ejemplo TRISB = 0 y hubiera sido lo mismo. Personalmente me gusta
esta manera, ya que "veo" el estado de cada pin. Por supuesto, es valido activar como entrada algunos pines,
y como salidas otros, haciendo algo parecido a TRISB = %11000111.

En la línea 6 encontramos una "etiqueta" ( loop: ). Esta no hace nada, solo sirve como referencia para
enviar el flujo del programa a esa línea desde otro lugar, mediante la sentencia "Goto".

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 5


La línea 7 pone en "1" el pin correspondiente a PORTB.3, de manera que en el pin 9 del microcontrolador
habrá 5V. Esta tensión hará que circule una corriente a través de la resistencia limitadora y el LED1, haciendo
que este se encienda, ya que el cátodo se encuentra conectado a 0V.

En 8 tenemos la sentencia WaitMs 500. WaitMs se encarga de hacer una pausa en milisegundos. La
duración de la pausa esta dada por el número que sigue a la instrucción, en este caso 500 milisegundos, o
medio segundo.

Luego, en 9, otra vez se vuelve a poner en 0 el pin 9, mediante PORTB.3 = 0 , lo que provoca que ese pin
se ponga a 0V, y no haya mas circulación de corriente a través de la resistencia y del LED, con lo que este se
apaga.

En la línea 10 se hace nuevamente una pausa de medio segundo, y por ultimo, la línea Goto Loop hace que
el programa continúe en la línea 6 (que es donde esta la etiqueta Loop).

El programa se repite indefinidamente, encendiendo el LED medio segundo, apagándolo otro medio
segundo.

Con esto, terminamos la primera entrega de este tutorial. Solamente hemos arañado la superficie de un
mundo apasionante. No te pierdas la segunda entrega la próxima semana.

Proyecto con un microcontrolador.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 6


Parte II

En la entrega anterior de este tutorial vimos como construir un programa que, una vez cargado en el
microcontrolador, hacia que un LED conectado a un pin del PORTB encendiese y apagase con una frecuencia
de 500 milisegundos. Hoy aprovecharemos ese mismo ejemplo para ver como compilar el programa BASIC
y como utilizar el WinPIC800 para enviarlo al microcontrolador.

Una vez que hemos escrito el programa en la ventana “BASIC Compiler” del PIC SIMULATOR IDE,
debemos compilarlo. Este proceso se encarga de transformar el código que hemos escrito (un fichero
“.BAS”) en un lenguaje muy parecido al ingles a una serie de bytes que hace lo mismo pero en un idioma
comprensible por el microcontrolador. Este nuevo fichero tendrá como extensión “.HEX”.

Para compilar, simplemente utilizamos la opción “Tools” --> “Compile & Assemble” (F8). Si además
queremos que el fichero resultante se cargue en el simulador para poder estudiarlo sin necesidad de grabarlo
en un PIC real, usamos la opción siguiente: “Tools” --> “Compile & Assemble & Load” (F9). En entregas
posteriores del tutorial veremos como simular nuestros programas.

Si no hemos cometido errores de sintaxis, el compilador creará el fichero .HEX y nos mostrará el mensaje de
la figura 2:

Figura 1: el programa en la ventana “BASIC Figura 2: el compilador creará el .HEX y nos mostrará
Compiler” este mensaje.
Este mensaje es muy importante, así que explicaremos línea a línea su contenido. La primera línea solamente
nos informa que la compilación tuvo éxito.

La segunda nos dice que tamaño tiene el fichero generado, medido en cantidad de “palabras” (words). En el
caso de los PICs de la serie 16F cada palabra tiene 14 bits de largo.

En el tercer renglón tenemos el tamaño total de la memoria del PIC que estemos utilizando también
expresado en “words”. Esta información, junto con la de la línea anterior, es útil durante el desarrollo de un
programa ya que nos da una idea de cuanto espacio nos queda disponible para nuestro programa.

La cuarta linea nos informa de la carpeta en donde se guardo el archivo .ASM y el nombre que tiene, que es
el mismo que el del fichero .BAS pero con diferente extensión. Este fichero es un “paso intermedio” que
realiza el compilador, pasando nuestro programa BASIC a ASM, antes de crear el HEX. Los más curiosos

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 7


pueden utilizar el contenido del fichero ASM para aprender algo sobre la programación en ese lenguaje.
En quinto lugar tenemos la carpeta y nombre del fichero LST generado.

La sexta línea nos informa de la ubicación del fichero HEX. Es importante tomar nota de su nombre y
ubicación, ya que es el que deberemos abrir desde WinPIC800 para enviarlo al PIC. La carpeta en que esta
este fichero es la misma en la que estaba guardado el fichero .BAS que escribimos en primer lugar.

Ya estamos listos para el segundo paso: utilizar WinPIC800 para enviar el programa al microcontrolador.
Vamos a asumir que tanto este programa como el driver del GTP-USB+ (o el programador que vayamos a
utilizar) están correctamente instalados, y que el programador esta conectado y listo para funcionar.

Lo primero es asegurarnos de que el WinPIC800 este correctamente configurado. Para ello dispone en el
menú principal de la opción “Configuración”. En “Hardware” nos aseguraremos que el programador elegido
sea el nuestro (figura 3). En “Software” hay una serie de solapas y opciones (figura 4) que básicamente
configuran los mensajes que recibiremos (o no) al utilizar el programa. En general, las opciones por defecto
funcionarán correctamente para todos.

Figura 3: Seleccionamos nuestro programador. Figura 4: las opciones por defecto funcionarán
correctamente para todos.
La figura 5 ilustra el paso siguiente: desde las listas que están a la derecha de la ventana principal del
WinPIC800 seleccionamos la familia y modelo del microcontrolador que vamos a utilizar. Este debe
coincidir con el que seleccionamos en el PIC SIMULATOR IDE, ya que el programa que se generó está
especialmente concebido para ese modelo en particular. Como familia seleccionamos “PIC 16F” y como
modelo “16F628A”.

Una vez que hemos hecho esto, WinPIC800 “sabe” como deberá enviar los datos al programador. Otro punto
a tener en cuenta en esta etapa del proceso es la posición que debe ocupar el PIC en el zócalo ZIF del
programador. Si tenemos dudas, podemos utilizar la ayuda incorporada en el programa, mediante la opción
marcada con un círculo rojo en la figura 6. Luego, debemos ir al menú “Archivo” --> “Abrir” y cargar el
fichero HEX que generamos con el PIC SIMULATOR IDE.

El led bicolor del GTP-USB+ estará en verde si todo esta correctamente instalado, por lo que podemos
proceder a enviar el fichero. Para ello, presionamos el icono “Grabar Todo” que se ve en la figura 7, y en un
par de segundos tenemos nuestro PIC grabado. El mensaje que veremos será el de la figura 8.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 8


Figura 5: seleccionamos la familia y modelo del Figura 6: Posición del PIC en el zócalo ZIF.
microcontrolador.

Figura 7: el icono “Grabar Todo”. Figura 8: ya tenemos nuestro PIC grabado.

Para probar que todo funciona, tenemos que armar el circuito y alimentarlo con 5V de corriente continua.
Veremos (si todo esta bien) el LED encendiendo y apagando cada medio segundo. Esto es así por que la
corriente que circula por el proviene del pin 9 del PIC (a través de la resistencia de 220 ohms), y cada vez
que el pin se pone en estado bajo deja de circular por el, apagándolo.

Seguramente la parte mas compleja y que mas tiempo nos ha llevado en esta practica es la de armar el
circuito. El programa se escribe fácilmente, y si hay errores, se puede corregir sin complicaciones. La etapa
de generación del fichero HEX y la grabación del mismo en el microcontrolador también es muy simple.
Seria muy bueno podernos evitar el trabajo de tener que armar un circuito físico diferente cada vez que
realizamos una práctica, ya que a lo largo de este tutorial realizamos muchas.

La solución a este problema viene de la mano de las denominadas “placas entrenadoras”. Estas placas tienen,
por lo general, un zócalo para colocar el microcontrolador, y proveen una serie de “periféricos” listos para
usar, tales como pulsadores, LEDs, pantallas LCD, algún buzzer, reles, salidas RS-232, USB y casi todo lo
que podamos imaginar. Por lo general, su precio aumenta junto con sus prestaciones, y su valor comienza en
unos 30 o 40 euros para las simples, hasta varios cientos por las más completas. Por supuesto, se trata de una
buena inversión por que nos ahora tiempo y dinero empleado en crear prototipos cada vez.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 9


Afortunadamente, los lectores de NeoTeo pueden armar su propia placa entrenadora. De hecho, hemos
publicado dos: una para PICs de 18 pines, y otra para los más grandes, de 40 pines. Estas placas son muy
básicas, solo tienen el PIC y 3 o 4 pulsadores y LEDs. Pero tienen un par de ventajas importantes: su costo es
muy bajo, y son totalmente ampliables mediante módulos, por lo que podemos ir construyéndolos a medida
que los necesitamos, y nos quedan para las prácticas siguientes.

Las prácticas de los capítulos siguientes estarán pensadas como para ser realizadas sobre estas placas
entrenadoras, para ahorrar tiempo. Por supuesto, como también brindaremos el circuito eléctrico en cada
caso, no habrá problemas si quieren seguir trabajando como hasta ahora.

A continuación, y para terminar por hoy, les muestro como modificar el ejemplo de la entrega anterior para
que funcione sobre la placa entrenadora de 18 pines. La única cosa que hay que cambiar es el pin utilizado
para conectar el LED. En el ejemplo original usamos un pin del PORTB, pero en la placa entrenadora (si no
tenemos ningún modulo adicional de E/S) solo tenemos LEDs conectados a los pines 4, 5, 6 y 7 del PORTA.
Así que el programa debería utilizar alguno de ellos. Supongamos que nos decidimos por usar el pin 7 del
PORTA (de ahora en más, PORTA.7. El programa modificado quedaría así:

AllDigital
TRISA = %01111111
TRISB = %00000000
loop:
PORTA.7 = 1
WaitMs 500
PORTA.7 = 0
WaitMs 500
Goto loop

Los cambios efectuados también incluyen la línea 3 (TRISA = %01111111) ya que tenemos que indicar
que el PORTA.7 se utilizara como salida. La figura 10 muestra como tenemos que configurar la sección
“Options” -->“Configuration Bits” para que el microcontrolador funcione correctamente en la placa
entrenadora. Lo mas importante es que le estamos indicando que no usaremos cristal para el oscilador, y que
esos dos pines (PORTA.6 y PORTA.7) estarán disponibles como entrada/salida.

La figura 11 muestra el trainer funcionado, con el LED rojo que indica que esta alimentado, y el verde
encendido. El círculo rojo indica la posición que tiene que tener el jumper en PORTA.7 para que se comporte
como salida. Si tienen alguna duda sobre el entrenador, pueden releer el artículo correspondiente.
Con esto damos por terminada la segunda entrega. Les recuerdo que en los foros pueden plantear sus dudas.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 10


Figura 9: El entrenador para PICs de 18 pines. Figura 10: "Configuration bits" en PIC SIMULATOR
IDE.

Figura 11: el trainer funcionado.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 11


Parte III

Como aprendimos, los pines de los puestos del PIC pueden emplearse como salidas (como en el ejemplo del
LED) o como entradas. Cuando mediante la instrucción TRIS indicamos al microcontrolador que un pin
determinado se comportara como entrada, este colocara en el bit correspondiente de la dirección del puerto
en cuestión un “1” si el pin esta en estado alto (por ejemplo, conectado a +5V) o un “0” si se encuentra en
estado bajo (conectado a masa o 0V).

Sabemos PIC BASIC tiene variables definidas para cada puerto (PORTA, PORTB, etc.) por lo que es muy
simple poder interpretar el estado de las entradas.

Antes de ver como emplear un pulsador como entrada, vamos en profundidad como se emplean las variables,
tema que resulta indispensable para poder escribir (e interpretar) programas que funcionen.

La programación seria prácticamente imposible sin el uso de variables, ya que solo podríamos escribir
programas “rígidos”, que no modificaran su comportamiento. Pero ¿Qué es una variable?.

Es sencillo: podemos imaginar las variables como “cajas” en la que podemos guardar algo. Supongamos que
disponemos de muchas de esas cajas, que en su frente tienen pegada una etiqueta con su nombre. Estas cajas
tienen ciertas particularidades, losque hace que solo se puedan guardar en ellas determinados tipos de
objetos.

En esta analogía, cada caja es una variable, su contenido es el valor que adopta, y la etiqueta es el nombre de
la variable. Como su nombre nos deja adivinar, el contenido de una variable puede ser modificado a lo largo
del programa.

En BASIC tenemos distintos tipos de variable, dedicadas a guardar distintos tipos de datos:

- Bit (un bit de longitud, almacena 0 o 1 únicamente)- Byte (un byte de longitud, almacena números enteros
entre 0 y 255)
- Word (dos bytes de longitud, almacena números enteros entre 0 y 65,535)
- Long (cuatro dos bytes de longitud, almacena números enteros entre 0 y 4,294,967,295)

(El tipo "Long" solo esta disponible mediante un modulo opcional al PIC SIMULATOR IDE).

A diferencia de otros BASIC, la declaración de variables puede ser hecha en cualquier parte del programa, y
todas son consideradas globales, es decir, su valor es accesible desde todas las subrutinas y zonas del
programa. Algunos puristas pueden considerar esto como una falencia del lenguaje, pero en general se puede
sacar bastante provecho de esta situación, como veremos a lo largo de esta serie de tutoriales.

El numero de variables esta lógicamente limitado al monto de memoria RAM disponible en cada
microcontrolador. Las variables deben ser declaras utilizando la instrucción DIM, como se muestra en los
siguientes ejemplos:
DIM A AS BIT
DIM TEMPERATURA AS BYTE

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 12


DIM TIEMPO AS WORD
DIM AUX AS LONG

También es posible utilizar vectores, que son una matriz de dimensiones 1xN. Por ejemplo, la sentencia
siguiente:

DIM DIAS(7) AS BYTE

declara un vector (al que nos referiremos algunas veces como "array") de siete elementos del tipo BYTE, que
serán accedidos mediante el uso de subíndice (entre paréntesis) del 0 al 6.

LA sentencia RESERVE le permite al programador reservar un número de posiciones de la RAM para su uso
en rutinas en assembler o para el In-Circuit Debugger de MPLAB. Simplemente, si queremos reservar 20
bytes de RAM, escribimos:

RESERVE 20

Las variables tipo Word, como vimos, están compuestas por dos bytes. El primero de ellos es llamado byte
"alto" y el otro "bajo", dado que el primero contiene los 8 bits mas significativos. En BASIC podemos
acceder individualmente a cada uno de los bytes que componen un Word mediante las extensiones ".HB"
(High byte, o byte alto) y ".LB" (Low Byte o byte bajo). Veamos un ejemplo:

DIM A AS BYTE
DIM B AS WORD
A = B.HB
A = B.LB 'Esto es lo mismo que A = B
B.HB = A
B.LB = A
B = A 'Esto también borra el byte alto de la variable B

Los bits individuales de cada variable pueden ser accedidos uno a uno también, simplemente poniendo como
extensión ".n" donde "n" es el numero de bit (1,2, 3, etc.)

DIM A AS BYTE
DIM B AS BIT
B = A.1
B = A.7
A.0 = A.5

Todos los registros del microcontrolador esta disponibles para usar en los programas BASIC, como si se
tratase de variables del tipo BYTE con el nombre del registro utilizado en las datasheet (PORTA, PORTB,
TRISA, etc.). Por supuesto, se puede acceder a bits individuales de los registros con la técnica vista párrafos
atrás. Algunos ejemplos:

TRISA.1 = 0
TRISB = 0
PORTA.1 = 1
PORTB = 255

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 13


STATUS.RP0 = 1
INTCON.INTF = 0

Existe una "forma corta" de acceder a los bits individuales de cada port, simplemente usando las variables
BASIC tipo byte RA, RB, RC, RD, RE o bien las tipo bit RA0, RA1, RA2,..., RE6, RE7

RA = 0xFF
RB0 = 1

En BASIC también podemos usar punteros. En realidad, cualquier variable definida como tipo BYTE o
WORD pude ser usada como un putero de memoria, usándola como argumento de la función POINTER. El
valor contenido por la variable debe tener un valor comprendido entre 0 y 511. a continuación, algunos
ejemplos:

DIM X AS WORD
DIM Y AS BYTE
X = 0x3F
Y = POINTER(X)
Y = Y + 0x55
X=X–1
POINTER(X) = Y
Y = 0xAA
X=X–1

POINTER(X) = Y

Una forma de escribir programas que nos resulten más fáciles de entender es el uso de nombres simbólicos, o
SYMBOL. Un "symbol" es una cadena que contiene código, asignado a un nombre. Al momento de
compilar, PIC BASIC hace la "búsqueda y reemplazo" de nuestros símbolos y luego genera el código ASM y
el HEX. Supongamos que tenemos un LED conectado al bit cero del puerto B. Mediante SYMBOL podemos
hacer:

SYMBOL LED1 = PORTB.0


SYMBOL ENCENDIDO = 1

Luego, si queremos encender el LED, en lugar de

PORTB.0 = 1

podemos hacer

LED1 = ENCENDIDO

que es mucho mas claro y fácil de leer.


Las constantes (valores que usamos en nuestro programa, y que, por ejemplo, asignamos a las variables)
pueden ser escritas en decimal (directamente el valor), en hexadecimal (anteponiendo "0x" o posponiendo
"H" al valor) o en binario (anteponiendo "%" al valor). Por ejemplo:

DIM A AS BIT

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 14


DIM B AS BYTE
A = TRUE
B = 0x55
B = %01010101

Por supuesto, se pueden asignar nombres a las constantes, usando la instrucción


CONST:

DIM A AS WORD
CONST PI = 314
A = PI

Hay tres instrucciones para el manejo individual de bits, que si bien no hacen nada que no se puede resolver
con otras instrucciones o símbolos, ayudan mucho en la lectura del código. Se tratan de HIGH, LOW y
TOGGLE, que ponen el bit en alto, bajo o lo invierten, respectivamente.
Importante: Si el bit implicado como argumento de una de estas instrucciones es un bit de un PORT, el
mismo bit en el TRIS correspondiente es puesto en cero, y dicho pin queda configurado como salida.
Algunos ejemplos:

HIGH PORTB.0
LOW ADCON0.ADON
TOGGLE OPTION_REG.INTEDG

Seguimos utilizando el PIC TRAINER para las practicas.


Con todo lo visto en mente, vamos a ver como hacer para leer el estado de un pulsador. Deberemos ver
primero como conectarlo al PIC. En el esquema (figura 1) que hay mas abajo puede verse como conectarlo.
Veamos como funciona eléctricamente: Cuando el pulsador esta abierto, el pin del PIC esta puesto a tierra
(masa, o 0V) a través de la resistencia de 10K (figura 2) que llamamos R1, por lo que el bit correspondiente a
ese pin (por ejemplo, PORTA.7) se pondrá en “0”.

Cuando presionamos el pulsador, la corriente circulará como se ve en la figura 3, pasando por el pulsador y
entrando al PIC por el pin en cuestión. El bit correspondiente se pondrá en “1”. Antes que me olvide, una
parte de la corriente casi despreciable ira también a masa a través de R1, pero a fines prácticos no lo tenemos
en cuenta. La función de esa resistencia es que no se produzca un cortocircuito entre +V y masa cuando
presionamos el pulsador.

Hay un tema a tener muy en cuenta, y lo haremos en la quinta o sexta entrega, que es el denominado “rebote”
que se produce en los contactos del pulsador. Por ahora despreciaremos ese efecto.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 15


Figura 1 Figura 2

Figura 3
¿Cómo debería ser el programa que pueda “leer” el estado del pulsador conectado al bit 7 del PORTA? Así:

AllDigital

TRISA.7 = 1 'Defino PORTA.7 como ENTRADA


TRISA.6 = 0 'Defino PORTA.6 como SALIDA
Symbol pulsador = PORTA.7
Symbol led = PORTA.6
loop:
led = pulsador
Goto loop

Analicemos el programa: ALLDIGITAL indica al compilador que se deben emplear todos los pines del
PORTA como E/S. Las dos líneas siguientes usan la función TRIS para definir el pin 7 del PORTA como
ENTRADA (poniendo ese bit en “1”) y el pin 6 del mismo puerto como SALIDA.

Las líneas SYMBOL declaran dos nombres simbólicos para que el programa quede mas claro. Es obvio que
esto tiene más utilidad en programas extensos, pero es bueno ir acostumbrarnos a usarlo siempre.

El resto del programa conforma un bucle que se repite eternamente, ejecutando la única línea existente entre
LOOP: y GOTO LOOP. En ella se asigna al pin cuyo nombre simbólico es LED (PORTA.6) el valor que

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 16


tome el pin de entrada llamado PULSADOR (PORTB.6). Esto hará que el LED “copie” el estado del
pulsador. Si utilizamos el entrenador de 18 pines que ya explicamos como construir, veremos que cada vez
que pulsamos el pulsador, el LED se enciende hasta que lo soltamos. No se trata de una aplicación demasiado
útil, pero es suficiente para ilustrar el funcionamiento de las entradas.

La próxima semana usaremos un modulo conectado al entrenador que contiene 8 LEDS y 8 pulsadores para
poder crear programas mas complejos. Hasta entonces.

Utilizaremos el Entrenador de 18 pines.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 17


Parte IV

Sabemos que un programa es, básicamente, una lista de instrucciones que el microcontrolador debe ejecutar
en orden para realizar una tarea determinada. De alguna manera, se asemeja a una receta de cocina
(programa) que el cocinero (microcontrolador) debe ir ejecutando. Con mucha frecuencia el cocinero debe
tomar decisiones en función de diversos parámetros, y realizar una cosa u otra.

Esto también ocurre en el mundo de los microcontroladores. En cualquier programa medianamente complejo
que realicemos, seguramente en algún punto debamos tomar alguna decisión basándonos en el estado de una
entrada o en el valor de una variable. Por supuesto, PIC BASIC incorpora instrucciones que nos permiten
este tipo de comportamiento, siendo la mas sencilla y frecuentemente utilizada la sentencia IF - THEN -
ELSE – ENDIF.

Resulta muy sencillo entender su funcionamiento si traducimos su significado al español. IF - THEN - ELSE
– ENDIF significa algo así como “SI ocurre tal cosa ENTONCES realizo esta tarea SINO hago esta otra FIN
SI”.

Existen varias formas de utilizar esta instrucción en PIC BASIC. Veremos los tres casos posibles,
comenzando por el más sencillo.

El caso más simple es el siguiente:

IF condición THEN instrucción

Como vimos, "IF" significa "SI....", y "THEN" significa "LUEGO" o "ENTONCES". Por lo tanto, el caso
anterior puede leerse como "SI se cumple la condición, entonces ejecuto la instrucción"

La "condición" es una expresión lógica que puede ser verdadera o falsa. En caso de ser verdadera, la
instrucción a continuación del THEN será ejecutada. En caso de la condición sea falsa, el programa seguirá
su ejecución con la instrucción siguiente al "IF – THEN".

Seguramente un ejemplo servirá para que lo comprendamos mejor. Supongamos el siguiente programa:

ALLDIGITAL 'Todos los pines como E/S.

TRISA = %11111111 'Todo el PORTA como entradas


DIM AUX AS BYTE 'Declaro la variable "AUX" como BYTE
DIM TOTAL AS BYTE 'Declaro la variable "TOTAL" como BYTE
TOTAL = 100 'Le asigno el valor 100 a la variable "TOTAL"
AUX = 5 'Le asigno el valor 5 a la variable "AUX"

IF PORTA.4 = 1 THEN AUX = 4

TOTAL = TOTAL + AUX 'Sumo a "TOTAL" el valor de "AUX"

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 18


Cuando comienza el programa, se declaran dos variables tipo BYTE (que como vimos antes, pueden
almacenar valores entre 0 y 255). A una de ellas, TOTAL, se le asigna el valor "100" y a la restante, AUX el
valor "5". Hasta aquí, no hay nada que no hayamos visto antes.

La línea siguiente realiza la siguiente tarea: evalúa si la condición PORTA.4 = 1 es cierta. En caso de que
efectivamente el valor presente en el bit 4 del PORTA sea "1" (ese pin del microcontrolador estará en estado
alto), se ejecuta la instrucción a continuación del THEN, por lo que la variable "AUX" toma el valor "4", y se
pasa a la instrucción de abajo. Si PORTA es igual a "0", se pasa a la instrucción siguiente sin más.

El valor final de la variable "TOTAL" depende entonces de cual sea el estado de PORTA.4 al momento de
hacer la evaluación. Si es igual a "1", "TOTAL" tendrá un valor de 104 (100 + 4). Si PORTA.4 = 0, "TOTAL"
tendrá un valor de 105 (10 +5).

Veamos algunos ejemplos validos de este caso:

IF PULSADOR = 1 THEN PORTA.0 = 1


IF B > A THEN LED=ON
IF B = 5 THEN A = 0
IF (A = 0) OR (B = 5) THEN C = 2
IF PORTA.0 THEN PORTB.3 = 0

En el ultimo ejemplo la condición PORTA.0 equivale a PORTA.0 = 1.

Segundo caso: muchas veces, luego de evaluar la condición necesitamos ejecutar más de una instrucción. En
los ejemplos vistos en el caso anterior siempre se ejecutaba una sola instrucción cuando la condición era
cierta. La manera de ejecutar múltiples sentencias dentro de una estructura IF-THEN implica emplear el
ENDIF, con lo que la sintaxis de la instrucción queda como sigue:

IF condición THEN
instrucción 1
instrucción 2
...
instrucción n
ENDIF

En realidad, no varía prácticamente nada respecto del primer caso. Solo debemos saber que en esta ocación
se van a ejecutar todas las instrucciones del bloque que se encuentren entre el THEN y el ENDIF cada vez
que condición sea verdadera.

Veamos un ejemplo. Supongamos el siguiente programa:

DIM A AS BYTE 'Declaro la variable "A" como BYTE


DIM B AS BYTE 'Declaro la variable "B" como BYTE
DIM C AS BYTE 'Declaro la variable "C" como BYTE
DIM D AS BYTE 'Declaro la variable "D" como BYTE
DIM TOTAL AS BYTE 'Declaro la variable "TOTAL" como BYTE

TOTAL = 0 'Le asigno el valor 0 a la variable "TOTAL"


A = 2 'Le asigno el valor 2 a la variable "A"

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 19


B = 5 'Le asigno el valor 5 a la variable "B"
C = 1 'Le asigno el valor 1 a la variable "C"
D = 0 'Le asigno el valor 0 a la variable "D"

IF A = 2 THEN
A = B + (C * D)
TOTAL = A * B
ENDIF

El ejemplo anterior, la condición “A = 2” es verdadera, ya ese es el valor que le asignamos a "A" al comienzo
del programa. Esto significa que las dos instrucciones dentro del bloque THEN-ENDIF se ejecutaran. Esto
hace que TOTAL tome el valor de 10 (¡chicos, hagan las cuentitas!). Si "A" hubiese tenido otro valor, esas
dos sentencias no se ejecutarían y TOTAL seguiría valiendo "0" al terminar el programa. ¿Fácil, verdad?

Este tutorial te permitira crear controladoras como esta.


Ahora, analicemos el último caso posible. A veces, de acuerdo al resultado de la condición, necesitamos
ejecutar un grupo u otro de instrucciones. Para eso, utilizamos la cláusula ELSE, que todavía no habíamos
empleado. La sintaxis en este caso queda como sigue:

IF condición THEN
instrucciónv 1
instrucciónv 2
...
instrucciónv n
ELSE
instrucciónf 1
instrucciónf 2
...
instrucciónf n
ENDIF

Es decir, si la condición es verdadera, se ejecutan las sentencias entre THEN y ELSE. Y si la condición es
falsa, las que estén entre ELSE y ENDIF. "ELSE" puede ser traducido como "en otro caso" o "si no...".

Veamos un ejemplo de esta situación. Supongamos el siguiente programa:

ALLDIGITAL 'Todos los pines como E/S.


TRISA = %11111111 'Todo el PORTA como entradas

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 20


DIM AUX AS BYTE 'Declaro la variable "AUX" como BYTE
DIM TOTAL AS BYTE 'Declaro la variable "TOTAL" como BYTE

TOTAL = 10 'Le asigno el valor 10 a la variable "TOTAL"


AUX = 2 'Le asigno el valor 2 a la variable "AUX"

IF PORTA.4 = 1 THEN
AUX = 4
TOTAL = TOTAL + 5
ELSE
AUX = 0
TOTAL = TOTAL + 15
ENDIF

El ejemplo anterior, la condición PORTA.4 = 1 determina que bloque de instrucciones se ejecutan. Si es


verdadera, AUX = 4 y TOTAL = TOTAL + 5 son usadas. Caso contrario se ejecutan AUX = 0 y TOTAL =
TOTAL + 15. Luego, independientemente de cual haya sido el caso, el programa sigue con la sentencia que
se encuentre a continuación del ENDIF.

Por ultimo, tenemos que saber que es posible "anidar" instrucciones IF-THEN-ELSE-ENDIF, con lo que se
pueden tomar decisiones verdaderamente complejas, con forma de “árbol”, donde cada condición representa
una “rama” diferente. Por supuesto, tenemos que ser cautos en el uso de esta característica ya que debido a
limitaciones en el tamaño de la pila y cantidad de memoria disponible del PIC podemos ocasionar un
desborde y el programa colapsara. Este seria un ejemplo de un anidamiento:

IF PORTB.1 = 1 THEN
IF A = 2 THEN
A = B + (C * D)
TOTAL = A * B
ELSE
A = 0
ENDIF
ELSE
A = 19
ENDIF

Las sentencias en color rojo corresponden a una estructura IF-THEN-ELSE-ENDIF y las que están en azul a
la otra, que se encuentra dentro ("anidada" en) de la primera.

IF… ENDIF no es la única instrucción de toma de decisiones que veremos. Antes de terminar esta cuarta
entrega, aprenderemos a utilizar la potente función LOOKUP. La función LOOKUP puede ser utilizada para
seleccionar un dato tipo “Byte” desde una lista de constantes del mismo tipo, en función del valor de un
índice (que también debe ser de tipo “Byte”). El resultado de la selección se almacena (¡como no!) también
en una variable tipo byte.
La forma de la función LOOKUP es realmente sencilla:

variable = LOOKUP(byte0, byte1, ..., byteN), indice

Cuando se ejecuta, “variable” tendrá el valor correspondiente al elemento que se encuentre en la posición

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 21


“índice” de la lista de valores que esta entre los paréntesis. Es importante recordar (lo vamos a repetir varias
veces) que el primer elemento de la lista corresponde al valor “0” de “índice”.

Veamos un ejemplo sencillo:

DIM indice AS BYTE


DIM variable AS BYTE
indice = 3
variable = LOOKUP(25, 35, 55, 70, 85, 100), indice
...

variable tendrá el valor "70" (decimal) al ejecutar este código. El primer elemento de la lista, recordemos,
corresponde al valor "0" de indice. Si bien la lista puede contener un máximo de 255 elementos, que es el
máximo direccionable por una variable indice de tipo byte, hay que asegurarse que el microcontrolador que
estamos empleando tenga memoria suficiente para albergarla.

El segundo ejemplo (extraído de la propia ayuda del PIC SIMULATOR IDE), nos muestra como manejar un
display LED de siete segmentos conectado al puerto B:

Dim digito As Byte


Dim mascara As Byte
'Comienzo el bucle principal
loop:
TRISB = %00000000
digito = 7
mascara = LookUp(0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
0x7f, 0x6f), digito
PORTB = mascara
WaitMs 1000 'Espero un segundo…
Goto loop

Lo que hace concretamente ese trozo de código es buscar dentro de la lista cual es el valor binario que
corresponde asignar al PORTB para que los segmentos adecuados enciendan en el display, mostrando el valor
que contiene la variable “digito”.

Si algunas o todas las constantes de la lista son valores ASCII, se puede hacer mas corta y legible la misma
utilizando como parte de ella una cadena de caracteres, como se ve a continuación.

MASK = LOOKUP("ABCDEFGHIJK"), INDEX

"A" seria el valor que tendría MASK cuando INDEX vale "0", y "K" cuando INDEX tenga el valor "10".
Por ultimo, en caso de que el valor de INDEX sea mayor a la cantidad de argumentos de la lista, el valor de
la variable (en este ejemplo MASK) no cambia.

Con esto terminamos la cuarta entrega del tutorial. En la siguiente, veremos como construir un proyecto que
emplee todo lo visto hasta aquí. ¡Hasta la próxima semana!

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 22


Placa utilizada en robótica, con un microcontrolador.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 23


Parte V

Utilizaremos como base la PIC TRAINER de 40 pines y el modulo de 8 Entradas/Salidas para hacer una serie
de programas que empleen las instrucciones y conceptos que hemos visto hasta aquí. Si no haz construido
estas dos placas, seria una buena idea de te pongas en ello, ya que a lo largo del tutorial las utilizaremos con
frecuencia.

Si no, siempre tienes la alternativa de utilizar un protoboard o crear una placa de circuito impreso cada vez,
aunque seguramente perderás mucho tiempo en ello.

El modulo de 8 E/S nos proporciona 8 LEDs para “jugar” con ellos, así que vamos a aprovecharlos.

Ejercicio 1: 8 LEDs destellando.


En nuestra primer y segunda entrega vimos como se hacia para encender y/o apagar una de las salidas del
microcontrolador. Es muy sencillo utilizar lo visto en esa oportunidad para ampliarlo a un mayor número de
salidas.

En esa oportunidad utilizábamos como salida el bit 7 del PORTA, por lo que las instrucciones que activaban
y desactivaban el LED eran PORTA.7 = 1 y PORTA.7 = 0 respectivamente. Hoy usaremos el PORTC de un
16F877A montado en el PIC TRAINER de 40 pines. Si nos atenemos a lo visto con anterioridad, para
encender las 8 salidas deberíamos tener 8 instrucciones separadas, del tipo PORTC.0 = 1… PORTC.7 = 1. El
programa que enciende y apaga las 8 salidas del PORTC quedaría así:

AllDigital

TRISC = %00000000 ‘Todos los pines como salidas

loop:
‘Enciendo los 8 LEDs
PORTC.0 = 1
PORTC.1 = 1
PORTC.2 = 1
PORTC.3 = 1
PORTC.4 = 1
PORTC.5 = 1
PORTC.6 = 1
PORTC.7 = 1

WaitMs 500 ‘Espero medio Segundo (500 ms)

‘Apago los 8 LEDs


PORTC.0 = 0
PORTC.1 = 0
PORTC.2 = 0
PORTC.3 = 0
PORTC.4 = 0

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 24


PORTC.5 = 0
PORTC.6 = 0
PORTC.7 = 0

WaitMs 500‘Espero medio Segundo (500 ms)


Goto loop

Este programa, como puede verse en las imágenes y videos que acompañan el tutorial, funciona
perfectamente. Pero existe una forma más concisa de hacer lo mismo. El truco esta en encender (o apagar)
todas las salidas en la misma instrucción. Esto tiene dos ventajas: nuestro programa será más corto y fácil de
entender, y no se producirá una pequeña demora (de 1 millonésima de segundo) entre la activación de una
salida y la siguiente, como ocurre en el programa anterior).

Si escribimos PORTC = %00000000 estamos poniendo en “0” (apagando) las 8 salidas en una sola
instrucción. Y si escribimos PORTC = %11111111 las encendemos a todas. Cada uno de los 0” o “1” de esas
instrucciones corresponde a cada una de las salidas. El de más a la izquierda corresponde al bit 7, el siguiente
al 6, y así sucesivamente hasta llagar al de la derecha que corresponder al bit 0. Nuestro programa
modificado quedaría así:

AllDigital

TRISC = %00000000 ‘Todos los pines como salidas

loop:
‘Enciendo los 8 LEDs
PORTC = %11111111
WaitMs 500 ‘Espero medio Segundo (500 ms)

‘Apago los 8 LEDs


PORTC = %00000000
WaitMs 500‘Espero medio Segundo (500 ms)

Goto loop

Como puede verse, el programa es mucho mas compacto que el anterior.

Ejercicio 2: LEDs saltarines.

Nada impide modificar el programa del ejercicio 1 para hacer que las salidas se activen en un orden diferente.
Supongamos por un momento que queremos encender los LEDs 0,1,4 y 5 primero, y luego apagarlos a la vez
que encendemos los restantes, y repetir esto indefinidamente.

El programa es prácticamente igual al ya visto, solo varían las instrucciones que le dicen al PIC que salidas
deben encenderse y apagarse en cada momento:

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 25


AllDigital
TRISC = %00000000 ‘Todos los pines como salidas
loop:
‘Enciendo 4 LEDs
PORTC = %11001100
WaitMs 500 ‘Espero medio Segundo (500 ms)

‘Apago los anteriores y enciendo los otros 4


PORTC = %00110011
WaitMs 500‘Espero medio Segundo (500 ms)

Goto loop

¿Sencillo, verdad?

Ejercicio 3: El LED viajero


Todos hemos visto esos juegos de luces donde la secuencia de encendido y apagado da la sensación de que
un punto luminoso se mueve de un lado a otro. Con lo visto hasta aquí, estamos en condiciones de hacerlo.
Solo tenemos que escribir un programa que encienda primero el primer LED, luego el segundo, el tercero,
etc., a medida que se apaga el anterior. Eso justamente es lo que hace el siguiente programa:

AllDigital

TRISC = %00000000 ‘Todos los pines como salidas

loop:

PORTC = %10000000
WaitMs 500 ‘Espero medio Segundo (500 ms)

PORTC = %01000000
WaitMs 500 ‘Espero medio Segundo (500 ms)

PORTC = %00100000
WaitMs 500 ‘Espero medio Segundo (500 ms)

PORTC = %00010000

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 26


WaitMs 500 ‘Espero medio Segundo (500 ms)

PORTC = %00001000
WaitMs 500 ‘Espero medio Segundo (500 ms)

PORTC = %00000100
WaitMs 500 ‘Espero medio Segundo (500 ms)

PORTC = %00000010
WaitMs 500 ‘Espero medio Segundo (500 ms)

PORTC = %00000001
WaitMs 500 ‘Espero medio Segundo (500 ms)

Goto loop

Ejercicio 4: El “Coche Fantástico”


Si hay algo que a todo el mundo le llama la atención, es el efecto de luces que tenia a bordo el “Auto
Fantástico”. En realidad, construir un circuito que haga esa tarea es muy simple. De hecho, unas pocas
modificaciones a nuestro programa del ejercicio 3 bastarían para hacerlo: solo hay que agregar las
instrucciones necesarias para que el punto de luz regrese y luego se repita indefinidamente. Eso es lo que
hace el programa siguiente:

AllDigital

TRISC = %00000000 ‘Todos los pines como salidas

loop:

PORTC = %10000000
WaitMs 500 ‘Espero medio Segundo (500 ms)

PORTC = %01000000

WaitMs 500 ‘Espero medio Segundo (500 ms)

PORTC = %00100000

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 27


WaitMs 500 ‘Espero medio Segundo (500 ms)

PORTC = %00010000
WaitMs 500 ‘Espero medio Segundo (500 ms)

PORTC = %00001000
WaitMs 500 ‘Espero medio Segundo (500 ms)

PORTC = %00000100
WaitMs 500 ‘Espero medio Segundo (500 ms)

PORTC = %00000010
WaitMs 500 ‘Espero medio Segundo (500 ms)

PORTC = %00000001
WaitMs 500 ‘Espero medio Segundo (500 ms)

‘Aquí comienza la secuencia de “regreso”


PORTC = %00000010
WaitMs 500 ‘Espero medio Segundo (500 ms)

PORTC = %00000100
WaitMs 500 ‘Espero medio Segundo (500 ms)

PORTC = %00001000
WaitMs 500 ‘Espero medio Segundo (500 ms)

PORTC = %00010000
WaitMs 500 ‘Espero medio Segundo (500 ms)

PORTC = %00100000
WaitMs 500 ‘Espero medio Segundo (500 ms)

PORTC = %01000000

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 28


WaitMs 500 ‘Espero medio Segundo (500 ms)

PORTC = %10000000
WaitMs 500 ‘Espero medio Segundo (500 ms)

Goto loop

Si queremos que el efecto sea más rápido, vasta con reducir los tiempos de demora de 500ms a, por ejemplo,
250ms. Incluso puede ser interesante poner tiempos distintos entre cada led y el siguiente, para que se
produzca un ejemplo de “aceleración” o “frenado” en la velocidad del punto luminoso.

Si vemos el listado de arriba, notaremos que es bastante extenso para la sencilla tarea que lleva a cabo.
Seguramente estarás pensando en que debe existir una manera más eficiente de hacer lo mismo. Y de hecho,
la hay.

SHIFTLEFT y SHIFTRIGHT
Estas dos son funciones que operan a nivel bit que pueden ser utilizadas para "correr" el contenido de
variable a la izquierda o a la derecha. Cada uno de los bits que componen la variable se desplazan una
posición (a la izquierda o a la derecha, de acuerdo a que función utilicemos). Esto tiene dos consecuencias.
En primer lugar, el bit de más a la izquierda (SHIFTLEFT) o derecha (SHIFTRIGHT) se pierde. Y el espacio
creado en el otro extremo se completa con un "0".

El siguiente programa hace lo mismo que el del ejercicio anterior, pero utilizando estas dos potentes
funciones y algunas de las instrucciones vistas en capítulos anteriores:

AllDigital

TRISC = %00000000 ‘Todos los pines como salidas


PORTC = %00000001
goleft:
WaitMs 500

PORTC = ShiftLeft(PORTC, 1)
If PORTC = %10000000 Then Goto goright
Goto goleft
goright:
WaitMs 500
PORTC = ShiftRight(PORTC, 1)
If PORTC = %00000001 Then Goto goleft
Goto goright

Lo que hace el programa es muy sencillo: enciende el primer bit del PORTC y espera durante medio

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 29


segundo. Luego, desplaza hacia la izquierda el contenido del byte que representa al PORTC en la memoria
del microcontrolador, y verifica si esos bits llegaron al extremo. Si es así, se invierte el sentido del
desplazamiento. El video siguiente muestra como se ve esto en el PIC TRAINER.

Como pueden ver, es mucho lo que se puede hacer con un poco de imaginación y el puñado de instrucciones
que hemos visto. A partir de ahora, en cada entrega del tutorial veremos instrucciones nuevas y realizaremos
diferentes ejercicios con ellas, de manera que sea mas fácil recordar que tarea realiza cada una. Siempre que
sea posible, intentaremos mostrar diferentes formas de llevar a cabo las mismas acciones.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 30


Parte VI

Seguramente habrán notado que usando una etiqueta y una instrucción GOTO podemos hacer que una parte
de nuestro programa se repita. El problema que tiene ese método es que utilizado así, en crudo, solo permite
que el bucle en cuestión se repetirá un numero infinito de veces.

Los lectores mas atentos se habrán dado cuenta que si empleamos una variable y la instrucción IF…ENDIF,
podemos ir contando la cantidad de veces que el bucle se ha ejecutado, para salirnos de el en el momento
deseado.

Vamos a verlo en detalle. Supongamos que necesitamos un bucle que se repita 20 veces. Podemos definir una
variable auxiliar, de tipo BYTE (que permite valores de hasta 255) asignarle el valor 0, y en cada iteración
del bucle sumarle 1. Cuando el valor de la variable sea igual a 20, sabremos que las instrucciones dentro del
bucle se han ejecutado ese número de veces. El programa podría quedar más o menos así:

DIM AUX AS BYTE 'Declaro la variable "AUX" como BYTE


AUX = 0 'Asigno "0" a la variable "AUX".

bucle: 'Aquí comienza el bucle que debe repetirse 20 veces…


instruccion1
instruccion2
...
instruccionn
AUX = AUX + 1 'Sumo 1 al valor de "AUX"

IF AUX = 20 THEN 'si "AUX" es igual a 20…


GOTO fuera 'Salto a la etiqueta “fuera”.
ENDIF
GOTO bucle 'fin del bucle.
fuera: 'aquí comienza el resto del programa


END

Este método funciona perfectamente, y puede modificarse para cualquier número de iteraciones, recordando
que la variable AUX deberá ser de tipo WORD si el número es mayor a 255. Si necesitáramos iterar más de
65535 veces, deberemos utilizar más de una variable.

Pero afortunadamente BASIC tiene instrucciones mas especificas, elegantes y potentes para resolver
este tipo de situaciones.

Un bucle actualiza las temperaturas de este display.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 31


FOR - TO - STEP – NEXT
Esta es quizás una de las instrucciones que esta disponible en todos los dialectos BASIC, desde la época de
las “home computers”. El BASIC del PIC SIMULATOR IDE también la soporta, y seguramente la
emplearemos en casi todos nuestros programas.

Esta estructura, al igual que el caso anterior, necesita de una variable tipo Byte o Word para funcionar. En
cada iteración del bucle, la variable va cambiando su valor. Cuando el valor de la variable alcanza o supera el
valor prefijado, el bucle termina. La forma del bucle es la siguiente:

FOR variable = valor_inicial TO valor_final STEP paso


instruccion1
instruccion2
...
instruccionn
NEXT variable

La cuenta comienza asignando a “variable” el “valor_inicial”, y termina cuando “variable” alcanza el valor
“valor_final”. Cada iteración del bucle el valor de la “variable” se incrementa el valor fijado por “paso”.

Veamos un ejemplo concreto. Supongamos que queremos sumar los números del 1 al 100. El programa
quedaría como sigue:

DIM A AS BYTE 'Declaro la variable "A" como BYTE


DIM TOTAL AS WORD 'Declaro la variable "TOTAL" como WORD
TOTAL = 0 'Asigno "0" a la variable "TOTAL".

FOR A = 1 TO 100 STEP 1 '"A" va de 1 a 100 de 1 en 1


TOTAL = TOTAL + A 'Sumo "A" al valor de "TOTAL".
NEXT A 'fin del bucle.

Hemos declarado la variable A como BYTE, ya que su valor va a mantenerse en el rango 0...255. Para
TOTAL utilizamos una variable tipo WORD, ya que la suma va a superar el valor máximo de un BYTE.
(Recordemos que WORD permite valores en el rango 0...65535)

El bucle se ejecuta 100 veces, la primera de ellas A vale 1, la segunda 2, la tercera 3, hasta la última en la que
vale 100. Ese incremento (1 por vez) esta dado por el valor a continuación del STEP. En los casos como este
en que STEP vale 1, puede omitirse, como veremos en ejemplos posteriores.

TOTAL comienza valiendo 0 (se le asigna ese valor fuera del bucle) y en cada iteración se le suma el valor
que tenga A en ese momento. De esa manera, TOTAL va tomando los valores 1, 3, 6, 10, .... 5050.
Tanto valor_inicial como valor_final y paso también pueden ser variables, lo que permite que un determinado
bucle FOR…NEXT sea utilizado dentro de una subrutina (como veremos más adelante) con diferentes
valores cada vez.

El siguiente trozo de código hace lo mismo que el anterior, pero emplea variables en lugar de valores fijos:

DIM A AS BYTE 'Declaro la variable "A" como BYTE


DIM INICIO AS BYTE 'Declaro la variable "INICIO" como BYTE

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 32


DIM FINAL AS BYTE 'Declaro la variable "FINAL" como BYTE
DIM PASO AS BYTE 'Declaro la variable "PASO" como BYTE
DIM TOTAL AS WORD 'Declaro la variable "TOTAL" como WORD

INICIO = 1 'Asigno "1" a la variable "INICIO".


FINAL = 100 'Asigno "100" a la variable "FINAL".
PASO = 1 'Asigno "1" a la variable "PASO".
TOTAL = 0 'Asigno "0" a la variable "TOTAL".

FOR A = INICIO TO FINAL STEP PASO '"A" va de 1 a 100 de 1 en 1


TOTAL = TOTAL + A 'Sumo "A" al valor de "TOTAL".
NEXT A 'fin del bucle.

Y el mismo ejemplo, sin usar STEP:

DIM A AS BYTE 'Declaro la variable "A" como BYTE


DIM TOTAL AS WORD 'Declaro la variable "TOTAL" como WORD

TOTAL = 0 'Asigno "0" a la variable "TOTAL".

FOR A = 1 TO 100 '"A" va de 1 a 100 de 1 en 1


TOTAL = TOTAL + A 'Sumo "A" al valor de "TOTAL".
NEXT A 'fin del bucle.

Si quisiéramos sumar otro grupo de números, bastaría con modificar el valor de las variables INICIO y
FINAL.

Hay casos en que es necesario que el valor de la variable de control del bucle se decremente en lugar de ir
aumentando. Un cronometro descendente seria una aplicación practica de este caso. Para lograr esto, se
puede usar un valor negativo para STEP. El siguiente ejemplo cuenta desde 50 hasta 20, de 5 en 5:

DIM A AS BYTE 'Declaro la variable "A" como BYTE

FOR A = 50 TO 20 STEP -5 '"A" va de 50 a 20 de 5 en 5


instruccion1
instruccion2
...
instruccionn
NEXT A 'fin del bucle.

De la misma manera que ocurría con IF-THEN-ELSE-ENDIF, pueden anidarse diferentes bucles FOR-TO-
STEP-NEXT , uno dentro de otro:

FOR variable1 = valor_inicial1 TO valor_final1 STEP paso1


FOR variable2 = valor_inicial2 TO valor_final2 STEP paso2
instruccion1

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 33


instruccion2
...
instruccionn
NEXT variable2
NEXT variable1

La única condición, igual que ocurría con IF… es que un bucle debe estar completamente contenido dentro
del otro, sino el compilador nos avisara del error y se negará a generar el archivo .HEX correspondiente.

El siguiente anidamiento daría un error en el compilador:

FOR variable1 = valor_inicial1 TO valor_final1 STEP paso1


FOR variable2 = valor_inicial2 TO valor_final2 STEP paso2
instruccion1
instruccion2
...
instruccionn
NEXT variable1
NEXT variable2

Para que el anidamiento sea correcto, el primer NEXT debe ser el correspondiente al segundo FOR (el de la
“variable2”). Este FOR se repetirá tantas veces como lo indique el FOR de la “variable1”

Para terminar, veamos el siguiente código:

AllDigital
TRISC = 0
Dim a As Byte

For a = 0 To 255
WAITMS 250

PORTC = a
Next a
Si lo compilamos y cargamos en al PIC TRAINER 40 conectado a la placa de 8 I/O como lo hicimos en la
entrega anterior, veremos como los LEDs “cuentan” en binario desde 0 a 255.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 34


Los LEDs “cuentan” en binario desde 0 a 255.
WHILE – WEND

La segunda estructura de control que proporciona PIC BASIC es WHILE - WEND. Su propósito también es
la construcción de bucles que se ejecutan un numero de veces, y se puede decir que esta a “mitad de camino”
entre la construcción de un bucle mediante etiquetas y GOTOs y la utilización de un FOR…NEXT. Su
estructura es la siguiente:

WHILE condición

instruccion1
instruccion2
...
instruccionn
WEND

Mientras que la condición sea verdadera, el grupo de instrucciones dentro del cuerpo del WHILE-WEND se
ejecuta. Las características de la condición son las mismas que vimos antes para la instrucción IF-THEN-
ELSE-ENDIF.

Por supuesto, si no somos cuidadosos al momento de elegir la condición, puede darse el caso de que el
numero de repeticiones del bucle sea infinito, y nunca salgamos de él. De hecho, esta circunstancia se
aprovecha en algunos programas para repetir indefinidamente un grupo de instrucciones. También hay que
tener presente que si la condición no es cierta al momento de ejecutar la primera vez el WHILE, el flujo del
programa pasara directamente a la instrucción posterior al WEND y las instrucciones dentro del bucle no se
ejecutaran ninguna vez.

No hay mucho mas para decir de WHILE-WEND , solo analizar algunos ejemplos:

Ejemplo 1:

El siguiente es un bucle infinito. Como dentro del cuerpo del WHILE-WEND no se cambia el valor de la
variable A, esta siempre vale "0" y la condición del WHILE nunca es falsa, por lo que se repite eternamente:
es un caso similar a los que vimos en la entrega anterior del tutorial.

DIM A AS BYTE
A = 0
...
WHILE A = 0
instruccion1
instruccion2
...
instruccionn
WEND
...

Ejemplo 2:
Las instrucciones dentro del siguiente WHILE-WEND no se ejecutan nunca, dado que la condición siempre
es falsa:

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 35


DIM A AS BYTE
A = 0
...
WHILE A > 0
instruccion1
instruccion2
...
instruccionn
WEND
...

Ejemplo 3:
Las instrucciones dentro del siguiente WHILE-WEND se ejecutan 20 veces, y al terminar la variable B
contiene la suma de los números del 0 al 20 naturales:

DIM A AS BYTE
DIM A AS BYTE

A = 0
B = 0

WHILE A < 20
A = A + 1 'Incremento la variable A
B = B + A 'Sumo a B el valor de la variable AWEND

Cuando A = 20, se suma su valor a A, y al llegar al WEND el control del programa se transfiere al WHILE,
donde se evalúa la condición A < 20, se determina que es falsa, y el programa pasa el control a la línea que
exista después del WEND.

Este bucle hace la misma suma que el que realizamos antes con FOR…NEXT. No se puede decir que uno sea
mejor o peor que el otro: solo son dos formas distintas de hacer lo mismo, y en cada situación decidiremos
cual nos conviene más.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 36


Parte VII

Continuando con la serie de notas dedicadas a aprender a programar microcontroladores, veremos las
instrucciones que dispone el lenguaje de programación PIC BASIC orientadas al manejo de displays LCD.

Existen en el mercado una enorme variedad de pantallas de cristal liquido, de un precio accesible, con
características comunes en cuanto a la interfaz y programación, gracias que la mayoría utiliza para
comunicarse con el “exterior” el mismo chip de la empresa Hitachi, el HD44780. Esto hace posible que con
un puñado de instrucciones podemos manejar desde un sencillo display de una línea de 8 caracteres hasta uno
de 4 líneas con 80 caracteres.

El aspecto físico de estas pantallas se puede ver en las fotos que ilustran la nota, básicamente son una
pequeña placa de circuito impreso con un par de integrados (tipo “gota”) pegados en una de sus caras, y la
pantalla propiamente dicha en la otra, rodeada de una estructura metálica que la protege. Esta placa casi
siempre dispone de agujeros para poder fijar el conjunto a un chasis o gabinete sin grandes complicaciones.
Desde el punto de vista eléctrico, hay un conector (a veces solo agujeros metalizados donde soldar los cables)
que tiene 14 pines en los que no poseen iluminación propia (backlite) o 16 en los que si la tienen.

Vista trasera de un LCD 2x16 típico. Hermoso: un LCD de 4 lineas de 40 caracteres, color
azul.
Mediante las señales apropiadas enviadas y recibidas mediante este conector el display es capaz de
representar caracteres, mostrar o esconder un cursor, borrar la pantalla, etc.

Descripción de los pines


Como mencionamos, la gran mayoría de los displays existentes en el mercado respetan la misma distribución
de pines. Igualmente, antes de conectar nada, debemos asegurarnos de que así sea, para no dañar de forma
permanente el LCD. Siempre es necesario tener a mano la “datasheet” (hoja de datos) del componente
electrónico que queremos usar.

Veamos que función cumple cada uno de los pines de un display LCD genérico:

Pines 1,2 y 3: Estos pines están dedicados a la alimentación y contraste del LCD. Efectivamente, el pin 1
(VSS) es el que se debe conectar al negativo (masa) de la alimentación, y el pin 2 (Vdd/Vcc) es el que va
unido al positivo (5 voltios). El pin 3 permite el ajuste del contraste del panel. Se puede unir al pin 1
mediante una resistencia de 220 ohms para obtener un contraste adecuado (pero fijo) o bien utilizar un
potenciómetro o preset de 10 KOhm para variar el contraste a gusto.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 37


Pines 4,5,6: Estos pines son de alguna manera los que controlan el funcionamiento del display. El pin 4,
también llamado RS (Registration Select) es el que le indica al controlador interno del LCD que el valor
presente en el bus de datos es un comando (cuando RS=0) o bien un carácter para representar (cuando
RS=1).

El pin 5 (“R/W” por “Read/Write” o “Leer/Escribir”) permite decidir si queremos enviar datos al display
(R/W=0) o bien nos interesa leer lo que el display tiene en su memoria o conocer su estado (R/W=1).

Por ultimo, el pin 6 (E por “Enable” o “habilitado”) es el que selecciona el display a utilizar. Es decir,
podemos tener varios LCD conectados a un mismo bus de datos (pines 7-14) de control, y mediante E
seleccionar cual es el que debe usarse en cada momento.

Pines 7, 8, 9, 10, 11, 12, 13, 14: Estos ocho pines son el “bus de datos” del controlador de la pantalla.
Llamados DB0-DB7 son los encargados de recibir (o enviar) los comandos o datos desde o hacia el display.
DB0 es el bit de menor peso y DB7 es el más significativo.

Por ultimo, los pines 15 y 16 son los que se utilizan para alimentar el (o los) LEDs de fondo de la pantalla,
que brindan la iluminación (backlight). El pin 15 debe ser conectado a 5 voltios y el 16 al negativo o masa de
la fuente. En estas condiciones, la luz de fondo esta encendida a 100% de su brillo. Nuevamente, se puede
utilizar un potenciómetro o preset para ajustar el brillo. Como una nota curiosa, muy frecuentemente estos
dos pines están ubicados ANTES del pin 1 (ver esquema). Debemos asegurarnos de cual es su posición
consultando la hoja de datos del fabricante o la serigrafía que existe sobre la placa del LCD.

Estos displays soportan dos modos de trabajo: en uno de ellos reciben en DB0-DB7 los 8 bits del dato, y en
el otro, llamado “modo de 4 bits” reciben los datos en dos mitades (nibbles) por los pines DB4-DB7, en dos
pasos sucesivos. Si bien esto puede complicar ligeramente la programación en assembler, en PIC BASIC es
completamente transparente, a la vez que supone un ahorro de 4 pines en el bus de datos, y esto en
microcontroladores con pocos pines de I/O es muy útil.

Los pines de un display LCD genérico. De esa forma podemos controlar el contraste del LCD.

A grandes rasgos, y a pesar de la simplicidad que brinda el disponer de un mismo integrado especializado en
casi todos los modelos de displays, la escritura en estos es relativamente compleja, dado que se deben
respetar protocolos de inicialización, tiempos entre envío de datos, etc., lo que hace bastante tediosa su
programación en assembler. Pero PIC BASIC dispone de un juego de instrucciones especiales para manejar

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 38


displays en modo “8 bits” y en modo “4 bits” que nos evitan toda esa complejidad. Veremos cuáles son y
algunos ejemplos de uso. La próxima semana realizaremos un módulo para el PIC TRAINER y escribiremos
varios programas de ejemplo.

El manejo de los LCD se hace mediante el uso de sentencias “DEFINE”, que le dicen al compilador a que
pines del microcontrolador hemos conectado cada uno de los pines del LCD. La forma de la instrucción
DEFINE es la siguiente:
DEFINE parametro = valor

Donde “parametro” es el nombre del parámetro al que le queremos asignar el “valor”. Los parámetros
disponibles para el manejo de LCD alfanuméricos son los siguientes:

LCD_BITS: Define el número de bits de la interfaz de datos. Se pueden asignar valores de 4 u 8, siendo 4 el
valor por defecto.
LCD_DREG: Define a que puerto del PIC tenemos conectado el port de datos del LCD. Los valores
permitidos son PORTA, PORTB, PORTC, etc. Por defecto se asume PORTB.

LCD_DBIT: Define cual es el primer pin del puerto que usamos para enviar los datos al LCD cuando
seleccionamos un bus de 4 bits. Solo puede ser el 0 (para los pines el 0, 1, 2 y 3) o 4 (para usar los pines 4, 5,
6 y 7). Por defecto se asume “4”, y esta instrucción se ignora para LCD_BITS = 8.

LCD_RSREG: Define a que puerto del PIC tenemos conectado el pin RS del LCD. Los valores permitidos
son PORTA, PORTB, PORTC, etc. Por defecto se asume PORTB.

LCD_RSBIT: Define a que pin del puerto tenemos conectado el pin RS del LCD. Por defecto se asume “3”.

LCD_EREG: Define a que puerto del PIC tenemos conectado el pin E del LCD. Los valores permitidos son
PORTA, PORTB, PORTC, etc. Por defecto se asume PORTB.

LCD_EBIT: Define a que pin del puerto tenemos conectado el pin E del LCD. Por defecto se asume “2”.

LCD_RWREG: Define a que puerto del PIC tenemos conectado el pin RW del LCD. Los valores permitidos
son 0, PORTA, PORTB, PORTC, etc. Por defecto se asume “0”, que significa “no usamos el pin RW”.

LCD_RWBIT: Define a que pin del puerto tenemos conectado el pin RW del LCD. Por defecto se asume
“0”, que significa “no usamos el pin RW”.
LCD_COMMANDUS: Define cuantos microsegundos demora la escritura de un comando en el display. Por
defecto, este valor es de 5000. La mayoría de los LCD funcionan bien con un valor de 2000, lo que hace más
rápidos nuestros programas.

LCD_DATAUS: Define cuantos microsegundos demora la escritura de un dato en el LCD. Por defecto, este
valor es de 100.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 39


LCD_INITMS: Define cuantos microsegundos demora la inicialización e la electrónica del LCD. Por
defecto, este valor es de 100.
Luego, tenemos una serie de instrucciones que manejan el envío de comandos e instrucciones al display:

LCDINIT debe utilizarse antes de enviar cualquier comando o dato al LCD. La forma de esta instrucción es
al siguiente:
LCDINIT n

Donde “n” es el tipo de cursor que queremos que muestre el display. “0” significa que el cursor estará oculto,
“1” significa que el cursor parpadeara, “2” nos mostrara un cursor subrayado, y “3” un cursor subrayado y
parpadeando.

LCDCMDOUT es la instrucción que envía comandos al LCD. Se emplea de la siguiente manera:


LCDCMDOUT comando

Donde “comando” es alguno de los siguientes:

LcdClear: Borra el contenido del LCD.


LcdHome: Lleva el cursor a la primera posición del primer renglón del LCD.
LcdLine2Home: Lleva el cursor a la primera posición del segundo renglón del LCD.
LcdLeft: Mueve el cursor una posición a la izquierda.
LcdRight: Mueve el cursor una posición a la derecha.
LcdShiftLeft: Desplaza el contenido del LCD una posición a la izquierda.
LcdShiftRight: Desplaza el contenido del LCD una posición a la derecha.
LcdLine1Clear: Borra la primera línea del LCD.
LcdLine2Clear: Borra la segunda línea del LCD.
LcdLine1Pos(x): Coloca el cursor en la posición “x” del primer renglón del LCD. “X” puede tener
cualquier valor entre 1 y 40
LcdLine2Pos(x): Coloca el cursor en la posición “x” del segundo renglón del LCD. “X” puede tener
cualquier valor entre 1 y 40

LCDOUT envía datos al display. Si son caracteres, simplemente los ponemos entre comillas a continuación
del comando. Si se trata de mostrar el contenido de una variable, se escribe la variable (precedida por “#”) a
continuación del comando. Si se necesitan imprimir varias variables, se pueden separar por “comas”.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 40


Un LCD en acción.
A continuación, un par de ejemplos de cómo se utilizan todas estas instrucciones. El primero se encarga de
mostrar un texto parpadeando en la primera línea del display. Intenten deducir como está conectado el LCD
al PIC mirando las instrucciones “DEFINE” del principio del programa.

DEFINE LCD_BITS = 8
DEFINE LCD_DREG = PORTB
DEFINE LCD_DBIT = 0
DEFINE LCD_RSREG = PORTD
DEFINE LCD_RSBIT = 1
DEFINE LCD_EREG = PORTD
DEFINE LCD_EBIT = 3
DEFINE LCD_RWREG = PORTD
DEFINE LCD_RWBIT = 2

LCDINIT 0 ‘inicializo el LCD sin cursor.

Loop:
LCDOUT "www.NeoTeo.com" ‘Muestra el texto…
WAITMS 1000 ‘Espero un segundo
LCDCMDOUT LcdClear ‘Borro el display

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 41


WAITMS 1000 ‘Espero un segundo
GOTO loop ‘Vuelvo a loop: para repetir indefinidamente.

El segundo ejemplo muestra como imprimir el contenido de una variable (“A”) en el LCD. Concretamente,
se muestra un texto en el primer renglón, mientras que en el segundo se cuentan los números del 65535 al 0
en el segundo.

DEFINE LCD_BITS = 8
DEFINE LCD_DREG = PORTBDEFINE LCD_DBIT = 0
DEFINE LCD_RSREG = PORTD
DEFINE LCD_RSBIT = 1
DEFINE LCD_EREG = PORTD
DEFINE LCD_EBIT = 3
DEFINE LCD_RWREG = PORTD
DEFINE LCD_RWBIT = 2
DIM A AS WORD
A = 65535
LCDINIT 3 ‘Cursor parpadeando
WAITMS 1000
loop:
LCDOUT "¡Estoy contando!” ‘Texto del primer renglón
LCDCMDOUT LcdLine2Home ‘Paso al Segundo renglón
LCDOUT #A ‘Muestro el valor de A
A = A – 1
WAITMS 250
LCDCMDOUT LcdClear ‘Limpio del display
GOTO loop
Esto es todo por hoy. La semana próxima veremos cómo implementar estos ejemplos en una placa de
expansión para nuestro PIC TRAINER, y también como definir nuestros propios caracteres especiales.

Veremos como definir nuestros propios caracteres. Estos LCD son ideales para modding.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 42


Parte VIII

En realidad, construir un modulo de expansión para nuestro PIC Trainer es muy sencillo, gracias a la
electrónica incluida a bordo de cada módulo LCD, que se encarga de las tareas más complejas.

Nuestro proyecto consiste básicamente en una serie de conectores que permiten al microcontrolador situado
en el PIC Trainer enviar los caracteres y comandos a la pantalla. Dado que los LCD tienen (generalmente) la
posibilidad de ajustar su contraste o luz de fondo, hemos previsto la electrónica necesaria para poder
seleccionar mediante una serie de jumpers alguna de esas funciones. Y por supuesto, hemos dotado a la placa
con un preset de 10K para regular el contraste del LCD.

Debido a que el consumo del modulo (sobre todo si hacemos uso de los LEDs de backlite) es algo elevado
(unos 200mA) para cargárselo al regulador de voltaje incluido en el PIC Trainer, hemos dotado a la placa del
LCD con su propio regulador. Hemos elegido para esta tarea a un “hermano menor” del 7805, el 78L05, que
en una capsula mucho más pequeña puede entregarnos 5V perfectamente regulados.

La siguiente imagen nos muestra el esquema eléctrico de nuestra nueva placa de expansión:

Esquema eléctrico de nuestra placa de expansión.


Como podemos ver, el circuito es verdaderamente sencillo: una tensión de alimentación de entre 7.5 y 15
voltios se conecta en la bornera de alimentación, pasa a través de un diodo que protege al regulador de
voltaje de una conexión errónea de la fuente de alimentación, y mediante el 78L05 y los condensadores
asociados es regulada a 5V.

El modulo LCD tiene conectados los cuatro bits más altos de su bus de datos a un conector tipo molex de 10
vías, al que hemos llamado “A”. Los restantes cuatro bits están unidos al conector B. De esta manera, si

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 43


queremos utilizar un programa que emplea solo cuatro bits para comunicarse con el modulo, usaremos el
conector A; y en caso de querer probar un programa que utiliza un bus de datos de 8 bits, utilizaremos ambos
conectores.

El tercer molex, llamado “C”, es el conector “de control”. En efecto, las líneas de control del LCD se
encuentra agrupadas en este conector, teniendo la posibilidad de seleccionar la función “R/W” mediante un
jumper (JP1). Si el jumper se encuentra colocado entre los pines 1 y 2, el control de la línea “R/W” estará en
manos del microcontrolador, por lo que el programa deberá poner un “0” en esa línea antes de poder escribir
en el. Si el jumper está en la posición 2-3, el LCD estará preparado para que escribamos en el todo el tiempo.
No podremos leer su memoria interna (tarea poco frecuente) y utilizaremos un pin menos en el
microcontrolador.

El cuarto pin de control corresponde al backlite. Esta es la iluminación trasera del display, que permite
utilizarlo en condiciones de iluminación pobre, por ejemplo de noche. Como el consumo del backlite es
excesivo para alimentarlo directamente desde un puerto del microcontrolador, hemos utilizado un transistor
2N3906 que se encargue de esa tarea.

El jumper JP2 sirve para seleccionar si el backlite va a estar encendido (jumper en 1-2), bajo el control del
PIC (jumper en 2-3) o apagado permanentemente (sin jumper). En caso de seleccionar el control desde el
microcontrolador, podremos utilizar pulsos PWM para regular la intensidad luminosa de los LEDs. Esto y el
control de velocidad de motores de corriente continua será tema de otro capítulo del tutorial.

Por último, el preset de 10k, que aparece en color azul en las fotos, es el encargado de fijar el nivel de
contraste del display, para que su lectura sea lo más cómoda posible.

El módulo LCD conectado al trainer. El módulo recien armado.


El armado del modulo de expansión no tiene secretos, es muy similar a otros que hemos realizado en
NeoTeo, con la salvedad de que en este caso hemos formado una especie de “sándwich” con la placa de
circuito impreso y el LCD, que se monta sobre pines de bronce para permitir que debajo de él se ubiquen el
transistor, la resistencia de su base y algunos puentes necesarios.

Para el armado utilizaremos de referencia las fotos incluidas en el artículo, y comenzaremos fabricando el
PCB mediante el método explicado anteriormente, para luego soldar todos los componentes, dejando para el
final el montaje del LCD.

En caso de que al alimentar el circuito el LCD este “en blanco”, deberemos ajustar el preset. Cuando el
cursor del mismo está en la mitad del recorrido, el display debería ser perfectamente legible.
Para realizar las prácticas, deberemos conectar este módulo con el PIC Trainer de 40 pines como se ve en la
foto siguiente.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 44


Disposicion de los conectores en el PIC Trainer. PORTD.0 a PORTD.3

PORTD.4 a PORTD.7 PORTB.0 a PORTB.3


Una vez conectado todo, podemos cargar en el PIC el primero de nuestros ejemplos:

A continuación, un par de ejemplos de cómo se utilizan todas estas instrucciones. El primero se encarga de
mostrar un texto parpadeando en la primera línea del display. Intenten deducir como está conectado el LCD
al PIC mirando las instrucciones “DEFINE” del principio del programa.

DEFINE LCD_BITS = 8
DEFINE LCD_DREG = PORTD
DEFINE LCD_DBIT = 0
DEFINE LCD_RSREG = PORTB
DEFINE LCD_RSBIT = 1
DEFINE LCD_EREG = PORTB
DEFINE LCD_EBIT = 3
DEFINE LCD_RWREG = PORTB
DEFINE LCD_RWBIT = 2

LCDINIT 0 ‘inicializo el LCD sin cursor.

Loop:

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 45


LCDOUT "www.NeoTeo.com" ‘Muestra el texto…
WAITMS 1000 ‘Espero un segundo
LCDCMDOUT LcdClear ‘Borro el display
WAITMS 1000 ‘Espero un segundo
GOTO loop ‘Vuelvo a loop: para repetir indefinidamente.

Como podemos deducir a partir de lo visto en el capitulo anterior, el LCD está conectado con el bus de datos
(de 8 bits) en el PORTD, el pin PORTB.1 se emplea para el control de la línea RS del LCD, el pin PORTB.3
para la línea E y el control de R/W está a cargo del PIC, mediante el pin PORTB.2.

En el modulo LCD debemos poner el jumper JP1 en la posición 1-2 para permitir al PIC 16F877A el control
de la gestión de lecto/escritura del LCD.

El siguiente ejemplo solo difiere del anterior en que se utiliza un bus de control de solo 4 bits de ancho, en la
parte baja del PORTD (D.0 a D3) y dejamos la línea R/W siempre en escritura. Para hacer esto, debemos
mover JP1 a la posición 2-3. El cable plano que une la parte alta del PORTD (conector 4) con el LCD puede
ser removido, ya que no pasaran datos por él. Así quedaría el programa:

DEFINE LCD_BITS = 4
DEFINE LCD_DREG = PORTD
DEFINE LCD_DBIT = 0
DEFINE LCD_RSREG = PORTB
DEFINE LCD_RSBIT = 1
DEFINE LCD_EREG = PORTB
DEFINE LCD_EBIT = 3

LCDINIT 0 ‘inicializo el LCD sin cursor.

Loop:
LCDOUT "www.NeoTeo.com" ‘Muestra el texto…
WAITMS 1000 ‘Espero un segundo
LCDCMDOUT LcdClear ‘Borro el display
WAITMS 1000 ‘Espero un segundo
GOTO loop ‘Vuelvo a loop: para repetir indefinidamente.

Si quisiesmos utilizar la parte alta del PORTD como bus de control del LCD, solamente deberíamos cambiar
la línea

DEFINE LCD_DBIT = 0
a
DEFINE LCD_DBIT = 4

El resto del programa quedaría igual. Por supuesto, se debe cambiar de lugar el cable plano de datos, y
ponerlo entre el conector 5 y el LCD, caso contrario, no veremos nada en el display.

El último ejemplo es una adaptación del ejemplo visto en el capitulo anterior: muestra como imprimir el
contenido de una variable (“A”) en el LCD. En el segundo renglón se cuentan los números del 65535 al 0 en
el segundo, mientras que se muestra un texto en el primero.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 46


DEFINE LCD_BITS = 8
DEFINE LCD_DREG = PORTD
DEFINE LCD_DBIT = 0
DEFINE LCD_RSREG = PORTB
DEFINE LCD_RSBIT = 1
DEFINE LCD_EREG = PORTB
DEFINE LCD_EBIT = 3
DEFINE LCD_RWREG = PORTB
DEFINE LCD_RWBIT = 2

DIM A AS WORD
A = 65535
LCDINIT 3 ‘Cursor parpadeando
WAITMS 1000

loop:
LCDOUT "¡Estoy contando!” ‘Texto del primer renglón
LCDCMDOUT LcdLine2Home ‘Paso al Segundo renglón
LCDOUT #A ‘Muestro el valor de A
A = A – 1
WAITMS 250
LCDCMDOUT LcdClear ‘Limpio del display
GOTO loop

Dejamos al lector la tarea de deducir como deben configurase los jumpers del modulo LCD y de qué manera
se conectan los cables entre el entrenado y el LCD.

Es muy recomendable realizar estas prácticas, por simples que puedan parecer, ya que servirán para tomar
confianza con el uso del display, y sobre todo, para poder comenzar a construir nuestros propios programas.

Vista del lado cobre. Diseño del PCB.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 47


Parte IX

Un “cartel de LEDs” , llamado “Publik” en algunos países, es un recurso utilizado muy frecuentemente con
fines publicitarios o informativos. Básicamente, consiste en una matriz de pixeles (si, como la pantalla de tu
ordenador), generalmente de un solo color (rojos), aunque con el descenso de los precios de os LEDs
individuales o en paneles, es cada vez más frecuentes ver carteles “bicolores” o incluso multicolores,
aprovechando la ventaja del los LEDs RGB, que pueden mostrar cualquier color.

Como es de suponer, el desarrollo, construcción y programación de un cartel e este tipo es una tarea bastante
compleja para un principiante, pero desde NeoTeo te animamos a hacerlo, ya que te guiaremos paso a paso a
lo largo de todo el proceso. Y seguramente aprenderás un montón de trucos al hacerlo.

Por motivos de simplificar el circuito y de no gastar demasiado dinero, nuestro cartel será monocromático,
utilizando LEDs de color rojo únicamente. Las dimensiones de la matriz utilizada serán de 7 filas por 80
columnas, lo que permite escribir unas 14 o 16 letras de 7 “pixeles” de altura. A pesar de no ser demasiado
grande, ya habrás sacado la cuenta de que se necesitan 560 LEDs para armar el cartel.

A lo largo de este tutorial hemos visto que encender un LED desde un microcontrolador. Y de hecho es algo
muy simple: conectamos el ánodo del LED al PIC, el cátodo a una resistencia y el extremo de la resistencia a
+V. Cuando el pin del microcontrolador está en “1”, el LED enciende. Este esquema, lamentablemente, no
sirve para la construcción de un cartel matricial como este, ya que al disponer de 560 LEDs necesitaríamos
tener un microcontrolador que tenga como mínimo ese número de pines de salida y por supuesto, no existe.

El secreto está en el multiplexado. Es decir, utilizar unos pocos pines de E/S del microcontrolador para
manejar una serie de circuitos integrados que se encarguen de excitar los LEDs. Hay varias maneras, y
muchos modelos diferentes de circuitos para hacer esto.

Pueden usarse un tipo de integrado digital llamado “LATCH”, que básicamente es una memoria en la que
escribimos un valor, y lo mantiene en sus salidas hasta que nosotros lo indiquemos. De esta manera, usando
varios latches podríamos encender los LEDs por turnos, rápidamente para que no se note el parpadeo, y de
esa manera formar una palabra en el cartel.

Otra forma es utilizar un registro de desplazamiento. Y de hecho, es de esta forma cómo vamos a diseñar
nuestro cartel. Un registro de desplazamiento funciona de la misma manera en que funciona una cola de
gente que espera para entrar en un cine. Por un extremo de la cola van ingresando las personas que llegan, y
por el otro van saliendo de la fila. En un registro de desplazamiento, en lugar de personas tenemos “0” y “1”.
Lo bueno de esto es que para “meter” datos (“0”s y “1”s) en el registro de desplazamiento solo hacen falta
tres pines del microcontrolador, independientemente de lo largo que sea.

Estos pines se encargan de tres tareas: Uno de ellos, al que denominaremos “DATA” es el encargado de
decirle al registro de desplazamiento que lo que introduciremos es un “0” o un “1”. El segundo se encarga de
avisar al registro que el dato ya está listo para ser ingresado, y lo llamaremos “CLOCK”. Y el ultimo, que no
es indispensable, es el “RESET”, que se encarga de “vaciar” la fila escribiendo “0”s en todas las salidas del
registro.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 48


En este proyecto utilizaremos un modelo de circuito integrado conocido como 74HC164N, que es un registro
de desplazamiento de 8 bits. Es decir, con el se puede armar una “fila” de 8 “personas”. Como nuestro cartel
tiene 80 columnas, necesitaremos utilizar 10 de estos integrados, uno a continuación del otro. En NeoTeo ya
hemos hablado sobre él, así que sería interesante que leas el artículo correspondiente si quieres saber más
sobre su funcionamiento.

En la figura siguiente puedes ver la función de cada pin de este integrado, y la manera de conectar uno a
continuación del otro para obtener un registro de desplazamiento de cualquier longitud.

Función de cada pin del 74HC164N. Interconexión de varios 74xx164N entre sí.
Bien, con el esquema explicado podemos encender los LEDs que queramos de una fila de 80 bits de largo. Si
en el registro de desplazamiento introducimos “11111…111”, los 80 LEDs estarán encendidos. Si queremos
encender uno por medio, escribiremos “10101…01”. Por supuesto, cuando lleguemos a la parte de la
programación veremos cómo se ingresan uno a uno los “0” y “1” en el registro.

Ahora bien: nuestro cartel tiene 7 filas, y lo explicado solo sirve para manejar una de ellas ¿debemos utilizar
un registro de desplazamiento para cada una de las filas restantes? Afortunadamente, la respuesta es no. Si
bien podríamos utilizar 7 registros de este tipo, la cantidad de circuitos integrados necesarios (56 de ellos), la
complejidad del circuito impreso y el costo implicado lo hacen poco aconsejable. Nosotros aprovecharemos
un “defecto” del ojo humano, que mantiene la imagen vista durante unos 20 o 30 milisegundos, para
“dibujar” una fila a la vez, pero muy rápidamente, de forma que todo el cartel parezca estar encendido a la
vez. Si, como en la tele o el cine.

Cuando comenzamos el articulo mencionábamos que para manejar cada LED serian necesarios 560 pines de
entrada/salida. Con el esquema propuesto solo necesitamos 7 para seleccionar la fila a escribir, y tres para
manejar el registro de desplazamiento. Es decir, un PIC de 3 u$s y 18 pines serviría perfectamente para
realizar el proyecto. Y es lo que usaremos, un 16F628A.

El resultado de este proyecto es muy vistoso. Se pueden tener diferentes tipos de letras.

¿Cómo funciona la matriz?

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 49


Como dijimos antes, la pantalla está formada por una serie de filas y columnas. La intersección entre ambas
contiene un LED. Para que este encienda, tiene que recibir simultáneamente un “0” en la fila, y un “1” en la
columna. Cuando se dan estas condiciones, la electrónica de la placa se encarga del encendido. La forma de
generar un mensaje sobre el display es relativamente sencilla, si nos atenemos al siguiente algoritmo:
1) Apagar todas las filas.
2) Escribir los valores correspondientes a la primer fila en el registro de desplazamiento, teniendo en
cuenta que el primer digito binario colocado corresponde al último LED de la fila, y el ultimo en
poner al de la primer columna.
3) Encenderla primer fila, esperar un tiempo, y volver a apagarla.
4) Repetir los pasos para las filas 2 a 7.

Los tiempos de demora que utilizamos en el programa de ejemplo permiten una visualización correcta, sin
molestos parpadeos y con los LEDS brillantes. Hay que tener en cuenta que si utilizamos tiempos mayores
para el encendido de cada fila, el brillo de los LEDS será mayor, pero también aumentara el parpadeo. No
utilizamos vectores ni otras alternativas que hubieran servido para crear un código más compacto, buscando
la claridad del programa, para que pueda servir como base a otros más completos/complejos.

Un punto a tener en cuenta es el brillo de los LEDs. Un LED, utilizado en aplicaciones “normales”, se
alimenta con unos 3V y requiere unos 15mA (varia ligeramente de un modelo a otro9 para brillar con una
buena intensidad. En nuestro caso, a pesar de que veremos las 7 filas encendidas al mismo tiempo, cada LED
solo estará encendido la séptima parte del tiempo, por lo que su brillo será siete veces inferior al normal, y
nuestro cartel apenas será visible.

Afortunadamente eso tiene solución: dado que los tiempos que permanecerá encendido cada LED no
superara unos pocos milisegundos, no se dañaran si hacemos circular una corriente mayor a la nominal, con
brillará mucho más intensamente, dando como resultado un cartel perfectamente visible.

Respecto de los LEDs, podremos utilizar LEDs discretos (y soldar 1120 terminales) o comprar “paneles” de
7x5 LEDs que tienen unos 14 o 16 terminales (según el modelo), estando ya interconectados en forma de
matriz.

Hemos dividido este proyecto en varias partes, ya que su complejidad impide explicarlo en un solo artículo,
así que en la próxima entrega diseñaremos la totalidad del hardware necesario, y en la siguiente nos
dedicaremos a programar nuestro cartel. ¡Hasta la próxima!

Podemos utilizar LEDs individuales. Panel de 7x5 LEDs, menos para soldar.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 50


Parte X

Nuestro cartel tiene fines meramente educativos, y la intención es gastar poco dinero para construirlo, así que
intentaremos realizarlo en base a un microcontrolador pequeño. Si el lector necesita un cartel de mayor
tamaño o con capacidad para almacenar textos o imágenes más extensos, deberá utilizar algún micro con
mayor capacidad y velocidad. El tamaño de la memoria EEPROM externa es bastante grande, pero también
puede ser ampliado con mucha facilidad.

Dividiremos el esquema electrónico del cartel en dos partes: en primer lugar veremos toda la lógica de
control, y en segundo, la “pantalla” con el registro de desplazamiento. A la hora de llevarlo a la práctica
puede incluso hacer dos circuitos impresos por separado. Esto le permitirá al lector experimentar con otros
controladores sin necesidad de volver a montar la placa de los displays.

El circuito controlador:
Este es el cerebro de nuestro cartel. Sera el encargado de gestionar el encendido de cada LED mediante
órdenes enviadas a las columnas (mediante el registro de desplazamiento que mencionamos en la nota
anterior) y a las filas.

Como una fila tendrá 80 LEDs, que eventualmente pueden estar todos encendidos, no podemos conectarlas
directamente a pines de E/S del PIC, por que la corriente que demandarían haría que el puerto del PIC se
destruya. Para evitar esto, utilizaremos en medio un transistor capaz de manejar esa corriente.

Analicemos el circuito. El centro de todo es el microcontrolador 16F628A, que tiene su pin de RESET
conectado a un pulsador y una resistencia de 10K. Este pulsador permite reiniciar el cartel cuando lo
necesitemos. También se ha implementado un circuito de reloj externo, basado en un cristal de 4 MHz y dos
condensadores de 22 nanofaradios. Esto le permite al PIC ejecutar un millón de instrucciones por segundo,
más que suficientes para este proyecto.

Los pines 1 y 2, correspondientes a los bits A2 y A3 del micro, se han utilizado para acceder a una memoria
EEPROM del tipo 24C256. Esta memoria es de acceso serial (por eso necesitamos solo dos pines), mediante
el protocolo I2C, y tiene capacidad para almacenar 32768 Bytes. Si nuestro programa hace uso de ella,
podemos guardar allí 32768 caracteres (con el display en modo texto) o más de 400 pantallas en modo
gráfico. Si resultara insuficiente, puede ponerse una memoria de mayor capacidad, siempre consultando la
hoja de datos de la misma para asegurarnos su compatibilidad con la del ejemplo.

Todo el puerto B del PIC está dedicado a controlar las filas del cartel. Como ya habrán notado, tenemos 8
salidas para filas, y nuestro cartel tiene solo 7 filas. Efectivamente, la fila 8 no se utilizara si nuestra
“pantalla” está construida con módulos LED de 7x5, pero el circuito de control está preparado para el uso (en
caso de que alguien los prefiera) de módulos de 8x8 o bien para crear un cartel de 8 filas mediante el uso de
LEDs sueltos. Quienes utilicen módulos de 7x9 pueden ahorrarse el transistor de la fila 8.

Por último, los pines 17 y 18, correspondientes a los bits A0 y A1 del micro se encargan de la gestión del
registro de desplazamiento. El programa deberá generar los pulsos de reloj necesarios por el pin 18, y
“meter” los datos en el registro por el pin 17.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 51


No hemos incluido una fuente de alimentación. Cualquier fuente comercial que sea capaz de entregar 5V y
2A será suficiente. Esos 5V deben estar bien regulados, y por supuesto, el software deberá estar escrito
correctamente, es decir, no encender varias filas al mismo tiempo, ya que el consumo de todo el cartel
encendido sería de unos 80 x 70 x 20mA = 11.2 A, destruyendo la fuente.

Este es el cerebro de nuestro cartel.


El display
Esta es la parte del proyecto que todo el mundo va a mirar, así que debemos ser prolijos al montarlo. Como
puede verse en el esquema eléctrico, hemos utilizado un total de 10 circuitos integrados 74HC164N para
construir el registro de desplazamiento de 80 bits de largo, uno para cada columna. Si alguien quiere hacer un
cartel más largo o más corto, deberá poner más o menos integrados. Cada uno maneja 8 columnas.

Si miramos el esquema del display, veremos que en la parte superior se muestra como está conectado cada
LED dentro de la matriz de 5x7. Esto es importante tenerlo en cuenta a la hora de comprar los módulos, ya
que hay una gran cantidad de modelos, y la mitad de ellos tienen los LEDs conectados en el sentido inverso.

Cada display también difiere en la función de cada terminal, por lo que se debe estar a atento a la hoja de
datos para diseñar el circuito impreso apropiado, y conectarlos como corresponda.

En el dibujo del circuito no hemos representado los 16 módulos ni los 10 circuitos integrados, por una
cuestión de espacio, pero es fácil darse cuenta de qué forma se conectan las filas y columnas de los demás
displays a cada 74HC164N.

No utilizaremos el pin de RESET de los 74HC164N. En lugar de ser controlados desde el microcontrolador,
cada RESET está puesto a +5V, de forma que el integrado funcione continuamente. Si por algún motivo se

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 52


desea borrar la pantalla, basta con enviar 80 “0”s al registro de desplazamiento y listo. El tiempo empleado
para esa tarea es despreciable, ya que el microcontrolador estará ejecutando 1 millón de instrucciones por
segundo. El utilizar una línea de control menos nos permitirá tener un PCB ligeramente más sencillo.

Cada salida de los 74HC164N, como dijimos, se conecta a una columna de la serie de displays . Esta
conexión se efectúa mediante un resistor de 1/8 de watt, que en el esquema se ha dibujado con un valor de
330 ohm. Ese fue el valor adecuado para el tipo de módulos que conseguimos para hacer el prototipo, pero su
valor variara de un modulo a otro. Se puede montar solo un display con resistores de 330 ohms, y ver como
es el brillo de los LEDs. Si es escaso, se puede bajar el valor a 220 o 100 ohms. Con eso debería ser
suficiente

En la próxima entrega, la última de este proyecto, veremos cómo utilizar el BASIC del PIC SIMULATOR
IDE para programar el cartel.

Hemos utilizado un total de 10 circuitos integrados 74HC164N.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 53


Parte XI

Como vimos en la primer y segunda entrega de esta serie, el cartel del LEDs que estamos construyendo
puede adoptar diferentes tamaños de acuerdo a las necesidades o componentes que cada uno consiga. Esto
hace que sea imposible proporcionar un programa específico que funcione en cualquier versión de cartel que
se haya construido, pero sin embargo podemos hacer algo mucho mejor: ver de qué manera se escribe un
programa de este tipo en BASIC (PIC SIMULATOR IDE) para que cada uno lo adecue a su proyecto.

Debemos pensar en un programa que nos permita mostrar pixeles individuales representados sobre la
pantalla de nuestro cartel. Vamos a tomar como ejemplo un cartel que tenga una longitud de 80 columnas y
7 filas de altura, pero todo lo que expliquemos puede ser adecuado para carteles de otro tamaño.

Lo primero que necesitamos saber es que el “barrido” del cartel debe hacerse por filas. Es decir, mostraremos
el contenido de la primera fila, esperamos un tiempo determinado (unos pocos milisegundos), mostramos el
de la segunda fila, esperamos nuevamente, y así hasta llegar a la última fila. El motivo de no emplear las
columnas para realizar el barrido es que como son más numerosas, el tiempo total que se necesita para
“escribir” por filas es mucho menor que el necesario para escribir por columnas, y en la práctica eso significa
que el brillo de nuestro cartel será mucho mayor si lo hacemos por filas, ya que cada LED permanecerá
encendido 1/7 del tiempo. Si lo hiciésemos por columnas, cada LED estaría encendido solo 1/80 del tiempo,
por lo que su brillo seria unas 10 veces menor.

Ahora bien, el primer problema a resolver es ¿Cómo escribo los datos de una fila del cartel? Bien, este tiene
una solución más que simple: solo debemos introducir en el registro de desplazamiento los “0” y “1”
necesarios para que los LEDs que queremos estén encendidos en esa fila tengan +V en sus ánodos. Por
supuesto, mientras hacemos esto todos los pines del microcontrolador que controlan las filas deberán estar
apagados, para que no se perciba una débil luminosidad en todos los LEDs de la fila que estamos escribiendo
a medida que pasan los datos a través del registro.

El primer valor que se debe “meter” en el registro de desplazamiento es el que corresponder a la última
columna. A medida que vamos ingresando los siguientes, se van desplazando (de ahí viene el nombre de
“registro de desplazamiento”) hacia el final del cartel. Cuando hayamos introducido el valor número 80 (que
corresponderá a la primera columna) el primer valor que metimos habrá llegado a su posición. En ese
momento tenemos todo el registro escrito, y ya podemos activar la salida del PIC que corresponde a esa fila
en particular.

El tiempo que debe estar encendida la fila se puede determinar empíricamente, pero por lo generan unos 10
milisegundos es suficiente. Si tenemos 7 filas, 10 milisegundos de demora permitirían escribir todo el cartel
en unos 70 milisegundos, por lo que obtendríamos un máximo de 1000/70 = 14 “frames” por segundo. Este
es un muy buen valor para una pantalla de este tipo, ya que solo estamos mostrando un texto y no un video.

En los cálculos anteriores no tuvimos en cuenta el tiempo que se demora en escribir los 80 valores en el
registro de desplazamiento. Veamos porque: cada valor ingresado en el registro de desplazamiento demora
unos 2 microsegundos. Es decir, demoramos 2 x 80 = 160 millonésimas de segundo en escribir toda la fila.
Si multiplicamos este valor por 7 tendremos en tiempo que necesitamos para escribir las 7 filas del cartel, lo
que nos da 1136 millonésimas de segundo, es decir, poco más de 1 milésima. Este es un tiempo despreciable
frente a las 70 milésimas que nos tomamos para mostrar la imagen de cada fila.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 54


Los carteles de este tipo se utilizan cada día más.
Ahora vamos a ver, en BASIC, como hacer para escribir un valor en el registro de desplazamiento.
Recordemos que el dato ingresa al registro en el momento que se produce la transición de “0” a “1” del pulso
de CLOCK, por lo que se deberán seguir los siguientes pasos para ingresar cada uno de los 80 valores
correspondientes a cada fila:
1) Fijar el valor del dato a escribir (si DATA es 1, hacer PORTA.0 = 1, si no PORTA.0 = 0)
2) Poner la línea de CLOCK en estado bajo (PORTA.1 = 0).
3) Esperar un 1 microsegundo (WaitUs 1)
4) Poner la línea de CLOCK en estado alto (PORTA.1 = 1). En este punto el dato entra
5) efectivamente en el registro de desplazamiento.
6) Esperar un 1 microsegundo (WaitUs 1)
7) Fin

En BASIC, si hemos declarado que:


Symbol clock = PORTA.1
Symbol data = PORTA.0
Un “0” se escribiría así:
data = 0
clock = 0
WaitUs 1
clock = 1
WaitUs 1

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 55


Y un “1” de la siguiente manera:

data = 1
clock = 0
WaitUs 1
clock = 1
WaitUs 1

Para escribir los 80 valores de la fila necesitamos hacer una subrutina que, tomando 10 bytes de la memoria
EEPROM (10 bytes x 8 bits = 80 bits, es decir, una fila completa) los vuelque al registro de desplazamiento.

Si repetimos 7 veces este procedimiento, tendríamos una pantalla de 7x80 completa. Eso significa que en la
EEPROM cada pantalla va a necesitar de 70 bytes (10 bytes por fila, 7 filas) para almacenar el mapa de bits
correspondiente.

Veamos un ejemplo de cómo podría ser la subrutina encargada de escribir un byte tomado de la EEPROM en
el registro de desplazamiento, a la que hemos llamado escriboByte:

escriboByte:
For columna = 1 To 8
If dato.7 = 0 Then
data = 0
clock = 0
WaitUs 1
clock = 1
WaitUs 1
Else
data = 1
clock = 0
WaitUs 1
clock = 1
WaitUs 1
Endif
aux = ShiftLeft(dato, 1)
Next columna
Return

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 56


Esta función debe ser llamada 10 veces para escribir la fila completa, con el valor a escribir guardado en la
variable “dato”. El motivo por el cual el bucle FOR-NEXT toma los bits del byte desde el 7 hasta el 0 se
debe a que justamente el último bit es el que debe ingresar primero al registro de desplazamiento, tal como
explicamos antes.

Debemos partir de la base de que la información de la EEPROM la vamos a grabar desde un ordenador, y que
seguramente crearemos un programa que permita, a partir de un texto determinado, generar los bits
individuales que componen el bitmap de cada pantalla del cartel. Esto simplifica muchísimo la programación
del microcontrolador, ya que solo debe dedicarse a leer la EEPROM y volcar su contenido al registro de
desplazamiento, sin tener que “dibujar” las letras a partir de una tabla ni nada por el estilo.

Para animar el texto mostrado en el display hay dos opciones. La primera de ella es que, una vez que el
bitmap de la EEPROM ha sido mostrado en la pantalla, comencemos a redibujarla continuamente (si no lo
hacemos, el texto desaparecerá de la pantalla) pero cada un tiempo determinado (1 segundo por ejemplo)
escribimos un bit “0” más en cada fila. Es decir, escribimos 81 bits en el primer segundo, 82 en el segundo,
etc. Esto hará que el texto se desplace de izquierda a derecha, y es la animación más fácil de implementar.
Sin embargo, lo normal es que los textos de desplacen en sentido contrario, por lo que nuestro programa
debería hacer lo siguiente: comenzar escribiendo 80 “0”s en el registro ANTES de enviar la información de la
fila, luego escribir 79 “0”s , y así sucesivamente. De esa manera, el texto al principio no será visible (estará
“dibujado” a la derecha, fuera del registro de desplazamiento), y luego a medida que el numero de “0”s
escritos va disminuyendo, comenzara a ser visible, entrando desde la derecha.

La segunda manera es que el software que escribe los datos en la EEPROM guarde cada “cuadro” de la
animación, uno a continuación del otro, y que el PIC se limite a escribir cada cuadro leído durante (por
ejemplo) un segundo. Esto vuelve a facilitar mucho la programación del PIC, a la vez que permite
animaciones mucho más complicadas.

Si sabemos que cada pantalla necesita de 70 bytes para almacenarse en la EEPROM, con una 24C256 de
32.768 Bytes podemos almacenar unas 470 pantallas, una cantidad nada despreciable.

Con esta entrega damos por terminado nuestro proyecto. Creemos que en los tres capítulos que dedicamos a
este tipo de carteles están las bases como para que cualquier hobbysta o estudiante se anime y pueda hacer
realidad su propio cartel de LEDs animado. No se trata de un proyecto sencillo, pero una vez terminado
seguramente los llenara de orgullo. Desde NeoTeo los animamos a que encaren este proyecto, y que por
supuesto, nos comenten los resultados.

Podemos emplear LEDs azules.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 57


Fuentes:

Tutorial de PicBasic
1. http://www.neoteo.com/tutorial-programacion-de-microcontroladores.neo
2. http://www.neoteo.com/tutorial-programacion-de-microcontroladores-2366.neo
3. http://www.neoteo.com/tutorial-programacion-de-microcontroladores-2423.neo
4. http://www.neoteo.com/tutorial-programacion-de-microcontroladores-2472.neo
5. http://www.neoteo.com/tutorial-programacion-de-microcontroladores-2523.neo
6. http://www.neoteo.com/tutorial-programacion-de-microcontroladores-2567.neo
7. http://www.neoteo.com/tutorial-programacion-de-microcontroladores-parte.neo
8. http://www.neoteo.com/tutorial-programacion-de-microcontroladores-2683.neo
9. http://www.neoteo.com/tutorial-programacion-de-microcontroladores-2767.neo
10. http://www.neoteo.com/tutorial-programacion-de-microcontroladores-3260.neo
11. http://www.neoteo.com/tutorial-programacion-de-microcontroladores-3415.neo

Entrenadora Pic18F2550
1. http://www.neoteo.com/entrenador-para-pic-18f2550.neo
2. http://www.neoteo.com/-19871-bootloader-para-18f2550-entrenador-neoteo.neo
3. http://www.neoteo.com/-19871-bootloader-para-18f2550-entrenador-neoteo/pg-2.neo
4. http://www.neoteo.com/-19871-bootloader-para-18f2550-entrenador-neoteo/pg-3.neo

Recursos:
• HEX y Cargador Download
• Proyecto completo Download
• MPLAB Página de Microchip
• C18 Página de Microchip
• Librerías completas Página de Microchip

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 58


Adicionales:

01 - Entrenador para PIC 18F2550

Con el entrenador que hoy te traemos comenzamos una pequeña serie de artículos que te permitirán disfrutar
un PIC de 8 bits de alto rendimiento: el 18F2550. En esta primera entrega abordaremos los detalles
constructivos y particularidades de este entrenador. Con las características elementales e imprescindibles de
hoy, esta herramienta de desarrollo nos ayudará a tener una plataforma de trabajo orientada a ensayar los
códigos que luego elevaremos hacia aplicaciones más complejas. Conectividad USB, bus I2C, múltiples
entradas analógicas con resolución de 10 bits y todas las prestaciones por descubrir que puede ofrecerte el
PIC18F2550. Si estabas necesitando un entrenador sencillo, robusto y útil, no busques más; aquí lo has
encontrado.

Dentro del micromundo de aquellos que nos dedicamos a hacer experimentos con microcontroladores
existimos los que trabajamos en forma exclusiva con PIC. Existen otras personas que sólo utilizan Atmel, por
ejemplo. Es decir, cuando un diseñador encuentra comodidad en el manejo y versatilidad en las prestaciones,
se decanta por una marca de preferencia o, como también se acostumbra a decir, por una familia en
particular. Hay quienes prefieren una marca específica para una aplicación en particular y otras marcas para
otros destinos, alternando así las opciones que el mercado ofrece según el diseño a realizar. Dentro de toda
esa fauna electrónica también convivimos los que “adoptamos” un tipo de microcontrolador y hacemos con
él todos los ensayos que intentamos aprender.

El PIC 18F2550, el pequeño "gigante" con USB


Así como tuvieron su época de esplendor el 16F84A, el 16F628A, el 16F877A, hoy el 18F2550 se presenta
como un microcontrolador muy similar al (también antiguo) 16F876A pero con las grandes ventajas que
brinda la familia 18F. Se destacan, entre otras cualidades, un mayor tamaño de memoria disponible para
almacenar programas, sumado a la posibilidad de realizar aplicaciones con conectividad USB. Ventajas muy
atractivas en la actualidad gracias a la proliferación de ordenadores móviles donde el puerto serie ha dejado
su reinado en manos de los puertos USB. Luego de armar y desarmar una y otra vez sobre una placa de

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 59


pruebas o un protoboard un circuito para ensayar, un nuevo termómetro I2C que hemos comprado, un
acelerómetro con salidas lineales o un flamante LCD gráfico que nos acaban de regalar, nos damos cuenta
que debemos tener un sistema armado y siempre funcional donde podamos realizar las prácticas iniciales
de aquellos dispositivos que luego traslademos hacia aplicaciones mayores, más elaboradas y complejas. Sin
embargo, siempre utilizamos el mismo protoboard que, sin que podamos evitarlo, con el uso intensivo
comienza a tener contactos que no funcionan del todo bien y muchas veces frustran nuestros intentos de
hacer un ensayo rápido y exitoso.

Todos los puertos tienen conexión al exterior


Otras ocasiones más graves son aquellas en las que, por la premura de lograr un trabajo rápido, equivocamos
conexiones elementales y dañamos componentes que nos cuestan mucho dinero. Peor aún es el caso de
aquellos que no poseen siquiera un protoboard y se encuentran obligados a armar un circuito sobre una placa
universal de pruebas. Los enjambres de cables y las soldaduras “gordas o anchas” pueden ser mortales para
un microcontrolador y un dolor de cabeza (y bolsillo) muy grande para nosotros. Es por todo esto que
decidimos armar este entrenador para PIC 18F2550. No para estudiar el funcionamiento del
microcontrolador mencionado sino para utilizar una plataforma sencilla de circuito y adaptarla de acuerdo a
los experimentos que vayan surgiendo en el camino y sean dignos de observar, estudiar y analizar.

¿Recuerdas la cantidad de montajes que hemos visto armados en un protoboard durante este año y el 2009?
Muchos en los que sólo deseábamos ensayar un trozo de código, un dispositivo I2C o una aplicación del
ADC de un microcontrolador. A partir de ahora los trabajos pequeños tendrán su soporte en este entrenador.
Tampoco será un desarrollo capaz de trabajar con múltiples microcontroladores, ni varias alimentaciones, ni
diferentes cristales osciladores. Nada de eso. Será el PIC que utilizamos siempre, con el cristal que
colocamos siempre, con posibilidad de instalar rápidamente el display que utilizamos siempre. Por lo tanto, a
este entrenador no te lo anunciamos como una gran novedad tecnológica ya que hay miles de aplicaciones
similares y superiores en la web. Te invitamos a que lo implementes para tener un trabajo más ordenado,
más prolijo y con resultados más rápidos y eficaces.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 60


Vista del circuito impreso desarrollado
El circuito impreso es de simple faz y puedes utilizar el material que te resulte más cómodo de trabajar.
Teniendo en cuenta que será una aplicación que utilizaremos a menudo, nosotros hemos hecho el prototipo
sobre FR3 (fibra de vidrio) pero si lo deseas, puedes hacer tu construcción sobre material más económico
(FR2). La distribución de los componentes sobre la placa está realizada de manera que si deseamos montar el
display tengamos fácil acceso a las entradas y salidas analógicas/digitales del puerto A y las disponibles del
puerto B y C. Recuerda que para el display se utilizan 6 pines del puerto B dejando RB0 y RB1 libres. A su
vez, estos pines corresponden a la conexión del bus I2C (SDA y SCL) y disponen, al igual que el display, de
un conector exclusivo identificado en la serigrafía del lado del cobre. De todos modos, como algunos saben,
existen técnicas de programación que permiten la coexistencia de interruptores (un teclado tipo matriz por
ejemplo) en el mismo puerto donde se conecta el display. Es por esta razón que el puerto B en su totalidad
está disponible con un conector a pesar de estar el display montado en la placa principal.

Vista superior de la placa armada

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 61


La alimentación del sistema no necesitará de una fuente externa en la mayoría de los casos. La alimentación
de 5Volts para el 18F2550 y para (en el caso de utilizarlo) el display pueden provenir sin inconvenientes
desde cualquier puerto USB del ordenador portátil o del ordenador de mesa. En la sumatoria de todos los
consumos de la placa, no llegaríamos nunca a comprometer la funcionalidad del puerto con consumos de
corriente perjudiciales. Por otro lado, si nuestros ensayos se deben realizar fuera del alcance de un ordenador,
podemos acceder con energía desde cualquier dispositivo que se pueda conectar a la red domiciliaria, al
encendedor del coche o cualquier otro dispensario de energía donde la gente acostumbra a conectar los
teléfonos móviles para su carga de baterías. Donde exista un conector USB podremos obtener energía y
experimentar con este entrenador que hoy te proponemos.

Utilizando un cristal de 20Mhz. podemos realizar aplicaciones que sean de fácil acceso a cualquier ordenador
mediante la conexión USB de datos. Un claro ejemplo de esta técnica lo encontramos en el voltímetro
realizado hace pocas semanas atrás. A partir de la facilidad que nos brinda el entrenador, teniendo todos los
elementos indispensables en una sola placa, conectar el 18F2550 al ordenador será, para aquellos que aún no
lo hayan hecho nunca, una tarea muy sencilla y una experiencia muy enriquecedora.

El entrenador con el LCD instalado y corriendo un programa de prueba


Las posibilidades de conexión que brinda la placa entrenadora son muy amplias. En el prototipo que hemos
preparado, encontramos cuatro entradas analógicas por el puerto A con conectores de tres terminales
dispuestos de manera perpendicular a la posición del PIC. En los tres terminales de cada conector
disponemos de GND, +5Volts y la entrada que nos lleva a cada pin del puerto A. Este tipo de construcción
permite instalar, por ejemplo, un potenciómetro en AN0, una fotocélula (LDR) en AN1, un termómetro tipo
LM35 en AN3, etc. Tener acceso a los 5Volts en cada conector permite alimentar cualquier dispositivo activo
que entregue información analógica a los ADC del puerto A. Debes recordar que mediante la configuración
del registro ADCON1 puedes seleccionar los pines del puerto A que trabajarán como entradas analógicas y
los que funcionarán en modo digital. Estos últimos a través de la instrucción TRIS, se configuran como
entradas o como salidas. Esto es universal en cualquier lenguaje de programación.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 62


Circuito propuesto para la placa entrenadora

Otras salidas digitales disponibles son RC0, RC1 y RC2, siendo esta última muy útil cuando trabajamos con
PWM. RC6 y RC7 se llevan hacia un conector independiente para posibilitar una salida directa hacia un
módulo de conversión TTL – RS232 / RS485 o para utilizarlos como salidas o entradas digitales.
Completan el montaje un conector ICSP para programar el PIC (al igual que lo hemos hecho siempre, o sea,
sin quitarlo de la placa), un pulsador de RESET y un puente (jumper) para conectar o desconectar la luz del
display (backlight). Aplicamos este último recurso para minimizar consumos en aquellos casos en que
estemos alimentando desde el puerto USB del ordenador cualquier fuente de datos conectada a alguna de las
entradas.

Para ensayar, para experimentar, para aprender. Todo con el 18F2550


Un entrenador sencillo, simple y que no viene a eclipsar ni a competir con nadie. No se intenta imitar nada
con este montaje, sólo tener las conexiones ordenadas en una sola placa siempre lista para usar. Dicho de otro
modo: la finalidad aquí es dejar de lado el protoboard para practicar con módulos que se puedan acoplar con
facilidad y ensayar códigos para PIC o para interfaces en el ordenador de manera rápida, sencilla y segura.
Esperamos que puedas armarlo y aprovechar todas las bondades y virtudes del PIC 18F2550 agregando los
módulos que construiremos y estudiaremos de aquí en adelante.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 63


02 - BootLoader para 18F2550 (Entrenador NeoTeo)

Un BootLoader es un pequeño conjunto de instrucciones que forman un programa y se graban, en este caso
en un microcontrolador, para permitir un posterior manejo y actualización de sus programas internos
(firmware) sin necesidad de utilizar programadores (hardware) específicos. Es decir, utilizas un programador
(o quemador) de microcontroladores una única vez para cargarle el mencionado BootLoader al
microcontrolador y luego te bastará con una sencilla aplicación en tu ordenador para cambiar a tu antojo el
funcionamiento de tus sistemas. Todo mediante una vulgar conexión al puerto USB. Las plataformas
modernas que se asemejan a Arduino (incluida ésta) utilizan este sistema de programación y NeoTeo no
podía quedar afuera. Ahora la programación está al alcance de todos.

Es imposible resumir en un sumario de pocas palabras las infinitas ventajas que posee un BootLoader.
Sólo debes imaginarte la situación: tu hardware, tu ordenador y un cable de conexión USB entre ambos. Eso
es todo lo que necesitas para transformar al entrenador NeoTeo en un voltímetro, en un videojuego, en un
operador de servomotores y en miles de cosas más. A pesar de que el conector ICSP es una de las
herramientas maestras de las que dispone una persona que se dedica a experimentar con microcontroladores,
la utilización de un BootLoader te ahorra el uso de un hardware adicional de trabajo como es el programador
(o quemador).

Con un BootLoader pre-cargado en el microcontrolador, eliminas el uso de un programador especial


(quemador)
Un ejemplo de las miles de ventajas que puedes tener sería este: Tú le has vendido a Max una aplicación y
luego de un tiempo de uso él te expresa su lamento y pesar sobre algunas deficiencias del producto, mientras
te comenta que desearía que hagas algunas mejoras para lograr un funcionamiento óptimo y acorde a sus
necesidades. ¿Qué deberías hacer en esa situación? ¿Pedirle a Max que desarme todo el equipo y te lo
envíe? Imposible. ¿Viajar tú de un país a otro para cambiar dos líneas de programa, conectar el hardware
programador y demorar menos de cinco minutos en resolver el problema? ¡De locos! En cambio, si el
sistema inicial posee la sencilla carga previa de un BootLoader, le envías a Max un pequeño archivo por
correo electrónico y él mismo podrá actualizar la versión de firmware con un elemental cable USB
conectado a su ordenador. Así trabajan Arduino, Amicus y todas las plataformas similares que compiten en
la web. Así de sencillo y tentador. ¿Quieres verlo? Observa como se cambia de una aplicación a otra diferente
en apenas algunos segundos:

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 64


El principio de funcionamiento de un BootLoader es fácil de comprender. Se trata de un pequeño software,
que se instala en un microcontrolador y ocupa un pequeño espacio de memoria dentro de él. Su única
funcionalidad es servir de “anfitrión” para permitir la programación o re-programación del microcontrolador
sin necesidad de un hardware específico, a veces costoso y que no es sencillo de armar ni utilizar. Toda la
tarea de reinstalar un nuevo software para lograr diferentes trabajos por parte del microcontrolador, o al
menos una actualización del firmware ya existente y funcional, se resume a un cable que une el
microcontrolador con el ordenador. Puede ser una conexión por puerto serie (COM) o, lo que es mejor aún y
que se utiliza en la actualidad, por puerto USB. Aquí tienes otro ejemplo de cómo funciona un sistema de
carga con BootLoader (carga un programa que enciende el LED amarillo)

El resto del trabajo lo realiza una aplicación instalada en el ordenador que será la encargada de detectar la
petición de grabación desde el microcontrolador y cargarle un nuevo programa o, como mencionamos antes,
actualizar el existente. Si el microcontrolador no realiza un llamado de solicitud anunciando una conexión
para una grabación de datos, el ordenador interpretará la conexión como un hecho natural y atenderá a la
aplicación existente y funcional dentro del microcontrolador trabajando en conjunto con este dispositivo y
realizando las operaciones que la aplicación requiera. Por ejemplo, el Voltímetro NeoTeo. También puede
suceder que no necesites conectar nunca tu aplicación a un ordenador para que realice su trabajo y cumpla
una tarea.

Por ejemplo: algunos de los carteles de LEDs que indican el recorrido de un transporte de pasajeros. Ese es
un claro ejemplo donde el desarrollo no se utiliza “enlazado” a un ordenador. El empleado que se encarga de
diagramar los viajes conecta un ordenador portátil mediante un cable USB, ejecuta una aplicación y con
un simple clic del ratón cambia los textos del cartel indicador. Otros sistemas más modernos y
sofisticados le transmiten al cartel la actualización de información mediante un enlace Wi-Fi. ¿Y cómo
cargan la información recibida dentro del microcontrolador? Mediante el BootLoader anfitrión que el
microcontrolador ya posee en su interior.

La Ley De Moore al acecho


Además, el camino irreversible de la miniaturización y la alta integración de los semiconductores nos
entregan día a día dispositivos más pequeños y en encapsulados (package) muy difíciles de manipular. La
mayoría de los microcontroladores “poderosos” del mercado comienzan a aparecer en encapsulados muy
pequeños. Esto significa que retirarlos de una placa, colocarlos en un programador y luego restituirlos al PCB
donde cumplen su función es un trabajo imposible de realizar sin destruir al menos una docena de pines y/o
calcinar el dispositivo y/o las vías del PCB. Por lo tanto, amigos, los tiempos de gloria del 16F84A, del
16F628A y hasta del mismo 18F2550 (que utilizamos en nuestra placa de entrenamiento) están llegando a su
final. Quizás la visión de quien escribe estas líneas pueda parecer algo pesimista. Pero si se detienen a
observar la mayoría de (por no decir todas) las placas de entrenamiento que comercializan las marcas líderes
en microcontroladores, notarán que poseen versiones de montaje superficial para sus MCU
(microcontroladores) y los medios de programación son el ICSP (con hardware programador) y por medio de
BootLoaders. Estos últimos pueden ser por puerto serie o por puerto USB.

Para muestra, basta el botón que acabas de ver: MPLAB Starter Kit for PIC 18F MCU (que sería el primer
escalón para comenzar a trabajar en el mundo de Microchip - MPLAB utilizando los PIC de la línea 18F)
trabaja mediante el uso de BootLoaders. Toda la intervención con el hardware se limita a conectar un cable
USB y a cargar nuestros programas. El soldador (cautín) ya comienza a desaparecer de la mesa de trabajo del

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 65


desarrollador. En su lugar comienzan a abundar otras herramientas virtuales que ayudarán a reducir en
forma notoria muchos métodos de “prueba y error” utilizados hasta ahora. Ya no bastará con que el sistema
funcione en el simulador dentro del ordenador sino que también deberá hacerlo en la placa de entrenamiento.
Pues entonces si hacia allí vamos, adaptemos nuestra placa de entrenamiento NeoTeo con el 18F2550 e
ingresemos al futuro nosotros también.

Una solución de código abierto


Microchip posee herramientas gratuitas que se pueden descargar desde su sitio web y nos pueden ayudar a
desarrollar aplicaciones con un mínimo de inversión y con la posibilidad de adquirir un aprendizaje muy
importante. Dentro de las posibilidades que ofrece el sitio para trabajar con BootLoaders encontramos una
aplicación dedicada a la familia del PIC 18F4550 mediante la conectividad USB que este microcontrolador
brinda. Sobre esta plataforma basaremos nuestro trabajo adaptando el “programa base” que Microchip
ofrece para satisfacer nuestras necesidades de uso dentro de la placa de entrenamiento NeoTeo.

Microchip ofrece una multitud de ejemplos y programas gratuitos para iniciarse en el mundo de los
microcontroladores.

Por ejemplo: en el BootLoader ofrecido (para el 18F4550) se utiliza el puerto D para colocar un LED
indicador de estado. El 18F2550 no posee puerto D y en consecuencia tendremos que efectuar alteraciones
allí. Por otro lado, un pulsador ubicado en el pin 4 del puerto B (en el desarrollo de Microchip para el
18F4550) nos resulta incómodo ya que el puerto B de nuestro entrenador estaría dedicado a un LCD
alfanumérico y al bus I2C. Esta sería entonces otra variante a realizar sobre el programa original. Dicho
nuevamente: partiendo de un sistema “base” reformaremos el BootLoader original para migrar desde un
18F4550 a un 18F2550.

Dentro de las cosas necesarias para desarrollar la aplicación de este artículo encontramos el software que
utilizaremos para armar nuestro BootLoader “a medida”. Para esto necesitamos tener instalado en nuestro
ordenador el entorno de trabajo MPLAB en su última versión (8.50 al momento de escribir este artículo), el
compilador MPLAB C para PIC18 (que en realidad es una versión de evaluación por 60 días que puede
desinstalarse y reinstalarse en forma indefinida) y por último necesitaremos la librería Microchip
Applications Library donde encontraremos una cantidad muy generosa de material para desarrollar
programas y aplicaciones. Por supuesto, dentro de este paquete se halla la aplicación (USB Framework) que
utilizaremos en este artículo, esto es, el conjunto de archivos BootLoader para diversas familias de
microcontroladores, entre ellas, la que utiliza nuestra placa entrenadora. Un detalle a destacar en este punto
es que creemos que no es necesario detallar un tutorial con todos los pasos para que instales estos programas.
Lo fundamental que debes saber es que son gratuitos y que si tienes alguna duda durante el proceso, la
instalación completa de todas las opciones presentadas es la mejor alternativa.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 66


Comienza el trabajo de reforma
Una vez instaladas las aplicaciones, encontraremos dentro de nuestro ordenador y en la ruta “C:\Microchip
Solutions\USB Device – Bootloaders\HID – Bootloader\HID Bootloader – Firmware for PIC18 Non – J
Devices” el código fuente a utilizar para nuestro propósito. Pero antes debemos saber qué vamos a reformar
y por qué lo haremos. En nuestro caso particular, realizaremos una adaptación del hardware y software
original para que se transforme en un instrumento compatible con nuestra placa entrenadora. Cabe aclarar
que el conjunto de archivos encontrados en la ruta indicada están preparados con las placas de entrenamiento
de Microchip, por lo tanto nos cruzaremos con múltiples asignaciones y reservas de hardware que para
nuestro objetivo son innecesarias. Por ejemplo, dentro de uno de los ficheros a reformar existen pines del
PIC18F4550 asignados a conexiones con el bus SPI, entre tantos pines reservados que para nuestro objetivo
primario no tienen utilidad. En otros casos, pines reservados del puerto D no existen dentro del PIC18F2550.

El Hardware
El programa básico que viene para trabajar con el 18F4550 posee un interruptor en el pin 4 del puerto B que
se utiliza para indicarle a la placa de entrenamiento que deseamos iniciar el sistema de carga de una nueva
aplicación al PIC mediante el uso del BootLoader. En nuestra aplicación (nuestra entrenadora) el puerto B
estaría reservado para la conexión de un display LCD y para el bus de datos I2C, por lo que sería apropiado
utilizar otros pines libres para colocar este pulsador. El pin 2 del puerto C es una buena opción para este
propósito. Por otro lado, el LED que indica la entrada en funcionamiento del PIC en el modo de carga de una
nueva aplicación se ubica en el pin 1 del puerto D en los archivos que corresponden al 18F4550.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 67


Placa utilizada para activar el modo BootLoader

Nuestro PIC no posee puerto D; por lo tanto no tenemos otra opción que cambiar la ubicación de este
indicador luminoso hacia el pin 1 del puerto C. De este modo, podemos notar y observar que necesitamos
construir una pequeña placa con un pulsador y un par de LEDs para adaptar nuestra entrenadora al trabajo
con un sistema de pre-carga o BootLoader. El aspecto del circuito y la placa es muy sencillo: se destaca el
pulsador para activar el modo BootLoader y los LEDs indicadores de estado. Gracias al uso de conectores
hembra utilizados en la placa entrenadora NeoTeo, es muy simple organizar un pequeño circuito impreso
para que el sistema final resulte cómodo, agradable y eficaz. Por lo tanto, queda claro entonces que hemos
utilizado los pines RC0, RC1, RC2 y GND para conectar la nueva placa en nuestra entrenadora. Estas
asignaciones de pines debemos trasladarlas al Software en el próximo paso .

Nuestra entrenadora con la flamante placa instalada La misma situación pero ensayando con un LCD

El turno del Software

Sólo un archivo del código ejemplo que ofrece Microchip deberá ser cambiado por las
razones mencionadas en los textos anteriores. Este archivo se encuentra en la ruta de acceso
que mencionamos antes y es io_cfg.h. El nombre del archivo es muy explícito en su función:
io_cfg es donde se configuran los pines de entrada y salida del proyecto. Todos los demás
archivos involucrados en el directorio son compatibles para una gran cantidad de
microcontroladores PIC 18F, entre ellos el que utiliza nuestra placa entrenadora, el 18F2550.
Los modelos soportados son PIC18F4553/4458/2553/2458, PIC18F4550/4455/2550/2455,
PIC18F4450/2450 y PIC18F14K50/13K50. Por lo tanto, cualquiera de estos
microcontroladores que utilice nuestro proyecto final podrá funcionar con este programa BootLoader
siempre que tengamos en cuenta una correcta distribución de pines de acuerdo a nuestra necesidad de
aplicación en el Hardware.
Hay muchas definiciones (#define) dentro del archivo indicado que escapan del uso sencillo y didáctico que

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 68


deseamos brindar en este artículo. Por ejemplo, las utilizadas para el uso de un potenciómetro (reóstato,
resistor variable) o de tarjetas FLASH de almacenamiento masivo de datos (SD / MMC). Todas esas
definiciones y asignación de pines fueron comentadas ya que sólo estamos detrás de un objetivo simple:
Cargar un archivo BootLoader y manejar nuestro desarrollo libre de programadores de PICs
únicamente con un cable USB. Esto es ideal para actualizaciones de firmware en tareas de campo. Las
ampliaciones que la experiencia nos exija pueden esperar. Primero debemos comprender bien qué estamos
haciendo y el potencial que tiene este desarrollo de manejar las actualizaciones de software de la manera más
sencilla a la que se pueda acceder con elementos de uso diario. Este razonamiento de comprensión y
familiarización con las herramientas es válido tanto para nosotros como para nuestros “clientes” o aquellas
personas a las que les brindamos nuestros desarrollos.

Resumiendo los cambios de Software: Sólo un archivo hay que reformar: io_cfg.h. Si utilizas la placa
entrenadora NeoTeo, te darás cuenta de manera muy fácil cómo y dónde hemos realizado la reforma si
husmeas en el archivo indicado. Notarás muchas líneas comentadas con la clásica doble barra inclinada (//).

Resumiendo el Hardware: Una elemental placa pequeña que puedes realizar en pocas horas utilizando
elementos de uso habitual en cualquier desarrollo. Resistores un pulsador, un capacitor, un impreso sencillo y
algunos pines de conexión.

Vista del impreso utilizado en nuestro ejemplo antes de colocar los componentes
Comencemos
Esto es el inicio del trabajo con BootLoaders en las aplicaciones ofrecidas a terceros. Como en todo orden
de la vida, existe gente convencida de que se trata de lo mejor en actualización de Firmware a distancia
(con posibilidad de ejecución por el mismo cliente) y otros insisten con que la técnica del ICSP (In Circuit
Serial Program) es la mejor ya que es uno mismo el que supervisa el trabajo de actualización y puede
solucionar cualquier “accidente” que por error pueda generar el cliente. Como mencionamos más arriba,
Microchip ofrece en la actualidad sistemas que son capaces de conectarse a la web de manera automática y
actualizar su firmware sin que el usuario se entere.

Es decir, hay muchos métodos y formas de trabajar con pre-cargadores de archivos o BootLoaders. Nosotros

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 69


te traemos el inicio de cómo lograr resultados exitosos desde el primer intento. Es por esto que te ofrecemos
al final del artículo dos archivos donde encontrarás todo lo necesario para comenzar. En el fichero
“Archivos_Unicos” encontrarás el HEX que debes grabar en el PIC con un grabador convencional de PICs
(quemador = PicKit2/Pickit3/ICD2/ICD3/GTP-USB +, etc) y al finalizar su grabación conectarás tu
desarrollo (o nuestra placa entrenadora) a cualquier puerto USB de tu ordenador para que el trabajo sea
identificado como una interfaz HID. Importante: Para que esta operación se realice con éxito, deberás
insertar el conector USB manteniendo pulsado el botón SW (BootLoader). La imagen obtenida muestra el
comienzo del proceso mientras el BootLoader se instala en la raíz de Dispositivos de Interfaz de Usuario
(HID)

Mensaje que aparece al ser detectado el sistema HID - BootLoader


Una vez conectado el sistema con el BootLoader pre-grabado en el PIC, detectado por el ordenador, instalado
y “listo para ser utilizado”, los LEDs comenzarán a encender en forma alternada. Esta es la señal de que el
BootLoader está listo para recibir el programa principal de trabajo. Ese será el momento en que todo estará
preparado para iniciar el funcionamiento del pequeño software que utilizarás para cargar los resultados de tus
"firmwares" en el PIC con sólo usar un cable USB. Un software gratuito, muy sencillo de utilizar y muy
intuitivo (a pesar de estar desarrollado en inglés) el HIDBootLoader es un programa que podrás ofrecer a
terceros para que ellos mismos actualicen el firmware del desarrollo que le has vendido, entregado, regalado
o prestado (este programa está incluído en los archivos que te ofrecemos para descargar). En primera
instancia, el programa detectará la conexión al dispositivo y su estado de BootLoader iniciado presentando
una pantalla como la siguiente, donde el botón para abrir una fila del tipo HEX se habilita.

Aspecto que presenta el programa HIDBootloader al encontrar que has pulsado el botón SW

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 70


Lo que continúa es muy fácil de intuir. Pulsando el botón “Open Hex File” accederás al archivo a cargar
dentro del PIC para programarlo con la real aplicación del desarrollo, por ejemplo, con el programa para
hacer funcionar un termómetro I2C o un reloj en tiempo real RTC. El paso siguiente es programar el PIC con
el botón “Program / Verify” y allí comenzará el proceso de grabación. Primero se borrará cualquier dato
contenido en la zona a programar dentro del PIC y una vez limpios los registros de memoria se dará paso a la
programación del dispositivo. Por último, el programa efectúa un control y verificación de las tareas
realizadas emitiendo un mensaje satisfactorio cuando todo transcurrió con normalidad.

Listo! El programa ha sido cargado y ya puedes pulsar RESET


Además de este fichero HEX pre-armado por nosotros y separado en un archivo aparte para que no te
confundas (Archivos_Unicos), en el fichero “BOOTLOADER_NEOTEO” está todo lo necesario para
trabajar y modificar este desarrollo, es decir, todo lo que MPLAB necesita para que puedas reformar la
aplicación a tu medida. Claro está, los archivos anteriores también están allí. Ahora sólo restan conceptos que
tú serás el único capacitado para resolver. Saber cuándo te encuentras frente a una aplicación que necesita
actualizaciones con tu presencia o no. Saber cuándo se justifica utilizar un BootLoader o cuándo un conector
ICSP es suficiente. Luego de toda esta explicación con palabras y gráficos.

Tal como mencionamos al principio, el BootLoader es un programa anfitrión que reside dentro del
microcontrolador y se utiliza para facilitar la programación de estos dispositivos. A pesar de ser un programa
pequeño, ocupa espacio de memoria interna en el microcontrolador que no podrá sobrescribirse ya que de
ese modo estaríamos pisoteando y arruinando las líneas de código del programa BootLoader con nuestro
código de aplicación. Para evitar esta catástrofe debemos “reservar” un espacio para que el BootLoader se
acomode dentro del microcontrolador y sólo sea activado mediante el pulsador (SW) dedicado a este
propósito. Este pequeño programa anfitrión que se desarrolla con esta aplicación se ubicará en la parte más
baja del mapa de memoria del PIC ocupando hasta la dirección 0xFFF. Por lo tanto todos los programas que
intentemos cargar deberán grabarse desde la posición 0x1000 en adelante. De lo contrario, romperemos el
programa BootLoader y el sistema desarrollado no funcionará.

¿Cómo se realiza esto? El los programas escritos en lenguaje ASM se utilizan las directivas ORG para
indicar el posicionamiento de los vectores de inicio de programas. En C o en C18 también se hacen llamadas
a lenguaje ASM para “mapear” los vectores de RESET, es decir, a partir de qué posición de memoria
comenzará a funcionar el PIC si el botón SW (BootLoader) no es activado al momento de conectar el
desarrollo al puerto USB. En el caso de cualquier lenguaje BASIC bastará con una declaración ubicada en
una única línea. Por ejemplo en Proton sería “DECLARE PROTON_START_ADDRESS = $1000”

Hay sistemas que utilizan menos espacio de memoria interna para el programa BootLoader, en los que el
vector de reset de una aplicación se ubica en 0x0800. Como habrás observado siempre, nuestra intención es
guiarte, ayudarte y recorrer juntos el camino que resulte más sencillo y cómodo para el inicio. MPLAB posee

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 71


una herramienta para visualizar la cantidad de memoria ocupada por el programa y nuestro BootLoader
(ejemplo extraído de la librería de Microchip) ofrece la siguiente imagen entrando en la vista de este
parámetro.

Utilización de los recursos de memoria según MPLAB

Resumen final
Antes de lanzarnos a diseñar aplicaciones con un sistema de BootLoader debemos tener en claro si la
aplicación justifica su uso. La experiencia nos dirá si es necesario o no. Vender un sistema de letreros
luminosos a una empresa de vehículos de transporte de larga distancia con sede en Estambul merece utilizar
este sistema de actualización a distancia realizado por algún técnico local o directivo de la empresa. Construir
una pequeña central que controle la temperatura y la humedad de nuestra habitación no justifica este trabajo
ya que el ICSP nos soluciona todo el problema en cuestión de minutos. Es decir, a partir de ahora y con las
herramientas en la mano, el que sabe y decide eres tú.

Por último, y como es lógico entender, el pulsador y los LEDs indicadores de funcionamiento deberán estar
integrados en tu construcción final de manera permanente si deseas utilizar el método de pre-cargador
(BootLoader). RC2 (para nuestra aplicación) siempre debe estar polarizada en un estado alto al encender el
sistema o al conectarlo al puerto USB. Caso contrario, el programa interpretará un estado bajo y de ese modo
creerá que queremos cargar un nuevo programa. Por lo tanto, esto no es algo que se pueda utilizar sólo para
cargar el programa al microcontrolador sino que es parte del Hardware final y definitivo. En cambio, los
pines que operan los LEDs indicadores pueden ser reutilizados dentro del Hardware para otras funciones.
Comparte tus experiencias, mejora nuestro desarrollo y cuéntanos tus resultados. Cerramos con la frase que
siempre te decimos: tú y tu ingenio sabrán hacerlo mejor.

Fuente: www.NeoTeo.com – Compilado por Ing. César Aguirre 72


Anexo 01: Diagrama PCB de Entrenadora NeoTeo Pic18F2550
Anexo 02: Microchip Pic18F2550 – Advance Information
PIC18F2455/2550/4455/4550
28/40/44-Pin High-Performance, Enhanced Flash USB
Microcontrollers with nanoWatt Technology
Universal Serial Bus Features: Peripheral Highlights:
• USB V2.0 Compliant SIE • High current sink/source: 25 mA/25 mA
• Low-speed (1.5 Mb/s) and full-speed (12 Mb/s) • Three external interrupts
• Supports control, interrupt, isochronous and bulk • Four Timer modules (Timer0 to Timer3)
transfers • Up to 2 Capture/Compare/PWM (CCP) modules:
• Supports up to 32 endpoints (16 bidirectional) - Capture is 16-bit, max. resolution 6.25 ns (TCY/16)
• 1-Kbyte dual access RAM for USB - Compare is 16-bit, max. resolution 100 ns (TCY)
• On-board USB transceiver with on-chip voltage - PWM output: PWM resolution is 1 to 10-bit
regulator • Enhanced Capture/Compare/PWM (ECCP) module:
• Interface for off-chip USB transceiver - Multiple output modes
• Streaming Parallel Port (SPP) for USB streaming - Selectable polarity
transfers (40/44-pin devices only) - Programmable dead-time
- Auto-Shutdown and Auto-Restart
Power Managed Modes:
• Addressable USART module:
• Run: CPU on, peripherals on - LIN bus support
• Idle: CPU off, peripherals on • Master Synchronous Serial Port (MSSP) module
• Sleep: CPU off, peripherals off supporting 3-wire SPI™ (all 4 modes) and I2C™
• Idle mode currents down to 5.8 µA typical Master and Slave modes
• Sleep current down to 0.1 µA typical • 10-bit, up to 13-channels Analog-to-Digital Converter
• Timer1 oscillator: 1.1 µA typical, 32 kHz, 2V module (A/D) with programmable acquisition time
• Watchdog Timer: 2.1 µA typical • Dual analog comparators with input multiplexing
• Two-Speed Oscillator Start-up
Special Microcontroller Features:
Flexible Oscillator Structure: • C compiler optimized architecture with optional
• Five Crystal modes, including High-Precision PLL extended instruction set
for USB • 100,000 erase/write cycle Enhanced Flash
• Two External RC modes, up to 4 MHz program memory typical
• Two External Clock modes, up to 40 MHz • 1,000,000 erase/write cycle data EEPROM
• Internal oscillator block: memory typical
- 8 user selectable frequencies, from 31 kHz to 8 MHz • Flash/data EEPROM retention: > 40 years
- User tunable to compensate for frequency drift • Self-programmable under software control
• Secondary oscillator using Timer1 @ 32 kHz • Priority levels for interrupts
• Fail-Safe Clock Monitor • 8 x 8 Single Cycle Hardware Multiplier
- Allows for safe shutdown if any clock stops • Extended Watchdog Timer (WDT):
- Programmable period from 41 ms to 131s
• Programmable Code Protection
• Single-supply 5V In-Circuit Serial Programming™
(ICSP™) via two pins
• In-Circuit Debug (ICD) via two pins
• Wide operating voltage range (2.0V to 5.5V)
Comparators

Program Memory Data Memory MSSP


EAUSART

10-bit CCP/
# Single- Timers
Device FLASH SRAM EEPROM I/O A/D ECCP SPP Master
Word SPI 8/16-bit
(bytes) (bytes) (bytes) (ch) (PWM) I2C
Instructions
PIC18F2455 24K 12288 2048 256 24 10 2/0 No Y Y 1 2 1/3
PIC18F2550 32K 16384 2048 256 24 10 2/0 No Y Y 1 2 1/3
PIC18F4455 24K 12288 2048 256 35 13 1/1 Yes Y Y 1 2 1/3
PIC18F4550 32K 16384 2048 256 35 13 1/1 Yes Y Y 1 2 1/3

 2003 Microchip Technology Inc. Advance Information DS39617A-page 1


PIC18F2455/2550/4455/4550
Pin Diagrams

28-Pin SDIP, SOIC

MCLR/VPP/RE3 1 28 RB7/KBI3/PGD
RA0/AN0 2 27 RB6/KBI2/PGC
RA1/AN1 3 26 RB5/KBI1/PGM
RA2/AN2/VREF-/CVREF 4 25 RB4/AN11/KBI0/RCV
5 24 RB3/AN9/CCP2*/VPO

PIC18F2455
PIC18F2550
RA3/AN3/VREF+
RA4/T0CKI/C1OUT 6 23 RB2/AN8/INT2/VMO
RA5/AN4/SS/LVDIN/C2OUT 7 22 RB1/AN10/INT1/SCK/SCL
VSS 8 21 RB0/AN12/INT0/SDI/SDA
OSC1/CLKI/RA7 9 20 VDD
OSC2/CLKO/RA6 10 19 VSS
RC0/T1OSO/T13CKI 11 18 RC7/RX/DT/SDO
RC1/T1OSI/CCP2*/UOE 12 17 RC6/TX/CK
RC2/CCP1 13 16 D+/VP
VUSB 14 15 D-/VM

40-Pin PDIP

MCLR/VPP/RE3 1 40 RB7/KBI3/PGD
RA0/AN0 2 39 RB6/KBI2/PGC
RA1/AN1 3 38 RB5/KBI1/PGM
RA2/AN2/VREF-/CVREF 4 37 RB4/AN11/KBI0/CSSPP
RA3/AN3/VREF+ 5 36 RB3/AN9/CCP2*/VPO
RA4/T0CKI/C1OUT 6 35 RB2/AN8/INT2/VMO
RA5/AN4/SS/LVDIN/C2OUT 7 34 RB1/AN10/INT1/SCK/SCL
RE0/CK1SPP/AN5 8 RB0/AN12/INT0/SDI/SDA
PIC18F4455
PIC18F4550

33
RE1/CK2SPP/AN6 9 32 VDD
RE2/OESPP/AN7 10 31 VSS
AVDD 11 30 RD7/SPP7/P1D
AVSS 12 29 RD6/SPP6/P1C
OSC1/CLKI/RA7 13 28 RD5/SPP5/P1B
OSC2/CLKO/RA6 14 27 RD4/SPP4
RC0/T1OSO/T13CKI 15 26 RC7/RX/DT/SDO
RC1/T1OSI/CCP2*/UOE 16 25 RC6/TX/CK
RC2/CCP1/P1A 17 24 D+/VP
VUSB 18 23 D-/VM
RD0/SPP0 19 22 RD3/SPP3
RD1/SPP1 20 21 RD2/SPP2

Note: Pinouts are subject to change.


* Assignment of this feature is dependent on device configuration.

DS39617A-page 2 Advance Information  2003 Microchip Technology Inc.


PIC18F2455/2550/4455/4550
Pin Diagrams (Continued)

RC1/T1OSI/CCP2*/UOE
RC0/T1OSO/T13CKI
RC2/CCP1/P1A
44-Pin QFN

RC6/TX/CK

RD3/SSP3
RD2/SSP2
RD1/SSP1
RD0/SSP0
D+/VP
D-/VM

VUSB
41
40
39

37
36
35
34
42
44
43

38
RC7/RX/DT/SDO 1 33 OSC2/CLKO/RA6
RD4/CCP2*/P2A 2 32 OSC1/CLKI/RA7
RD5/SSP5/P1B 3 31 VSS
RD6/SSP6/P1C 4 30 AVSS
RD7/SSP7/P1D 5 PIC18F4455 29 VDD
VSS 6 28 AVDD
AVDD 7 PIC18F4550 27 RE2/OESPP/AN7
VDD 8 26 RE1/CK2SPP/AN6
RB0/AN12/INT0/SDI 9 25 RE0/CK1SPP/AN5
RB1/AN10/INT1/SCK/SCL 10 24 RA5/AN4/SS/LVDIN/C2OUT
RB2/AN8/INT2/VMO 11 23 RA4/T0CKI/C1OUT
15
16
17
18
19
20
21
22
12
13
14

RA0/AN0
RB4/AN11/KBI0/CSSPP
RB5/KBI1/PGM
RB3/AN9/CCP2*/VPO

MCLR/VPP/RE3

RA1/AN1
RA2/AN2/VREF-/CVREF
NC

RB6/KBI2/PGC
RB7/KBI3/PGD

RA3/AN3/VREF+

RC1/T1OSI/CCP2*/UOE
RC2/CCP1/P1A
RC6/TX/CK

RD3/SPP3
RD2/SPP2
RD1/SPP1
RD0/SPP0

44-Pin TQFP
D+/VP
D-/VM

VUSB

NC
41
40
39

37
36
35
34
42
44
43

38

RC7/RX/DT/SDO 1 33 NC
RD4/SPP4 2 32 RC0/T1OSO/T13CKI
RD5/SPP5/P1B 3 31 OSC2/CLKO/RA6
RD6/SPP6/P1C 4 30 OSC1/CLKI/RA7
RD7/SPP7/P1D 5 PIC18F4455 29 VSS
VSS 6 28 VDD
VDD 7 PIC18F4550 27 RE2/OESPP/AN7
RB0/AN12/INT0/SDI/SDA 8 26 RE1/CK2SPP/AN6
RB1/AN10/INT1/SCK/SCL 9 25 RE0/CK1SPP/AN5
RB2/AN8/INT2/VMO 10 24 RA5/AN4/SS/LVDIN/C2OUT
RB3/AN9/CCP2*/VPO 11 23 RA4/T0CKI/C1OUT
15
16
17
18
19
20
21
22
12
13
14
RB4/AN11/KBI0/CSSPP
RB5/KBI1/PGM

MCLR/VPP/RE3
RA0/AN0
RA1/AN1
RA2/AN2/VREF-/CVREF
NC
NC

RB6/KBI2/PGC
RB7/KBI3/PGD

RA3/AN3/VREF+

Note: Pinouts are subject to change.


* Assignment of this feature is dependent on device configuration.

 2003 Microchip Technology Inc. Advance Information DS39617A-page 3


PIC18F2455/2550/4455/4550
NOTES:

DS39617A-page 4 Advance Information  2003 Microchip Technology Inc.


Note the following details of the code protection feature on Microchip devices:
• Microchip products meet the specification contained in their particular Microchip Data Sheet.

• Microchip believes that its family of products is one of the most secure families of its kind on the market today, when used in the
intended manner and under normal conditions.

• There are dishonest and possibly illegal methods used to breach the code protection feature. All of these methods, to our
knowledge, require using the Microchip products in a manner outside the operating specifications contained in Microchip's Data
Sheets. Most likely, the person doing so is engaged in theft of intellectual property.

• Microchip is willing to work with the customer who is concerned about the integrity of their code.

• Neither Microchip nor any other semiconductor manufacturer can guarantee the security of their code. Code protection does not
mean that we are guaranteeing the product as “unbreakable.”

Code protection is constantly evolving. We at Microchip are committed to continuously improving the code protection features of our
products. Attempts to break microchip’s code protection feature may be a violation of the Digital Millennium Copyright Act. If such acts
allow unauthorized access to your software or other copyrighted work, you may have a right to sue for relief under that Act.

Information contained in this publication regarding device Trademarks


applications and the like is intended through suggestion only
and may be superseded by updates. It is your responsibility to The Microchip name and logo, the Microchip logo, dsPIC,
ensure that your application meets with your specifications. KEELOQ, MPLAB, PIC, PICmicro, PICSTART, PRO MATE and
No representation or warranty is given and no liability is PowerSmart are registered trademarks of Microchip
assumed by Microchip Technology Incorporated with respect Technology Incorporated in the U.S.A. and other countries.
to the accuracy or use of such information, or infringement of
FilterLab, microID, MXDEV, MXLAB, PICMASTER, SEEVAL
patents or other intellectual property rights arising from such
and The Embedded Control Solutions Company are
use or otherwise. Use of Microchip’s products as critical
registered trademarks of Microchip Technology Incorporated
components in life support systems is not authorized except
in the U.S.A.
with express written approval by Microchip. No licenses are
conveyed, implicitly or otherwise, under any intellectual Accuron, Application Maestro, dsPICDEM, dsPICDEM.net,
property rights.
ECONOMONITOR, FanSense, FlexROM, fuzzyLAB, In-
Circuit Serial Programming, ICSP, ICEPIC, microPort,
Migratable Memory, MPASM, MPLIB, MPLINK, MPSIM,
PICC, PICkit, PICDEM, PICDEM.net, PowerCal, PowerInfo,
PowerMate, PowerTool, rfLAB, rfPIC, Select Mode,
SmartSensor, SmartShunt, SmartTel and Total Endurance are
trademarks of Microchip Technology Incorporated in the
U.S.A. and other countries.

Serialized Quick Turn Programming (SQTP) is a service mark


of Microchip Technology Incorporated in the U.S.A.

All other trademarks mentioned herein are property of their


respective companies.

© 2003, Microchip Technology Incorporated, Printed in the


U.S.A., All Rights Reserved.

Printed on recycled paper.

Microchip received QS-9000 quality system


certification for its worldwide headquarters,
design and wafer fabrication facilities in
Chandler and Tempe, Arizona in July 1999
and Mountain View, California in March 2002.
The Company’s quality system processes and
procedures are QS-9000 compliant for its
PICmicro® 8-bit MCUs, KEELOQ® code hopping
devices, Serial EEPROMs, microperipherals,
non-volatile memory and analog products. In
addition, Microchip’s quality system for the
design and manufacture of development
systems is ISO 9001 certified.

DS39617A-page 5 Advance Information  2003 Microchip Technology Inc.


WORLDWIDE SALES AND SERVICE
AMERICAS ASIA/PACIFIC Korea
168-1, Youngbo Bldg. 3 Floor
Corporate Office Australia
Samsung-Dong, Kangnam-Ku
2355 West Chandler Blvd. Suite 22, 41 Rawson Street
Seoul, Korea 135-882
Chandler, AZ 85224-6199 Epping 2121, NSW
Tel: 82-2-554-7200 Fax: 82-2-558-5932 or
Tel: 480-792-7200 Australia
82-2-558-5934
Fax: 480-792-7277 Tel: 61-2-9868-6733
Technical Support: 480-792-7627 Fax: 61-2-9868-6755 Singapore
Web Address: http://www.microchip.com 200 Middle Road
China - Beijing
#07-02 Prime Centre
Atlanta Unit 915
Singapore, 188980
3780 Mansell Road, Suite 130 Bei Hai Wan Tai Bldg.
Tel: 65-6334-8870 Fax: 65-6334-8850
Alpharetta, GA 30022 No. 6 Chaoyangmen Beidajie
Beijing, 100027, No. China Taiwan
Tel: 770-640-0034
Tel: 86-10-85282100 Kaohsiung Branch
Fax: 770-640-0307
Fax: 86-10-85282104 30F - 1 No. 8
Boston Min Chuan 2nd Road
China - Chengdu
2 Lan Drive, Suite 120 Kaohsiung 806, Taiwan
Westford, MA 01886 Rm. 2401-2402, 24th Floor, Tel: 886-7-536-4818
Tel: 978-692-3848 Ming Xing Financial Tower Fax: 886-7-536-4803
Fax: 978-692-3821 No. 88 TIDU Street
Chengdu 610016, China Taiwan
Chicago Tel: 86-28-86766200 Taiwan Branch
333 Pierce Road, Suite 180 Fax: 86-28-86766599 11F-3, No. 207
Itasca, IL 60143 Tung Hua North Road
China - Fuzhou Taipei, 105, Taiwan
Tel: 630-285-0071
Unit 28F, World Trade Plaza Tel: 886-2-2717-7175 Fax: 886-2-2545-0139
Fax: 630-285-0075
No. 71 Wusi Road
Dallas Fuzhou 350001, China EUROPE
4570 Westgrove Drive, Suite 160 Tel: 86-591-7503506
Austria
Addison, TX 75001 Fax: 86-591-7503521
Tel: 972-818-7423 Durisolstrasse 2
China - Hong Kong SAR A-4600 Wels
Fax: 972-818-2924 Unit 901-6, Tower 2, Metroplaza Austria
Detroit 223 Hing Fong Road Tel: 43-7242-2244-399
Tri-Atria Office Building Kwai Fong, N.T., Hong Kong Fax: 43-7242-2244-393
32255 Northwestern Highway, Suite 190 Tel: 852-2401-1200 Denmark
Farmington Hills, MI 48334 Fax: 852-2401-3431 Regus Business Centre
Tel: 248-538-2250 China - Shanghai Lautrup hoj 1-3
Fax: 248-538-2260 Room 701, Bldg. B Ballerup DK-2750 Denmark
Kokomo Far East International Plaza Tel: 45-4420-9895 Fax: 45-4420-9910
2767 S. Albright Road No. 317 Xian Xia Road France
Kokomo, IN 46902 Shanghai, 200051 Parc d’Activite du Moulin de Massy
Tel: 765-864-8360 Tel: 86-21-6275-5700 43 Rue du Saule Trapu
Fax: 765-864-8387 Fax: 86-21-6275-5060 Batiment A - ler Etage
China - Shenzhen 91300 Massy, France
Los Angeles
Rm. 1812, 18/F, Building A, United Plaza Tel: 33-1-69-53-63-20
18201 Von Karman, Suite 1090 No. 5022 Binhe Road, Futian District Fax: 33-1-69-30-90-79
Irvine, CA 92612 Shenzhen 518033, China
Tel: 949-263-1888 Germany
Tel: 86-755-82901380 Steinheilstrasse 10
Fax: 949-263-1338 Fax: 86-755-8295-1393 D-85737 Ismaning, Germany
Phoenix China - Shunde Tel: 49-89-627-144-0
2355 West Chandler Blvd. Room 401, Hongjian Building Fax: 49-89-627-144-44
Chandler, AZ 85224-6199 No. 2 Fengxiangnan Road, Ronggui Town Italy
Tel: 480-792-7966 Shunde City, Guangdong 528303, China Via Quasimodo, 12
Fax: 480-792-4338 Tel: 86-765-8395507 Fax: 86-765-8395571 20025 Legnano (MI)
San Jose China - Qingdao Milan, Italy
2107 North First Street, Suite 590 Rm. B505A, Fullhope Plaza, Tel: 39-0331-742611
San Jose, CA 95131 No. 12 Hong Kong Central Rd. Fax: 39-0331-466781
Tel: 408-436-7950 Qingdao 266071, China Netherlands
Fax: 408-436-7955 Tel: 86-532-5027355 Fax: 86-532-5027205 P. A. De Biesbosch 14
Toronto India NL-5152 SC Drunen, Netherlands
6285 Northam Drive, Suite 108 Divyasree Chambers Tel: 31-416-690399
Mississauga, Ontario L4V 1X5, Canada 1 Floor, Wing A (A3/A4) Fax: 31-416-690340
Tel: 905-673-0699 No. 11, O’Shaugnessey Road United Kingdom
Fax: 905-673-6509 Bangalore, 560 025, India 505 Eskdale Road
Tel: 91-80-2290061 Fax: 91-80-2290062 Winnersh Triangle
Japan Wokingham
Benex S-1 6F Berkshire, England RG41 5TU
3-18-20, Shinyokohama Tel: 44-118-921-5869
Kohoku-Ku, Yokohama-shi Fax: 44-118-921-5820
Kanagawa, 222-0033, Japan
Tel: 81-45-471- 6166 Fax: 81-45-471-6122 07/28/03

DS39617A-page 6 Advance Information  2003 Microchip Technology Inc.


This datasheet has been download from:

www.datasheetcatalog.com

Datasheets for electronics components.


Anexo 03: Microchip Pic18F2550
Flash Microcontroller Programming Specification
Anexo 04: Microchip Pic18F2550
28/40/44-Pin, High-Performance, Enhanced Flash,
USB Microcontrollers with nanoWatt Technology