Prefacio
Para simplificar las cosas y eliminar algunos prejuicios, me permitir darte algunos consejos antes de leer este libro. Deberas empezar leyendo desde el captulo que ms te interesa, en cualquier orden que encuentres conveniente. A medida que pasa el tiempo, lee las partes que puedes necesitar en el momento exacto. Si algo empieza a funcionar sin que t sepas exactamente como, no debera molestarte demasiado. De todas formas, es mejor que tu programa trabaje a que no lo haga. Siempre mantente en el lado prctico de la vida. Es mejor terminar la aplicacin a tiempo, que sea confiable y, por supuesto, que se te pague lo mejor posible. En otras palabras, no importa si la manera exacta en que los electrones se mueven dentro de la unin PN, escapa a tu conocimiento. No se supone que sepas toda la historia de la electrnica para que puedas asegurar un ingreso para ti o tu familia. No esperes encontrar todo lo que necesitas en un solo libro. La informacin est dispersada literalmente en todo lugar alrededor nuestro, as que es necesario coleccionarla y ordenarla diligente y cuidadosamente. Si haces esto, el xito es inevitable. Tengo toda la esperanza de haber hecho algo que valga la pena para que t inviertas tu tiempo en ello. Atentamente Nebojsa Matic Traducido y revisado por: Ing. Roger R. Guachalla Narvez xoroger@yahoo.es Septiembre 2008 La Paz Bolivia
Capitul 1: lo bsico
Introduccin 1.1 Por qu Basic? 1.2 Escogiendo el PIC adecuado para la tarea 1.3 Una palabra acerca de la escritura de cdigo 1.4 Escribiendo y compilando t programa 1.5 Cargando un programa al microcontrolador 1.6 Haciendo correr un programa 1.7 Resolviendo errores
Introduccin
La simplicidad y facilidad que traen los lenguajes de programacin de alto nivel, as como las amplias aplicaciones con microcontroladores hoy en da, fueron las razones para estimular a algunas compaas para ajustar y mejorar el lenguaje de programacin BASIC y as acomodar mejor sus necesidades de programacin. Qu es lo que nosotros obtuvimos? Principalmente, que el desarrollo de aplicaciones es ms rpido y ms fcil con todas las rutinas predefinidas que trae el Basic, siendo que la programacin en lenguaje ensamblador tomara muchsimo ms tiempo. Esto permite al programador concentrarse en resolver las tareas importantes sin perder su tiempo en, por ejemplo, el cdigo para imprimir en un display LCD. Para evitar cualquier confusin en el texto, necesitamos clarificar algunos trminos que estaremos usando frecuentemente a lo largo del libro:
Lenguaje de Programacin es un conjunto de comandos y de reglas con las cuales escribimos el
programa. Existen varios lenguajes de programacin como ser BASIC, C, Pascal, etc. Existe mucha informacin del lenguaje de programacin BASIC en Internet, por lo que nos enfocaremos especficamente en la programacin de microcontroladores.
Programa es una secuencia de comandos escritos en un lenguaje de programacin que el
microcontrolador ejecuta uno despus de otro. El Captulo 2 trata con la estructura de un programa Basic en detalle.
Compilador es un programa que corre en la computadora y su tarea es traducir el cdigo original Basic
en un lenguaje de ceros y unos que puede ser introducido al microcontrolador. El proceso de traduccin de un programa Basic a un cdigo ejecutable HEX***(1) se muestra en la figura inferior. El programa escrito en BASIC y grabado con el nombre program.pbas es traducido por el compilador al cdigo ensamblador (program.asm). El cdigo ensamblador generado luego es traducido en un cdigo ejecutable HEX que puede ser escrito a la memoria del microcontrolador.
Programador es un dispositivo que usamos para transferir nuestros archivos HEX desde el computador
***(1) Nota del traductor: Estrictamente hablando el archivo HEX no es cdigo en lenguaje mquina sino un archivo ASCII en un formato estndar del cual los circuitos Programadores extraen el cdigo ejecutable.
fcil de usar. Hoy en da, esta reputacin est siendo ampliada al mundo de los microcontroladores. BASIC permite un desarrollo ms rpido y fcil de las aplicaciones para PIC comparado con el lenguaje ensamblador de Microchip MPASM. Cuando se escribe cdigo para los MCUs (microcontroladores), los programadores frecuentemente tratan con las mismos tareas, como ser comunicacin serial, impresin en displays LCD, generacin de seales PWM (modulacin de ancho de pulso), etc. Con el propsito de facilitar la programacin, BASIC provee un nmero de libreras y rutinas incorporadas destinadas a resolver estos problemas. En lo referente a la velocidad de ejecucin y el tamao de programa, MPASM tiene una pequea ventaja con respecto del Basic. Esa es la razn para que exista una opcin de combinar BASIC y cdigo ensamblador - el ensamblador es usado comnmente para partes del programa cuya ejecucin de tiempo es crtica o siendo que los mismos comandos son ejecutados un gran nmero de veces. Los microcontroladores modernos como ser el PIC, ejecutan instrucciones en un solo ciclo. Si el reloj de un microcontrolador es de 4 MHz, entonces una instruccin en ensamblador requiere 250 nseg x 4 = 1 seg. Ya que cada comando Basic es tcnicamente una secuencia de instrucciones en ensamblador, el tiempo exacto necesario para su ejecucin puede ser calculado simplemente sumando los tiempos de ejecucin de las instrucciones en ensamblador.
Cuando el programa est completado y ha sido grabado como un archivo .pbas, puede ser compilado haciendo un clic en el icono de compilacin (Compile Icon) (o simplemente digitando CTRL+F9) en el IDE de mikroBasic. El procedimiento de compilacin ocurre en dos pasos consecutivos: 1. El compilador convertir el archivo .pbas al cdigo ensamblador y lo grabar como blink.asm
2. Entonces, el compilador automticamente llamar al ensamblador, que convierte el archivo .asm a un cdigo ejecutable HEX listo para ser programado en el microcontrolador. En realidad no se puede ver la diferencia entre los dos pasos, ya que el proceso es automtico e indivisible. En caso de tener errores de sintaxis en el cdigo del programa, este no ser compilado y el archivo HEX no ser generado. Los errores deben ser corregidos en el archivo original .pbas y luego el archivo fuente debe ser compilado otra vez. La tcnica ms recomendada es escribir y probar partes lgicas pequeas de un programa para hacer la depuracin ms sencilla.
El archivo MCL (mikro compile library) es creado para cada mdulo que hayas incluido en el proyecto. En el proceso de compilacin, los archivos .mcl sern enlazados para generar los archivos de salida .asm, .lst y .hex. Si deseas distribuir tu mdulo sin dar a conocer el cdigo fuente, puedes enviar su librera compilada (con la extensin de archivo .mcl). Entonces otro usuario podr usar tu librera como si tuviese el cdigo fuente. Aunque el compilador es capaz de determinar qu rutinas estn implementadas en la librera, es una prctica comn proveer los prototipos de las rutinas en un archivo de texto separado. El archivo HEX es el que necesitas para programar al microcontrolador. Comnmente, el archivo HEX se genera usando un estndar de 8 bits en formato Intel HEX, que es aceptado por una gran mayora del software de programacin. El dispositivo de programacin (Programador) con un software de interface instalado en el PC est a cargo de escribir los contenidos fsicos del archivo HEX en la memoria interna del microcontrolador. Los contenidos del archivo blink.hex se ven abajo:
:100000000428FF3FFF3FFF3F031383168601FF30A5 :10001000831286000630F000FF30F100FF30F2005E :10002000F00B13281A28F10B16281928F20B1628A2 :10003000132810281A30F000FF30F100F00B2128AF :100040002428F10B21281E284230F000F00B26282E :1000500086010630F000FF30F100FF30F200F00BB7 :1000600032283928F10B35283828F20B3528322868 :100070002F281A30F000FF30F100F00B4028432801 :10008000F10B40283D284230F000F00B45280428B1 :100090004828FF3FFF3FFF3FFF3FFF3FFF3FFF3F3E :02400E007A3FF7 :00000001FF
Adems de cargar el cdigo de programa en la memoria de programacin, el Programador tambin configura el microcontrolador destino, incluyendo el tipo de oscilador, las protecciones de la memoria contra las lecturas, el temporizador perro guardin (watchdog timer), etc. La siguiente figura muestra la conexin entre el PC, el Programador y el MCU.
Te en cuenta que el software de programacin debe ser usado solamente para la comunicacin con el dispositivo Programadorno est diseado para escritura de cdigo.
El oscilador puede ser un cristal de 4 MHz y 2 capacitores de 22 pF. La tasa de funcionamiento del microcontrolador, es decir la velocidad a la cual el programa corre, depende altamente de la frecuencia del oscilador. Durante el desarrollo de una aplicacin, la cosa ms sencilla de hacer es usar el circuito de reset interno el pin MCLR se conecta a +5V a travs de una resistencia de 10K. La figura inferior muestra el esquema de una configuracin mnima para la operacin de un microcontroladorPIC.
Para ver los efectos del programa BLINK, la resistencia y el diodo LED estn conectadas al pin RB7 del puerto B
Despus de conectar la energa elctrica en el circuito mostrado, en microcontrolador PIC debera hacer parpadear al diodo LED cada segundo. Si el LED no parpadea entonces revisa la siguiente seccin del libro.
cuando se usa como salida, debido a que este pin tiene salida open collector en vez del estado bipolar usual. Esto implica que si apagamos este bit ir al nivel bajo, pero si encendemos el pin ste estar flotando en vez de ir al nivel alto. Para que el pin se comporte de manera esperada, se debe colocar una resistencia pull-up entre RA4 y +5V. El valor de la resistencia est entre 4.7K y 10K dependiendo de la corriente necesaria para entrada en esta forma, el pin funciona como cualquier otro pin de entrada. Muchas veces el problema no radica en el hardware sino en el software. Siempre depura tus programas paso a paso, revisando que los valores de las variables son las esperadas. Recuerda que si bien el compilador te avisa acerca de los errores de sintaxis, los errores de semntica (es decir de significado) solo pueden ser detectados por simulacin. Un programa bien comentado vale por dos. Es fcil recordar el algoritmo utilizado cuando el programa es pequeo o si lo revisas nuevamente despus de un par de das. Sin embargo cuando mires tu programa despus de un par de meses y si este ronda por algunos cientos de lneas, entonces agradecers haber comentado las partes relevantes de tu cdigo. Cuando empieces a realizar proyectos serios, comienza por un diagrama en bloques, especificando claramente la asignacin, nombres y funcin de los pines de I/O. A continuacin realiza un diagrama de flujo general. Finalmente codifica el programa en lenguaje BASIC.
Ms problemas aparecern si planificas trabajar con los PICs de manera seria. Algunas veces parece que el programa va a funcionar pero no lo hace sin importar cuntas veces los revises. Slo recuerda que existe ms de una forma para resolver un problema, y que un algoritmo distinto puede ser la solucin. Recuerda la ley de Murphy "si algo puede salir mal, normalmente saldr mal" que ha aplicado al campo de los microcontrolador es dira "si un programa corre la primera vez, algo est mal"
***(2) PIC 16F628A Este modelo es el reemplazo directo del PIC16F84 (comparten el mismo patillaje). Tiene 16 bit de I/O (Puertos A y B). Puerto B: Posee resistencias pull-up internas Activar pull-up: OPTION_REG.NOT_RBPU=0 Desactivar pull-up: OPTION_REG.NOT_RBPU=1 (valor por omisin) Puerto A: RA0, RA1, RA2, RA3: Pines de doble funcin: Comparador analgico (AN0, AN1,AN2,AN3) valor por omisin despus de un Reset Pines de I/O: desactivar el comparador (CMCON = 7) RA4: Pin de I/O de salida en drenaje abierto (Opendrain): para su funcionamiento requiere una resistencia (10k) a +5V) y adems funciona con LOGICA NEGADA. (0=5v, 1=0v) Ver el Circuito ejemplo. RA5: Pin de doble funcin: _MCLR o Reset (Configurar en Device Flags : MCLRE_ON) puerto digital de ENTRADA solamente (Configurar en Device Flags: MCLRE_OFF). RA6,RA7: Pines de doble funcin: Entrada y Salida de Reloj (clock) Pines de I/O: Habilitar el oscilador interno sin salida de reloj (Configurar en Device Flags: INTRC_OSC_NOCLKOUT). El oscilador interno, en base a una Resistencia y un Capacitor, tiene una frecuencia de 4MHz. La precisin del RC interno NO es buena y no es recomendable para aplicaciones que requiere un clculo de tiempo estable.
VCC VCC 16 15
U1
RA7/OSC1/CLKIN RA0/AN0 RA1/AN1 RA6/OSC2/CLKOUT RA2/AN2/VREF RA3/AN3/CMP1 RA5/MCLR RA4/T0CKI/CMP2 RB0/INT RB1/RX/DT RB2/TX/CK RB3/CCP1 RB4 RB5 RB6/T1OSO/T1CKI RB7/T1OSI PIC16F628A 17 18 1 2 3 6 7 8 9 10 11 12 13
R2
10k
R1
10k 4
Circuito ejemplo: Pin RA4 como salida digital con lgica negada. Pin RA5 como Reset
Reset
R3
330 Led
D1
VCC
Introduccin
Este captulo tiene que ver con los elementos del lenguaje BASIC y las formas para usarlos eficientemente. Aprender a programar no es complicado, pero se requiere habilidad y experiencia para escribir cdigo que se eficiente, legible, y fcil de manejar. Ante todo, se supone que el programa debe ser comprensible, de manera tal que el mismo programador, o alguien ms que est trabajando en la aplicacin, pueda realizar las correcciones y/o mejoras necesarias. Te proveo un cdigo ejemplo escrito de manera clara y ordenada para darte una idea de cmo deberan escribirse los programas:
'****************************************************************************** ' Microcontrolador : P16F877A ' ' Proyecto: Led_Blinking (leds parpadeando) ' Este proyecto esta diseniado para trabajar con el PIC 16F877A ' con ajustes menores, debera trabajar con cualquier otro MCU PIC ' ' El codigo muestra diodos leds parpadeando conectados al PORTB ' Los diodos se encienden y apagan cada segundo '****************************************************************************** program LED_Blinking main: TRISB = 0 PORTB = %11111111 Delay_ms(1000) PORTB = %00000000 Delay_ms(1000) goto main end. ' ' ' ' ' ' ' ' Inicio del programa Configurar los pines del PORTB como salida Encender los leds del PORTB Esperar 1 segundo Apagar los leds del PORTB Esperar 1 segundo Bucle infinito Final del programa
A travs del uso adecuado de comentarios, smbolos, etiquetas y otros elementos usados en BASIC, el programa puede generarse de manera ms clara y entendible, ofreciendo al programador una gran ayuda. Tambin es aconsejable dividir programas grandes en entidades lgicas separadas (como ser rutinas y mdulos) que pueden ser usadas cuando se las necesite. Esto tambin incrementa la reusabilidad del cdigo. Los nombres de las rutinas y etiquetas que indican un segmento del programa deberan tener un sentido comn. Por ejemplo, un segmento de programa que intercambia (swap) los valores de 2 variables, podra tener el nombre Swap, etc.
2.1 Identificadores
Los identificadores son nombres usados para referenciar valores almacenados, tal como variables y constantes. Cada programa, mdulo, procedimiento o funcin debe estar identificada (de ah el nombre) por un identificador. Un identificador vlido:
1. Debe empezar con una letra del alfabeto Ingles con el carcter subrayado ( underscore ) ( _ ) 2. Consiste de caracteres alfanumricos y el underscore ( _ ) 3. No puede contener caracteres especiales:
~ ! @ # $ % ^ & * ( ) + ` - = { } [ ] : " ; ' < > ? , . / | \
4. Puede ser escrito en una mezcla de maysculas/minsculas ya que el BASIC no los diferencia insensitive); ej. Primero, PRIMERO, primero, pRiMeRo representan a 1 nico identificador.
(case
Los elementos que son ignorados por el compilador incluyen espacios, nuevas lneas, y tabulaciones. Todos estos elementos son conocidos colectivamente como espacio en blanco. El espacio en blanco sirve nicamente para hacer el cdigo ms legible no tiene ningn efecto sobre la compilacin. Algunos identificadores estn reservados en BASIC, lo que significa que no los puedes usar como tus propios identificadores (ej. Las palabras function, byte, if, etc.) Para ms informacin, por favor revisa la Gua de Referencia Rpida para el lenguaje Basic (Quick Reference Guide for Basic language) de MIKROBASIC. Tambin, BASIC tiene un nmero de identificadores predefinidos que estn listados en el Captulo 4: Instrucciones.
2.2. Operadores
El lenguaje BASIC posee un conjunto de operadores que son usados para asignar y comparar valores, adems de realizar otras operaciones. Los objetos manipulados para este propsito se llaman operandos (los cuales a su vez pueden ser variables, constantes, u otros elementos). Los operadores en BASIC deben tener por lo menos dos operandos, con la excepcin de los operadores unitarios. Los operadores sirven para crear expresiones e instrucciones que componen el programa. Existen cuatro tipos de operadores en BASIC: 1. 2. 3. 4. Operadores aritmticos Operadores booleanos Operadores Lgicos (bit a bit) Operadores relacionales (Operadores de comparacin)
2.3 Expresiones
Una expresin es una construccin que retorna un valor. La sintaxis de BASIC te restringe a expresiones de una sola lnea, donde el carcter Retorno de Carro (carriage return) marca el final de la expresin. Las expresiones ms simples son variables y constantes, mientras que expresiones ms complejas pueden ser construidas de expresiones ms simples usando operadores, llamadas a funcin, ndices, y asignaciones de tipo (typecasts). Aqu tienes una expresin simple:
A = B + C
' Esta expresion suma los valores de las variables B y C ' y almacena el resultado en la variable A.
Necesitas prestar atencin a que la suma debe estar dentro del rango de la variable A para evitar el rebalse (overflow) y el error computacional evidente. Si el resultado de la expresin es de 428, y la variable A es del tipo byte (con un rango de 0 a 255), el resultado obtenido ser de 172, que es obviamente errneo.
2.4 Instrucciones
Cada instruccin determina una accin a ser realizada. Como una regla, las instrucciones se ejecutan en el orden exacto en el cual fueron escritos en el programa. Sin embargo, el orden de su ejecucin puede ser cambiada mediante saltos, llamadas a rutinas, o una interrupcin.
' Si la variable Tiempo es igual a 60, ' entonces saltar a la etiqueta Minuto
La instruccin if..then contiene expresin Time = 60 compuesta de dos operandos, la variable Tiempo, la constante 60 y el operador de comparacin (=). Generalmente, las instrucciones pueden ser divididas en instrucciones condicionales (toma de decisiones), bucles (loops) (bloques repetitivos), saltos (jumps), e instrucciones incorporadas (built-in) (ej. Para acceder a los perifricos del microcontrolador). El conjunto de instrucciones esta explicado en detalle en el Captulo 4: Instrucciones.
***char puede ser tratada como un byte en todo aspecto. Los tipos estructurados incluyen: Arreglo (Array), que representan una coleccin indexada de elementos del mismo tipo, a menudo llamado tipo base. El tipo base puede ser cualquier tipo simple. Cadena (String) que representa una secuencia de caracteres. Es un arreglo que contiene caracteres y el primer elemento de la cadena mantiene el nmero de caracteres de esta (mximo nmero es de 255). El signo es un atributo importante de los tipos de datos, y afecta la forma en la que la variable es tratada por el compilador. Las variables sin signo (unsigned) pueden contener el siguiente rango de nmeros:
byte word
0 .. 255 0 .. 65535
2.6 Constantes
Constantes son datos cuyo valor no puede ser cambiado durante el tiempo de ejecucin (runtime). Cada constante se declara usando un nombre nico que debe ser un identificador vlido. Una buena prctica consiste en escribir los nombres de constantes en maysculas. Si usas frecuentemente el mismo valor fijo a lo largo del programa, deberas declararlo como constante (por ejemplo, si el mximo nmero permitido es 1000). Esto constituye una buena prctica ya que el valor puede ser cambiado simplemente modificando la declaracin, en vez de ir a lo largo de todo el programa y ajustando cada ocurrencia manualmente. Es tan simple como:
const MAX = 1000
Las constantes pueden ser declaradas en forma decimal, hexadecimal o binaria. Las constantes decimales se escriben sin ningn prefijo. Las constantes hexadecimales comienzan con un signo $, mientras que las binarias lo hacen con el signo %.
const A = 56 const B = $0F const C = %10001100 ' 56 decimal ' 15 hexadecimal ' 140 binario
Es importante entender porque las constantes deben ser usadas y como esto afecta al MCU. El usar una constante en un programa no consume memoria RAM. Esto es muy importante debido al espacio RAM limitado (PIC16F877 tiene 368 bytes/localidades).
2.7 Variables
Las variables son datos cuyo valor puede ser cambiado durante el tiempo de ejecucin. Cada variable se declara bajo un nombre nico que debe ser un identificador vlido. Este nombre es usado para acceder a una localidad de memoria ocupada por la variable. Se puede ver a la variable como un
contenedor de datos y, debido que tiene un tipo, le instruye al compilador como interpretar los datos que contiene. En BASIC, las variables requieren ser declaradas antes de poder ser usadas. Es obligatorio especificar un tipo de datos para cada variable. Las variables se declaran as:
dim identicador as tipo
Donde identificador es cualquier identificador vlido y tipo es de cualquier tipo de datos. Por ejemplo:
dim temperatura as byte dim voltaje as word ' Declarar variable temperatura del tipo byte ' Declarar variable voltaje del tipo word
Los bits individuales de las variables byte (incluyendo a los registros SFR como ser PORTA, etc.) pueden ser accedidos mediante el punto (.), en los extremos derecho o izquierdo de una expresin. Por ejemplo:
Data_Port.3 = 1 ' Encender el bit 3 de la variable byte Data_Port
2.8 Smbolos
Los smbolos hacen posible reemplazar una expresin con un alias de identificacin nico. El uso de smbolos puede incrementar la legibilidad del cdigo. La sintaxis del BASIC te restringe a expresiones de lnea nica, permitiendo atajos para constantes, expresiones simples, llamadas a funcin, etc. El alcance (scope) de un identificador de smbolo es todo el archivo fuente en el cual est declarado. Por ejemplo:
symbol MaxPermitido = 234 ' Simbolo como un alias para un valor numerico symbol PUERTO = PORTC ' Simbolo como un alias par un Registro de Funcion Especial symbol RETARD1S = Delay_ms(1000) ' Simbolo como un alias para una llamada a procedimiento ... if teA > MaxPermitido then teA = teA - 100 end if PUERTO.1 = 0 RETARD1S ...
Nota que el usar un smbolo en un programa tcnicamente no consume memoria RAM el compilador simplemente reemplaza cada ocurrencia del smbolo con el cdigo apropiado de la declaracin.
2.9 Directivas
Las directivas son palabras de significado especial para el BASIC, pero a diferencia de otras palabras reservadas, estas aparecen solamente en contextos donde los identificadores definidos por el usuario no pueden ocurrir. No puedes definir un identificador que sea igual a una directiva.
Directiva Absolute Org Significado especifica una direccin exacta de una variable en RAM especifica la direccin exacta de una rutina en ROM
Absolute especifica la direccin de inicio en RAM para una variable (si la variable es multi-byte, los bytes ms
altos son almacenados en localidades consecutivas). La directiva Absolute es aadida a la declaracin de la variable:
dim rem as byte absolute $22 ' La variable rem ocupara 1 byte en la direccion $22 dim dot as word absolute $23 ' La variable dot ocupara 2 bytes en las direcciones $23 and $24
especifica la direccin de inicio de la rutina en ROM. Para la familia PIC16, la rutina debe caber en una pgina de otra forma, el compilador reportar un error. La directiva Org es aadida a la declaracin de la rutina:
Org sub procedure Prueba org $200 ' El procedimiento Prueba empezara en la direccion $200 ... end sub
2.10 Comentarios
Los comentarios son textos que se aaden al cdigo con el propsito de realizar una descripcin o aclaracin, y son completamente ignorados por el compilador.
' Cualquier texto entre el apostrofe y el final de la ' linea constituye un comentario. Su alcance es de una lnea solamente.
Constituye una buena prctica comentar tu cdigo, de manera tal que t o cualquier otra persona pueda volver a usarla posteriormente. De otro modo, a menudo es til comentar partes del cdigo que tengan problemas, de manera que puedan ser reparadas o modificadas luego. Los comentarios deben dar informacin acerca del
propsito de lo que hace el programa. Comentar algo como Encender Pin0 simplemente explica la sintaxis pero falla a indicar el propsito de la instruccin. Algo similar a Activar el Rele puede ser mucho ms til. Los editores especializados poseen resalte en colores de sintaxis (syntax highlighting) es fcil de distinguir comentarios del cdigo debido al color diferente, adems los comentarios usualmente aparecen en letras cursivas.
2.11 Etiquetas
Las etiquetas representan la forma ms directa de controlar el flujo del programa. Cuando marcas cierta lnea del programa con una etiqueta, puedes saltar a esa lnea a travs de la instruccin goto y gosub. Es conveniente pensar en las etiquetas como marcas de libro (bookmarks). Nota que la etiqueta main debe ser declarada en cada programa BASIC debido a que marca el inicio del mdulo principal.
Goto es una instruccin de salto incondicional. Salta a la etiqueta especificada y la ejecucin del programa
saltar a la etiqueta especificada, la direccin previa es almacenada en la pila (stack). El programa continuar ejecutndose normalmente desde la etiqueta, hasta alcanzar la instruccin return esta terminar la subrutina y regresar al la primera lnea del programa inmediatamente despus de la instruccin gosub que la llam. Aqu tienes un ejemplo simple:
program prueba main: ' algunas instrucciones... ' simple bucle infinito usando una etiqueta mi_bucle: ' algunas instrucciones... ' ahora saltamos nuevamente a la etiqueta mi_bucle goto mi_bucle end.
Nota: Aunque puede parecer una buena idea para los principiantes el programar usando saltos y etiquetas, debers tratar de no depender de estas. Esta forma de pensamiento se desva de la programacin procedimental y te puede ensear malos hbitos. Es mucho mejor usar procedimientos y funciones, haciendo que el cdigo sea ms legible y ms fcil de mantener.
Donde NombreProcedimento es cualquier identificador vlido, Instrucciones son una secuencia de instrucciones que son ejecutadas al llamarse el procedimiento, y ListaParametros juntamente con DeclaracionesLocales son declaraciones opcionales de las variables y/o las constantes.
sub procedure pr1_procedimiento(dim par1 as byte, dim par2 as byte, dim byref vp1 as byte, dim byref vp2 as byte) dim locS as byte par1 = locS + par1 + par2 vp1 = par1 or par2 vp2 = locS xor par1 end sub
par1 y par2 son pasadas al procedimiento por valor, pero las variables marcadas con la palabra clave byref son pasadas por referencia direccin (address). Esto significa que la llamada al procedimiento
pr1_procedure(tA, tB, tC, tD)
pasa tA y tB por valor: crea par1=tA; y par2=tB luego manipula par1 y par2 de manera tal que tA y tB permanecen sin cambio; pasa tC y tD por direccin: cualquier cambio realizado en vp1 y vp2 es tambin reflejado en tC y tD. La declaracin de funciones es similar a la declaracin de procedimientos, con la excepcin de que la funcin posee un tipo de retorno y valor de retorno especificados. La declaracin de funciones tiene la forma:
sub function NombreFuncion(ListaParametros) as TipoRetorno DeclaracionesLocales Instrucciones end sub
donde NombreFuncion es cualquier identificador vlido, TipoRetorno es cualquier tipo simple, Instrucciones son una secuencia de instrucciones a ser ejecutadas cuando se llama a la funcin, y ListaParametros juntamente con DeclaracionesLocales son declaraciones opcionales de las variables y/o las constantes. En BASIC, usamos la palabra clave Result para asignar un valor de retorno a la funcin. Por ejemplo:
sub function Calc(dim par1 as byte, dim par2 as word) as word dim locS as word locS = par1 * (par2 + 1) Result = locS end sub
Ya que las funciones retornan valores, las llamadas a funcin son tcnicamente expresiones. Por ejemplo, si has definido una funcin llamada Calc, la cual recibe dos argumentos enteros y retorna un entero, entonces la llamada a funcin Calc(24, 47) es una expresin entera. Si I y J son variables enteras, entonces I+Calc(J,8) es tambin una expresin entera.
2.13 Mdulos
Los programas grandes pueden ser divididos en mdulos que permitan un mantenimiento ms sencillo del cdigo. Cada mdulo es un archivo, que puede ser compilado separadamente; los mdulos compilados son enlazados para crear una aplicacin. Nota que cada archivo de cdigo fuente debe terminar con la palabra clave end seguida de un punto. Los mdulos te permiten: 1. Separar programas grandes en segmentos que pueden ser editados separadamente, 2. Crear libreras que pueden ser usadas en diferentes programas, 3. Distribuir libreras a otros desarrolladores sin entregar el cdigo fuente. En el IDE de mikroBasic, todo el cdigo fuente incluyendo al programa principal se almacena en archivos (.pbas). Cada proyecto consiste de un archivo de proyecto nico, y uno o ms archivos mdulos. Para construir (build) un proyecto, el compilador necesita ya sea un archivo fuente o un archivo compilado para cada mdulo. Cada aplicacin en BASIC tiene un mdulo principal y cualquier nmero de archivos mdulos adicionales. Todos los archivos fuente tienen la misma extensin (pbas). El archivo principal es identificado por la palabra clave program al inicio, mientras que los otros archivos tienen la palabra clave module. Si deseas incluir un mdulo, aade la palabra clave include seguido del nombre del archivo entre comillas. Por ejemplo:
program proyecto_de_prueba include "math2.pbas" dim tA as word dim tB as word main: tA = sqrt(tb) end.
La palabra clave include indica al compilador que archivo compilar. El ejemplo de arriba incluye el mdulo math2.pbas en el archivo del programa. Obviamente, la rutina sqrt usada en el ejemplo est declarada dentro del mdulo math2.pbas. Si deseas distribuir tu mdulo sin entregar el cdigo fuente, puedes enviar tu librera compilada (extensin de archivo .mcl). El usuario podr usar tu librera tal y como si tuviera el cdigo fuente. Aunque el compilador es capaz de determinar que rutinas estn implementadas en la librera, es una prctica comn proveer los prototipos de las rutinas en un archivo texto separado. Los archivos mdulos deben estar organizados de la siguiente forma:
module nombre_unidad include ... symbol ... const ... dim ... ' nombre del Modulo ' incluir otros modulos si es necesario ' declaracion de Simbolos ' declaracion de Constantes ' declaration de Variables
sub procedure nombre_procedimiento ' declaracion de Procedimientos ... end sub sub function nombre_function ... end sub end. ' declaracion de Funciones
Nota que no existe una seccin de cuerpo en el mdulo los archivos mdulos sirven para declarar funciones, procedimientos, constantes y variables globales.
Capitulo 3: Operadores
Introduccin 3.1 Operadores Aritmticos 3.2 Operadores Booleanos 3.3 Operadores Lgicos (bit a bit) 3.4 Operadores Relacionales (Operadores de Comparacin)
Introduccin
En las expresiones complejas, los operadores con precedencia superior son evaluados antes que los operadores con precedencia inferior; los operadores de igual precedencia son evaluados de acuerdo a su posicin en la expresin empezando desde la izquierda.
Operator not *, div, mod, and, <<, >> +, -, or, xor =, <>, <, >, <=, >= cuarta Prioridad primera (ms superior) segunda tercera (ms inferior)
substraccin
multiplicacin byte, short, integer, words divisin byte, short, integer, words byte, short, integer, words
div
mod
resto
A div B es el valor de A dividido entre B redondeado hacia abajo al entero ms cercano. El operador mod retorna el residuo obtenido al dividir los operandos. En otras palabras, X mod Y = X - (X div Y) * Y
Si se utiliza 0 (cero) explcitamente como el segundo operando (ej. X div 0), el compilador reporta un error y no genera cdigo. Pero en caso de divisin implcita por cero: X div Y, donde Y es 0 (cero), el resultado es el mximo valor para el tipo apropiado (por ejemplo, si X y Y son words, el resultado es $FFFF). Si el nmero es convertido de un tipo menos complejo a uno ms complejo, los bytes superiores son llenados con ceros. Si el nmero es convertido de un tipo ms complejo a uno menos complejo, los datos simplemente se truncan (los bytes superiores se pierden). Si el nmero es convertido de un tipo menos complejo a uno ms complejo, los bytes superiores son llenados con unos si el bit de signo es igual a 1 (el nmero es negativo). Los bytes superiores se llenan con ceros si el bit de signo es igual a 1 (el nmero es positivo). Si el nmero es convertido de un tipo ms complejo a uno menos complejo, los datos simplemente se truncan (los bytes superiores se pierden). BASIC tambin posee dos operadores aritmticos unarios:
Operador Operacin Tipos de Operandos short, integer, longint short, integer, longint Tipo del Resultado short, integer, longint short, integer, longint
Los operadores aritmticos unarios pueden ser usados para cambiar el signo de las variables:
va = 3 vb = -va 'asignar el valor de -3 a la variable vb
Por ejemplo:
if (astr > 10) and (astr < 20) then PORTB = 0xFF end if
byte, word, byte, word, short, short, integer, integer, long long byte, word, byte, word, short, short, integer, integer, long long byte, word, byte, word, short, short, integer, integer, long long byte, word, byte, word, short, short, integer, integer, long long
and
or
or bit a bit
xor
<<
desplazamiento byte, word, byte, word, a la izquierda short, short, integer, integer, de bit long long desplazamiento byte, word, byte, word, a la derecha de short, short, integer, integer, bit long long
>>
<< : desplazar el operando hacia la izquierda un nmero de bits especificado a la derecha del operando
Por ejemplo, si necesitas extraer el nibble superior de una variable tipo byte, puedes hacerlo as:
dim temp as byte main: temp=$35 temp=temp>>4 end.
valor inicial de temp $35 extraer el nibble superior, ahora temp tiene el valor $03
Todos los Verdadero tipos simples Falso Todos los Verdadero tipos simples Falso Todos los Verdadero tipos simples Falso Todos los Verdadero tipos simples Falso Todos los Verdadero tipos simples Falso Todos los Verdadero tipos simples Falso
<>
distinto de
<
menor que
>
mayor que
<=
>=
Introduccin
Las expresiones definen acciones algortmicas dentro de un programa. Expresiones simples como asignaciones y llamadas a procedimientos pueden ser combinadas para formar bucles, expresiones condicionales, y otras expresiones estructuradas. Las expresiones simples no contienen a otras expresiones. Estas incluyen asignaciones, y llamadas a procedimientos y funciones. Las expresiones estructuradas son construidas en base a otras expresiones. Usa expresiones estructuradas cuando desees ejecutar otras expresiones de manera secuencial, condicional, repetida.
if Expresion then Instrucciones1 [ else Instrucciones2 ] end if Esta instruccin selecciona una de dos posibles rutas de programa. La instruccin if..then es la instruccin fundamental de bifurcacin de programa en PIC BASIC y puede usada en distintas formas que permiten la flexibilidad necesaria para la realizacin de toma lgica de decisiones. Expresion retorna un valor Verdadero (True) Falso (False) . Si Expresion es Verdadero, entonces Instrucciones1 son ejecutadas; de otra forma, si la clusula opcional else est presente, Instrucciones2 son ejecutadas. Instrucciones1 e Instrucciones2 pueden ser instrucciones de cualquier tipo.
*** ***
Descripcin
Ejemplo
La forma ms simple de esta instruccin se muestra en la figura inferior. El ejemplo prueba el botn conectado a RBO cuando el botn est presionado, el programa salta a la etiqueta Suma donde el valor de la variable j es incrementado. Si el botn no est presionado, el programa salta de regreso a la etiqueta Main.
goto Main Suma: j = j + 1 end. La forma ms compleja de esta instruccin es la bifurcacin de programa con la clausula ELSE: Si el botn est presionado, se incrementa el valor de la variable j de otra forma el valor de la variable se decrementa.
dim j as byte Main: if PORTB.0 = 0 then j = j + 1 else j = j - 1 endif goto Main end.
Descripcin
La instruccin select case es usada para seleccionar una de varias bifurcaciones disponibles en la trayectoria del programa. Consiste de una variable Selector que funciona como una condicin de conmutacin (switch), y una lista de valores posibles. Estos valores pueden ser constantes, nmeros, o expresiones. Eventualmente, puede existir una instruccin else que es ejecutada si ninguna de las etiquetas corresponde al valor del selector. Tan pronto como la instruccin select case es ejecutada, solo una de las instrucciones Instrucciones1..Instrucciones_N ser ejecutada. El Valor que coincide con el Selector determina que instrucciones sern ejecutadas. Si ninguno de los tems de Valor coincide con el Selector, entonces las Instrucciones_Else en la clausula else (si es que existe) sern ejecutadas.
Ejemplo
select case W case 0 B = 1 PORTB = B case 1 A = 1 PORTA = A case else PORTB = 0 end select ... select case Identificacion case pruebaA PORTB = 6 Res = T mod 23 case pruebaB + pruebaC T = 1313 case else T = 0 end select
goto Etiqueta La instruccin goto salta a la etiqueta especificada incondicionalmente, y la ejecucin del programa contina normalmente desde ese punto. Evita usar goto con demasiada frecuencia, debido a que los programa sobre-etiquetados tienden a ser menos legibles.
Descripcin
Ejemplo
program prueba main: ' algunas instrucciones ... goto miEtiqueta ' algunas instrucciones ... miEtiqueta: ' algunas instrucciones ... end.
4.2 Bucles
Las expresiones de bucle (loop) permiten repetir una o ms instrucciones un nmero de veces. La expresin conductora determina el nmero de iteraciones que tendr el bucle. 4.2.1 Instruccin FOR
Sintaxis
for Contador = ValorInicial to ValorFinal [step ValorPaso] Instruccion_1 Instruccion_2 ... Instruccion_N next Contador
Descripcin
La instruccin for requiere que se especifique el nmero de iteraciones en que se ejecutar el bucle.
Contador es una variable; ValorInicial y ValorFinal son expresiones compatibles con Contador; Instruccin es cualquier instruccin que no cambie el valor de Contador; ValorPaso es el valor aadido al Contador en cada iteracin. ValorPaso es opcional, y su valor por omisin (default) es 1 si no se incluye la clausula step. Ten cuidado si usas valores grandes para ValorPaso, pues pueden ocurrir errores de desbordamiento (overflow). Cada instruccin entre for y next ser ejecutada una vez por iteracin.
Ejemplo
Aqu tienes un ejemplo simple de un bucle for usado para sacar cdigo hexadecimal en el PORTB conectado a un decodificador ctodo comn de display de 7 segmentos. Nueve dgitos saldrn por el display con retardos de 1 segundo. for i = 1 to 9 portb = i delay_ms(1000) next i
4.2.2 Instruccin DO..LOOP Continuar el bucle (loop) hasta que la condicin sea verdadera
Sintaxis do Instruccion_1 ... Instruccion_N loop until Expresion Expresion retorna un valor Verdadero (True) Falso (False) . La instruccin do..loop ejecuta Instruccion_1; ...; Instruccion_N continuamente, revisando la Expresion despus de cada iteracin. La instruccin do..loop termina cuando la Expresion se torna Verdadero. La secuencia es ejecutada por lo menos una vez debido a que la revisin de Expresion se realiza al final.
*** ***
Descripcin
Ejemplo
I = 0 do I = I + 1 ' ejecutar estas 2 instrucciones PORTB = I ' hasta que I sea igual a 10 (diez) loop until I = 10
while Expresion Instruccion_1 Instruccion_2 ... Instruccion_N wend Expresion es revisado primero. Si el valor es Verdadero , todas las instrucciones siguientes entre while y wend sern ejecutadas ( alternativamente, solamente una instruccin). Las instrucciones continuarn ejecutndose hasta que Expresion retorne Falso. while terminar cuando Expresion retorne Falso. while es similar a do..loop, con excepcin que la revisin se realiza al inicio del bucle. Si Expresion retorna Falso en la revisin, las Instrucciones no sern ejecutadas.
*** ***
Descripcin
Ejemplo
Descripcin
Las principales razones para incluir ensamblador son: El lenguaje BASIC no posee las instrucciones requeridas para un tarea especfica, si las
posee el cdigo resultante es sumamente complicado o confuso. Se requiere la mxima velocidad de ejecucin posible para esa parte del programa El mximo ahorro en tamao de cdigo para esa parte del programa
El lenguaje Ensamblador (Assembler) es el ms eficaz de todos los lenguajes en lo referente a tamao de cdigo y en velocidad de ejecucin. Sin embargo la curva de aprendizaje de dicho lenguaje es alta comparada con el BASIC. El Ensamblador nos acerca profundamente al hardware del PIC. Te recomiendo que lo aprendas una vez que hayas aprendido el BASIC. Para ello existen una infinidad de cursos y tutoriales en Internet. Un excelente libro para aprender ensamblador con los PIC es Microcontrolador PIC16F84 Desarrollo de Proyectos de los autores Enrique Palacios, Fernando Ramiro y Lucas J. Lpez.
***2
Ejemplo
Introduccin
Se dice comnmente que un microcontrolador es una computadora completa en un solo chip, lo que implica que tiene ms que ofrecer que simplemente un CPU (microprocesador). Esta funcionalidad adicional se encuentra localizada en los subsistemas del microcontrolador, llamados tambin los perifricos integrados. Estos (sub)dispositivos bsicamente tienen dos funciones principales: expanden las posibilidades del MCU hacindolo ms verstil, y ellos liberan al CPU de las tareas que son repetitivas y tontas (principalmente comunicacin). Cada microcontrolador contiene por lo menos un par de perifricos integrados comnmente, estos incluyen temporizadores, mecanismos de interrupcin y conversores AD. Microcontroladores ms potentes pueden comandar un nmero mayor y ms diverso de perifricos. En este captulo, cubriremos algunos sistemas comunes y las formas de poder utilizarlos desde el lenguaje de programacin BASIC.
Aqu tenemos un ejemplo sencillo: En el bucle principal, el programa mantiene el diodo led LED_run encendido y el diodo led LED_int apagado. Si presionamos el botn T se genera la interrupcin el microcontrolador para de ejecutar el programa principal e inicia el procedimiento de interrupcin.
program TestearInterrupcion symbol LED_run = PORTB.7 symbol LED_int = PORTB.6 sub procedure interrupt if INTCON.RBIF = 1 then INTCON.RBIF = 0 else if INTCON.INTF = 1 then LED_run = 0 LED_int = 1 Delay_ms(500) INTCON.INTF = 0 else if INTCON.T0IF = 1 then INTCON.T0IF = 0 else if INTCON.EEIF = 1 then INTCON.EEIF = 0 end if end if end if end if end sub main: TRISB = %00111111 OPTION_REG = %10000000 INTCON = %10010000 PORTB = 0 eloop: LED_run = 1 LED_int = 0 goto eloop end. ' ' ' ' ' Pines RB6 y RB7 son salida Desactivar resistencias pull-up internas y configurar la interrupcion por flanco de bajada en RB0 Habilitar interrupciones externas Valor inicial en PORTB ' LED_run se conecta al pin 7 del PORTB ' LED_int se conecta al pin 6 del PORTB ' Rutina de Servicio de Interrupcion ' Hubo cambio en los pines RB4-RB7? ' Hubo una interrupcion Externa(pin RB0)?
' Hubo una interrupcion del Timer0? ' El ciclo de escritura EEPROM termino?
' Mientras no hay interrupcion, el bucle es infinito ' LED_run esta encendido ' LED_int esta apagado
Ahora, Que ocurre cuando presionamos el botn? Nuestra rutina de interrupcin primero analiza la interrupcin revisando los bits bandera (flag) con las instrucciones if..then, debido a que existen distintas causas posibles para una interrupcin. En nuestro caso, ocurri una interrupcin externa (el pin RBO/INT cambi de estado) y por lo tanto el bit INTF del registro INTCON se puso en 1 (set). Entonces el microcontrolador cambia el estado de LED_run y LED_Int, y provee un retardo de medio segundo para que podamos ver el cambio. Posteriormente limpia el bit INTF para poder habilitar nuevas interrupciones, y regresa a ejecutar el programa principal. En situaciones donde el microcontrolador debe responder a eventos no relacionados con el programa principal, es sumamente til tener una rutina de servicio de interrupcin. Tal vez, uno de los mejores ejemplos es la multiplexacin de displays de 7 segmentos si el cdigo de multiplexacin est ligado a la interrupcin del temporizador, el programa principal estar mucho menos saturado ya que el proceso de refresco (refresh) de los displays se realizar en el fondo (background).
El potencimetro da 0V en un extremo y +5V en el otro debido a que usamos conversin de 8-bit, nuestro voltaje digitalizado puede tener 256 pasos. El siguiente programa lee el voltaje en el pin RA0 y lo muestra en los diodos led del puerto B. Si ningn led esta encendido, el resultado es cero y si todos los diodos se encienden, el resultado es 255.
program ADC_8 main: TRISA = %111111 PORTD = 0 TRISD = %00000000 ADCON1 = %1000010 ' Puerto A configurado como entrada ' Puerto D configurado como salida ' Puerto A configurado en modo analogo, ' 0 y 5V son valores de voltaje de referencia, ' y el resultado esta alineado a la derecha ' (6 bits ms altos de ADRESH son cero). ' Reloj del ADC es generado por circuito RC interno; ' voltaje es medido en RA2 y ' permite el uso del conversor AD ' Pausa de 500 ms
ADCON0 = %11010001
' Esperar que el ADC termine Delay_ms(5) if ADCON0.2 = 1 then goto wait end if PORTD = ADRESL Delay_ms(500) goto eloop end. ' ' ' ' Mostrar 8 bits inferiores en el puerto D Pausa de 500 ms Repetir todo otra vez Final del programa
Primero, necesitamos inicializar adecuadamente los registros ADCON1 y ADCON0. Despus, ponemos a 1 (set) el bit ADCON0.2 el cul inicializa la conversin y luego revisamos ADCON0.2 para determinar si la conversin ha terminado. Si termin, el resultado se almacena en ADRESH y ADRESL desde donde puede ser copiado al puerto D.
El ejemplo anterior tambin podra realizarse utilizando la instruccin ADC_Read. El siguiente ejemplo utiliza una resolucin de 10-bit:
= %11111111 = %00000000
' PORTA configurado como entrada ' PORTD configurado como salida ' PORTA configurado en modo analogo, ' 0 y 5V son valores de voltaje de referencia, ' y el resultado esta alineado a la derecha ' Ejecutar la conversion y guardar el resultado ' en la variable AD_Res ' ' ' ' Mostrar el byte inferior del resultado en PORTD Pausa de 500 ms Repetir todo otra vez Final del programa
ADCON1 = %1000010
Ya que un puerto es insuficiente para mostrar el resultado completo, podemos usar un LCD para desplegar los 10 bits del resultado. El esquema de conexin y el programa correspondiente se muestran a continuacin. Para ms informacin acerca de las rutinas LCD, revisa el Captulo 5: Rutinas de Libreras.
program ADC_con_LCD dim AD_Res as word dim dummyCh as char[6] main: TRISA TRISB = %1111111 = 0 ' PORTA configurado como entrada ' PORTB configurado como salida (para el LCD) 'PORTA configurado en modo analogo, ' 0 y 5V son valores de voltaje de referencia, ' y el resultado esta alineado a la derecha ' Inicializar LCD ' Limpiar LCD ' y apagar el cursor
ADCON1 = %10000010
' Ejecutar la conversion y guardar el resultado ' en la variable AD_Res LCD_Out(1, 1, " ") ' Limpiar el resutado previo en el LCD WordToStr(AD_Res, dummyCh) ' Convertir el resultado a texto, LCD_Out(1, 1, dummyCh) ' e imprimirlo en linea 1, columna 1 Delay_ms(500) goto eloop end. ' Pausa de 500 ms ' Repetir todo otra vez ' Final del programa
program Timer0_1segundo dim cnt as byte dim a as byte dim b as byte sub procedure interrupt cnt = cnt + 1 ' Incrementar el valor de cnt en cada interrupcion TMR0 = 96 INTCON = $20 ' Setear (poner a 1) T0IE, limpiar (poner en 0) T0IF end sub main: a = 0 b = 1 OPTION_REG = $84 TRISB = 0 PORTB = $FF cnt = 0 TMR0 = 96 INTCON = $A0
Asignar pre-escalador al TMR0 PORTB configurado como salida Inicializar PORTB Inicializar cnt
' Habilitar interrupcion para TMRO ' Si cnt es 200, entonces invertir los leds en PORTB, ' y resetear cnt
do if cnt = 200 then PORTB = not(PORTB) cnt = 0 end if loop until 0 = 1 ' Repetir infinitamente end. ' Final del programa
El pre-escalador se configura en 32, de manera tal que el reloj interno se divide en 32 y el TMR0 se incrementa cada 31 microsegundos. Si el TMR0 se inicializa en 96, el desbordamiento ocurre en (256-96)*31 us = 5 ms. El programa incrementa cnt por cada interrupcin, midiendo el tiempo transcurrido de acuerdo al valor de esta variable. Cuando cnt alcanza 200, el total de tiempo transcurrido es de 200*5 ms = 1 segundo.
' Si cnt es 152, entonces invertir los leds en PORTB, ' y resetear cnt do if cnt = 152 then PORTB = not(PORTB) cnt = 0 end if loop until 0 = 1 ' Repetir infinitamente end. ' Final del programa
El pre-escalador es seteado a 00 de manera tal que no existe divisin interna del reloj y el rebalse ocurre cada 65536 ms. El programa incrementa cnt por cada interrupcin, midiendo el tiempo transcurrido de acuerdo al valor de esta variable. Cuando cnt alcanza 152, el total de tiempo transcurrido es de 152*65536 ms = 9.96 segundos.
RS-232 es un estndar para el intercambio serial binario de datos entre un DTE (Equipo Terminal de Datos) y un DCE (Equipo de Comunicacin de Datos), comnmente usado en los puertos seriales de un computador personal. Es una comunicacin serial asncrona de 2-lineas (Tx para transmisin y Rx para recepcin) con un rango efectivo de 10 metros. El microcontrolador puede establecer comunicacin con la lnea serial RS-232 a travs de un USART (Transmisor Receptor Sncrono Asncrono Universal) en hardware que es una parte integral de los microcontroladores PIC16F87X. El USART contiene registros buffer especiales para recibir y transmitir datos as como un generador de Tasa de Baudios para configurar la tasa de transferencia. Este ejemplo muestra la transferencia de datos entre el microcontrolador y el computador PC conectados con un chip de interface de lnea RS-232 MAX232 (Ver ***Nota del Traductor al final del captulo) que cumple el papel de ajustar los niveles de seales en el lado del microcontrolador (convierte niveles de voltaje RS-232 +/- 12V a niveles TTL de 0-5V y viceversa).
El siguiente programa de ejemplo ilustra el uso de comunicacin serial hardware. El dato recibido desde el PC es almacenado en la variable dat y luego es retornada al PC como confirmacin de transferencia exitosa. Por lo tanto es fcil revisar si la comunicacin trabaja adecuadamente. El formato de transferencia es 8N1 (8 bits de datos, sin paridad y 1 bit de parada) y la tasa de transferencia es de 2400 baudios.
program Eco_USART dim dat as byte main: USART_Init(2400) while true if USART_Data_Ready = 1 then dat = USART_Read USART_Write(dat) end if wend end. ' Inicializar el modulo USART con una ' velocidad de 2400 Baud ' Si el dato es recibido entonces ' Leer el dato ' y enviarlo de Nuevo por el USART
Para poder establecer comunicacin, el PC debe tener un software de comunicacin instalado (un programa denominado Terminal). Un software Terminal es parte del IDE de MikroBasic. Puede ser accedido a travs del men Tools>USART Terminal por la combinacin de teclas Control+T. El Terminal te permite monitorear la transferencia y configurar todos los parmetros de transferencia. Primero necesitamos configurar la velocidad de transferencia a 2400 Baudios para igualar a la velocidad programada en el microcontrolador. Luego, seleccionar el puerto de comunicacin serial adecuado seleccionando uno de los 4 disponibles (revisa que el cable serial est conectado al PC). Despus de realizar estos ajustes, al hacer Click en Connect (Conectar) se inicia la comunicacin. Digita un mensaje y luego haz Click en Send Message el mensaje ser enviado al microcontrolador y luego retornar mostrndose en la pantalla. Nota que la comunicacin serial puede tambin estar basada en software en 2 pines cualesquiera del microcontrolador para ms informacin, revisa el Captulo 9: Comunicaciones. ***Nota del traductor: Mira con cuidado el esquema de conexin entre el PIC y el PC. Notars que el MAX232 requiere de 4 capacitores electrolticos de igual valor para su funcionamiento. Este chip se alimenta con +5V, sin embargo provee voltajes de +/- 12V. El secreto est en que los capacitores funcionan como duplicadores de voltaje. Si observas la polaridad y la conexin de dos de estos capacitores, notars que, en uno de ellos, el polo negativo se conecta a +5V y en el otro, el polo positivo a Tierra. Esta configuracin es CORRECTA debido a las razones explicadas anteriormente. Adicionalmente, el cable serial solo requiere 3 lneas conectadas: Rx (pin 2), Tx(pin 3) y Tierra(pin 5). El esquema muestra algunos pines puenteados entre s esto no es estrictamente necesario pues por lo general no realizamos un control de handshake (protocolo de sincronizacin).
Introduccin
Los microcontroladores trabajan muy bien con 1s y 0s, pero los humanos no. Nosotros necesitamos luces indicadoras, nmeros, letras, grficos, sonidos Para poder comprender la informacin presentada de una mejor y ms rpida manera, necesitamos que esa informacin se nos muestre en diferentes formas. En la prctica, la comunicacin humanomquina requiere recursos (de parte de la mquina) substanciales, as que algunas veces es mejor dedicar un microcontrolador entero a esa tarea. Este tipo de dispositivo se denomina Interface Humano-Mquina simplemente HMI. Entonces se requiere que el segundo microcontrolador obtenga los deseos humanos del HMI, que haga el trabajo y luego ponga los resultados otra vez en el HMI, de manera tal que el operador humano pueda verlos. Claramente, la forma ms importante de comunicacin entre el sistema microcontrolador y un humano es la comunicacin visual. En este captulo discutiremos varias formas de desplegar datos, desde los ms simples hasta los ms elaborados. Vers cmo utilizar diodos leds, displays de 7-segmentos, LCDs de caracteres y LCDs grficos. Tambin consideraremos usar el BASIC para la sealizacin por sonido necesaria en ciertas aplicaciones. Solo recuerda: cuanto ms amigable sea la comunicacin, se requerirn ms recursos del MCU.
mientras que la mxima corriente alcanza los 25mA. El alto consumo de corriente puede representar un problema para dispositivos con fuente de poder en base a bateras, en ese caso se deben utilizar diodos led de baja corriente de consumo (Id 1 2 mA). Para que un led emita luz a capacidad mxima, es necesario conectarlo adecuadamente o podra resultar daado ( peor an, el MCU podra daarse).
El polo positivo se conecta al nodo, mientras que tierra est conectada al ctodo. Para fines de diferenciacin, el ctodo est marcado con una seccin plana en la empaquetadura siendo el pin de menor longitud. El led emitir luz solamente si la corriente fluye del nodo al ctodo; de otra forma no existir corriente. Se aade una resistencia en serie con el led, limitando as la mxima corriente que fluye a travs del diodo y protegindolo de un dao irreparable. El valor de la resistencia puede ser calculado a partir de la ecuacin mostrada en la figura, donde Vr representa el voltaje en la resistencia. Si usamos una fuente de +5V y queremos una corriente de 10 mA a travs de la resistencia, se debe usar un valor de 330 . El led puede ser conectado al microcontrolador de dos formas. La primera es hacer que el MCU encienda al led con un uno lgico y la segunda es con un cero lgico. La primera forma no es muy frecuente (lo que no significa que no tenga aplicaciones) debido a que requiere que el microcontrolador sea la fuente de corriente Id. La segunda forma trabaja con corrientes de led ms altas.
PORTB configurado como salida Encender leds en PORTB Esperar 1 segundo Apagar leds en PORTB Esperar 1 segundo Bucle infinito
Ya que los dgitos de 7-segmentos poseen mejor tolerancia de temperatura que los displays LCD, son muy comunes en aplicaciones industriales. Su uso satisface todos los criterios incluyendo los de orden financiero. Son comnmente utilizados para mostrar los valores obtenidos de los sensores, etc. Una de las formas de conexin de los displays de 7-segmentos se muestra en la figura inferior. El sistema est conectado par usar dgitos de 7-segmentos de ctodo comn. Esto significa que los segmentos emiten luz cuando un 1 lgico llega a sus terminales, y que la salida de todos los segmentos debe estar conectada por un transistor al ctodo comn, tal como se muestra en la figura. Si el transistor se encuentra en el modo de conduccin, cualquier segmento con un 1 lgico emitir luz, y si no est en modo de conduccin, ningn segmento emitir luz, sin importar es estado de los pines.
Digito de Decenas Digito de Unidades
Las bases de los transistores T1 y T2 estn conectadas al pin0 y el pin1 del PORTA. Poniendo un 1 en estos pines activan los transistores, permitiendo que cualquier segmento, desde el a hasta el h, emita luz con un 1 lgico. Si ponemos un 0 en la base de los transistores, ninguno de los segmentos emitir luz, sin importar es estado de los pines.
Usando el esquema previo, podemos mostrar una secuencia de nueve dgitos de esta manera:
program Siete_seg_1_digito dim i as byte ' La function mask retorna una mascara del parametro 'num' ' para un display catodo comun de 7-seg sub function mask(dim num as byte) as byte select case num case 0 result case 1 result case 2 result case 3 result case 4 result case 5 result case 6 result case 7 result case 8 result case 9 result end select end sub main: INTCON TRISA TRISB PORTB PORTA = = = = = 0 0 0 0 2 ' Deshabilitar interrupciones PEIE, INTE, RBIE, T0IE ' Puertos A y B configurados como salida
= = = = = = = = = =
$3F $06 $5B $4F $66 $6D $7D $07 $7F $6F
Digito de unidades
' Barrer digitos del 0 al 9 ' Mostrar la mascara del digito en puerto B ' Esperar 1 segundo ' Bucle infinito
El propsito del programa es de desplegar los nmeros del 0 al 9 en el display Digito de unidades, con un retardo de 1 segundo. Para poder mostrar un nmero, su mscara debe ser colocada en PORTB. Por ejemplo, si necesitamos mostrar el 1, los segmentos b y c deben estar en 1 y el resto en 0. Si (de acuerdo al esquema anterior) los segmentos b y c estn conectados a los pines segundo (RB.1) y tercero (RB.2) del PORTB, entonces los valores 0000 y 0110 deben ser colocados en el PORTB. Por lo tanto, la mscara para el nmero 1 es el valor 0000 0110 06 en hexadecimal. La siguiente tabla contiene los correspondientes valores de mscaras para los nmeros 0 9:
HEXADECIMAL
0 1 2 3 4 5 6 7 8 9
0 0 0 0 0 0 0 0 0 0
0 0 1 1 1 1 1 0 1 1
1 0 0 0 1 1 1 0 1 1
1 0 1 0 0 0 1 0 1 0
1 0 1 1 0 1 1 0 1 1
1 1 0 1 1 1 1 1 1 1
1 1 1 1 1 0 0 1 1 1
1 0 1 1 0 1 1 1 1 1
$3F $06 $5B $4F $66 $6D $7D $07 $7F $6F
Sin embargo no ests limitado a desplegar solamente dgitos. Puedes utilizar el decodificador de displays de 7seg (Tools>7 Segment Decoder), un herramienta integrada en el IDE de MikroBasic, para obtener el cdigo hexadecimal de cualquier otra combinacin posible de los segmentos que quisieras desplegar. Pero, Qu hacemos si necesitamos mostrar ms de un dgito en dos o ms displays? Debemos poner, lo suficientemente rpido, una mscara en el primer dgito y luego activar su transistor, posteriormente ponemos la segunda mscara y activamos el segundo transistor (por supuesto, si uno de los transistores est en el modo de conduccin, el otro no deber estarlo porque sino ambos dgitos desplegarn el mismo valor). Este proceso se conoce como multiplexacin: los dgitos son desplegados en forma tal que el ojo humano tiene la impresin de que ambos dgitos estn funcionando simultneamente en realidad solo uno de los displays esta activado en cualquier instante. Ahora, digamos que necesitamos mostrar el nmero 38. Primero, el nmero debe ser separado en decenas y unidades (en este caso, dgitos 3 y 8) y sus mscaras deben ser enviadas al PORTB. El resto
del programa es muy similar al ltimo ejemplo, con excepcin de tener una transicin causada por el despliegue de un dgito despus del otro:
program Siete_seg_2_digitos dim dim dim v as byte por1 as byte por2 as byte
sub procedure interrupt begin if v = 0 then PORTB = por2 ' Enviar la mascara de decenas al PORTB PORTA = 1 ' Activar 1er display de 7seg, desactivar 2do v = 1 else PORTB = por1 ' Enviar la mascara de unidades al PORTB PORTA = 2 ' Activar 2do display de 7seg, desactivar 1ero v = 0 end if TMR0 = 0 ' Limpiar TMRO INTCON = $20 ' Limpiar TMR0IF y activar TMR0IE end sub main: OPTION_REG TRISA TRISB PORTB PORTA TMR0 por1 por2 INTCON while true nop wend end. = = = = = = = = = $80 0 0 0 0 0 $7F $4F $A0 ' ' ' ' ' ' ' ' ' Activar resistencias Pull-up internas PORTA configurado como salida PORTB configurado como salida Limpiar PORTB (asegurar que los LEDs esten apagados) Limpiar PORTA (desactivar ambos displays) Limpiar TMRO Mascara para '8' (revisa la tabla arriba) Mascara para '3' (revisa la tabla arriba) Habilitar T0IE
' Bucle infinito, esperar la interrupcin ' hacer nada (perder tiempo)
El problema de multiplexacin est resuelto por ahora, pero probablemente tu programa no tiene el nico propsito de desplegar valores constantes en displays de 7seg. Usualmente es solo una subrutina para mostrar cierta informacin. Sin embargo, esta forma de mostrar datos en un display ha probado ser muy conveniente para programas ms complicados. Tambin puedes mover la parte del programa que realiza el barrido de los dgitos (manejo de mscaras) a la rutina de interrupcin.
El siguiente ejemplo incrementa la variable i desde 0 hasta 99 mostrando los valores en displays. Despus de llegar al 99, la cuenta empieza nuevamente.
program Siete_seg_Contador dim i as byte dim j as byte dim v as byte dim por1 as byte dim por2 as byte ' Esta funcion retorna mascaras para display 7-seg catodo comun sub function mask(dim num as byte) as byte select case num case 0 result = $3F case 1 result = $06 case 2 result = $5B case 3 result = $4F case 4 result = $66 case 5 result = $6D case 6 result = $7D case 7 result = $07 case 8 result = $7F case 9 result = $6F end select end sub sub procedure interrupt if v = 0 then PORTB = por2 ' Preparar mascara para digito de decenas PORTA = 1 ' Activar 1ero, desactivar 2ndo display 7-seg v = 1 else PORTB = por1 ' Preparar mascara para digito de unidades PORTA = 2 ' Activar 2ndo, desactivar 1er display 7-seg v = 0 end if TMR0 = 0 INTCON = $20 end sub main: OPTION_REG = $80 por2 = $3F j = 0 TMR0 = 0 INTCON = $A0 ' Deshabilitar PEIE, INTE, RBIE, T0IE TRISA = 0 TRISB = 0 PORTB = 0 PORTA = 0 do for i = 0 to 99 j = i mod 10 por1 = mask(j)
j = (i div 10) mod 10 ' Preparar digito de decenas por2 = mask(j) Delay_ms(1000) next i loop until false end. ' Retardo de 1 segundo ' Bucle infinito
En el curso del programa principal, el programador no necesita preocuparse para actualizar (refreshing) el display. Basta con llamar a la subrutina mask cada vez que el display necesita cambiar.
El LCD se conecta al microcontrolador a travs de un bus de 4-bit u 8-bit (4 u 8 lneas). La seal R/W est a tierra, debido a que la comunicacin es en un sentido (hacia el LCD). Algunos displays tienen luz de fondo (backlight) incorporada que puede ser encendida con el pin RD1 a travs de un transistor PNP BC557. El siguiente ejemplo imprime texto en el LCD a travs de una interface de 4-bit. Se asume usamos la configuracin de pines por omisin. que
program Prueba_LCD_4bit dim Text as char[20] main: TRISB = 0 LCD_Init(PORTB) LCD_Cmd(LCD_CURSOR_OFF) Text = "mikroelektronika" LCD_Out(1, 1, Text) end.
' PORTB configurado como salida ' Inicializar LCD en PORTB ' Apagar cursor ' Imprimir texto en el LCD
El segundo ejemplo imprime texto en el LCD a travs de una interface de 8-bit, con una configuracin de pines definida por el usuario.
program Prueba_Lcd_8bit dim text as char[20] main: TRISB = 0 TRISD = 0 Lcd8_Init(PORTB, PORTD) Lcd8_Cmd(Lcd_CURSOR_OFF) text = "mikroElektronika" Lcd8_Out(1, 1, text) end.
PORTB configurado como salida PORTD configurado como salida Inicializar LCD en PORTB y PORTD Apagar cursor
BASIC ofrece una librera comprensiva para los GLCD refirete al Captulo 5: Rutinas de Libreras Incorporadas para ms informacin. El siguiente ejemplo demuestra las posibilidades del GLCD y la librera mencionada. Nota que la librera solo funciona con microcontroladores PIC18.
program GLCD_test include "GLCD_128x64.pbas" dim text as string[25] main: PORTC PORTB PORTD TRISC TRISD TRISB
= = = = = =
text = "Circle" ' dibujar circulos GLCD_Put_Text(0, 7, text, NONINVERTED_TEXT) GLCD_Circle(63,31,10) Delay_Ms(4000) GLCD_Clear_Screen ' dibujar rectangulos text = "Rectangle" GLCD_Put_Text(0, 7, text, NONINVERTED_TEXT) GLCD_Rectangle(10, 0, 30, 35) Delay_Ms(4000) GLCD_Clear_Screen ' dibujar lineas text = "Line" GLCD_Put_Text(55, 7, text, NONINVERTED_TEXT) GLCD_Line(0, 0, 127, 50) GLCD_Line(0,63, 50, 0) Delay_Ms(5000) ' Fonts Demo GLCD_Clear_Screen ' demostracin de tipos de letra text = "Fonts DEMO" GLCD_Set_Font(FONT_TINY) GLCD_Put_Text(0, 4, text, NONINVERTED_TEXT) GLCD_Put_Text(0, 5, text, INVERTED_TEXT) GLCD_Set_Font(FONT_BIG) GLCD_Put_Text(0, 6, text, NONINVERTED_TEXT) GLCD_Put_Text(0, 7, text, INVERTED_TEXT) Delay_ms(5000) wend end.
program Sound
sub procedure Tone1 Sound_Play(200, 200) end sub sub procedure Tone2 Sound_Play(180, 200) end sub sub procedure Tone3 Sound_Play(160, 200) end sub sub procedure Melody Tone1 Tone2 Tone3 Tone3 end sub main: TRISB = $F0 Sound_Init(PORTB, 2) Sound_Play(50, 100)
while true if Button(PORTB,7,1,1) then Tone1 end if while TestBit(PORTB,7) = 1 nop wend if Button(PORTB,4,1,1) then Melody end if while TestBit(PORTB,4) = 1 nop wend wend end.
' Si se presiona el botn RB4 ' se toca la melodia ' Esperar a que el boton sea liberado
Introduccin
No existe un programa en el mundo que no interactu con la memoria de alguna forma. Primero, durante su ejecucin, obtiene los datos operacionales desde, usa, altera, vuelve a almacenarla en, la memoria de programa. Segundo, a menudo es necesario guardar y manejar grandes cantidades de datos que son obtenidos desde distintas fuentes, ya sea desde un mdulo de adquisicin de datos de la temperatura de un motor para una imagen en mapa de bits a ser desplegada en un GLCD. En este captulo nos enfocaremos en lo problemas referidos a la segunda forma, es decir repasaremos las tcnicas para la manipulacin de datos en los denominados dispositivos y sistemas de almacenamiento de memoria.
Nota: Ten en cuenta que todas las interrupciones estarn deshabilitadas durante la ejecucin de la rutina EEPROM_Write (el bit GIE del registro INTCON ser limpiado (puesto en 0)). La rutina repondr (pondr a 1) el bit cuando acabe. Asegura un retardo mnimo de 20ms entre usos sucesivos de las rutinas EEPROM_Write y EEPROM_Read.Aunque la EEPROM escribir el valor correcto, EEPROM_Read podra retornar un resultado indefinido. En el siguiente ejemplo, escribiremos una secuencia de nmeros a localizaciones sucesivas de la EEPROM. Posteriormente, los leeremos y los sacaremos por el PORTB para verificar el proceso.
program EEPROM_test dim i as byte dim j as byte main: TRISB = 0 for i = 0 to 20 EEPROM_Write(i, i + 6) next i Delay_ms(30) for i = 0 to 20 PORTB = EEPROM_Read(i) for j = 0 to 200 Delay_us(500) next j next i end.
La EEPROM serial se conecta la microcontrolador a travs de las lneas SCL y SDA. SCL (Serial CLock) es una seal de reloj que sincroniza la transferencia de datos por la lnea SDA (Serial DAta), con frecuencias que van hasta 1 MHz.
La comunicacin I2C permite la conexin de mltiples dispositivos en una lnea nica. Por lo tanto, los bits A1 y A0 tienen la opcin de asignar direcciones a ciertos dispositivos I2C conectando los pines A1 y A0 a tierra y +5V (una lnea I2C puede ser una EEPROM en la direccin $A2 y, digamos, un reloj de tiempo real PCF8583 en la direccin $A0). El bit R/W del byte de direccin selecciona la operacin de lectura o escritura de datos de memoria. Ms detalles de la comunicacin I2C puede ser encontrada en el Captulo 21. BUS I2C de libro Microcontrolador PIC16F84 Desarrollo de Proyectos de Palacios, Remiro y Lpez. El siguiente programa enva datos a la EEPROM en la direccin 2. Para verificar la transferencia, leeremos los datos a travs del I2C de la EEPROM y enviaremos el valor al PORTD. Para ms informacin acerca de la Librera I2C consulta el Captulo 5: Rutinas Incorporadas y de Librera
program Prueba_EEPROM dim EE_adr as byte dim EE_data as byte dim jj as word main: I2C_init(100000) TRISD = 0 PORTD = $ff I2C_Start I2C_Wr($a2) EE_adr = 2 I2C_Wr(EE_adr) EE_data = $aa I2C_Wr(EE_data) I2C_Stop for jj = 0 to 65500 nop next jj I2C_Start I2C_Wr($a2) EE_adr = 2 I2C_Wr(EE_adr) I2C_Repeated_Start I2C_Wr($a3) EE_data = I2C_Rd(1) I2C_Stop PORTD = EE_data SinFin: goto SinFin end.
Inicializar modo maestro completo PORTD configurado como salida Inicializar PORTD Secuencia de inicio I2C Enviar byte a traves de I2C(commando al 24cO2)
' Enviar byte(direccion de EEPROM) ' Enviar dato(dato a ser escrito) ' Secuencia de parada I2C ' Pausa mientras la EEPROM escribe los datos
' Secuencia de inicio I2C ' Enviar byte a traves de I2C ' ' ' ' ' ' ' Enviar byte(direccion de EEPROM) Secuencia de Reinicio I2C Enviar byte (requerir datos de la EEPROM) Leer el dato Secuencia de parada I2C Mostrar dato en PORTD Bucle infinito
directamente con el Flash del MCU. Nota: Las rutinas difieren para las familias PIC16 y PIC18, por favor refirete al Captulo 5: Rutinas Incorporadas y de Librera. El siguiente cdigo demuestra el uso de las rutinas de la librera de Memoria Flash:
program Prueba_flash_pic18 const FLASH_ERROR = $FF const FLASH_OK = $AA dim toRead as byte dim i as byte dim toWrite as byte[64] main: TRISB = 0 for i = 0 to 63 toWrite[i] = i next i Flash_Write($0D00, toWrite) ' Para PIC18
PORTB = 0 toRead = FLASH_ERROR for i = 0 to 63 toRead = Flash_Read($0D00+i) if toRead <> toWrite[i] then PORTB = FLASH_ERROR Delay_ms(500) else PORTB = FLASH_OK end if next i end.
escribir contenidos del arreglo empezando en la direccion 0x0D00 Verificar la escritura apagar PORTB inicializar estado como Error leer 64 localizacioes consecutivas empezando desde 0x0D00 Parar al primer error Indicar error
' PORTB configurado como salida ' ' ' ' ' ' ' ' ' ' ' escribir el valor de i empezando de la direccion 0x0A00 Verificar la escritura apagar PORTB inicializar estado como Error leer 64 localizacioes consecutives empezando desde 0x0A00 Parar al primer error i contiene la direccion de la localicacion erronea Indicar error
Las rutinas de acceso a archivos pueden escribir (grabar) un archivo. Los nombres de archivo deben tener exactamente 8 caracteres de longitud y ser escritos en MAYUSCULAS. El usuario debe asegurarse que cada archivo tenga un nombre diferente, ya que las rutinas CF no revisan si existen archivos con nombres repetidos. Antes de realizar una operacin de escritura, asegrate que no sobre escribas (overwrite) el sector de Arranque (Boot) FAT ya que esto podra hacer que tu tarjeta no pueda ser
leda en la PC cmara digital. Herramientas de mapeo de discos, como ser Winhex, pueden ser de gran utilidad.
Aqu tienes un ejemplo en BASIC del uso de una tarjeta CF. Un grupo de archivos es escrito en la tarjeta CF. Esto puede ser revisado posteriormente conectando la tarjeta CF en una PC cmara digital. Observa la forma en que el archivo se graba: Primero, se inicializa el ciclo write-to-file (escribir a archivo), indicndole al PIC que todas las instrucciones CF_File_Write_Byte consecutivas sern escritas a un nuevo archivo; Luego, la escritura de datos se realiza (usando CF_File_Write_Byte); Finalmente, se sealiza la finalizacin del ciclo de escritura a archivo (write-to-file) mediante una llamada a la rutina CF_File_Write_Complete. En ese instante, se le da un nombre al archivo acabado de crear.
program Archivo_CompactFlash dim dim dim dim i1 as word index as byte fname as char[9] ext as char[4]
'Para PIC18
CF_Init_Port(PORTB, PORTD) do nop loop until CF_DETECT(PORTB) = true Delay_ms(50) end sub
'Procedimiento de inicio 'PORTC configurado como salida. 'Sera usado solamente para indicar 'el final del programa. 'Inicializar puertos
'Esperar hasta que se inserte tarjeta CF 'Esperar hasta que la CF se estabilice, 'es decir :fuente de poder estable y el 'controlador tarjeta CF este encendido
main: ext = "txt" 'Extension de archive sera "txt" index = 0 'Indice de archivo a ser escrito while index < 5 PORTC = 0 Inicio PORTC = index CF_File_Write_Init(PORTB, PORTD)'Inicializacion para escribir 'el nuevo archivo i1 = 0 while i1 < 50000 CF_File_Write_Byte(PORTB,PORTD,48+index)'Escribe 50000 bytes al archivo inc(i1) wend fname = "RILEPROX" 'Nombre de longitud 8 caracteres y 'en MAYUSCULAS fname[8] = 48 + index 'Asegurar que los archivos tienen nombres 'diferentes CF_File_Write_Complete(PORTB,PORTD, fname, ext) 'Cerrar el archivo Inc(index) wend PORTC = $FF end.
Si no requieres usar tu tarjeta CF para conectarla a un PC o cmara digital, sino solamente como un simple dispositivo de almacenaje para el microcontrolador PIC, entonces puedes ignorar todo el sistema FAT y guardar los datos directamente en los sectores de la memoria CF:
'Inicializar escritura en el sector 'con direccion 590 '1 sector de 512 bytes 'Escribir 512 bytes al sector (590)
'Inicializar escritura en el sector 'con direccion 590 '1 sector de 512 bytes for i = 0 to 511 'Leer 512 bytes del sector (590) PORTC = CF_Read_Byte(PORTB, PORTD) 'y mostrar datos en PORTC Delay_ms(1000) next i end.
for i = 0 to 511 CF_Write_Byte(PORTB, PORTD, i + 11) next i PORTC = $FF Delay_ms(1000) CF_Read_Init(PORTB, PORTD, 590, 1)
Introduccin
Cuando empieces a escribir programas reales con los PIC, pronto encontrars una sensacin de no tener suficiente espacio, de que lo que necesitas son solamente algunos pines extra y algunos bytes de memoria adicionales para terminar el trabajo. Quizs puedas resolver este problema cambiando a un PIC ms grande, esto funcionar, al menos por un tiempo. quizs acabas de encontrar el sensor perfecto que realiza todo el trabajo por si solo, lo nico que necesitas es conectarlo al PIC para transferir los datos. Eso es, si es que sabes cmo conectarlo. Si te han ocurrido estos problemas o algunos bastante similares, es hora de que le ensees al PIC y a ti mismo algunas lecciones de comunicacin. Existen muchas maneras de que dos dispositivos se comuniquen hoy en da, y los PICs estn bien equipados para esta tarea. Dependiendo del trabajo que se tiene que realizar, el intercambio de datos lo que bsicamente representa la comunicacin puede ser realizada de una manera relativamente simple, tal como la comunicacin SPI, puede extenderse a una red entera de varios dispositivos MCUs, PCs, cmaras, sensores inteligentes, etc. Con una mayor demanda de comunicacin, las reglas del comportamiento de los dispositivos deben enmarcarse en un conjunto ms amplio de escenarios posibles y, por lo tanto, los protocolos de comunicacin crecern dramticamente en complejidad (por ejemplo, CAN). Considera tus necesidades cuidadosamente antes de lanzarte a una solucin basada en CAN. Existen diferentes mtodos de comunicacin, que ofrecen muchas posibilidades en distintos niveles de complejidad. La regla bsica de mantenlo lo ms simple posible se aplica aqu bastante bien: No uses herramientas de comunicacin ms complejas de lo que realmente necesitas! En este captulo, te encontrars con varios medios de comunicacin que estn siendo usados por los MCUs PIC, y las formas en las cuales puedes accederlas y usarlas en el lenguaje de programacin BASIC. Quizs hayas notado que algunos de los dispositivos de comunicacin tienen su contraparte en software, lo que significa que puedes tener la misma funcionalidad de comunicacin en hardware a
travs de un conjunto de rutinas en software que pueden ser usadas a travs del lenguaje BASIC. Deberas usar estas rutinas de comunicacin en software una vez que hayas utilizado los recursos reales en hardware pero an as necesitas una lnea de comunicacin adicional.
El USART en si mismo puede ser configurado para comunicarse en muchas formas. La ms frecuente es, por supuesto, la que permite al PIC hablar con la PC. Este antiguo estndar, conocido como RS232, es entendido por un 99.9% de las PCs, aunque ltimamente est siendo reemplazado por el estndar USB. Puedes ver, en la imagen inferior, cmo conectar el PIC al PC. Tienes que aadir un chip adicional entre ambos (MAX232) que simplemente ajusta los niveles de voltaje el USART a los niveles requeridos por el estndar RS232.
Como puedes ver, necesitas dos lneas para este tipo de comunicacin: una para la recepcin de datos (llamada Rx), y la otra para la transmisin (Tx). Aqu tienes un programa simple en BASIC en el que el PIC recibe datos desde el PC y luego los vuelve a enviar:
program RS232com dim received_byte as byte
main: USART_Init(2400) while true if USART_Data_Ready = 1 then received_byte = USART_Read USART_Write(Received_byte) end if wend end.
' Inicializar modulo USART ' Si se recibe un dato: ' leer dato recibido, ' enviarlo de Nuevo al USART
Cuando compiles este programa y lo escribas en el PIC, puedes abrir algn programa de comunicacin serial en tu PC (programa Terminal), tal como el Windows Terminal, configurar los parmetros de conexin, abrir la conexin, y enviar algunos caracteres al PIC. Si todo est bien, el PIC te devolver los mismos datos.
program soft_uart_test dim received_byte as byte dim rec_ok as byte main: Soft_UART_Init(PORTB, 1, 2, 2400)
' inicializar UART por software ' debes indicar que pines ' usar como Rx y Tx
while true do received_byte = Soft_UART_Read(Rec_ok) loop until rec_ok Soft_UART_write(received_byte) wend end.
software para simular el dispositivo USART real en hardware. Trabajar con el UART en software es casi idntico que con el USART hardware, la nica diferencia es la inicializacin. Puedes ver esto en el siguiente ejemplo:
' Configuracion estandard ' ' ' ' ' Inicializar max7219 Seleccionar max7219 Enviar direccion (1) al max7219 Enviar datos (7) al max7219 Desactivar max7219
SELECCIONAR MAX modo BCD para la decodificacion de digitos DESACTIVAR MAX SELECCIONAR MAX intensidad de luminosidad de segmentos DESELECT MAX SELECCIONAR MAX Acutalizacin del Display (refresh) DESACTIVAR MAX SELECCIONAR MAX Encender el display DESACTIVAR MAX SELECCIONAR MAX No realizar prueba (test) DESACTIVAR MAX
Usar el software SPI es similar a cualquier comunicacin por software el software contenido en las rutinas BASIC simula al dispositivo real. Tomando esto en cuenta, debes ser cuidadoso con las rutinas de inicializacin. Aqu hay un ejemplo que utiliza el SPI por software para hablar con otro chip (el conversor A/D de 12-bit de canal mltiple LTC1290) , esta vez por medio del pin RD1.
'******************************************************************************* ' Proyecto: LTC1290 ' Este codigo demuestra el uso de las rutinas software para la comunicacion SPI. ' Tambien, este ejemplo demuestra el trabajo con el ADC LTC1290. ' el pin CS del LTC1290 debe estar conectado al pin RD1 ' y los pines DSO, SDI, SCKL deben estar conectados apropiadamente. ' El resultado de la conversion AD se muestra en el display LCD. ' Probado en los chips 16F877A y 18F452 '******************************************************************************* program ltc1290 dim low_res as byte dim high_res as byte dim t as char[17] sub procedure Display_ADval 'Formatea y muestra el resultado en el LCD dim tmp as word dim value as longint tmp = word((high_res << 4)) + word(low_res <B>>> 4) value = (5000*tmp) <B>>> 12 tmp = word(value) t[1]= 48 + word(tmp div 1000) t[3]= 48 + word((tmp div 100) mod 10) t[4]= 48 + word((tmp div 10) mod 10) t[5]= 48 + word(tmp mod 10) t[2]= 46 t[0]= 5 'el largo del string esta en el elemento cero LCD_out(2, 1, t) end sub main: PIE1 = 0 INTCON = 0 TRISB = 0 LCD_Init(PORTB) LCD_Cmd(LCD_CURSOR_OFF) low_res = 110 high_res = 1 Display_ADval
deshabilitar interrupciones configurar PORTB como salida inicializar LCD en el PORTB cursor LCD apagado
Soft_SPI_Config(PORTD,7,6,5) SetBit(PORTD,1) ClearBit(TRISD,1) t = "mikroElektronika" LCD_Out(1, 1, t) while true ClearBit(PORTD,1) high_res = Soft_SPI_Read(255) low_res = Soft_SPI_Read(0) SetBit(PORTD,1) Display_ADval Delay_ms(1) wend end.
' pin RD1 es salida ' mostrar "mikroElektronika" en el LCD ' ' ' ' ' ' seleccionar LTC1290 obtener byte alto de la conversion AD obtner 4 bits lsb de la conversion AD desactivar LTC1290 formatear y mostrar valor en el LCD esperar 1 ms para la siguiente conversion