Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Manual Pic Simulator PDF
Manual Pic Simulator PDF
INDICE
Capitulo 01 - La interfaz
Capitulo 06 - Variables
Capitulo 11 - FOR-TO-STEP-NEXT
Capitulo 13 - LOOKUP
Capitulo 15 - MODULOS
CAPITULO 01 – LA INTERFAZ
Debido a que se trata de un software concebido desde el vamos como un entorno,
la integración entre los diferentes módulos que lo componen es completa y sin
problemas.
Una vez instalado el programa, el icono que lo representa aparecerá en nuestro
escritorio, y haciendo doble clic sobre el se abrirá la pantalla principal del
programa, que al menos hasta la versión sobre la que se desarrolla este tutorial (la
5.91) esta en ingles:
Antes de ver en que consiste cada opción del menú principal, vamos a analizar
rápidamente cada sección de esta pantalla:
En la parte superior, y justo debajo de la barra de menú tenemos tres cuadros de
texto que nos muestran la ruta completa hacia el programa que tenemos cargado
en el simulador (Program Location), el microcontrolador que hemos seleccionado
Todos estos valores pueden ser cambiados, como veremos en el segundo capitulo,
desde la barra de menú.
El recuadro que esta inmediatamente debajo del anterior nos muestra (cuando
estamos corriendo una simulación de nuestro programa) cual es la instrucción
assembler en curso (Last Instruction) y cual será la siguiente a ejecutar (Next
Instruction):
Por ultimo, y a la derecha del cuadro anterior, tenemos el valor de todos los
registros de propósito general (GPRs, o general purpose register). La lista tiene
dos columnas, cada una indicando la dirección del registro (Addr.) y su valor en
hexadecimal (Hex. Value):
La mayoría de las funciones de las que dispone esta herramienta están agrupadas
dentro del menú principal de la aplicación. Es de destacar que todos los módulos
que se pueden invocar desde aquí se abren en ventanas separadas, y pueden ser
configuradas (como veremos) para que se sitúen permanentemente delante de las
demás ventanas, de manera que no las perdamos de vista. Este es el menú
principal:
Estas son: Step By Step (paso a paso), Slow (Lenta), Normal (Normal), Fast
(Rápida), Extremely Fast (muy rápida) y Ultimate (No Refresh) que es la mas
rápida de todas, pero que no actualiza la pantalla principal del simulador. Esta
opción resulta muy útil para "adelantar" partes del programa que sabemos que no
tienen problemas. Todas pueden ser invocadas con CTRL+F1 a CTRL+F6, tal como
se ve en la figura anterior.
Tools es el submenú encargado de invocar a cada uno de los módulos que integran
el simulador, y que veremos en detalle en capítulos siguientes. Tal como se ve en la
figura, la mayoría de ellos se pueden activar mediante la combinación de la tecla
CTRL y alguna mas.
Hardware Stack Viewer nos permite conocer el valor de cada uno de los niveles
del stack (generalmente llamado pila en español). Esto puede resultar útil para
depurar los programas que tienen muchas subrutinas anidadas o cuando
sospechamos que hay desbordamientos del stack. Además de ver el nivel de stack
Existe también una vista alternativa del estado de los registros especiales, que
pude resultar mas cómoda en algunos casos. Es la correspondiente a la opción
Alternative SFR Viewer, y muestra en columnas la dirección en hexa del registro,
el nombre "de pila" del mismo (TMR0, PCL, STATUS, etc), y el valor del mismo, en
hexadecimal y en binario.
Además de los diez puntos de parada anteriores, se pueden definir cinco puntos
especiales, mediante la herramienta Special Breakpoints. La diferencia entre esta
y la anterior herramienta (y lo que la hace tan especial) es que en este caso los
puntos de inspección se fijan mediante una condición (Break Condition) o por el
estado de algún registro (Register Address). Los botones SET y DEL permiten
habilitar y deshabilitar individualmente cada una de las condiciones.
El LCD Module es la versión virtual del típico display LCD con controlador Hitachi
que usamos en todos nuestros proyectos. Es posible configurar completamente su
funcionamiento, mediante el botón Setup. Al presionarlo, la ventana aumenta su
tamaño y aparecen una serie de cuadros de selección desde donde podremos elegir
el numero de filas y columnas del display, el color del mismo, a que puerto están
conectadas las líneas de datos y si son 4 u 8, y donde están conectadas (puerto y
pin) las líneas RS, R/W y E. También se pueden configurar los tiempos de delay del
display, para que su simulación sea lo mas fiel posible a la realidad.
Otras dos herramientas sumamente útiles para comprender que esta haciendo en
cada momento el microcontrolador son el osciloscopio (Oscilloscope) de cuatro
canales, con posibilidad total de configuración de cada uno de ellos, y el Signal
Generator (generador de señales) también de cuatro canales y con posibilidad de
generar pulsos de periodo y relación cíclica ajustable. Por supuesto, habrá capítulos
en que haremos uso de ellas.
No podía faltar el modulo con los displays LED de 7 segmentos, presentes en una
gran cantidad de proyectos. En este caso, la herramienta 7-Segment LED Display
Panel nos proporciona 4 dígitos completamente configurables (nuevamente
mediante el botón Setup presente en cada uno de ellos), y podemos elegir el pin al
que esta conectada cada uno de los segmentos, si son de ánodo o cátodo común,
etc.
La ultima herramienta es una útil lista con el valor de cada una de las variables
presentes en nuestro programa. Recibe el nombre de Watch Variables (ver
variables) y es una lista de texto donde en una columna aparece el nombre de la
variable en cuestión y en otra su valor. Esta lista se actualiza constantemente
durante la simulación.
Sistema Decimal:
Como su nombre lo indica, el sistema decimal toma como base para construir los
números potencias sucesivas del numero 10. Se utilizan los símbolos del "0" al "9",
y el peso de cada cifra esta dado por su posición, dado que se multiplica por 10
elevado a la posición en que se encuentra el digito menos uno. Como en todos los
sistemas de numeración, el digito de menos "peso" es el que esta mas a la derecha,
y el de mas "peso" el que se encuentra mas a la izquierda.
Potencia de
10^7 10^6 10^5 10^4 10^3 10^2 10^1 10^0
10:
Dado que este sistema es el que usamos todo el tiempo, no nos detenemos a
pensar en como se construye cada numero, pero cuando leemos el numero "123"
en realidad esta "construido" de la siguiente manera:
100 + 20 + 3 =
123
Sistema binario:
El sistema binario, el ideal para usar en electrónica debido a que solo posee dos
símbolos, el 0 y el 1, que pueden ser codificados como presencia o ausencia de
tensión, utiliza como base el numero 2 en lugar del 10. En todo lo demás, es
exactamente igual al decimal. Si nos parece mas complicado, es solamente por
que no tenemos la suficiente practica con el.
Un numero binario esta construido mediante una secuencia de dígitos binarios (que
para abreviar llamamos "bits"). Muchas veces, se agrupan de diferentes maneras
para poder trabajarlos mas cómodamente, y a esas agrupaciones de les da un
nombre, siendo los mas utilizados los siguientes:
Bit 1 1
Nibble 4 0101
Byte 8 00000101
Word 16 0000000000000101
Nibble 0101
Byte 00000101
Word 0000000000000101
Dentro de un byte (la agrupación de bits mas común) se numeran los bits que lo
componen de acuerdo a la siguiente convención:
7 6 5 4 3 2 1 0
El bit cero recibe generalmente el nombre de LSB (least significant bit o "bit menos
significativo"). De la misma manera, al ubicado mas a la izquierda se lo llama MSB
(most significant bit o "bit mas significativo"). Y nos referimos a los demás bits
intermedios por su numero de bit correspondiente: bit 2, bit 3, etc.
De todo esto podemos deducir que el tipo de dato mas pequeño que podemos
manejar es el bit, que solo puede tener dos valores: 1 o 0. Estos dos estados
representan generalmente "encendido" o "apagado", "verdadero" o "falso", "si" o
"no", etc.
Como podemos ver en la tabla de mas arriba, el nibble es la unión de cuatro bits.
Dado que 2x2x2x2 = 16, este es el numero de valores posibles que puede tomar
un nibble.
La estructura mas utilizada es el byte, que agrupa 8 bits (o dos nibbles), y que
puede tomar valores entre 0 y 255 (2^8 valores posibles). Si tomamos dos bytes y
los "pegamos" uno detrás del otro, obtenemos una palabra (word), que permite
65536 (2^16) valores diferentes.
Sistema hexadecimal:
Si tomamos 16 símbolos para representar los números (en lugar de dos o diez),
obtenemos un sistema que se llama hexadecimal. A los símbolos 0..9 se agregan
las letras A, B, C, D, E y F, y es un sistema de numeración muy utilizado en
programación. Algunas de sus ventajas son que cada digito de un numero
hexadecimal es exactamente un nibble, o que cada dos dígitos hexadecimales son
un byte. Esto proporciona una forma muy compacta de representar valores.
1 0000 0001 1
10 0000 1010 A
233 11101001 E9
Algunos ejemplos.
Capitulo 06 - Variables:
El BASIC tenemos distintos tipos de variable, según el dato que puedan almacenar:
El tipo "Long" solo esta disponible mediante un modulo opcional al PIC SIMULATOR
IDE.
A diferencia de otros BASIC, la declaración de variables puede ser hecha en
cualquier parte del programa, y todas son consideradas globales, es decir, su valor
es accesible desde todas las subrutinas y zonas del programa. El numero de
variables esta lógicamente limitado al monto de memoria RAM disponible en cada
microcontrolador. Las variables las declaramos utilizando 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, que son una matriz de dimensiones 1xN . Por
ejemplo, la sentencia siguiente:
declara un vector (al que nos referiremos algunas veces como "array") de diez
elementos del tipo BYTE, que serán accedidos mediante el uso de subíndice (entre
paréntesis) del 0 al 9.
RESERVE 20
Las variables tipo Word, como vimos, están compuestas por dos bytes. el primero
de ellos es llamado byte "alto" y el otro "bajo", dado que el primero contiene los 8
bits mas significativos. En BASIC podemos acceder individualmente a cada uno de
los bytes que componen un Word mediante las extensiones ".HB" (High byte, o
byte alto) y ".LB" (Low Byte o byte bajo) . Veamos un ejemplo:
DIM A AS BYTE
DIM B AS WORD
A = B.HB
A = B.LB 'Esto es lo mismo que A = B
B.HB = A
B.LB = A
B = A 'Esto también borra el byte alto de la variable B
DIM A AS BYTE
DIM B AS BIT
B = A.1
B = A.7
A.0 = A.5
Todos los registros del microcontrolador esta disponibles para usar en los
programas BASIC, como si se tratase de variables del tipo BYTE con el nombre del
registro utilizado en las datasheet (PORTA, PORTB, TRISA, etc.). Por supuesto, se
puede acceder a bits individuales de los registros con la técnica vista párrafos atrás.
Algunos ejemplos:
TRISA.1 = 0
TRISB = 0
PORTA.1 = 1
PORTB = 255
STATUS.RP0 = 1
INTCON.INTF = 0
Existe una "forma corta" de acceder a los bits individuales de cada port,
simplemente usando las variables BASIC tipo byte RA, RB, RC, RD, RE o bien las
tipo bit RA0, RA1, RA2, ..., RE6, RE7
RA = 0xFF
RB0 = 1
DIM X AS WORD
DIM Y AS BYTE
X = 0x3F
Y = POINTER(X)
Y = Y + 0x55
X = X - 1
POINTER(X) = Y
Y = 0xAA
X = X - 1
POINTER(X) = Y
Una forma de escribir programas que nos resulten 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.
PORTB.0 = 1
podemos hacer
LED1 = 1
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
DIM A AS WORD
CONST PI = 314
A = PI
Hay tres instrucciones para el manejo individual de bits, que si bien no hacen nada
que no se puede resolver con otras instrucciones o símbolos, ayudan mucho en la
lectura del código. Se tratan de HIGH, LOW y TOGGLE, que ponen el bit en alto,
bajo o lo invierten, respectivamente.
HIGH PORTB.0
LOW ADCON0.ADON
TOGGLE OPTION_REG.INTEDG
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)
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. Solo es
posible efectuar una operación lógica por instrucción (aunque es muy posible que
próximas versiones permitan mas flexibilidad. Este al tanto de las novedades!).
Estas operaciones también están disponibles para variables tipo Word o Byte.
Veamos algunos ejemplos:
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
Para estas practicas, utilizaremos un PIC16F628A, uno de los mas difundidos y que
mas o menos viene a reemplazar al viejo y popular PIC16F84, ya obsoleto. El
diagrama circuital que utilizaremos para las primeras practicas es el siguiente:
Si bien se supone que quien esta leyendo este tutorial tiene una buena idea sobre
electrónica y microcontroladores, igualmente vamos a hacer una muy breve
descripción del circuito.
El primer paso es, desde el menú "Opciones" -> "Select Microcontroller", elegir
el PIC16F628A.
Una vez hecho esto, arrancamos el edito de BASIC (presionando CTRL-C, por
ejemplo), y escribimos el siguiente código:
La línea 001 utiliza la sentencia AllDigital para convertir todos los pines del micro
en pines de E/S. Esto equivale a deshabilitar los comparadores, conversores A/D y
todos los módulos que pudiese tener nuestro microcontrolador. No es la única
manera de hacer esto, pero si la mas sencilla desde el punto de vista del
programador BASIC.
Las líneas 003 y 004 convierten todos los pines del puerto A en entradas ( TRISA =
%11111111 ) y los del puerto B en salidas ( TRISB = %00000000 ). El "%" indica que
el numero que viene a continuación esta en binario. Se podría haber escrito, por
ejemplo TRISB = 0 y hubiera sido lo mismo. Personalmente me gusta esta manera,
ya que "veo" el estado de cada pin. Por supuesto, es valido activar como entrada
algunos pines, y como salidas otros, haciendo algo parecido a TRISB = %11000111 .
En la línea 006 encontramos una "etiqueta" ( loop: ). Esta no hace nada, solo sirve
como referencia para enviar el flujo del programa a esa línea desde otro lugar,
mediante la sentencia "Goto".
En 008 tenemos la sentencia WaitMs 500 . WaitMs se encarga de hacer una pausa
en milisegundos. La duración de la pausa esta dada por el numero que sigue a la
instrucción, en este caso 500 milisegundos, o medio segundo.
En 010 se hace nuevamente una pausa de medio segundo, y por ultimo, la línea
Goto Loop hace que el programa continúe en la línea 006 (que es donde esta la
etiqueta Loop).
Si volvemos a la ventana principal del PIC SIMULATOR IDE, y desde "Tools" ->
"Microcontroller View" abrimos la vista del microntrolador, al darle "Start" a la
simulación tendremos algo parecido a lo que sigue:
Se podría haber utilizado la instrucción SYMBOL para hacer mas claro el programa.
En el siguiente ejemplo, hemos hecho algunos cambio y obtenido un programa que
hace exactamente lo mismo que el anterior, pero que resulta mas claro de
entender, ya que se aproxima algo mas al "lenguaje natural":
Si volvemos a la ventana principal del PIC SIMULATOR IDE, y desde "Tools" ->
"Microcontroller View" abrimos la vista del microntrolador, al darle "Start" a la
simulación tendremos algo parecido a lo que sigue:
l pin 6, correspondiente a RB0 esta en "OFF" por que el pulsador del pin 17 (RA0)
esta en OFF. Si con el mouse hacemos un click sobre la "T" que esta al lado del pin
17, la vista del microcontrolador pasara al estado que muestra la imagen siguiente:
Recordemos que el botón "T" significa "cambio" (Toggle) por lo que el estado del
pin 17 permanecerá en alto hasta que lo pulsemos otra vez, y el estado del
microcontrolador volverá a ser el inicial. Como en cualquier curso, conviene realizar
estas practicas, que aunque puedan parecer muy sencillas nos ayudaran a conocer
las herramientas disponibles y "tomar confianza" al programa. También es
interesante el realizar cambios en el programa BASIC, recompilar y analizar los
resultados.
Existen varias formas de utilizar esta instrucción. Comenzaremos con los casos mas
sencillos y a lo largo de este capitulo iremos agregando complejidad hasta ver
todas las posibilidades.
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".
IF PORTA.4 = 1 THEN A = 4
Cundo comienza el programa, se declaran dos variables tipo BYTE (que pueden
almacenar valores entre 0 y 255), y a TOTAL se le asigna el valor "0" y a "A" el
valor "2". Hasta aquí, no hay nada que no hayamos visto antes.
IF A = B THEN PORTA.0 = 1
IF B > A THEN A = B
IF B = 5 THEN A = 0
IF (A = 0) OR (B = 5) THEN C = 2
IF PORTA.0 THEN PORTB.3 = 0
IF condición THEN
instrucción 1
instrucción 2
...
instrucción n
ENDIF
No varia prácticamente nada respecto del primer caso, solo que esta vez se van a
ejecutar todas las instrucciones que se encuentren entre el THEN y el ENDIF cada
vez que condición sea verdadera.
IF A = 2 THEN
A = B + (C * D)
TOTAL = A * B
ENDIF
IF condición THEN
instrucciónv 1
instrucciónv 2
...
instrucciónv n
ELSE
instrucciónf 1
instrucciónf 2
...
instrucciónf n
ENDIF
IF PORTA.4 = 1 THEN
A = 4
TOTAL = TOTAL + 5
ELSE
A = 0
TOTAL = TOTAL + 15
ENDIF
Por ultimo, tenemos que saber que es posible "anidar" instrucciones IF-THEN-
ELSE-ENDIF, con lo que se pueden tomar decisiones verdaderamente complejas.
Por supuesto, tenemos que ser cautos en el uso de esta característica ya que
debido a limitaciones en el tamaño de la pila y cantidad de memoria disponible del
PIC podemos ocasionar un desborde y el programa colapsara. Este seria un ejemplo
de un anidamiento:
IF PORTB.1 = 1 THEN
IF A = 2 THEN
A = B + (C * D)
TOTAL = A * B
ELSE
A = 0
ENDIF
ELSE
A = 19
ENDIF
Así como la toma de decisiones que vimos en el capitulo anterior esta presente en
casi todos nuestros programas, las estructuras que permiten repetir un grupo de
instrucciones un numero determinado de veces también son indispensables. En PIC
SIMULATOR IDE hay dos de ellas. Veremos en este capitulo la primera, FOR - TO
- STEP - NEXT.
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:
Veamos un ejemplo concreto. Supongamos que queremos sumar los números del 1
al 100. El programa quedaría como sigue:
TOTAL comienza valiendo 0 (se le asigna ese valor fuera del bucle) y en cada
iteración se le suma el valor que tenga A en ese momento. De esa manera, TOTAL
va tomando los valores 1, 3, 6, 10, .... 5050.
Hay casos en que es necesario que el valor de la variable de control del bucle se
decremente en lugar de ir aumentando. En ese caso, se puede usar un valor
negativo para STEP. El siguiente ejemplo cuenta desde 50 hasta 20, de 5 en 5:
La única condición es que un bucle este completamente dentro del otro. El siguiente
anidamiento daría un error en el compilador:
AllDigital
TRISB = 0
Dim a As Byte
For a = 0 To 15
PORTB = a
Next a
WHILE condición
instruccion1
instruccion2
...
instruccionn
WEND
No hay mucho mas para decir de WHILE-WEND , solo analizar algunos ejemplos:
Ejemplo 1: El siguiente es un bucle infinito. Como dentro del cuerpo del WHILE-
WEND no se cambia el valor de la variable A, esta siempre vale "0" y la condición
del WHILE nunca es falsa, por lo que se repite eternamente:
DIM A AS BYTE
A = 0
...
WHILE A = 0
instruccion1
instruccion2
...
instruccionn
WEND
...
DIM A AS BYTE
A = 0
...
WHILE A > 0
instruccion1
instruccion2
...
instruccionn
WEND
...
DIM A AS BYTE
DIM A AS BYTE
A = 0
B = 0
WHILE A < 10
A = A + 1 'Incremento la variable A
B = B + A 'Sumo a B el valor de la variable A
WEND
Capitulo 13 – 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.
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 algunas o todas las constantes de la lista son valores ASCII, se puede hacer
mas corta y legible la misma utilizando como parte de ella una cadena de
caracteres, como se ve a continuación.
"A" seria el valor que tendría MASK cuando INDEX vale "0", y "K" cuando INDEX
tenga el valor "10".
TRISB = 0x00
PORTB = %00000011
goleft:
WaitUs 5 'esta demora debe ser mayor si no es una simulación!
PORTB = ShiftLeft(PORTB, 1)
If PORTB = %11000000 Then Goto goright
Goto goleft
goright:
WaitUs 5 'esta demora debe ser mayor si no es una simulación!
PORTB = ShiftRight(PORTB, 1)
If PORTB = %00000011 Then Goto goleft
Goto goright
Lo que hace el programa es muy sencillo: enciende los dos primeros bits del
PORTB, espera un tiempo, los desplaza hacia la izquierda, si esos bits llegaron al
extremo de la variable tipo byte que es el PORTB, se invierte el sentido del
desplazamiento. La siguiente animación flash ilustra el efecto, tal como se puede
ver en el simulador:
Capitulo 15 - MODULOS
DIM A AS BYTE
DIM B AS BYTE
A = 10
READ A, B
WRITE 11, B
Usando interrupciones
La rutina de la interrupción se debe poner como el resto de subprogramas después de la
declaración END. Debe comenzar con ON INTERRUPCIÓN y terminar con la
declaracion RESUMEN. Si las operaciones aritméticas, los órdenes o algunas otras
declaraciones complejas se utilizan en rutina de la interrupción, entonces EXCEPTO la
declaración SAVE SYSTEM debe ser colocado a la derecha después de la declaración ON
INTERRUPT para ahorrar el contenido de los registros usados por el sistema. ENABLE y
DISABLE las declaraciones puede ser utilizado en programa principal controlar el bit de
GIE en registro de INTCON. La declaración RESUME fijará el bit de GIE que permitirá
nuevas interrupciones. Por ejemplo:
DIM A AS BYTE
A = 255
TRISA = 0
PORTA = A
INTCON.INTE = 1
ENABLE
END
ON INTERRUPT
A = A - 1
PORTA = A
INTCON.INTF = 0
RESUME
DIM T AS WORD
T = 0
TRISA = 0xFF
ADCON1 = 0
TRISB = 0
OPTION_REG.T0CS = 0
INTCON.T0IE = 1
ENABLE
loop:
ADCIN 0, PORTB
GOTO loop
END
ON INTERRUPT
SAVE SYSTEM
T = T + 1
INTCON.T0IF = 0
RESUME
2400, 4800, 9600, 14400, 19200, 28800, 31250, 38400, 56000 y 57600. Si se omite la
velocidad el UART, este es configurado para la velocidad 9600.
La declaración de HSERIN se puede utilizar para cargar una lista de las variables de un
Byte o Word con los valores recibidos en puerto serial. Esta declaración esperará hasta
que el número requerido de Bytes se recibe en puerto serial.
La declaración de HSERGET tiene un argumento que deba ser una variable de un Byte.
Si hay un carácter que espera en el almacenador intermediario de la recepción que será
cargado en la variable, si no 0 valores serán cargados. Aquí están algunos ejemplos:
DIM I AS BYTE
HSEROPEN 38400
WAITMS 1000
FOR I = 20 TO 0 STEP -1
HSEROUT "Number: ", #I, CrLf
WAITMS 500
NEXT I
DIM I AS BYTE
HSEROPEN 19200
loop:
HSERIN I
HSEROUT "Number: ", #I, CrLf
GOTO loop
DIM I AS BYTE
HSEROPEN 19200
loop:
HSERGET I
IF I > 0 THEN
HSEROUT "Number: ", #I, CrLf
WAITMS 50
ENDIF
GOTO loop
La primer argumento de ambas declaraciones debe ser uno de los pines del
microcontrolador, mientras que el segundo argumento es velocidad: 300, 600, 1200,
2400, 4800, 9600 o 19200.
Usar velocidades más altas con frecuencia de reloj baja podía causar errores de trama.
Para SEROUT la declaración entonces sigue la lista de las discusiones que se enviarán
al puerto serial. Puedes utilizar secuencias, la palabra clave del LF para carácter de
avance de línea o palabra clave para el retorno del carro - secuencia de CRLF del
avance de línea, constante y variable. Si se utiliza el signo “#” antes de que el nombre
de una variable entonces su representación decimal será enviada a través del puerto
serial.
DIM I AS BYTE
loop:
SERIN PORTC.7, 9600, I
SEROUT PORTC.6, 9600, "Number: ", #I, CrLf
GOTO loop
Por ejemplo, porque EEPROMs de la familia 24C (con las entradas de la dirección de
dispositivo conectadas con la tierra) el valor 0xA0 podria ser utilizado para el slave
address. Ambas declaraciones tomarán control sobre el bit 0 del slave address durante la
comunicación.
Adelante la discusión de ambas declaraciones debe ser una variable del octeto o de la
palabra (ésta depende del dispositivo usado) que contiene la dirección de la localización
DEFINE LCD_BITS = 8
DEFINE LCD_DREG = PORTB
DEFINE LCD_DBIT = 0
DEFINE LCD_RSREG = PORTD
DEFINE LCD_RSBIT = 1
DEFINE LCD_EREG = PORTD
DEFINE LCD_EBIT = 3
DEFINE LCD_RWREG = PORTD
DEFINE LCD_RWBIT = 2
DIM ADDR AS WORD
DIM DATA AS BYTE
SYMBOL SDA = PORTC.2
SYMBOL SCL = PORTC.3
LCDINIT 3
WAITMS 1000
FOR ADDR = 0 TO 31
LCDCMDOUT LcdClear
DATA = 255 - ADDR
I2CWRITE SDA, SCL, 0xA0, ADDR, DATA
LCDOUT "Write To EEPROM"
LCDCMDOUT LcdLine2Home
LCDOUT "(", #ADDR, ") = ", #DATA
WAITMS 1000
NEXT ADDR
FOR ADDR = 0 TO 31
LCDCMDOUT LcdClear
I2CREAD SDA, SCL, 0xA0, ADDR, DATA
LCDOUT "Read From EEPROM"
LCDCMDOUT LcdLine2Home
LCDOUT "(", #ADDR, ") = ", #DATA
WAITMS 1000
NEXT ADDR
AllDigital
Define LCD_BITS = 8
For addr = 0 To 10
data = 200 - addr
SPICSOn
SPISend 0x06
SPICSOff
SPICSOn
SPISend 0x02
SPISend addr
SPISend data
SPICSOff
Lcdcmdout LcdClear
Lcdout "Write To EEPROM"
Lcdcmdout LcdLine2Home
Lcdout "(", #addr, ") = ", #data
WaitMs 500
Next addr
For addr = 0 To 10
SPICSOn
SPISend 0x03
SPISend addr
SPIReceive data
SPICSOff
Lcdcmdout LcdClear
Lcdout "Read From EEPROM"
Lcdcmdout LcdLine2Home
Lcdout "(", #addr, ") = ", #data
WaitMs 500
Next addr
Define LCD_BITS = 8
Define LCD_DREG = PORTD
Define LCD_DBIT = 0
Define LCD_RSREG = PORTE
Define LCD_RSBIT = 0
Define LCD_RWREG = PORTE
Define LCD_RWBIT = 1
Define LCD_EREG = PORTE
Define LCD_EBIT = 2
Define LCD_READ_BUSY_FLAG = 1
Lcdinit
SPICSOn
SPISendBits 6, %100110
SPISendBits 8, %00000000
SPICSOff
For addr = 0 To 10
data = 200 - addr
SPICSOn
SPISendBits 6, %101000
SPISendBits 8, addr
SPISend data
SPICSOff
SPICSOn
SPISend 0x00
SPICSOff
Lcdcmdout LcdClear
Lcdout "Write To EEPROM"
Lcdcmdout LcdLine2Home
Lcdout "(", #addr, ") = ", #data
WaitMs 500
Next addr
For addr = 0 To 10
SPICSOn
SPISendBits 6, %110000
SPISendBits 8, addr
SPIReceive data
SPICSOff
Lcdcmdout LcdClear
Lcdout "Read From EEPROM"
Lcdcmdout LcdLine2Home
Lcdout "(", #addr, ") = ", #data
WaitMs 500
Next addr
Los tres últimos parámetros pueden ser fijados a los valores más bajos cuando se utiliza
el módulo LCD integrada simulador. Si R / W se conecta a la línea de
microcontroladores y LCD_READ_BUSY_FLAG parámetro se pone a 1 usando
DEFINE directiva, entonces estos parámetros demora será ignorado por el compilador y
el momento correcto será ejecutado por la lectura de la situación de la bandera ocupado
en la pantalla LCD.
DEFINE LCD_BITS = 8
DEFINE LCD_DREG = PORTB
DEFINE LCD_DBIT = 0
DEFINE LCD_RSREG = PORTD
DEFINE LCD_RSBIT = 1
DEFINE LCD_EREG = PORTD
DEFINE LCD_EBIT = 3
DEFINE LCD_RWREG = PORTD
DEFINE LCD_RWBIT = 2
LCDINIT LcdCurBlink
loop:
LCDOUT "Hello world!"
WAITMS 1000
LCDCMDOUT LcdClear
WAITMS 1000
GOTO loop
DEFINE LCD_BITS = 8
DEFINE LCD_DREG = PORTB
DEFINE LCD_DBIT = 0
DEFINE LCD_RSREG = PORTD
DEFINE LCD_RSBIT = 1
DEFINE LCD_EREG = PORTD
DEFINE LCD_EBIT = 3
DEFINE LCD_RWREG = PORTD
DEFINE LCD_RWBIT = 2
DIM A AS WORD
A = 65535
LCDINIT 3
WAITMS 1000
loop:
LCDOUT "I am counting!"
LCDCMDOUT LcdLine2Home
LCDOUT #A
A = A - 1
WAITMS 250
LCDCMDOUT LcdClear
GOTO loop
Las declaraciones relacionadas LCD tendrá control sobre TRIS registros relacionados
con los pines utilizados para interfaz LCD, pero si usted utiliza los pines PORTA
PORTE en los dispositivos con A / D Converter Módulo entonces debe tomar el control
sobre el registro ADCON1 utilizado para fijar las patillas como digital I / O.
Usted puede configurar hasta ocho caracteres definidos por el usuario que se utilizará en
Para los LCD con cuatro líneas de caracteres adicionales simbólico LCDCMDOUT
declaración de los argumentos se pueden utilizar: LcdLine3Home, LcdLine4Home,
LcdLine3Clear, LcdLine4Clear, LcdLine3Pos y LcdLine4Pos () (). Argumento de
LcdLine3Pos y LcdLine4Pos () () puede ser un número en el rango (1-40) o variable de
tipo Byte de datos. El valor que figura en la variable que debe ser de la misma gama.
Antes de utilizar estos elementos de idioma, valores correctos determinar LCD tipo
debe ser asignado a LCD_LINES y LCD_CHARS parámetros usando DEFINE
directivas.
DEFINE LCD_LINES = 4
DEFINE LCD_CHARS = 16
DEFINE LCD_BITS = 8
DEFINE LCD_DREG = PORTB
DEFINE LCD_DBIT = 0
DEFINE LCD_RSREG = PORTD
DEFINE LCD_RSBIT = 1
DEFINE LCD_EREG = PORTD
DEFINE LCD_EBIT = 3
DEFINE LCD_RWREG = PORTD
DEFINE LCD_RWBIT = 2
LCDINIT 3
loop:
LCDCMDOUT LcdClear
LCDCMDOUT LcdLine1Home
LCDOUT "This is line 1"
LCDCMDOUT LcdLine2Home
LCDOUT "This is line 2"
LCDCMDOUT LcdLine3Home
LCDOUT "This is line 3"
LCDCMDOUT LcdLine4Home
LCDOUT "This is line 4"
WAITMS 1000
LCDCMDOUT LcdLine1Clear
LCDCMDOUT LcdLine2Clear
LCDCMDOUT LcdLine3Clear
LCDCMDOUT LcdLine4Clear
LCDCMDOUT LcdLine1Pos(1)
LCDOUT "Line 1"
LCDCMDOUT LcdLine2Pos(2)
LCDOUT "Line 2"
LCDCMDOUT LcdLine3Pos(3)
LCDOUT "Line 3"
LCDCMDOUT LcdLine4Pos(4)
LCDOUT "Line 4"
WAITMS 1000
GOTO loop
Antes de utilizar las declaraciones relacionadas con los LCD gráfica, el usuario debe
configurar la interfaz gráfica con el módulo LCD utilizando DEFINE directivas. Aquí
está la lista de parámetros disponibles:
• GLCD_DREG - define el puerto cuando las lineas de datos (tiene que ser un
puerto de 8 bits)
• GLCD_RSREG - define el puerto RS cuando está conectado a la línea
• GLCD_RSBIT - define el pin RS cuando está conectado a la línea
• GLCD_EREG - define el puerto donde E es conectado a la línea
• GLCD_EBIT - define el pin donde E es conectado a la línea
• GLCD_RWREG - define el puerto en el R / W está conectado a la línea
• GLCD_RWBIT - donde se define el pin R / W está conectado a la línea
• GLCD_CS1REG - define el puerto donde CS1 está conectado a la línea
• GLCD_CS1BIT - define el pin donde CS1 está conectado a la línea
• GLCD_CS2REG - define el puerto donde CS2 está conectado a la línea
• GLCD_CS2BIT - define el pin donde CS2 está conectado a la línea
La declaracion GLCDINIT debe ser colocado en algún lugar al comienzo del programa
básico antes de cualquier otra declaracion relacionada con el modulo Grafico LCD.
Las declaraciones relacionadas con el modulo Grafico LCD tendrá control sobre TRIS
registros relacionados con las clavijas utilizadas para LCD de interfaz, pero si utiliza los
pines de los puertos donde esten los Modulos A / D y / o módulos de la comparación,
debe tomar el control Durante el registro correspondiente (s) (ADCON1, ANSEL,
GLCDINIT
loop:
GLCDCLEAR 0xAA
WAITMS 1000
GLCDCLEAR 0x55
WAITMS 1000
GOTO loop
DIM I AS BYTE
DIM J AS BYTE
GLCDINIT
FOR I = 0 TO 127
FOR J = 0 TO 63
GLCDPSET I, J
NEXT J
NEXT I
DIM I AS BYTE
GLCDINIT
GLCDCLEAR 0xFF
FOR I = 0 TO 15
GLCDCLEAN I
WAITMS 500
NEXT I
GLCDWRITE declaración puede tener varios argumentos separados por ','. Cuerdas,
constantes y variables byte se puede utilizar como sus argumentos. Constantes y de los
valores de las variables se interpretan como códigos ASCII. Si '#' signo se utiliza antes
de que el nombre de una variable (byte o palabra tipo de datos) entonces su
representación decimal está escrito. Por ejemplo:
DIM I AS BYTE
GLCDINIT
FOR I = 0 TO 15
GLCDPOSITION I, 0
GLCDWRITE "Page: ", #I
WAITMS 250
NEXT I
El modulo interno PWM se puede utilizar en tres diferentes frecuencias de salida para
cada ciclo de trabajo de cuatro resoluciones de apoyo de PWMON declaración (de 10
bits, 9 bits, 8-bits y 7 bits). Así, el módulo PWM se puede activar con PWMON
declaración en 12 modalidades. Aquí está la lista de todos los modos en 4MHz
frecuencia de reloj (de otras frecuencias de reloj, los valores deben ser ajustados
proporcionalmente):
Los pulsos se miden en unidades de 10us, por lo que es posible medir los pulsos en el
rango de 0.01-2.55ms. El valor almacenado en la variable de servos normales debería
estar en el rango 100-200. El segundo argumento de la SERVOOUT declaración debe
ser un Byte variable o constante que determina la duración de los impulsos generados.
Para un funcionamiento adecuado de la meta servo SERVOOUT declaración debe ser
ejecutado 15-20 veces durante un segundo. Aquí hay un ejemplo de la servo operación
inversa:
Bobinas A y C son en realidad parte de una sola bobina con conexión común. Lo mismo
es válido para B, D bobina y conexiones.
AllDigital
ADCON1 = 0x0E
Define STEP_A_REG = PORTB
Define STEP_A_BIT = 7
Define STEP_B_REG = PORTB
Define STEP_B_BIT = 6
Define STEP_C_REG = PORTB
Define STEP_C_BIT = 5
Define STEP_D_REG = PORTB
Define STEP_D_BIT = 4
Define STEP_MODE = 2
WaitMs 1000
StepHold
WaitMs 1000
loop:
Adcin 0, an0
an0 = an0 * 60
an0 = an0 + 2000
StepCW 1, an0
Goto loop
AllDigital
Define STEP_A_REG = PORTB
Define STEP_A_BIT = 7
Define STEP_B_REG = PORTB
Define STEP_B_BIT = 6
Define STEP_C_REG = PORTB
Define STEP_C_BIT = 5
Define STEP_D_REG = PORTB
Define STEP_D_BIT = 4
Define STEP_MODE = 2
WaitUs 300
StepHold
WaitUs 1000
loop:
StepCCW 16, 300
WaitUs 1000
StepCW 24, 300
WaitUs 1000
Goto loop
Este ejemplo puede ser muy corto mediante dos declaraciones de alto nivel especifico
en BASIC DS18S20. DS18S20START declaración iniciará una sola conversión de
temperatura. Según la hoja de datos del dispositivo de conversión se completará en en la
mayoría de 750ms. Después de ese período, el valor medido puede ser leído por
DS18S20READT declaración en la que requiere de dos variables de tipo Byte de datos
como argumentos. El primer argumento contendrá el valor de temperatura de 0,5 grados
centígrados en las unidades (por ejemplo, el valor 100 representa la temperatura de 50
grados). El segundo argumento contendrá el valor 0x00 si la temperatura es positivo y
valor 0xFF si es negativo. Por ejemplo:
● FUNCIONES AVANZADAS
La directiva STARTFROMZERO se utiliza en el compilador se inicia el programa de
cero programa de ubicación de memoria flash (reset vector) y utilizar el programa de la
memoria disponible. Interrupción de la rutina si se utilizan, deben ejecutarse mediante el
uso de código ensamblador. El compilador también dejará el control de registro
PCLATH al usuario suponiendo que todo el código está en la misma página de la
memoria del programa. Esta característica avanzada se puede utilizar en el desarrollo de
aplicaciones del gestor de arranque, por ejemplo.