Menu
in

TUTORIAL: Programación de microcontroladores – Entrega 3

En las dos primeras entregas de nuestro tutorial, vimos como manejar una de las salidas del microcontrolador para encender y apagar un LED. Hoy aprenderemos a leer el estado de un pulsador y usar variables.

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
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
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
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

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.

¿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 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.

Escrito por Ariel Palazzesi

Leave a Reply