CAPÍTULO 2: PROGRAMACIÓN DE LOS MICROCONTROLADORES Usted seguramente sabe que no solo es suficiente conectar el microcontrolador a los otros componentes y encender una fuente de alimentación para hacerlo funcionar, ¿verdad? Hay que hacer algo más. se necesita programar el microcontrolador para que sea capaz de hacer algo útil. Este capítulo trata de la programación en Basic, por lo que vamos a presentar lo básico que tiene que saber para escribir un programa. Le puede parecer complicado, sobre todo si no tiene experiencia en este campo. no se rinda, respire profundamente y empiece a programar...
2.1 LENGUAJE DE PROGRAMACIÓN El microcontrolador ejecuta el programa cargado en la memoria Flash. Esto se denomina el código ejecutable y está compuesto por una serie de ceros y unos, aparentemente sin significado. Dependiendo
de
la
arquitectura
del
microcontrolador, el código binario está compuesto por palabras de 12, 14 o 16 bits de anchura. Cada palabra es interpretada por la CPU como una instrucción a ser ejecutada durante el funcionamiento
del
microcontrolador.
Como es más fácil trabajar con co n el sistema de numeración hexadecimal, el código ejecutable se representa con frecuencia como una serie de los números hexadecimales denominada código Hex. A todas las instrucciones que el microcontrolador puede reconocer y ejecutar se le denominan colectivamente Juego de instrucciones. En los microcontroladores PIC con las palabras de programa de 14 bits de anchura, el conjunto de instrucciones tiene 35 instrucciones diferentes.
Normalmente los programas se escriben en el lenguaje ensamblador cuando se requiere controlar completamente la ejecución de programa. Como el proceso de escribir un código ejecutable era considerablemente arduo, en consecuencia fue creado el primer lenguaje de programación denominado ensamblador (ASM). El proceso de programación se hizo un poco más complicado. Por otro lado, el proceso de escribir un programa dejó de ser una pesadilla. Las instrucciones en ensamblador consisten en las abreviaturas con significado. Un programa denominado ensamblador instalado en la PC compila las instrucciones del lenguaje ensamblador a código máquina (código binario). Este programa compila instrucción a instrucción sin optimización. La ventaja principal del lenguaje ensamblador es su simplicidad y el hecho de que a cada instrucción cle orresponde una localidad de memoria. Como permite controlar todos los procesos puestos en marcha dentro del microcontrolador, este lenguaje de programación todavía sigue siendo popular. Por otro lado, los programas se ejecutan siempre a alta velocidad y en la mayoría de casos no es necesario saber en detalle qué ocurre dentro del microcontrolador. A pesar de todos los lados l ados buenos del lenguaje l enguaje ensamblador, ensa mblador, los programadores siempre han necesitado un lenguaje de programación similar al lenguaje utilizado en el habla cotidiana. Por último, los lenguajes de programación de alto nivel (Basic entre otros) fueron creados. La ventaja principal de estos lenguajes es la simplicidad de escribir un programa. Varias instrucciones en ensamblador se sustituyen por una sentencia en Basic. El programador ya no tiene que conocer el conjunto de instrucciones del microcontrolador utilizado. Ya no es posible conocer exactamente cómo se ejecuta cada sentencia, de todas formas ya no importa.
Normalmente los programas se escriben en el lenguaje ensamblador cuando se requiere controlar completamente la ejecución de programa. Como el proceso de escribir un código ejecutable era considerablemente arduo, en consecuencia fue creado el primer lenguaje de programación denominado ensamblador (ASM). El proceso de programación se hizo un poco más complicado. Por otro lado, el proceso de escribir un programa dejó de ser una pesadilla. Las instrucciones en ensamblador consisten en las abreviaturas con significado. Un programa denominado ensamblador instalado en la PC compila las instrucciones del lenguaje ensamblador a código máquina (código binario). Este programa compila instrucción a instrucción sin optimización. La ventaja principal del lenguaje ensamblador es su simplicidad y el hecho de que a cada instrucción cle orresponde una localidad de memoria. Como permite controlar todos los procesos puestos en marcha dentro del microcontrolador, este lenguaje de programación todavía sigue siendo popular. Por otro lado, los programas se ejecutan siempre a alta velocidad y en la mayoría de casos no es necesario saber en detalle qué ocurre dentro del microcontrolador. A pesar de todos los lados l ados buenos del lenguaje l enguaje ensamblador, ensa mblador, los programadores siempre han necesitado un lenguaje de programación similar al lenguaje utilizado en el habla cotidiana. Por último, los lenguajes de programación de alto nivel (Basic entre otros) fueron creados. La ventaja principal de estos lenguajes es la simplicidad de escribir un programa. Varias instrucciones en ensamblador se sustituyen por una sentencia en Basic. El programador ya no tiene que conocer el conjunto de instrucciones del microcontrolador utilizado. Ya no es posible conocer exactamente cómo se ejecuta cada sentencia, de todas formas ya no importa.
Aunque siempre se puede insertar en el programa una secuencia escrita en ensamblador.
El proceso de escribir un programa en Basic. Al seleccionar la opción apropiada, el programa será compilado en el ensamblador y luego en el código hex que será cargado en el microcontrolador. Similar al lenguaje ensamblador, un programa especializado e instalado en la PC se encarga de compilar un programa a código máquina. A diferencia del ensamblador, los compiladores para los lenguajes de programación de alto nivel crean un código ejecutable que no es siempre tan corto como el código escrito en ensamblador.
La figura anterior describe el proceso de la compilación de programa escrito en Basic en código hex.
Ejemplo de un programa simple escrito en Basic:
VENTAJAS DE LOS LENGUAJES DE PROGRAMACIÓN DE ALTO NIVEL Si alguna vez ha escrito un programa para un microcontrolador PIC en lenguaje ensamblador, probablemente sepa que la arquitectura RISC carece de algunas instrucciones. Por ejemplo, no hay instrucción apropiada para multiplicar dos
números. Por supuesto, este problema se puede resolver gracias a la aritmética que permite realizar las operaciones complejas al descomponerlas en un gran número de operaciones más simples. En este caso, la multiplicación se puede sustituir con facilidad por adición sucesiva (a x b = a + a + a + ... + a). Ya estamos en el comienzo de una historia muy muy larga... No hay que preocuparse al utilizar uno de estos lenguajes de programación de alto nivel como es Basic, porque el compilador encontrará automáticamente la solución a éste problema y otros similares. Para multiplicar los números a y b, basta con escribir a*b.
2.2 CARACTERÍSTICAS PROGRAMACIÓN BASIC
PRINCIPALES
DEL
LENGUAJE
DE
Similar al uso de cualquier lengua que no está limitada a los libros y a las revistas, el lenguaje de programación Basic no está estrechamente relacionado a un tipo particular de ordenador, procesador o sistema operativo. Esto puede ser un problema, ya que Basic varía ligeramente dependiendo de su aplicación (como diferentes dialectos de una lengua). Por consiguiente, en este libro no vamos a darle una descripción detallada de todas las características de Basic, sino presentar una aplicación muy concreta de Basic, lenguaje de programación utilizado en el compilador mikroBasic PRO for PIC.
El Basic es un lenguaje de programación simple y fácil de entender. Para utilizarlo correctamente, basta con conocer sólo unos pocos elementos básicos en los que consiste cada programa. Estos son:
Identificadores Comentarios Operadores Expresiones Instrucciones Constantes
Variables Símbolos Directivas Etiquetas Procedimientos y funciones Módulos
Aquí está un ejemplo de cómo no se debe escribir un programa. Los comentarios no están incluidos, nombres de etiquetas no tienen significado, secciones del código no están agrupadas...Este programa funciona correctamente, pero sólo el programador que lo escribió conoce su propósito y modo de ejecución (como máximo uno o dos días). En la siguiente figura se muestra la estructura de un programa simple escrito en Basic, destacando las partes en las que consiste. Esto es un ejemplo de cómo se debe escribir un programa. Las diferencias son más que obvias...
ESTRUCTURA DE PROGRAMA Similar a los otros lenguajes de programación, Basic dispone de un conjunto de reglas estrictamente definidas que se deben observar al escribir un programa. Para escribir un programa en Basic, es necesario instalar un software que proporciona el entorno de trabajo apropiado y entiende estas reglas en la PC... Al escribir una carta, se necesita un programa para procesar palabras. En este caso, se necesita el compilador mikroBasic PRO for PIC. A diferencia de la mayoría de programas a los que está acostumbrado a manejar, el proceso de escribir programas en el compilador no empieza por seleccionar la opción File>New, sino Project>New. ¿Por qué? Bueno, usted escribe un programa en un documento con extensión .mbas (mikroBasic). Una vez que se ha escrito el programa, el mismo se debe compilar en código HEX para crear un nuevo documento con extensión .hex. Al mismo tiempo el compilador generará
automáticamente varios documentos aparte de ése. Por ahora el propósito de estos documentos no importa. Por supuesto, hay algo para conectarlos todos. Usted ya lo adivina - se trata de un proyecto. El programa que escribe es sólo una parte del proyecto.
Sólo para estar seguro de que estamos hablando en los mismos términos... A partir de ahora la palabra módulo se refiere a un documento con extensión .mbas. El texto que contiene se refiere a un programa. Cada proyecto escrito en el compilador mikroBasic PRO for PIC es de extensión .mbppi (microBasic Project for PIC) y consiste en un módulo como mínimo (módulo principal - Main Module). Cada proyecto en el mikroBasic PRO for PIC requiere un solo módulo principal. Lo identifica la palabra clave program y ordena al compilador por dónde empezar el proceso de la compilación. Al crear con éxito un proyecto vacío en Project Wizard, el módulo principal (main module) será visualizado automáticamente en la ventana Code Editor:
program MyProject ' El módulo principal es denominado MyProject main: ' Procedimiento principal ... '* ... '* Escribir el código de programa aquí ... '*
end. A la palabra clave program no le puede preceder nada, excepto comentarios. Como hemos mencionado anteriormente, el proyecto puede incluir a otros módulos que, a diferencia del módulo principal, empiezan por la palabra clave module.
module MyModule ... ... ...
' Módulo auxiliar Auxiliary es denominado MyModule '* '* Implementos '*
end.
Para que el compilador pueda reconocer todos los módulos que pertenecen a un proyecto, es necesario especificarlos en el módulo principal por medio de la palabra clave include seguida por un nombre del módulo entre comillas. La extensión de estos ficheros no se debe incluir. Se permite sólo un módulo por cláusula include. El número de las cláusulas include no está limitado, pero todas ellas deben estar especificadas inmediatamente después del nombre del programa (módulo principal). Ejemplo: program MyProgram include "utils" include "strings" include "MyUnit"
' Inicio de programa (módulo principal denominado ‘MyProgram’) ' Otros módulos incluidos son: ' Módulo ‘utils’ ' Módulo ‘strings’ ' Módulo ‘MyUnit’
...
ORGANIZACIÓN DEL MÓDULO PRINCIPAL El módulo principal se puede dividir en dos secciones: declaraciones y el cuerpo
de programa. ¿Qué es una declaración en la programación? Una declaración es un proceso de definir las propiedades de los identificadores que se utilizarán en el programa. Como la mayoría de los demás lenguajes de programación, Basic también requiere que todos los identificadores estén declarados antes de ser utilizados en el programa. Si no es así, el compilador no puede interpretarlos correctamente. Ejemplo de la declaración de una variable denominada distancia: dim distance as float
' Declarar la variable distancia
Como se puede ver, es una variable de punto flotante, o sea un número con posición decimal opcional. Las otras dos variables están declaradas y nombradas velocidad y tiempo. Ahora, se pueden utilizar en el siguiente programa: Esto es un ejemplo de cómo escribir el módulo principal correctamente:
ORGANIZACIÓN DE OTROS MÓDULOS Los otros módulos empiezan por la palabra clave module. Cada módulo consiste en tres secciones: include, interface e implementation. Solo la sección implementation es obligatoria. Empieza por la palabra clave implements. Vea el siguiente ejemplo:
IDENTIFICADORES Los identificadores son los nombres arbitrarios asignados a los objetos básicos del lenguaje teles como constantes, variables, funciones, procedimientos etc. A alguien se le ocurrió utilizar la palabra identificador en vez de utilizar el nombre. Así de simple. Aquí están las reglas a observar al utilizar los identificadores.
Los identificadores pueden incluir cualquiera de los caracteres alfabéticos A-Z (a-z), los dígitos 0-9 y el carácter subrayado '_'. El primer carácter de un identificador no puede ser un dígito. Ningún identificador puede contener caracteres especiales tales como ! [{ # $ % & etc. Basic no es sensible a la diferencia entre minúsculas y mayúsculas, lo que significa que FIRST, first y First son identificadores idénticos.
El símbolo ^ (signo de intercalación) se utiliza para denotar un operador exponencial, el símbolo * (asterisco) se utiliza para denotar la multiplicación, mientras que los demás símbolos tienen el significado común. Las palabras clave ya utilizadas por el compilador no deben ser utilizadas como identificadores. Lista alfabética de las palabras clave en Basic:
Abstract And Array As At Asm Assembler Automated Bdata Begin Bit Case Cdecl Class Code Compact Const Constructor Contains Data Default Deprecated Destructor Dispid Dispinterface Div Do Downto Dynamic Else End Except Export Exports External Far File Finalization Finally For Forward
Function Goto Idata If Ilevel Implementation In Index Inherited Initialization Inline Interface Io Is Label Large Library Message Mod Name Near Nil Not Object Of On Or Org Out Overload Override Package Packed Pascal Pdata Platform Private Procedure Program Property Protected
Public Published Raise Read Readonly Record Register Reintroduce Repeat Requires Resourcestring Rx Safecall Sbit Set Sfr Shl Shr Small Stdcall Stored String Stringresource Then Threadvar To Try Type Unit Until Uses Var Virtual Volatile While With Write Writeonly Xdata Xor
Una lista de identificadores que no deben ser utilizados en el programa
COMENTARIOS Los comentarios son las partes del programa utilizados para aclarar las instrucciones de programa o para proporcionar más información al respecto. En Basic, cualquier texto que sigue a un apóstrofo (') se considera un comentario, Los comentarios no se compilan al código ejecutable. El compilador es capaz de reconocer los caracteres especiales utilizados para designar dónde los comentarios comienzan y terminan y no hace nada de caso al texto entre ellos durante la compilación. Aunque los comentarios no pueden afectar a la ejecución de programa, son tan importantes como cualquier otra parte de programa. Aquí está el porqué... Con frecuencia es necesario mejorar, modificar, actualizar, simplificar un programa... No es posible interpretar incluso los programas simples sin utilizar los comentarios.
ETIQUETAS Las etiquetas proporcionan el modo más fácil de controlar el flujo de programa. Se utilizan para denotar las líneas particulares en el programa donde se deben ejecutar la instrucción de salto y la subrutina apropiada. Todas las etiquetas deben terminar por ‘:’ así que el compilador las puede reconocer con facilidad.
CONSTANTES Las constantes son los números o caracteres cuyo valor no puede ser cambiado durante la ejecución de programa. A diferencia de las variables, las constantes se almacenan en la memoria ROM del microcontrolador para guardar el mayor espacio posible de la memoria RAM. El compilador reconoce las constantes por sus nombres y el prefijo const. Cada constante se declara bajo un nombre único que debe ser un identificador válido. Las constantes pueden ser en formatos decimal, hexadecimal o binario. El compilador los distingue por su prefijo. Si una constante no lleva prefijo, se considera decimal por defecto. FORMATO
PREFIJO
EJEMPLO
Decimal
const MAX = 100
Hexadecimal 0x o $
const MAX = 0xFF
Binario
const MAX = %11011101
Punto flotante
Las constantes se declaran en la parte de declaración del programa o de la rutina. La sintaxis es la siguiente: const nombre_de_constante [as type] = valor
Los nombres de las constantes se escriben normalmente con mayúsculas. El tipo de una constante se reconoce automáticamente por su tamaño. En el siguiente ejemplo, la constante MINIMUM se considera un entero con signo y ocupa dos bytes de la memoria Flash (de 16 bits): const MINIMUM = -1000 ' Declarar la constante MINIMUM
El tipo de constante se especifica opcionalmente. En la ausencia de tipo, el compilador lo considera “el menor” tipo conveniente al valor de constante. const MAX as longint = 10000 const MIN = 1000 const SWITCH = "n"
' Compilador supone el tipo word ' Compilador supone el tipo char
En el siguiente ejemplo, una constante denominada T_MAX se declara de modo que tenga el valor fraccional 32.60. Ahora, el programa puede comparar la
temperatura anteriormente medida con la constante con el nombre con significado en vez del número 32.60. const T_MAX = 32.60 const T_MAX = 3.260E1
' Declarar temperatura T_MAX ' Otra forma de declarar la constante T_MAX
Una constante de cadena consiste en una secuencia de caracteres. Debe estar encerrada entre comillas. Un espacio en blanco se puede incluir en la constante de cadena y representa un carácter. Las constantes de cadena se utilizan para representar cantidades no numéricas tales como nombres, direcciones, mensajes etc. const Message_1 = "Press the START button" const Message_2 = "Press the RIGHT button" const Message_3 = "Press the LEFT button"
' Mensaje 1 para LCD ' Mensaje 2 para LCD ' Mensaje 3 para LCD
En este ejemplo, al enviar la constante Message_1 al LCD, el mensaje ‘press the START button’ aparecerá en la pant alla.
VARIABLES Una variable es un objeto nombrado capaz de contener un dato que puede ser modificado durante la ejecución de programa. Cada variable se declara bajo un nombre únicoque debe ser un identificador válido. Por ejemplo, para sumar dos números (número1 + número2) en el programa, es necesario tener una variable para representar qué es lo que llamamos suma en vida cotidiana. En este caso, número1, número2 y suma son variables. La sintaxis es la siguiente: dim nombre_de_variable as type
Las variables en Basic son de un tipo, lo que significa que es necesario especificar el tipo de dato que se asignará a la variable. Las variables se almacenan en la memoria RAM y el espacio de memoria ocupado (en bytes) depende de su tipo. Aparte de las declaraciones de una sola variable, las variables del mismo tipo, se pueden declarar en forma de una lista. Aquí, lista de identificadores es una lista de identificadores válidos delimitados por comas, mientras que tipo puede ser cualquier tipo de dato.
dim i, j, k as byte dim counter, temp as word
'Definir variables i, j, k 'Definir variables contador y temp
SÍMBOLOS Los símbolos en Basic permiten crear los macros simples sin parámetros. Cualquier línea de código se puede reemplazar por un solo identificador. Los símbolos pueden aumentar legibilidad y reutilización de código cuando se utilizan correctamente. Los símbolos deben ser declarados al principio del módulo, bajo el nombre del módulo y la directiva opcional include. El ámbito de un símbolo es siempre limitado al módulo en el que ha sido declarado. symbol nombre_de_símbolo = código
Aquí, nombre_de_símbolo debe ser un identificador válido que se utilizará por todo el código. El especificador código puede ser cualquier línea de código (literales, asignaciones, llamadas de función etc.) symbol MAXALLOWED = 216 symbol OUT = PORTA symbol MYDELAY = Delay_ms(762) dim cnt as byte
' Símbolo MAXALLOWED para el valor numérico ' Símbolo OUT para SFR ' Símbolo MYDELAY para llamada de procedimiento ' Variable cnt
main: if cnt > MAXALLOWED then cnt = 0 OUT.1 = 0 MYDELAY
' Programa comprueba si cnt > 216 ' Si lo es, ' los siguientes tres comandos ' se ejecutarán
end if ...
' Si no lo es, el programa continúa aquí
Los símbolos no se almacenan en la memoria RAM. El compilador reemplaza los símbolos por las líneas del código apropiadas asignadas durante la declaración.
TIPOS DE DATOS EN BASIC Hay varios tipos de datos que se pueden utilizar en el lenguaje de programación Basic. La siguiente tabla muestra el rango de valores que estos datos pueden tener cuando se utilizan en su forma básica.
TIPO DE DATO
DESCRIPCIÓN
TAMAÑO (NÚMERO DE BITS)
RANGO DE VALORES
bit
Un bit
1
0o1
sbit
Un bit
1
0o1
byte, char
Carácter
8
0 ... 255
short
Entero con signo corto
word
Entero sin signo
16
0 ... 65535
integer
Entero con signo
16
-32768 ... 32767
longword
Palabra de 32 bits
32
0 ... 4294967295
longint
Palabra de 32 bits asignada
32
-2147483648 ... 2147483647
32
±1.17549435082*10-38 ... ±6.80564774407*1038
float
Punto flotante
-127 ... 128
CONVERSIÓN DE T IPOS DE DA TOS A UTOMÁTICA
El compilador automáticamente realiza la conversión implícita en los siguientes casos:
si una sentencia requiere una expresión del tipo particular, y se utiliza la expresión de tipo diferente; si un operador requiere un operando de tipo particular, y se utiliza un operando de tipo diferente; si una función requiere un parámetro formal de tipo particular, y se le asigna el objeto de tipo diferente; y si el resultado de una función no corresponde al tipo del valor devuelto de la función declarada.
PRO MO CIÓN
Cuando los operandos son de tipos diferentes, mediante la conversión implícita se realiza la promoción de tipo más bajo a tipo más alto, de la siguiente manera:
bit → byte short, byte/char → integer, word, longint, longword integer, word → longint, longword short, byte/char, integer, word, longint, longword → float
RECORTE DE DATOS
En las sentencias de asignación y en las sentencias que requieren una expresión de tipo particular, el valor correcto será almacenado en el destino sólo si el resultado de expresión no excede al rango del destino. Al contrario, si el resultado de la expresión resulta en un tipo más complejo de lo esperado, los datos que exceden se recortarán, o sea los bytes más altos se pierden. dim i as byte dim j as word
'Variable i ocupa un solo byte de la memoria RAM ' Variable j ocupa dos bytes de la memoria RAM
... j = $FF0F i=j
' i se convierte en $0F, el byte más alto $FF se pierde
CON VER SIÓN DE D A TOS E XPL ÍCITA
La conversión explícita se puede ejecutar bajo cualquier expresión en cualquier punto al escribir la palabra clave de tipo deseado (byte, word, short, integer,
longint, float...) delante de la expresión que será convertida. La expresión debe estar encerrada entre paréntesis. La conversión explícita no puede ser realizada bajo el operando de la izquierda del operador de asignación. a = word(b) word(b) = a
' Conversión explícita de la expresión b ' Compilador informa de un error
Como no afecta a la representación binaria de los datos, un caso especial es una conversión entre tipos de datos con signo y sin signo. dim a as byte dim b as short '... b = -1 ' a is 255, not -1 a = byte(b) ' El dato no cambia su representación binaria %11111111 ' pero el compilador la interpreta de la manera diferente
OPERADORES Un operador es un símbolo que denota una operación aritmética, lógica u otra operación particular. Cada operación se realiza sobre uno o más operandos (variables o constantes) en una expresión. Además, cada operador dispone de la
ejecución de prioridad y de la asociatividad. Si una expresión contiene más de un operando, los operandos se ejecutarán en orden de su prioridad. Hay 4 categorías de prioridad en Basic. Los operadores que pertenecen a la misma categoría tienen igual prioridad. Si dos o más operandos tienen el mismo nivel de prioridad, las operaciones se realizan de izquierda a derecha. Los paréntesis se utilizan para definir la prioridad de la operación dentro de la expresión. A cada categoría se le asigna una de dos reglas de asociatividad: de izquierda a derecha o de derecha a izquierda. Refiérase a la siguiente tabla: PRIORIDAD
OPERADORES
ASOCIATIVIDAD
Alta
@ not + -
de derecha a izquierda
* / div mod and << >>
de izquierda a derecha
+ - or xor
de izquierda a derecha
= <> < > <= >=
de izquierda a derecha
Baja
OPERA DORE S A RITMÉTICOS
Los operadores aritméticos se utilizan para realizar operaciones aritméticas. Estas operaciones se realizan sobre los operandos numéricos y siempre devuelven los resultados numéricos. Las operaciones binarias se realizan sobre dos operandos, mientras que las operaciones unitarias se realizan sobre un operando. Todos los operadores aritméticos se asocian de izquierda a derecha. OPERADOR
OPERACIÓN
+
Adición
-
Resta
*
Multiplicación
/
División - punto flotante
div
División - redondear
mod
Remanente
DIVISIÓN PO R CER O
Si un cero (0) se utiliza explícitamente como el segundo operando en la operación de división (x div 0), el compilador informa de un error y no generará un código. En caso de una división implícita, o sea, en el caso de que el segundo operando sea un objeto cuyo valor es 0 (x div y, w y=0), el resultado será indefinido. OPERADORES RELA CIONALES
Los operadores relacionales se utilizan para comparar dos variables y determinar la validez de su relación. En mikroBasic, todos los operadores relacionales devuelven 255 si la expresión es evaluada como verdadera (true). Si una expresión es evaluada como falsa (false), el operador devuelve 0. Lo mismo se aplica a las expresiones tales como ‘si la expresión es evaluada como verdadera, entonces...’ OPERADOR
SIGNIFICADO
EJEMPLO
CONDICIÓN DE VERACIDAD
>
es mayor que
b>a
si b es mayor que a
>=
es mayor o igual que
a >= 5
si a es mayor o igual que 5
<
es menor que
a
si a es menor que b
<=
es menor o igual que
a <= b
si a es menor o igual que b
=
es igual que
a=6
si a es igual que 6
<>
no es igual que
a <> b
si a no es igual que b
OPERAD ORES LÓGICOS DE MA NEJO DE B ITS
Los operadores lógicos de manejo de bits se realizan sobre los bits de un operando. Se asocian de izquierda a derecha. La única excepción es el complemento not que realiza un desplazamiento de derecha a izquierda. Los operadores de manejo de bits se enumeran en la siguiente tabla: OPERANDO
SIGNIFICADO
EJEMPLO
RESULTADO
<<
desplazamiento a la izquierda
A = B << 2
B = 11110011
A = 11001100
>>
desplazamiento a la derecha
A = B >> 3
B = 11110011
A = 00011110
and
Y lógico para manejo de bits
C = A and B
A=11100011 B=11001100
C = 11000000
or
O lógico para manejo de bits
C = A or B
A=11100011 B=11001100
C = 11101111
not
NO lógico para manejo de bits
A = not B
B = 11001100
A = 00110011
xor
EXOR lógico para manejo de bits
C = A xor B
A = 11100011 C = 00101111 B = 11001100
Los operadores de manejo de bits y (and), o (or) y xor realizan las operaciones lógicas sobre los pares de bits de operandos apropiados. El operador not complementa cada bit de un solo operando. $1234 and $5678
$1234 or $5678 $1234 xor $5678 not $1234
' resultado es $1230 porque: ' $1234 : 0001 0010 0011 0100 ' $5678 : 0101 0110 0111 1000 ' ---------------------------' y : 0001 0010 0011 0000 ... eso es, $1230 'equivale a $567C ' equivale a $444C ' equivale a $EDCB
OPERADORES DE DESPLA ZAMIENTO
Hay dos operadores de desplazamiento de bits en mikroBasic. Son el operador << que realiza un desplazamiento de bits a la izquierda y el operador >> que realiza un desplazamiento de bits a la derecha. Los operadores de desplazamiento de bits tienen dos operandos cada uno. El operando izquierdo es un objeto que se desplaza, mientras que el derecho indica el número de posiciones a mover el objeto. Los dos operandos deben ser de tipo entero. El operando derecho debe ser el valor positivo. Al desplazar a la izquierda los bits que salen por la izquierda se pierden, mientras que los ‘nuevos’ bits a la derecha se rellenan con ceros. Por lo tanto, el
desplazamiento del operando que carece de signo a la izquierda por n posiciones equivale a multiplicarlo por 2 n si todos los bits descartados son ceros. Lo mismo se puede aplicar a los operandos con signo si todos los bits descartados son iguales que el signo de bit.
dim num as word num = 1 num << 5
' declarar la variable num como word ' asignarle el valor decimal 1 (00000000 00000001 bin.) ' equivale a 32 (00000000 00100000 bin.)
Al desplazar a la derecha los bits que salen por la derecha se pierden, mientras que los ‘nuevos’ bits a la izquierda se rellenan con ceros (en caso del operando sin
signo) o con el signo de bit (en caso del operando con signo). El desplazamiento del operando a la derecha por n posiciones equivale a dividirlo por 2 n. dim num as integer num = 0xFF56 num >> 4
' declarar variable num como signed integer 'asignarle el valor hex FF56 (11111111 01010110 bin.) ' equivale a 0xFFF5 (11111111 11110101 bin.)
SENTENCIAS CONDICIONALES Las condiciones son ingredientes comunes de un programa. Las condiciones permiten ejecutar una o varias sentencias dependiendo de validez de una expresión. En otras palabras, ‘Si se cumple la condición (...), se debe hacer (...). De lo contrario, se debe hacer (...)’. Una sentencia condicional puede ser seguida
por una sola sentencia o por un bloque de sentencias a ser ejecutadas. SENTENCIA CONDICIONAL IF
La sintaxis en una forma simple de la sentencia if es: if expresión then operaciones
end if
Si el resultado de la expresión es verdadero (distinto de 0), las operaciones se realizan y el programa continúa con la ejecución. Si el resultado de la expresión es falso (0), las operaciones no se realizan y el programa continúa inmediatamente con la ejecución. El operador if se puede utilizar en combinación con el operador else: if expresión then operaciones1
else
other operaciones2
end if
Si el resultado de la expresión es verdadero (distinto de 0), las operaciones1 se realizan. De lo contrario, las operaciones2 se realizan. Después de realizar estas operaciones, el programa continúa con la ejecución. SENTENCIAS IF ANIDADA S
La sentencia if anidada necesita una atención adicional. Es una sentencia utilizada dentro de otra sentencia if. Siguiendo la regla, se descomponen empezando por la sentencia if más anidada, mientras que cada sentencia else se enlaza a la más cercana sentencia if disponible a la izquierda.
SENTENCIA CASE STATEMENT
La sentencia select case es una sentencia condicional de ramificación múltiple. Consiste en una expresión (condición) selector y una lista de los valores posibles de la expresión. La síntaxis de la sentencia select case es la siguiente: El especificador selector es una expresión evaluada como un valor entero. Los especificadores value_1...value_n representan los valores posibles del selector. Pueden ser literales, constantes o expresiones de constantes. Los especificadores statements_1 ...statements_n pueden ser cualquier sentencia. La cláusula case else es opcional. Primero se evalúa el valor de la expresión selector. Después se compara con todos los valores disponibles. Si los valores son iguales (selector y uno de valores), se ejecutarán las sentencias que siguen a los valores iguales y termina la sentencia select case. En el caso de que coincidan los valores múltiples se ejecutarán las sentencias que siguen a los primeros valores iguales. Si no coincide ningún valor con el selector, se ejecutarán las sentencias_por_defecto en la cláusula
case
else
(si
hay
alguna).
Ejemplo de la sentencia select case: select case decimal_digit case 0
'El valor del dígito decimal se está comprobando
mask = %01111110 case 1 mask = %00110000 case 2 mask = %01101101 case 3 mask = %01111001 case 4 mask = %00110011 case 5 mask = %01011011 case 6 mask = %01011111 case 7 mask = %01110000 case 8 mask = %01111111 case 9 mask = %01111011
'Visualizar "0" 'Visualizar "1"
end select
Esta rutina de programa convierte los dígitos decimales en la combinación binaria apropiada en el puerto para visualizarlos en el LED. BUCLES DE PROGRAMA
Algunas instrucciones (operaciones) deben ejecutarse más de una vez en el programa. Un conjunto de comandos que se repiten es denominado un bucle de programa. Cuántas veces se ejecutará, es decir cuánto tiempo el programa se quedará en el bucle, depende de las condiciones de salir del bucle.
BUCLE W HILE
El bucle while aparece cuando el número de iteraciones no está especificado. Es necesario comprobar la condición de iteración antes de ejecutar un bucle. En otras palabras, el bucle while se ejecuta una vez cumplidas todas las condiciones necesarias para su ejecución. La sintaxis del bucle while se parece a lo siguiente: while expresión sentencias
wend
El especificador sentencias representa un grupo de sentencias que se ejecutan repetidamente hasta que el valor del especificador expresión que representa una expresión siga siendo verdadero. En otras palabras, el programa se queda en el bucle hasta que la expresión llegue a ser falsa. El valor de la expresión se comprueba antes de que se ejecute la siguiente iteración. Si el valor de la expresión es falso antes de entrar el bucle, no se ejecuta ninguna iteración, esto es las sentencias no se ejecutarán nunca. El programa continúa con la ejecución desde el fin del bucle while (desde las instrucciones que siguen a la instrucción wend). Un tipo especial del bucle de programa es un bucle infinito. Se forma si la condición
para
salir
del
bucle
sigue
sin
cambios
dentro
del
bucle.
La ejecución es simple en este caso ya que el resultado es siempre verdadero (1 siempre será diferente de 0), lo que significa que el programa se queda en el bucle: while 1
' Se puede escribir ‘verdadero’ en vez de ‘1’
... ...
' Las expresiones se ejecutarán repetidamente (bucle infinito)
wend
BUCLE FOR
El bucle for se utiliza cuando el número de iteraciones está especificado. La sintaxis del bucle for es la siguiente: for contador = valor_inicial to valor_final [step valor_de_paso] sentencias next contador
La variable contador se incrementa por el valor de paso con cada iteración de bucle. El parámetro valor_de_paso es un valor entero opcional, que es igual a 1 si es omitido. Antes de ejecutar la primera iteración el contador se pone al valor_inicial y se incrementa hasta llegar o exceder al valor_ final. Con cada iteración se ejecutan las sentencias. Las expresiones valor_inicial y valor_final deben ser compatibles con el contador. El especificador sentencia puede ser cualquier sentencia que no afecta al valor del contador. El parámetro valor_de_paso puede ser negativo, lo que permite contar atrás. for k=1 to 5 operation ... next k
' La variable k se incrementa cinco veces (de 1 a 5) y ' cada vez sigue ejecutándose la "operación"
Un conjunto de instrucciones (operación) se ejecutará cinco veces. Después, al comprobar que k<5 sea falsa (después de 5 iteraciones k=5) y el programa saldrá del bucle for. BUCLE DO
La sentencia do se utiliza cuando el número de iteraciones no está especificado. El bucle se ejecuta repetidamente hasta que la expresión siga siendo verdadero. La sintaxis del bucle do es la siguiente: do sentencias loop until expresión
En este caso, el especificador sentencias representa un grupo de sentencias que se ejecutarán hasta que la expresión siga siendo verdadera. Las condiciones del bucle se comprueban al final del bucle, así que el bucle se ejecuta al menos una vez, sin reparar en si la condición es verdadera o falsa. En el siguiente ejemplo, el programa se queda en el bucle do hasta que la variable a alcance 1E06 (un millón de iteraciones). a=0
' Establecer el valor inicial
a = a+1
' Operación en marcha ' Comprobar la condición
do
loop until a <= 1E06
ESCRIBIR CÓDIGO EN LENGUAJE ENSAMBLADOR
A veces el proceso de escribir un programa en Basic requiere las partes del código escritas en ensamblador. Esto permite ejecutar algunas partes del programa de una forma definida con precisión en un período de tiempo exacto. Por ejemplo, cuando se necesita que los pulsos muy cortos (de unos microsegundos) aparezcan periódicamente en un pin del microcontrolador. En tales casos la solución más simple sería escribir el código ensamblador en la parte del programa que
controla
la
duración
de
pulsos.
El comando asm se utiliza para introducir una o más instrucciones en ensamblador en el programa escrito en Basic: asm instrucciones en ensamblador ...
end asm
Las instrucciones en ensamblador pueden utilizar los objetos (constantes, variables, rutinas etc.) anteriormente declarados en Basic. Por supuesto, como el programa entero está escrito en Basic, sus reglas se aplican al declarar estas constantes y variables. Veamos al siguiente ejemplo:
MATRICES Una matriz es una lista organizada y limitada de variables del mismo tipo denominadas elementos. Este tipo es denominado tipo básico. Cada elemento es referenciado por un índice único así que los diferentes elementos pueden tener el mismo valor. Para declarar una matriz, es necesario especificar el tipo de sus elementos (denominado tipo de matriz), su nombre y el número de sus elementos encerrados entre corchetes: dim nombre_de_matriz as tipo_de_componente [número_de_componentes]
Los elementos de una matriz se identifican por su posición. Los índices van desde 0 (el primer elemento de una matriz) a N-1 (N es el número de elementos contenidos en la matriz). El compilador tiene que “saber” cuántas localidades de
memoria debe alojar al declarar una matriz. Por eso, el tamaño de una matriz no puede ser variable. Para explicar con más claridad, una matriz puede ser pensada como una lista más o menos larga o corta de variables del mismo tipo en la que a cada una se le asigna un número ordinal que siempre empieza por cero. A esta matriz se le denomina vector. En la tabla de la derecha se muestra una matriz denominada estante que contiene 100 elementos. ELEMENTOS DE LA MATRIZ
CONTENIDO DE ELEMENTOS
estante[0]
7
estante[1]
23
estante[2]
34
estante[3]
0
estante[4]
0
estante[5]
12
estante[6]
9
...
...
...
...
estante[99]
23
En este caso, el contenido de una variable (elemento) representa un número de productos que contiene el estante. A los elementos se les puede acceder por medio de la indexación, o sea, al especificar sus índices encerrados entre corchetes: dim shelf as byte [100]
' Declarar la matriz "estante" con 100 elementos
shelf [4] = 12 temp = shelf [1]
' 12 elementos están ‘colocados’ en el estante [4]
' Variable estante [1] se copia a la variable temp
En las matrices de constantes, a los elementos se les pueden asignar sus contenidos durante la declaración de matriz. En el siguiente ejemplo, una constante de matriz denominada CALENDARIO se declara y a cada elemento se le asigna un número específico de días: const CALENDARIO as byte [12]= (31,28,31,30,31,30,31,31,30,31,30,31)
El número de los valores asignados no debe exceder la longitud de la matriz especificada, solo puede ser menor. En este caso, a los elementos ”de sobra” se
les asignarán ceros. SENTENCIA GOTO
La sentencia goto le permite hacer un salto absoluto a otro punto en el programa. Esta característica se debe utilizar con precaución ya que su ejecución puede causar un salto incondicional sin hacer caso a todos los tipos de limitaciones de anidación. El punto destino es identificado por una etiqueta, utilizada como un argumento para la sentencia goto. Una etiqueta consiste en un identificador válido seguido por dos puntos (:). La sintaxis de la sentencia goto es: goto: nombre_de_etiqueta
La sentencia ejecuta un salto al especificador nombre_de_etiqueta que representa una etiqueta. La sentencia goto puede preceder o seguir a una etiqueta. Por lo tanto, no es posible hacer un salto hacia o desde un procedimiento o función. La sentencia goto se puede utilizar para salir de cualquier nivel de las estructuras anidadas. No es recomendable saltar a bucles u otras sentencias estructuradas, ya que se pueden producir resultados inesperados.
SENTENCIA GOSUB
Una subrutina es una parte del código dentro de un programa largo ejecutado a petición. Realiza una tarea específica, es relativamente independiente del resto del código. El intérprete del compilador salta a la subrutina, la ejecuta y vuelve al programa principal. Las palabras clave gosub y return se utilizan en Basic para denotar el inicio y el final de la subrutina: gosub nombre_de_etiqueta ... ... ... nombre_de_etiqueta: ... return
Las subrutinas se consideran difíciles de mantener, leer y manejar, igual que la sentencia goto. Es recomendable utilizarla solo si no hay otra solución. ACCESO A LOS B ITS INDIVIDUAL ES
El compilador mikroBasic PRO for PIC instalado en la PC, incluye una lista de los microcontroladores PIC soportados, con todos los registros, sus direcciones exactas y los nombres de bits. El compilador le permite acceder a los bits individuales de estos registros por sus nombres, sin especificar sus posiciones (el compilador ya las ‘conoce’). Hay muchas formas de acceder y modificar a un bit
individual dentro de un registro. Por ejemplo, vamos a acceder al bit GIE (Global Interrupt Enable - Habilitación global de interrupciones) por ejemplo. Es el séptimo bit del registro INTCON. A este bit se le puede acceder por su nombre, al escribir lo siguiente: INTCON.GIE = 0 ' Poner a cero el bit GIE
Para denotar la posición de bit en un registro en lugar de un nombre de bit se pueden utilizar una variable, una constante, una llamada a función o una expresión encerrada entre paréntesis. Además, para acceder a los bits individuales se utilizan las constantes globales predefinidas B0, B1, … , B7, o 0, 1, … 7, donde 7
se considera el bit más significante.
INTCON.B0 = 0 ADCON0.5 = 1 i=5 STATUS.(i+1) = 1
' Poner a cero el bit 0 del registro INTCON ' Poner a uno el bit 5 del registro ADCON0 ' Poner a uno el bit 6 del registro STATUS
Por fin, a u n bit deseado se le puede acceder al utilizar un nombre “alias”. En este caso, es el GIE_bit: GIE_bit = 1 ' Poner a uno el bit GIE
TIPO SBIT
El compilador mikroBasic PRO for PIC tiene un tipo de dato sbit. Esto es un tipo de dato más corto que se refiere a un solo bit. Si al tipo sbit se le asigna una variable, el bit apropiado de un registro será cambiado al cambiar esta variable sin especificar el nombre y la localidad del registro. La variable sbit se comportará como un puntero. Para declarar la variable sbit, basta con escribir: dim Nombre_de_bit as sbit at Nombre_de_registro.Posición_de_bit ' Módulo principal program MyProgram ...
dim Output1 as sbit at PORTB.0
' Variable Output1 es de tipo sbit
... Output1 = 1
' Pin del puerto PORTB.0 está a uno (5V)
Si una variable de tipo sbit no está definida en el mismo módulo donde se utiliza, la palabra clave external debe ser utilizada. Además, el especificador de memoria apropiado se debe añadir: dim nombre_de_bit as sbit sfr external module MyModule ...
dim Output1 as sbit sfr external ... Output1 = 1
' Esto no es el módulo principal y el bit Output1 ' no está definido aquí
' Pin PORTB.0 (definido en el ejemplo anterior como Output1) está a uno (5V)
TIPO BIT
El compilador mikroBasic PRO for PIC proporciona un tipo de dato bit que se puede utilizar para declarar las variables.
dim bf as bit
A diferencia de variables de tipo sbit, solo el nombre de bit está declarado aquí, mientras que el compilador almacena una variable bit en algunos de los registros libres de la RAM. Como se puede ver, no es necesario especificar un bit de algún registro específico. La localidad exacta de la variable de tipo bit es desconocida al usuario. Los tipos Bit y sbit se utilizan con los siguientes limitaciones:
No pueden ser utilizados para las listas de argumentos y como valores devueltos de funciones No pueden ser utilizados como un miembro de estructuras No pueden ser utilizados como elementos de matrices No pueden ser inicializados No se puede apuntar a ellos Sus direcciones no se pueden leer, por eso el operador unitario @ no se puede utilizar con variable de este tipo
dim ptr as ^bit dim arr as array[5] of bit
' inválido ' inválido
FUNCIONES Y PROCEDIMIENTOS Las funciones y los procedimientos, denominados bajo el nombre común de rutinas, son subprogramas (bloques de sentencias autónomos) que ejecutan ciertas tareas a base de un número de los parámetros de entrada. Las funciones devuelven un valor después de la ejecución, mientras que los procedimientos no devuelven un valor. PROCEDIMIENTOS
Un procedimiento es un bloque de código nombrado, o sea, una subrutina con algunas características adicionales. Por ejemplo, puede aceptar parámetros. Los procedimientos se declaran de la siguiente manera: sub procedure [ declaraciones locales ] cuerpo de procedimiento
end sub
´nombre_de_procedimiento (lista_de_parámetros)
El especificador nombre_de_procedimiento representa un nombre de procedimiento y debe ser un indentificador válido. La lista_ de_parámetros entre paréntesis representa una lista de parámetros formales declarados de manera similar a variables. En mikroBasic PRO for PIC, los parámetros se le pasan a un procedimiento por valor. Para pasar los parámetros por dirección, es necesario añadir la palabra clave byref al principio de la declaración de los parámetros. Las declaraciones locales son declaraciones opcionales de variables y constantes que se refieren sólamente al procedimiento dado. El cuerpo de procedimiento es una secuencia de sentencias que se ejecutarán después de llamar al procedimiento.
Una llamada a procedimiento se realiza al especificar su nombre seguido por los parámetros actuales colocados en el mismo orden que los parámetros formales correspondientes. Después de llamar a procedimiento, todos los parámetros formales se crean como los objetos locales inicializados por los valores de los argumentos actuales. 'Añadir dos números sub procedure add (dim byref sum as word, dim x, y as byte) sum = x + y ' añadir los números x e y y almacenar el resultado en la variable sum ' fin del subprocedimiento end sub
Ahora, podemos llamar al procedimiento add para hacer cálculo del peso total de una carga, por ejemplo: add (peso_bruto, peso_neto, peso_tara)
FUNCIONES
Las funciones deben estar declaradas apropiadamente para ser interpretadas correctamente durante el proceso de la compilación. sub function nombre_de_función (lista_de_parámetros) as valor_devuelto [ declaraciones locales ] cuerpo de función
end sub
Cada declaración contiene los siguientes elementos:
Nombre_de_función es un identificador utilizado para llamar a función (nombre_de_función en el ejemplo)
Tipo de resultado (valor devuelto) es un tipo de dato de los datos devueltos (tipo_devuelto en el ejemplo) Declaración de los parámetros: cada parámetro consiste en una variable, constante, puntero o matriz precedidos por su tipo de dato especificado similar a una declaración de variable regular (lista_de_parámetros en este ejemplo). Se utilizan para pasar la información de la función al llamarla. Declaraciones locales son declaraciones opcionales de variables y constantes que se refieren solamente a la función dada. Cuerpo de función es una secuencia de sentencias que serán ejecutadas después de llamar a la función. Aquí está un ejemplo de cómo definir y utilizar la función power:
'función que hace cálculo de xn basado en los parámetros de entrada x y n (n > 0) sub function power(dim x, n as byte) as longint ' x y n son bytes, resultado es longint ' i es un byte dim i as byte result = 1 ' resultado = 1 si n = 0 if n > 0 then for i = 1 to n result = result*x next i
end if end sub
Ahora, podemos llamar a la función power para hacer cálculo de 312 por ejemplo: tmp = power(3, 12) ' Hacer cálculo de 3*12
L IBRER ÍAS D E FUNCION ES Y PROCED IMIENTOS
Las declaraciones de todas las funciones y procedimientos utilizados en Basic se almacenan normalmente en los ficheros de módulo especial y se les denominan librerías. Antes de utilizar una librería en el programa, es necesario especificar el módulo apropiado por medio de la cláusula include al principio de programa. Esto es una regla general. Si escribe un programa en el compilador mikroBasic PRO for PIC basta con marcar la librería deseada en la lista y el módulo apropiado será automáticamente incluido en el proyecto. El compilador ya contiene un gran número de estas librerías. Si el compilador encuentra una función o procedimiento desconocidos durante la ejecución de programa, primero va a buscar su declaración en las librerías anteriormente marcadas.
RUTINAS INTEGRADAS EN EL COMPILA DOR MIKROBA SIC PRO FOR PIC
Aparte de las librerías de funciones y procedimientos, el compilador mikroBasic PRO for PIC proporciona un conjunto de las funciones integradas y útiles: Lo Hi Higher Highest Inc Dec Chr Ord SetBit ClearBit TestBit Delay_us Delay_ms
Vdelay_Advanded_ms Vdelay_ms Delay_Cyc Clock_KHz Clock_MHz Reset ClrWdt DisableContextSaving SetFuncCall SetOrg GetDateTime GetVersion
Las rutinas Delay_us y Delay_ms se generan en la parte del programa de la que se llaman. Vdelay_ms, Delay_Cyc y Get_Fosc_kHz son las rutinas actuales en Basic. Sus fuentes se pueden encontrar en el archivo Delays.mbas ubicado en el archivo uses del compilador.
PREPROCESADOR Un preprocesador es una parte integral de cada compilador. Su función es de reconocer y ejecutar las instrucciones del preprocesador. ¿Qué son instrucciones del preprocesador? Son instrucciones especiales que no pertenecen al lenguaje Basic, sino que están integrados en el compilador. Antes de compilar, el compilador inicia al preprocesador que pasa por el programa en búsqueda de estas instrucciones. Si encuentra una, el preprocesador las sustituirá por otro texto que, dependiendo del tipo de comando, puede ser un archivo (comando include) o sólo una corta sentencia de caracteres (comando define). Entonces, el proceso de compilar puede empezar. Las instrucciones pueden estar en cualquier parte del programa fuente y se refieren solamente a la parte del programa en la que aparecen hasta el final del programa.
DIRECTIVA DEL PREPROCESADOR INCLUDE Muchos programas repiten con frecuencia el mismo conjunto de comandos un par de veces. Para escribir un programa más rápidamente, estos comandos y declaraciones se agrupan normalmente en los módulos particulares que se pueden incluir en el programa con facilidad por medio de la directiva include. Para decir con más precisión, la directiva include importa el texto del otro documento en el programa, sea un conjunto de comandos o bien un conjunto de comentarios etc.
COMPILA CIÓN CONDICIONA L
Las directivas de la compilación condicional se utilizan generalmente para facilitar la modificación y compilación de los programas fuente para los diferentes microcontroladores. El compilador mikroBasic PRO for PIC soporta a la compilación condicional. Todas las directivas de la compilación condicional deben terminar dentro del módulo en el que han empezado. DIRECTIVAS #IF, #ELIF, #ELSE, Y #ENDIF
Las directivas condicionales #if, #elif, #else y #endif se ejecutan de manera similar a las sentencias condicionales comunes en Basic. Si una expresión escrita después de #if tiene un valor distinto de cero, las líneas de programa que siguen
a la directiva #if serán interpretadas como un código de programa válido y compiladas en código hex. La sintaxis es la siguiente: #if constant_expression_1 [#elif constant_expression_2 ] ... [#elif constant_expression_n ] [#else ] #endif
'Si expresión_de_constante_1 no es cero, 'sección_1 será compilada 'Si expresión_de_constante_2 no es cero, 'sección_2 será compilada 'Si expresión_de_constante_n no es cero, 'sección_n será compilada 'Si no se compila ninguna de las secciones anteriores 'sección_final será compilada 'Final de la directiva #if
Cada directiva #if en un archivo fuente debe terminar por una directiva #endif de cierre correspondiente. Entre las directivas #if y #endif puede haber cualquier número de las directivas #elif, pero sólo se permite una directiva #else. Si está presente la directiva #else, debe ser la última directiva antes de la directiva #endif. Sección puede ser cualquier código de programa reconocido por el compilador o preprocesador. El preprocesador selecciona una sección al evaluar la expresión_de_constante que sigue a cada directiva #if o #elif hasta encontrar una expresión_de_constante verdadera (distinta de cero). Si todas las expresiones-constantes son evaluadas como falsas o no aparecen ninguna directiva #elif, el preprocesador selecciona la sección_final que sigue a la cláusula #else. Si se omite la cláusula #else y todas las expresiones_constantes en el bloque #if son evaluadas como falsas, no se seleccionará ninguna sección para un procesamiento posterior.
Por último, resulta que solamente una sección del código será compilada, aunque esté vacía.
PUNTEROS Como ya hemos mencionado, a cada objeto en el programa (variable, procedimiento, subrutina etc.) se le asigna una dirección de memoria particular. Al declarar una variable en el programa el compilador le asigna automáticamente una localidad de la memoria RAM libre. Durante la programación, estas direcciones no
son visibles para los programadores. La posibilidad de acceder a los diferentes objetos por sus nombres (identificadores) en vez de por sus direcciones es una de las ventajas principales de los lenguajes de programación de alto nivel. En realidad, es más fácil manejar las palabras (nombres) que los números. Además, el compilador se encarga de los objetos asociados y de sus direcciones.
Direccionar
los
objetos
al
especificar
sus
nombres
es
direccionamiento
denominado directo.
Sin embargo, a veces se necesita utilizar las direcciones de localidades de memoria. En este caso se utilizan los punteros - variables que almacenan la dirección de memoria de un objeto. Entonces, es posible acceder a los objetos que utilizan solamente los punteros. Por eso esta forma de direccionar es denominada direccionamiento indirecto. Antes de utilizar un puntero es necesario declarar su tipo de datos. Solo hay que anteponer el signo de intercalación (^) al tipo. dim pointer_p as ^word ' puntero_p apunta al dato de tipo word
Se le recomienda almacenar una varible en una localidad de memoria RAM específica, luego se debe utilizar la directiva absolute en el programa de la siguiente manera: dim variable_a as word absolute 12
' variable_a ocupará una palabra ' (16 bits) en la dirección 12
Para acceder a los datos en la localidad de memoria del puntero, necesita posponer el signo de la intercalación (^) al nombre del puntero. Veamos el ejemplo de la declaración del anteriormente mencionado puntero puntero_p , que apunta a la palabra (en este caso, es anteriormente definida variable_a almacenada en la dirección 12 en la RAM). A la variable apuntada variable_a se le asigna el valor 26: dim pointer_p as ^word
'Puntero_p a punta al dato de tipo word
... ... pointer_p = 12 'Puntero_p apunta a la dirección de memoria 12 ... puntero_p^ = 26 'Variable a en la localidad de memoria 12 tiene valor 2 'Similar a la directiva absolute utilizada para las variables, la 'directiva org especifica la dirección inicial de una rutina en la 'memoria ROM. Se añade a la declaración de la rutina. Por ejemplo:
sub procedure proc(dim par as word) org 0x200 ...
end sub
' El procedimiento empezará ' en la dirección 0x200
En este caso, al puntero puntero_p se le asigna el valor 12 (puntero_p =12), lo que significa que la dirección de memoria 12 está especificada.
Si quiere cambiar el valor de una variable apuntada, basta con cambiar el valor del puntero y posponer el signo de intercalación (^) al valor. Veamos la figura a la derecha: a la variable variable_a en la dirección 12 se le asigna el valor 26 por medio del puntero puntero_p. Los punteros pueden apuntar a los datos almacenados en cualquier espacio de memoria disponible y pueden residir en cualquier espacio de memoria disponible menos en el espacio de memoria de programa (ROM). @ OPERADOR
El operador @ devuelve la dirección de un objeto, o sea, crea un puntero sobre su operando. Las siguientes reglas se aplican al operando @:
Si X es una variable, @X devuelve la dirección de X. Si F es una rutina (función o procedimiento), @F crea un puntero a F.
dim temp as word ptr_b as ^byte
ptr_arr as ^byte[10] arr as byte[10] main: ptr_b = @arr temp = @arr ptr_arr = @arr end.
' operador @ devolverá ^byte ' operador @ devolverá ^byte ' operador @ devolverá ^byte[10]
Si la variable X es de tipo matriz, el operador @ devolverá el puntero a su primer elemento básico, excepto en el caso de que la parte izquierda de la expresión en la que se utiliza X sea el puntero a matriz. En este caso, el operador @ devolverá el puntero a matriz, y no a su primer elemento básico. Estructu ra de programa en mikro Basic PRO for PIC:
1. Cada programa normalmente empieza con un comentario que proporciona información sobre el propósito del programa, fecha de programa, programador, versión, cambios a la versión anterior etc. Estos comentarios (cabecera) no son obligatorios, pero es una buena costumbre escribirlos y tenerlos en el programa. 2. Cada programa empieza con una directiva de programa seguida por el nombre de programa. 3. Si el programa contiene otros módulos, aparte del módulo principal, sus nombres se deben especificar al utilizar la directiva include (una directiva inlcude para cada módulo). Por consiguiente, si el compilador durante la compilación del módulo principal llega a un objeto que no es declarado (función, variable etc.), primero va a buscar su declaración dentro de los módulos declarados. Si no encuentra la declaración apropiada, el compilador informará de error. 4. La directiva include (si hay alguna) es seguida por la parte de código que sirve de declarar variables, constantes, procedimientos, subprogramas, funciones y otros objetos que se utilizarán más tarde en el programa. Estas declaraciones se utilizan para reservar los registros de la memoria RAM para almacenar los datos así como para enseñar al compilador cómo ejecutar una función o un procedimiento. Por ejemplo, un dato de tipo byte ocupa un solo registro, mientras que un dato de tipo float ocupa cuatro registros. 5. El programa principal empieza con la directiva main: (siempre seguida por dos puntos). También es llamada ‘cuerpo de programa’. 6. Cada programa termina con la directiva end. (siempre seguida por un punto).
2.3 COMPILADOR MIKROBASIC PRO FOR PIC Todo lo que usted ha leído hasta ahora sobre la programación en Basic es sólo teoría. Es útil saberlo, pero no se olvide de que este lenguaje de programación no está tan relacionado con algo concreto y tangible. Podrá experimentar muchos
problemas con los nombres exactos de los registros, sus direcciones, nombres de los bits de control particulares, y muchos más al empezar a escribir su primer programa en Basic. El punto es que usted necesita más que una teoría para que el microcontrolador haga algo útil. Teniendo en cuenta de que “Es mejor prevenir que curar”, hay que avisarle de todas las cosas por resolver antes de que empiece a escribir un programa para el microcontrolador. Antes que nada, necesita un programa instalado en la PC que “eniende” el lenguaje de programación a utilizar y que proporciona un entorno de trabajo apropiado. No hay un compilador apropiado para un tipo de compilador, tampoco para todos los microcontroladores. Normalmente se utiliza un software para programar los similares microcontroladores de un fabricante.
En las secciones anteriores hemos presentado el lenguaje mikroBasic, especialmente diseñado para programar los PIC. Ahora, cuando sabe lo suficiente sobre ese lenguaje, es hora de presentar el software que utilizará para desarrollar y editar los proyectos. Este software se le denomina Entorno de desarrollo integrado (Integrated Developement Environment - IDE) e incluye todas las herramientas necesarias para desarrollar los proyectos (editor, depurador etc.). Como implica su nombre, mikroBasic PRO for PIC está pensado para escribir los programas para los microcontroladores PIC en Basic. Este compilador contiene las informaciones de arquitectura de los microcontroladores PIC (registros, sus direcciones exactas, módulos de memoria, funcionamiento de sus módulos, juego de instrucciones, disposición de pines etc.). Además incluye las herramientas apropiadas para programar los microcontroladores PIC. Lo primero que tiene que hacer al iniciar el compilador es seleccionar el chip y frecuencia de operación de la lista. Esto no es un final, sino un comienzo. Por fin puede empezar a escribir el programa en Basic.
El proceso de crear y ejecutar un proyecto contiene los siguientes pasos: Crear un proyecto (nombre de proyecto, configuración de proyecto, dependencias entre archivos); Editar un programa; Compilar el programa y corrección de errores; Depurar (ejecutar el programa paso a paso para asegurarse de que se ejecutan las operaciones deseadas); Programar un microcontrolador (cargar el archivo .hex generado por el compilador en el microcontrolador utilizando el programador PICflash).
IDE DEL MIKROBASIC PRO FOR PIC Al iniciar el IDE del compilador mikroBasic PRO for PIC por primera vez, aparecerá una ventana como se muestra a continuación:
Desgraciadamente, una descripción detallada de todas las opciones disponibles de este IDE nos tomaría mucho tiempo. Por eso vamos a describir sólo lo más importante del compilador mikroBasic PRO for PIC. De todos modos, para obtener
más información presione el botón de Ayuda (Help) [F1]. En el capítulo cuatro se presentan varios ejemplos y se da una explicación detallada de cómo crear un nuevo proyecto y escribir un programa. PROJECT MANAGER (Adm inistrador d e proyecto)
Un programa escrito en el compilador mikroBasic PRO for PIC no es un archivo autónomo, sino que forma parte de un proyecto que incluye un código hex, un código ensamblador y otros archivos. Algunos de ellos se requieren para compilar el programa, mientras que otros se crean durante el proceso de compilación. La ventana Project Manager le permite manejar todos los ficheros del proyecto. Basta con pulsar con el botón derecho del ratón sobre una carpeta y seleccionar la opción que necesita para su proyecto. LIBRARY MANAGER
Las librerías contienen un gran número de funciones listas para ser utilizadas. Las librerías en mikroBasic proporcionan muchas facilidades para escribir programas para los microcontroladores PIC. El compilador debe “conocer” todas las dependencias del
archivo fuente de mikroBasic para compilarlo apropiadamente. Abra la ventana Library Manager, y marque las que quiere utilizar en el programa. Al marcar una librería, se añade automáticamente al proyecto y se enlaza durante el proceso de la
compilación.
Así,
no
necesita
incluir
las
librerías
manualmente en sus archivos del código fuente por medio de la directiva del preprocesador #include. Por ejemplo, si su programa utiliza un LCD no hace falta escribir nuevas funciones ya que al seleccionar la librería Lcd, usted podrá utilizar funciones listas para ser utilizadas de la librería Lcd en su programa. Si esta librería no está seleccionada en la ventana Library Manager, cada vez que intente utilizar una función de la librería LCD, el compilador le informará de un error. Una descripción de cada librería está disponible al pulsar con el botón derecho del ratón sobre su nombre y seleccionar la opción Help. CODE EXPLORER (Exp lorad or d e código) La ventana Code Explorer le permite localizar funciones y procedimientos dentro de los programas largos. Por ejemplo, si usted busca una función utilizada en el programa, basta con pulsar dos veces sobre su nombre en esta ventana, y el cursor estará automáticamente posicionado en la línea apropiada en el programa.
PROJECT SETTINGS (Con figu ración de proy ectos )
Al compilar un proyecto, el compilador genera el archivo .hex que se cargará en el microcontrolador. Estos archivos serán diferentes ya que depende del tipo del microcontrolador así como del propósito de la compilación. Por esta razón es necesario ajustar algunos parámetros de proyectos utilizando la ventana Project Settings.
Device (dispositivo): Al seleccionar el tipo del microcontrolador a utilizar permite al compilador extraer el archivo de definición asociado. El archivo de definición de un microcontrolador contiene la información específica de sus registros SFR, de sus direcciones de memoria y algunas variables de programación específicas a ese tipo del microcontrolador. Es obligatorio crear un archivo .hex compatible. Oscillator (oscilador): Se debe especificar la velocidad de operación del microcontrolador. Por supuesto, este valor depende del oscilador utilizado. El compilador la necesita para compilar rutinas, lo que requiere información del tiempo (por ejemplo, la función Delay_ms). Más tarde, el programador necesitará esta información también. La velocidad de operación se configura de modo que permita al oscilador interno del microcontrolador funcionar a una frecuencia seleccionada.
Build/Debugger Type: Todo el proceso de compilar (building) está compuesto por análisis sintáctico (parsing), compilar, enlazar (linking) y generar los archivos .hex. El tipo de compilación le permite ajustar el modo de compilación. Dependiendo del modo
seleccionado,
difieren
los
archivos
generados
a
cargar
en
el
microcontrolador.
Build type - release: Al elegir esta opción, el compilador no puede afectar más a la ejecución de programa después de la compilación. El programa a cargar en el microcontrolador no será modificado de ninguna manera. Build type - ICD debug: El archivo .hex generado contiene los datos adicionales que permiten el funcionamiento del depurador. Una vez completado el proceso de la compilación y cargado el programa en la memoria del microcontrolador, el compilador se queda conectado al microcontrolador por medio del cable USB y el programador, y todavía puede afectar a su funcionamiento. Una herramienta
denominada mikroICD (Depurador en circuito - In Circuit Debugger) permite ejecutar el programa paso a paso y proporcionar un acceso al contenido actual de todos los registros del microcontrolador. El simulador software se puede utilizar en ambos modos de compilación para el propósito de depurar. Le permite simular su programa al reproducir el comportamiento del microcontrolador. El simulador no utiliza los dispositivos reales para simular el funcionamiento del microcontrolador, así que algunas operaciones no pueden ser reproducidas (por ejemplo, interrupción). De todos modos, resulta más rápido depurar un programa por medio de un simulador. Además, no se requiere ningún dispositivo destino. Note que es posible modificar cualquier configuración en cualquier momento mientras se edita el programa. No se olvide de recompilar y reprogramar su dispositivo después de modificar una configuración.
EDITAR Y COMPILAR PROGRAMAS CODE EDITOR (Editor d e código )
El proceso de escribir y editar programas se debe realizar dentro de la ventana principal del IDE denominada Code Editor. Un gran número de opciones utilizadas para configurar sus funciones y el diseño se encuentran en el menú Tools/Options [F12]. Al escribir el programa no se olvide de los comentarios. Los comentarios son muy importantes para depurar y mejorar el programa. Además, aunque el compilador no tenga las restricciones de formateo, siempre debe seguir a las mismas reglas de editar (como en los ejemplos proporcionados en este libro). Como no hay limitaciones de extensión, no vacile en utilizar los espacios en blanco para hacer su código más legible.
Al escribir un programa, compile su código de forma regular con el propósito de corregir cuánto más errores de sintaxis. Asimismo usted puede compilar su programa cada vez que se complete la redacción de una nueva función así como probar su comportamiento al utilizar modo de depuración. De este modo, resulta más fácil solucionar los errores de programa. De lo contrario, usted tendrá que editar el programa entero. COMPILA R Y SOLUCIONAR ERRORES
Para compilar su código, pulse sobre la opción Build en el menú Project. En realidad, el proyecto entero se ha compilado, y si la compilación se ha realizado con éxito, se generarán los archivos de salida (asm, .hex etc.). Una compilación se ha realizado con éxito si no se ha encontrado ningún error. Durante el proceso de compilación se generan muchos mensajes que se visualizan en la ventana Messages. Estos mensajes consisten en información, advertencia y errores. Cada error encontrado se asocia con su línea de programa y su descripción. Como un error en su código puede generar mucho más errores, simplemente debe intentar solucionar el primer error en la lista y después recompile su programa. En otras palabras, es recomendable solucionar los errores uno a uno.
En el ejemplo anterior el programa informa de un error de sintaxis en la línea 80. La compilación le permite corregir su programa por medio de solucionar todos los errores en mikroBasic. Cuando todos los errores se solucionen, su programa está listo para ser cargado en el microcontrolador. De todas formas, su tarea todavía no está terminada, porque aún no sabe si su programa se comporta como se esperaba o no. DEPURAR EL PROGRAMA
Como ya hemos visto, hay dos modos de depurar: un depurador software que simula el funcionamiento del microcontrolador (modo por defecto) y depurador hardware (mikroICD) que lee directamente el contenido de la memoria del microcontrolador. El procedimiento de depuración es el mismo sin reparar en el modo elegido. En caso de elegir la opción ICD debug, hay que cargar el programa en el microcontrolador antes de depurarlo. La depuración es un paso muy importante ya que permite probar el programa después de una compilación realizada con éxito, o solucionar los errores descubiertos mientras se ejecuta el programa. Para iniciar la depuración, pulse sobre la opción Start debugger del menú Run. El editor del código será ligeramente modificado automáticamente y aparecerá una ventana denominada Watch Values. El principio de depuración se basa en ejecutar el programa paso a paso y monitorear el contenido de los registros y los valores de las variables. De este modo, es posible comprobar el resultado de un cálculo y ver si algo inesperado ha ocurrido. Al ejecutar el programa paso a paso, podrá localizar los problemas con facilidad. Durante una depuración el programa será modificado, por lo que usted siempre debe recompilar el programa después de cada corrección, y reiniciar el depurador para comprobar qué ha sido modificado.
SIMULADOR SOFTWARE Si quiere ser un programador y dedicarse a programar los microcontroladores, tenga en cuenta de que los programas nunca funcionan al primer intento. Por eso, empiece a funcionar un simulador. El simulador es una parte integral del compilador utilizado para simular el funcionamiento del microcontrolador.
Antes de empezar a utilizar el simulador, seleccione el modo de funcionamiento en la ventana Project Settings (Build type - release), compile el programa y pulse sobre la opción Run /Start Debugger. El compilador se pone automáticamente en el modo de simulación. En este modo se monitorea el estado de todos los bits de registros y se le permite ejecutar el programa paso a paso durante el monitoreo del
funcionamiento
del
microcontrolador
en
la
pantalla.
Hay varios iconos, utilizados para el funcionamiento del simulador, que aparecerán en la barra de herramientas cuando el compilador entre en este modo.
Estos iconos tienen el siguiente significado:
Step Into: Ejecuta una sola instrucción. Cuando la instrucción es una llamada a una subrutina, el depurador hará un salto a la subrutina y se detendrá después de ejecutar la primera instrucción dentro de la subrutina. Step Over: Se ejecuta una sola instrucción. Cuando la instrucción es una llamada a una subrutina, el depurador no hará un salto a la subrutina, sino que se ejecutará toda la subrutina. El depurador se detiene a la primera instrucción después de la llamada a la subrutina. Parece como si se saltara una línea de programa aunque se ha ejecutado toda la subrutina. El estado de todos los registros será cambiado. Este comando se ejecuta cuando es necesario acelerar la ejecución de los bucles de programa largos. Run To Cursor: El programa se ejecuta hasta la línea en la que se encuentre el cursor. Step out: Se ejecutan las demás instrucciones dentro de la rutina. El depurador se detiene inmediatamente al salir de la subrutina.
Los puntos de ruptura hacen el proceso de depurar los programas de una manera más eficiente, puesto que permiten ejecutar el programa a toda velocidad y detenerlo automáticamente en una línea específica (punto de ruptura). Eso resulta muy útil, permitiéndole comprobar sólo las partes críticas del programa y no perder el tiempo probando todo el programa línea a línea. Para añadir o quitar un punto de ruptura basta con pulsar sobre la línea apropiada en el lado izquierdo del editor del código, o presionar [F5]. Una pequeña ventana denominada Breakpoints muestra dónde están los puntos de ruptura. Note que las líneas designadas como puntos de ruptura están marcadas en rojo.
La línea que se está ejecutando actualmente está marcada en azul. Es posible leer el contenido de registros y variables seleccionados en la ventana Watch Values en cualquier momento. Para saltar directamente a los puntos de ruptura, utilice el comando Run/Pause Debugger.
VENTANA WATCH VALUES El depurador software y hardware tienen la misma función de monitorear el estado de los registros durante la ejecución del programa. La diferencia es que el depurador software simula ejecución de programa en una PC, mientras que el depurador ICD (depurador hardware) utiliza el microcontrolador. Cualquier cambio de estado lógico de los pines se indica en el registro (puerto) apropiado. Como la ventana Watch Values permite monitorear el estado de todos los registros, resulta fácil comprobar si un pin está a cero o a uno. La última modificación está marcada en rojo en la ventana Watch Values. Esto le permite localizar la modificación en el archivo list durante el proceso de la depuración. Para visualizar esta ventana es necesario seleccionar la opción View/Windows/Watch Values. Entonces usted puede hacer una lista de re-gistros/variables que quiere monitorear.
STOPWATCH (Cronómetro)
Si quiere saber cuánto tiempo tarda un microcontrolador en ejecutar una parte del programa, seleccione la opción Run/View Stopwatch. Aparecerá una ventana como se muestra en la figura a la derecha.¿Cómo funciona un cronómetro? Eso es pan comido...El tiempo que tarda un comando (step into, step over, run/pause etc.) en ejecutarse por el depurador se mide automáticamente y se visualiza en la ventana Stopwatch. Por ejemplo, se mide tiempo para ejecutar un programa, tiempo para ejecutar el último paso etc.
DEPURADOR EN CIRCUITO La otra forma de comprobar la ejecución de programa es al utilizar el depurador mikroICD (depurador en circuito). El mikroICD (depurador en circuito) es una parte integral del programador PICflash. Se utiliza con el propósito de probar y depurar los programas. El proceso de probar y depurar se realiza al monitorizar los estados de todos los registros dentro del microcontrolador durante su funcionamiento en entorno real. Para habilitar la depuración, es necesario seleccionar las opciones Build Type-ICD Debug y Debugger-mikroICD antes de cargar el programa en el microcontrolador. Tan pronto como se inicie el depurador mikroICD, aparecerá una ventana como se muestra en la siguiente Figura. El depurador mikroICD se comunica con el microcontrolador PIC por sus pines utilizados para la programación. Por eso no se pueden utilizar como pines de E/S durante la ejecución de la depuración de programa. Durante la operación del depurador mikroICD, el programador y la PC deben estar conectados al utilizar un cable USB.
Opciones del depurador mikroICD:
Start Debugger [F9] Run/Pause Debugger [F6] Stop Debugger [Ctrl+F2] Step Into [F7] Step Over [F8] Step Out [Ctrl+F8] Toggle Breakpoint [F5] Show/Hide Breakpoints [Shift+F4] Clear Breakpoints [Ctrl+Shift+F4]
Cada de estos comandos se activa por medio de los atajos de teclado o al pulsar sobre el icono apropiado en la ventana Watch Values. El depurador mikroICD también ofrece funciones tales como ejecutar el programa paso a paso, detener la ejecución de programa para monitorear el estado de los registros actualmente activos por medio de los puntos de ruptura, monitorear los valores de algunas variables etc. El siguiente ejemplo muestra una ejecución de programa paso a paso utilizando el comando Step Over.
Paso1:
En este ejemplo la línea de programa 31 está marcada por el azul, lo que quiere decir que es la siguiente en ser ejecutada. El estado actual de todos los registros dentro del microcontrolador se puede visualizar en la ventana Watch Values del mikroICD. Paso 2:
Después de ejecutar el comando Step Over [F8] el microcontrolador ejecutará la línea de programa 31. La siguiente línea en ser ejecutada (32) está marcada por el azul. El estado de los registros cambiados durante la ejecución de esta instrucción se puede visualizar en la ventana Watch Values.
CARGAR EL PROGRAMA EN EL MICROCONTROLADOR Si ha solucionado todos los errores en su código y cree que su programa está listo para ser utilizado, el siguiente paso es cargarlo en el microcontrolador. El programador PICflash se utiliza para este propósito. Es una herramienta diseñada
para programar todos los tipos de microcontroladores PIC. Está compuesto por dos partes:
La parte hardware se utiliza para poner en el búfer un código hexadecimal (el programa a ser cargado en el microcontrolador) y para programar el microcontrolador por medio de niveles de voltaje específicos. Durante el proceso de la programación, un nuevo programa se escribe en la memoria flash del microcontrolador, mientras que el programa anterior se borra automáticamente. La parte de software se encarga de enviar el programa (archivo .hex) a la parte hardware del programador por medio de un cable USB. Se activa al pulsar sobre la opción mE_Programmer del menú Tools o al pulsar [F11]. Por consiguiente, es posible modificar algunas configuraciones del programador y controlar el funcionamiento de la parte hardware (Cargar, Escribir, Verificar...).
Se puede reprogramar el microcontrolador tantas veces como se necesite.
HERRAMIENTAS DEL COMPILADOR El compilador mikroBasic PRO for PIC proporciona herramientas que en gran medida simplifican el proceso de escribir el programa. Todas estas herramientas se encuentran en el menú Tools. En la siguiente sección vamos a darle una breve descripción de todas ellas.
TERMINAL USA RT
El terminal USART representa una sustitución para la estándar Windows Hyper Terminal. Se puede utilizar para controlar el funcionamiento del microcontrolador que utiliza la comunicación USART. Tales microcontroladores están incorporados en un dispositivo destino y conectados al conector RS232 de la PC por medio de un cable serial. La ventana USART terminal dispone de opciones para configurar la comunicación serial y visualizar los datos enviados/recibidos. EDITOR EEPROM
Al seleccionar la opción EEPROM Editor del menú Tools, aparecerá una ventana como se muestra en la siguiente figura. Así es cómo funciona la memoria EEPROM del microcontrolador. Si quiere cambiar de su contenido después de cargar el programa en el microcontrolador, ésta es la forma correcta de hacerlo. El nuevo contenido es un dato de un tipo específico (char, int o double), primero debe
seleccionarlo, introducir el valor en el campo Edit Value y pulsar sobre Edit. Luego, pulse sobre el botón Save para guardarlo como un documento con extensión .hex. Si la opción Use EEPROM in Project está activa, los datos se cargarán automáticamente en el microcontrolador durante el proceso de la programación. VENTANA A SCII CHART
Si necesita representar numéricamente un carácter ASCII, seleccione la opción ASCII chart del menú Tools. Aparecerá una tabla, como se muestra en la figura que está a continuación.
Usted probablemente sabe que cada tecla de teclado está asociada con un código (código ASCII). Como se puede ver, los caracteres que representan los números tienen valores diferentes. Por esta razón, la instrucción de programa para visualizar el número 7 en un LCD no visualizará este número, sino el equivalente a la instrucción BEL. Si envía el mismo número en forma de un carácter a un LCD, obtendrá el resultado esperado - número 7. Por consiguiente, si quiere visualizar un número sin convertirlo en un carácter apropiado, es necesario añadir el número 48 a cada dígito en el que consiste el número a visualizar. EDITOR DE SIETE SEGMENTOS
Un editor de siete segmentos le permite determinar con facilidad el número a poner en un puerto de salida con el propósito de visualizar un símbolo deseado. Por supuesto, se da por entendido que los pines del puerto deben estar
conectados a los segmentos del visualizador de manera apropiada. Basta con colocar el cursor en cualquier segmento del visualizador y pulsar sobre él. Se visualizará inmediatamente el número a introducir en el programa.
LCD CUSTOM CHARACTER (Caracteres LCD definidos po r el usuario)
Además de los caracteres estándar, el microcontrolador también puede visualizar los caracteres creados por el programador. Al seleccionar la herramienta LCD custom character, se evitará un pesado trabajo de crear funciones para enviar un código apropiado a un visualizador. Para crear un símbolo, pulse sobre los cuadros pequeños en la ventana LCD custom character, luego seleccione la posición y la fila y pulse sobre el botón generate. El código apropiado aparece en otra ventana. No es necesita pulsar más. Copy to Clipboard (copiar al portapapeles) - Paste (pegar)...
GENERADOR DE MAPA DE B ITS PARA UN L CD GRÁFICO
El generador de mapa de bits para un LCD gráfico es una herramienta insustituible en caso de que el programa que escribe utilice el visualizador LCD (GLCD). Esta herramienta le permite visualizar un mapa de bits con facilidad. Seleccione la opción Tools/Glcd Bitmap Editor aparecerá la ventana apropiada. Para utilizarlo, seleccione el tipo de visualizador a utilizar y cargue un mapa de bits. El mapa de
bits debe ser monocromático y tener la resolución apropiada del visualizador (128 x 64 píxeles en este ejemplo). El procedimiento a seguir es igual que en el ejemplo anterior: Copy to Clipboard... Un código generado que utiliza herramientas para controlar los visualizadores LCD y GLCD contiene funciones de la librería Lcd. Si las utiliza en el programa, no se olvide de marcar la caja de chequeo junto a esta librería en la ventana Library Manager. Así el compilador
será
reconocer estas correctamente.
capaz
de
funciones
LIBRARÍAS Uno de los elementos más importantes del compilador mikroBasic PRO for PIC es Library Manager, que por supuesto merece nuestra
atención.
Para que una función o un procedimiento realice una cierta tarea al escribir un programa, basta con encontrarla/encontrarlo en una de las librerías incluidas en el compilador y utilizarla. Una librería representa un archivo llamado cabecera. Contiene un conjunto de variables y constantes escritas en mikroBasic. Cada librería tiene un propósito específico. Por ejemplo, para que un procedimiento genere una señal de audio, abra la librería Sound en la ventana Library Manager y pulse dos veces sobre el procedimiento apropiado Sound_Play. Una descripción detallada de este procedimiento aparece en la pantalla. Copíelo en su programa y ajuste los parámetros apropiados. Al marcar esta librería, sus funciones estarán disponibles y no será necesario utilizar la librería
include.
El mikroBasic PRO for PIC incluye las librerías misceláneas y las librerías para el hardware.
L IBRER ÍAS M ISCEL ÁNEA S
Las librerías misceláneas contienen algunas funciones de propósito general: LIBRARÍA
DESCRIPCIÓN
Button Library
Eliminar la influencia del rebote de contacto
Conversions Library Rutinas para conversiones de números en cadenas y BCD/decimal C Type Library
Probar y convertir los caracteres
String Library
Automatizar las tareas relacionadas con las cadenas
Time Library
Rutinas para calcular el tiempo en el formato de tiempo UNIX
Trigon Library
Funciones trigonométricas
LIBRAR IES L IBRERÍAS PARA EL HARDW ARE
Las librerías para el hardware incluyen las funciones utilizadas para controlar el funcionamiento de los módulos hardware: LIBRARÍA
DESCRIPCIÓN
ADC Library
Utilizada para el funcionamiento del convertidor A/D
CAN Library
Utilizada para las operaciones con el módulo CAN
CANSPI Library
Utilizada para las operaciones con el módulo CAN externo (MCP2515 o MCP2510)
Compact Flash Library
Utilizada para las operaciones con las tarjetas de memoria Compact Flash
EEPROM Library
Utilizada para las operaciones con la memoria EEPROM incorporada
Ethernet PIC18FxxJ60 Library
Utilizada para las operaciones con el módulo Ethernet incorporado
Flash Memory Library
Utilizada para las operaciones con la memoria Flash incorporada
Graphic Lcd Library
Utilizada para las operaciones con el módulo LCD gráfico con resolución 128x64
I²C Library
Utilizada para las operaciones con el módulo de comunicación serial I 2C incorporado