Páginas

jueves, 1 de marzo de 2012

[Emb Comp Lab] Sintaxis BASIC en PIC

BASIC es el acrónimo de Beginners All-purpose Symbolic Instruction Code ("Código de instrucciones simbólicas de propósito general para principiantes")

"Forma parte de la familia de lenguajes de alto nivel. Originalmente fue desarrollado como una herramienta de enseñanza; se diseminó entre las microcomputadoras hogareñas a partir de la década de 1980. Actualmente continúa siendo muy popular, en muchos dialectos bastante distintos del original. FUENTE: http://es.wikipedia.org/wiki/BASIC

Se dice que es un lenguaje hecho para niños, que ya esta en desuso, pero la verdad es de los pocos lenguajes "old school" que siguen vigentes para su uso.

BASIC fue diseñado para permitir a los estudiantes escribir programas usando terminales de un computador en tiempo compartido. Estaba pensado para reducir notablemente la complejidad de los otros lenguajes del momento, diseñado específicamente para un usuario más sencillo fuera del área de las ciencias de la computación y a quien no le interesaba tanto la velocidad, sólo el hecho de ser capaz de programar y usar la máquina sin demasiadas complicaciones. Los diseñadores del lenguaje también querían que permaneciera en el dominio público, lo cual contribuyó a que se diseminara rápidamente.

Los ocho principios que rigeron el diseño de BASIC fueron:
  1. Ser fácil de usar para los principiantes.
  2. Ser un lenguaje de propósito general (no orientado).
  3. Permitir a los expertos añadir características avanzadas, conservando simple el lenguaje para los principiantes.
  4. Ser interactivo.
  5. Proveer mensajes de error claros y amigables.
  6. Responder rápido en los programas pequeños.
  7. No requerir un conocimiento del hardware de la computadora.
  8. Proteger al usuario del sistema operativo.

Tipos de Datos


En BASIC existen 4 distintos tipos de variables, según el dato que puedan almacenar:
  • 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 bytes de longitud, almacena números enteros entre 0 y 4,294,967,295)
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. El numero de variables esta lógicamente limitado al monto de memoria RAM disponible en cada microcontrolador.
Las variables deben ser declaradas antes de utilizarlas, mediante la instrucción DIM, como se muestra en los siguientes ejemplos:
 DIM A AS BIT
 DIM B AS BYTE
 DIM X AS WORD
 DIM Y AS LONG
También es posible utilizar vectores o arreglos, es decir, una matriz de dimensiones 1xN . Por ejemplo:
 DIM A(10) AS BYTE
aqui declaramos un vector de diez elementos del tipo BYTE, que serán accedidos mediante el uso de subíndice (entre paréntesis) del 0 al 9.

Las variables tipo WORD 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 BYTE pueden ser accedidos individualmente 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

RESERVE


La sentencia RESERVE le permite al programador reservar un numero 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

Puertos


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
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
Los registros PORTA, PORTB (y en algunos casos PORTC) contienen el estado de los terminales de entrada-salida correspondiente.
Los registros TRISA, TRISB (y en algunos casos TRISC) se utilizan para configurar los terminales de entrada-salida.

SYMBOL


Una forma de escribir programas que nos resulten mucho mas 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
Luego, si queremos encender el LED, en lugar de
 PORTB.0 = 1
podemos hacer
 LED1 = 1
que es mucho mas claro y fácil de leer. Por supuesto, el código que aparece a la derecha del igual no puede contener instrucciones o comandos reservados del sistema.

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

GOTO


Esta es una de las instrucciones más polemicas que se encuentra en todos los dialectos BASIC. GOTO significa literalmente "IR A", y sirve justamente para desviar el flujo del programa a otro punto. Para usar GOTO, es necesario poner una etiqueta en el lugar al que queremos "saltar". Las etiquetas son simplemente nombres terminados en ":", tal como se ve a continuación:
 ...
 calculos:
 ...
 ...
 ...
 GOTO calculos
 ...
En el ejemplo anterior, el programa se ejecutará hasta encontrar la instrucción "GOTO calculos", que hara que se ejecuten nuevamente las instrucciones siguientes a la etiqueta "calculos:". Cabe aclarar que las etiquetas no son un código ejecutable, es decir, no realizan ninguna acción, solo son un "marcador" del lugar al que se puede saltar con GOTO.

Operaciones Lógicas y Matemáticas


Se dispone de cinco operaciones matemáticas básicas, disponibles para las variables tipo BYTE y Word. Estas son
  • suma (operador +)
  • resta (operador -)
  • multiplicación (operador *)
  • division (operador /)
  • módulo (operador MOD)
Por supuesto, el compilador es capaz de combinarlas para obtener operaciones matemáticas mas complejas. Ejemplos:
 DIM A AS WORD
 DIM B AS WORD
 DIM X AS WORD
 A = 123
 B = A * 234
 X = 2
 X = (12345 - B * X) / (A + B)
Tambien es posible calcular raíces cuadradas (aunque el resultado debe ser entero) con la función SQR:
 DIM A AS WORD
 A = 3600
 A = SQR(A)
Para las variables de tipo BIT existen siete operaciones lógicas disponibles. Estas operaciones también están disponibles para variables tipo WORD o BYTE. Por ejemplo:
 DIM A AS BIT
 DIM B AS BIT
 DIM X AS BIT
 X = NOT A
 X = A AND B
 X = A OR B
 X = A XOR B
 X = A NAND B
 X = A NOR B
 X = A NXOR B
 DIM A AS WORD
 DIM B AS WORD
 A = A OR B
 PORTB = PORTC AND %11110000

CICLOS

IF - THEN - ELSE - ENDIF


Como sabemos, al igual que en otros lenguajes de programación, esta sentencia sirve para tomar alguna decisión durante el flujo del programa.
El caso mas simple para utilizar esta instruccion es:
 IF condición THEN instrucción
"IF" significa "SI....", y "THEN" significa "LUEGO" o "ENTONCES". 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".

Muchas veces, luego de evaluar la condición necesitamos ejecutar mas de una instrucción. En los ejemplos vistos en el CASO 1 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:
 IF condición THEN
   instrucción 1
   instrucción 2
   ...
   instrucción n
 ENDIF


Otras veces que de acuerdo a la condición, queremos ejecutar un grupo u otro de instrucciones. Para eso, utilizamos el ELSE:
 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...".

FOR - TO - STEP - NEXT


Nos permite repetir un proceso una determinada cantidad de veces.
Esta estructura necesita 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
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
     instruccion2
     ...
     instruccionn
  NEXT variable2
 NEXT variable1

WHILE - WEND


Tiene el mismo proposito que la estructura anterior. Su declaracion es:
 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. 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 el. 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.

LOOKUP


La función LOOKUP puede ser utilizada para seleccionar un Byte desde una lista de constantes del mismo tipo, de acuerdo al valor de un índice (también 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 la siguiente:
 variable = LOOKUP(byte0, byte1, ..., byteN), indice
Por ejemplo:
 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.

Cabe mencionar que la version de BASIC utilizada en los microcontroladores es mas sencilla que la utilizada en las versiones de escritorio, si desean saber mas sobre este lenguaje pueden visitar este tutorial:
Tutorial BASIC

Referencias

1 comentario: