Anda di halaman 1dari 73

MikroElectronika

Programacin de Microcontroladores PIC en MikroBasic


Nebojsa Matic Traduccin al espaol por Roger Guachalla Narvez xoroger@yahoo.es

2008 Edicin en lnea www.mikroe.com

Programando microcontroladores PIC en BASIC


Tabla de contenidos
Prefacio Captulo 1: Lo bsico Captulo 2: Elementos de lenguaje Basic Capitul 3: Operadores Capitul 4: Estructuras de control Captulo 5: Rutinas incorporadas y de librera (NO TRADUCIDO) Captulo 6: Ejemplos con perifricos integrados PIC Capitul 7: Ejemplos para desplegar datos Captulo 8: Ejemplos con memoria y medios de almacenamiento Capitul 9: Ejemplos de comunicacin (INCONCLUSO) Apndice A: IDE de mikroBasic

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

hacia la memoria del microcontrolador.

***(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.

1.1 Por qu Basic?


Originalmente creado como una herramienta de fcil uso, BASIC se hizo popular en computadoras hogareas en los 1980s, y se mantiene popular hoy en da en varios dialectos altamente evolucionados. El nombre BASIC, de acuerdo a una tradicin cientfica computacional viene de la sigla, Beginner's All-purpose Symbolic Instruction Code (Cdigo de Instrucciones Simblicas de Propsito General para Principiantes). BASIC sigue siendo considerado por muchos usuarios de PC como el lenguaje de programacin ms

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.

1.2 Escogiendo el PIC adecuado para la tarea


Actualmente, las mejores opciones para el desarrollo de aplicaciones usando Basic son: el famoso PIC16F84, su nuevo reemplazo el PIC16F628A, los PIC PIC16F87x, PIC16F62x y PIC18Fxxx. Estos controladores tienen memoria de programa incorporada con tecnologa FLASH que proveen un borrado y reprogramacin rpida, permitiendo as una depuracin tambin rpida. Mediante un simple clic del ratn en el software de programacin, el programa del microcontrolador puede ser borrado instantneamente y luego recargado sin remover el chip. Tambin el programa que ha sido grabado en la memoria flash permanece despus de quitar la energa. Adems de la memoria de cdigo flash, los microcontroladores de las series PIC16F87x y PIC16F6x, tambin poseen entre 64 a 256 bytes de memoria EEPROM interna, que puede ser usada para guardar datos del programa y otros parmetros cuando la energa est apagada. BASIC tiene instrucciones de lectura y escritura de EEPROM que pueden ser usadas para cargar y guardar datos al EEPROM. Familias de microcontroladores PIC ms antiguas (12C67x, 14C000, 16C55x, 16C6xx, 16C7xx, and 16C92x) tienen memoria de programa basada en tecnologa EPROM/ROM, de manera tal que pueden ser programadas solamente una vez (versin OTP con memoria ROM) o tienen una ventana de vidrio (versin con memoria EEPROM) que permiten el borrado a travs de unos cuantos minutos de exposicin a luz UV (ultravioleta). Las versiones OTP son usualmente ms econmicas y son elegidas para la fabricacin en serie de productos terminados. Para poder tener una informacin completa acerca de un modelo especfico del microcontrolador en una aplicacin, debes obtener su hoja de datos (Datasheet) de la pgina web www.microchip.com.
Los ejemplos de programas desarrollados a lo largo del libro estn diseados para correr en microcontroladores PIC16F84 o PIC6F877, pero con ajustes menores, pueden ser ejecutados en cualquier otro microcontrolador PIC.

1.3 Una palabra acerca de la escritura de cdigo


Tcnicamente, cualquier editor de texto que pueda grabar un archivo como texto ASCII puro (sin smbolos especiales para el formato) puede ser usado para escribir tu cdigo BASIC. An as, no hay necesidad de hacerlo "a mano" existen entornos especializados que se ocupan de la sintaxis del cdigo, la memoria libre y proveen todas las herramientas necesarias para escribir un programa. El IDE (entorno de desarrollo integrado) de mikroBasic incluye un editor de cdigo altamente configurable, diseado para satisfacer las necesidades de usuarios novicios o experimentados. El uso de color para sintaxis, plantillas de cdigo, asistentes de cdigo y parmetros, autocorreccin para errores comunes, y otras opciones proveen un entorno cmodo para escribir un programa. Si t no has tenido experiencia previa con IDEs avanzados, de seguro te preguntars que hacen los asistentes de cdigo y de parmetros. Estas son utilidades que facilitan la escritura de cdigo. Por ejemplo, si escribes la primera letra de una palabra en el editor de cdigo y luego presionas CTRL+SPACE, todos los identificadores que concuerdan con las letras que escribiste aparecern en un panel flotante. Puedes seguir escribiendo para reducir las opciones, o puedes seleccionar uno de la lista usando las teclas de direccin y Enter. En combinacin con la ayuda comprensiva, herramientas integradas, extensas libreras, y el Explorador de Cdigo (Code Explorer) el cul te permite monitorear fcilmente los tems de tu programa, todas las herramientas necesarias estn a tu disposicin.

1.4 Escribiendo y compilando t programa


El primer paso es escribir el cdigo. Cada archivo fuente es grabado en un archivo de texto nico que tiene la extensin .pbas. Aqu tienes un ejemplo de un programa simple en BASIC, blink.pbas.
program LED_Blink main: TRISB = 0 bucle: PORTB = $FF Delay_ms(1000) PORTB = 0 Delay_ms(1000) goto bucle end. ' Configurar los pines del PORTB como salida ' ' ' ' ' Encender los leds en el PORTB Esperar 1 segundo Apagar los leds en el PORTB Esperar 1 segundo Regresar al bucle infinito

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.

1.5 Cargando un programa al microcontrolador


Como resultado de una compilacin exitosa del cdigo anterior, mikroBasic generar los siguientes archivos: blink.asm -archivo ensamblador blink.lst -archivo del listado blink.mcl -librera de compilacin mikro blink.hex -archivo ejecutable que es escrito en la memoria del microcontrolador

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.

1.6 Haciendo correr un programa


Para el funcionamiento apropiado de microcontrolador, es necesario proveer una fuente de energa, un oscilador, y un circuito de reset. La fuente puede ser construida con un rectificador diodo puente simple juntamente con un regulador de voltaje LM7805 tal y como se muestra en la figura de abajo

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.

1.7 Resolviendo errores


Existen algunos problemas comunes encontrados a la hora de hacer funcionar un microcontrolador PIC. Necesitas revisar que los componentes externos estn funcionando y revisar si sus valores corresponden a los requeridos y finalmente ver si todas las conexiones estn correctas. Te presentar algunas notas que puedes encontrar tiles.
Revisa si el pin MCLR est conectado a +5V, a travs de la resistencia de 10K. Si el pin se deja desconectado, estar en un nivel "flotante" y puede que funcione algunas veces pero usualmente no lo har. El chip tiene un circuito de reset al encendido (power-on-reset), de manera tal que la resistencia pull-up en el pin MCLR debera ser suficiente. Revisa si la conexin con el oscilador es estable. Para la mayora de los microcontroladores es adecuado comenzar con una frecuencia de 4 MHz. Revisa la fuente de energa. Los microcontroladores PIC consumen muy poca energa pero la fuente tiene que estar bien filtrada. A la salida del rectificador, la corriente es directa pero puede ser pulsante, y de esta forma no es conveniente para dar energa al microcontrolador. Para evitar la pulsacin, coloca un capacitador electroltico con una capacitada alta (470 uF) a la salida del rectificador. Si el microcontrolador PIC supervisa dispositivos que requieren mucha energa, stos pueden provocar un mal funcionamiento en las lneas de energa y causar que el microcontrolador empiece a comportarse de una forma extraa. An un display de siete segmentos puede inducir cadas de tensin (el peor caso es cuando todos los leds del display estn encendidos), si es que la fuente no es capaz de producir la corriente necesaria (por ejemplo si estamos alimentando el circuito con una batera de 9 V). Algunos microcontroladores tienen pines I/O multifuncionales ***(2), por ejemplo la familia PIC16F62x (PIC16F628A). Los microcontroladores de esta familia estn provistos con compradores anlogos en el puerto A. Despus de poner estos chips en funcionamiento, el puerto A est configurado en el modo anlogo, lo que trae un comportamiento inesperado en las funciones de los pines de este puerto. Cuando se hace un reset, cualquier pin que tenga entradas anlogas ingresar al modo anlogo (si los mismos pines son usados como lneas digitales stos necesitan ser configurados en el modo digital). Una fuente posible de errores es que el quinto pin del puerto A (RA4) exhibe un comportamiento singular

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

Capitulo 2: Elementos del lenguaje BASIC


Introduccin 2.1 Identificadores 2.2 Operadores 2.3 Expresiones 2.4 Instrucciones 2.5 Tipos de datos 2.6 Constantes 2.7 Variables 2.8 Smbolos 2.9 Directivas 2.10 Comentarios 2.11 Etiquetas 2.12 Procedimientos y Funciones 2.13 Mdulos

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)

Los operadores son explicados en detalle en el captulo 3.

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.

if Tiempo = 60 then goto Minuto end if

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

2.5 Tipos de Datos


El tipo determina el rango permitido de valores para una variable, y adems que operaciones se pueden realizar con estas. Tambin determina la cantidad de memoria usada para cada instancia de esa variable. Los tipos de datos simples incluyen:
Tipo byte char*** word short integer longint Tamao 8-bit 8-bit 16-bit 8-bit 16-bit 32-bit Rango de valores 0 .. 255 0 .. 255 0 .. 65535 -128 .. 127 -32768 .. 32767 -2147483648 .. 2147483647

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

Las variables con signo pueden contener nmeros positivos y negativos:


short integer longint -128 .. +127 -32768 .. +32767 -2147483648 .. +214748364

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

continua normalmente desde ese punto.


Gosub es una instruccin de salto similar al Goto, con la excepcin de que est ligada a la palabra return. Al

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.

2.12 Procedimientos y Funciones


Los procedimientos y funciones, referidas como rutinas, son bloques de instrucciones auto-contenidos que pueden ser llamados desde diferentes lugares en un programa. Una funcin es una rutina que devuelve un valor al ejecutarse. Un procedimiento es una rutina que no devuelve un valor. Una vez que las rutinas han sido definidas, puedes llamarlas cualquier nmero de veces. El procedimiento es llamado para realizar un cierta tarea, mientras que la funcin es llamada para calcular un cierto valor. La declaracin de un procedimiento tiene la forma:
sub procedure NombreProcedimiento(ListaParametros) DeclaracionesLocales Instrucciones end sub

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

' fin del Modulo

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)

3.1 Operadores Aritmticos


Operator +

Revisin de los operadores aritmticos en BASIC:


Operacin adicin Tipos de Operandos byte, short, integer, words, longint byte, short, integer, words, longint Tipo del Resultado byte, short, integer, words, longint byte, short, integer, words, longint integer, words, long byte, short, integer, words byte, short, integer, words

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

+ (unario) Identidad de signo - (unario) Negacin de signo

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

3.2 Operadores Booleanos


Los opeadores booleanos no son operadores verdaderos, debido a que no existe un tipo de datos booleano definido en BASIC. Estos operadores corresponden a la lgica Booleana estndar. No pueden ser usados con ningn tipo de datos, sin solamente para construir expresiones condicionales complejas.

Operador not and or

Operacin negacin conjuncin disjuncin

Por ejemplo:
if (astr > 10) and (astr < 20) then PORTB = 0xFF end if

3.3 Operadores Lgicos (Bit a bit)


Revisin de los operadores lgicos en BASIC:
Operador not Operacin negacin bit a bit Tipos de Operandos Tipo del Resultado

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

and bit a bit

or

or bit a bit

xor

xor bit a bit

<<

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

(debe ser positivo y menor que 255).


>> : desplazar el operando hacia la derecha un nmero de bits especificado a la derecha del operando

(debe ser positivo y menor que 255).

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

3.4 Operadores Relacionales (Operadores de Comparacin)


Los operadores relacionales (operadores de Comparasin) son usados comunmente en bucles condicionales para controlar el flujo del programa. Revisin de los operadores relacionales enBASIC:
Operador = Operacin igual a Tipos de Operandos Tipo del Resultado

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

<=

menor o igual que mayor o igual que

>=

Capitulo 4: Estructuras de Control


Introduccin 4.1 Expresiones Condicionales 4.1.1. Instruccin IF..THEN 4.1.2 Instruccin SELECT..CASE 4.1.3 Instruccin GOTO 4.2 Bucles 4.2.1 Instruccin FOR 4.2.2 Instruccin DO..LOOP 4.2.3 Instruccin WHILE 4.3 Instruccin ASM

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.

4.1 Expresiones Condicionales


Las expresiones condicionales son usadas para cambiar el flujo de ejecucin de un programa al encontrar una condicin especfica. La instruccin bsica para realizar esta bifurcacin cambio de flujo (branching) en el lenguaje BASIC es la instruccin IF, con algunas variantes que proveen la flexibilidad necesaria.

4.1.1 Instruccin IF..THEN


Sintaxis

bifurcacin condicional de programa

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

Se considera Falso al valor 0 (cero) y Verdadero a cualquier valor distinto de cero.

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.

dim j as byte Main: if PORTB.0 = 0 then goto Suma end if

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.

4.1.2 Instruccin SELECT..CASE bifurcacin condicional mltiple de programa


Sintaxis select case Selector case Valor_1 Instrucciones1 case Valor_2 Instrucciones2 ... case Valor_N Instrucciones_N [ case else Instrucciones_else ] end select

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

4.1.3 Instruccin GOTO


Sintaxis

Salto incondicional a la etiqueta especificada

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

Repeticin de un segmento de programa

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

Se considera Falso al valor 0 (cero) y Verdadero a cualquier valor distinto de cero.

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

4.2.3 Instruccin WHILE


Sintaxis

Continuar el bucle mientras la condicin sea verdadera

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

Se considera Falso al valor 0 (cero) y Verdadero a cualquier valor distinto de cero.

Ejemplo

while I < 90 I = I + 1 wend ... while I > 0 I = I div 3 PORTA = I wend

4.3 Instruccin ASM Insertar bloque de instrucciones en lenguaje Ensamblador


Sintaxis asm ListaInstrucciones end asm Algunas veces es til escribir parte de un programa en ensamblador . La instruccin asm puede ser usada para insertar instruccines en lenguaje ensamblador PIC en el cdigo BASIC. Nota que no puedes usar nmeros como direcciones absolutas para las variables SFR GPR para las variables en las instrucciones en ensamblador. En vez de esto, puedes usar nombres simblicos (el archivo de listado mostrar estos nombres as como sus direcciones). Ten cuidado al insertar cdigo ensamblador BASIC no revisar si las instrucciones en ensamblador han cambiado las localizaciones de memoria ya antes utilizadas por la variables BASIC.
***1 ***2 ***1

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

SFR: Registros de Funcin Especial; GPR: Registros de propsito general

Ejemplo

asm movlw 67 movwf TMR0 end asm

'mover al acumulador (W) el nmero 67 'mover el valor en el W al registro del Timer0

Capitulo 6: Ejemplos con perifricos integrados PIC


Introduccin 6.1 Mecanismo de Interrupcin 6.2 Conversor AD interno 6.3 Temporizador TMR0 6.4 Temporizador TMR1 6.5 Mdulo PWM 6.6 Mdulo UART en hardware (Comunicacin RS-232)

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.

6.1 Mecanismos de Interrupcin


Las interrupciones son mecanismos que permiten una respuesta casi instantnea a eventos tales como el desbordamiento de un contador, el cambio de estado en un pin, datos recibidos, etc. En el modo normal, el microcontrolador ejecuta el programa principal mientras no existan eventos que causaran una interrupcin. Al llegar la interrupcin, el microcontrolador detiene la ejecucin del programa principal y comienza la parte especial del programa que analiza y maneja la interrupcin. Esta parte del programa se conoce como la rutina de servicio de interrupcin. En BASIC, la rutina de servicio de interrupcin es definida con la palabra interrupt. Cualquier cdigo que se almacene en este procedimiento, ser ejecutado cuando exista una interrupcin. Primero, necesitamos determinar que evento provoc la interrupcin, ya que el microcontrolador PIC llama a la misma rutina de interrupcin sin importar la fuente de interrupcin. Despus de eso viene el manejo de la interrupcin, que significa la ejecucin del cdigo apropiado para el evento de disparo (trigger) de la interrupcin.

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

6.2 Conversor AD Interno


Algunos microcontroladores poseen un Conversor Anlogo Digital (ADC) incorporado. Comunmente estos conversores tienen una resolucin de 8-bit 10-bit permitindoles tener una sensitividad de 19.5 mV 4.8mV respectivamente (asumiendo un voltaje de alimentacin de +5V). El programa de conversin AD ms simple sera usar la resolucin de 8-bit y un voltaje de referencia de +5V (valor con el cul, el valor ledo desde el pin del microcontrolador se compara). En el siguiente ejemplo medimos el voltaje en el pin RA0 el cual est conectado a un potencimetro (ve la figura abajo).

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

Delay_ms (500) eloop: ADCON0.2 = 1 wait:

' Inicio de conversion

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

program ADC_10 dim AD_Res as word

main: TRISA TRISD

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

eloop: AD_Res = ADC_read(2)

PORTD = Lo(AD_Res) Delay_ms(500) goto eloop end.

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

Lcd_Init(PORTB) Lcd_Cmd(LCD_CLEAR) Lcd_Cmd(LCD_CURSOR_OFF) eloop: AD_Res = ADC_Read(2)

' 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

6.3 Temporizador TRM0


El temporizador (timer) TMR0 es un registro de funcin especial de 8-bit con un rango de trabajo de 256. Asumiendo que usamos un oscilador de 4MHz, TMR0 puede medir un rango de 0-255 microsegundos (a 4MHz, TMR0 se incrementa cada microsegundo). Este periodo puede ser incrementado si se utiliza el pre-escalador. El pre-escalador divide el reloj en una relacin especfica (la configuracin del pre-escalador se realiza en el registro OPTION_REG). El siguiente programa muestra como generar 1 segundo utilizando el timer TMR0. Para propsitos de visualizacin, el programa invierte el estado de los leds en PORTB cada segundo. Antes del programa principal, TMR0 se debe habilitar interrupciones. Es decir, el bit 2 y el bit 7 (GIE) del registro INTCON deben estar a 1(set). Esto habilita las interrupciones globales.

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.

6.4 Temporizador TRM1


El temporizador (timer) TMR1 es un registro de funcin especial de 16-bit con un rango de trabajo de 65536. Asumiendo que usamos un oscilador de 4MHz, TMR1 puede medir un rango de 0-65535 microsegundos (a 4MHz, TMR1 se incrementa cada microsegundo). Este periodo puede ser incrementado si se utiliza el pre-escalador. El pre-escalador divide el reloj en una relacin especfica (la configuracin del pre-escalador se realiza en el registro T1CON). Antes del programa principal, TMR1 debe ser habilitado configurando el primer bit (b0) del registro T1CON. Este primer bit define el reloj interno para TMR1 lo pondremos a cero. Otros registros importantes para trabajar con el TMR1 son PIR1 y PIE1. El primero contiene la bandera de rebalse (overflow flag) (bit 0) y el otro es usado para habilitar la interrupcin del TMR1 (bit 0). Teniendo la interrupcin del TMR1 habilitada y habiendo limpiado su bandera, solo requerimos habilitar las interrupciones globales y las interrupciones de perifricos en el registro INTCON (bits 7 y 6 respectivamente).El siguiente programa de ejemplo muestra como generar 10 segundos usando el TMR1. Para propsitos de visualizacin, el programa invierte el estado de los leds en PORTB cada 10 sg. .
program Timer1_10sec dim cnt as byte sub procedure interrupt cnt = cnt + 1 pir1.0 = 0 ' Limpiar bandera de interrupcion del TMR1 end sub main: TRISB = 0 T1CON = 1 PIR1.TMR1IF = 0 PIE1 = 1 PORTB = $F0 cnt = 0 INTCON = $C0

' Limpiar TMR1IF ' Habilitar interrupciones ' Inicializar cnt

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

6.5 Mdulo PWM


Los microcontroladores de la serie PIC16F87X tienen 1 o 2 salidas PWM incorporadas (empaquetaduras de 40-pin tienen 2, empaquetaduras de 28-pin tienen 1). Las salidas PWM estn localizadas en los pines RC1 y RC2 (MCUs de 40-pin), en el pin RC2 (MCUs de 28-pin). Consulta con la librera PWM (Captulo 5.2: Rutinas de Libreras) para ms informacin. El siguiente ejemplo usa la librera PWM para obtener varias intensidades de luz en el led conectado al pin RC2. La variable que representa la relacin de seales en 1 (On) y 0 (Off) se incrementa continuamente en el bucle, tomando valores entre 0 a 255. Esto resulta en una variacin en el nivel de intensidad de luz emitida por el diodo LED. Despus de alcanzar el valor 255, el proceso comienza otra vez.
program Prueba_PWM_LED dim j as byte main: TRISB = 0 PORTB = 0 j = 0 TRISC = 0 PORTC = $FF PWM_Init(5000) PWM_Start while true Delay_ms(10) j = j + 1 PWM_Change_Duty(j) PORTB = CCPR1L wend end. ' PORTB configurado como salida ' Limpiar PORTB ' ' ' ' ' ' ' ' ' PORTC configurado como salida Setear PORTC a $FF Inicializar modulo PWM Iniciar PWM Bucle infinito Esperar 10ms Incrementar j Configura nueva relacion de trabajo (duty ratio) Enviar valor de CCPR1L al PORTB

6.6 Mdulo UART en hardware (Comunicacin RS-232)


La forma ms simple de transferir datos entre el microcontrolador y otro dispositivo, ej. Computador PC u otro microcontrolador, es la comunicacin RS-232 (tambin referida como EIA RS-232C V.24).

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

Capitul 7: Ejemplos para desplegar datos


Introduccin 7.1 Diodo LED 7.2 Display de 7-Segmentos 7.3 Display LCD, Interfaces de 4-bit y 8-bit 7.4 LCD Grfico 7.5 Sealizacin por Sonido

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.

7.1 Diodo LED


Sin duda alguna uno de los componentes ms usados en electrnica es el diodo led (Light Emitting Diode (Diodo Emisor de Luz)). Algunas de las caractersticas de los diodos led incluyen: tamao, forma, color, voltaje de trabajo (voltaje de diodo) Vd y corriente de diodo Id. Los leds pueden tener bases de formas circulares, rectangulares, triangulares, aunque los fabricantes de estos componentes pueden producir cualquier forma requerida para propsitos especficos. El tamao, es decir el dimetro para leds de base circular, tiene un rango de 3 a 12 mm, siendo los tamaos de 3 5 mm los ms comnmente utilizados. Los colores ms comunes incluyen al rojo, amarillo, verde, naranja, azul, etc. El voltaje de trabajo es de 1.7V para el rojo, 2.1V para el verde y 2.3 para el naranja. Este voltaje puede ser superior dependiendo del fabricante. Normalmente, la corriente Id a travs del led es de 10mA,

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.

Led se enciende con un 1 lgico

Led se enciende Con un 0 lgico

Los leds estn conectados al puerto B y se encienden con un 1 lgico

El siguiente ejemplo conmuta los leds en el puerto B cada segundo.


program LEDs_Parpadeando main: TRISB = 0 PORTB = %11111111 Delay_ms(1000) PORTB = %00000000 Delay_ms(1000) goto main end.

' ' ' ' ' '

PORTB configurado como salida Encender leds en PORTB Esperar 1 segundo Apagar leds en PORTB Esperar 1 segundo Bucle infinito

7.2 Display de 7-Segmentos


Los dgitos de 7-segmentos representan una forma ms avanzada de comunicacin visual. El nombre proviene de los 7 leds (existe un octavo led para mostrar el punto (.)) conectados para formar los dgitos decimales del 0 al 9. La apariencia de un dgito de 7-segmentos se muestra en la figura.

Hacia el pin del microcontrolador que controla este segmento

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

' Habilitar display

Digito de unidades

do for i = 0 to 9 PORTB = mask(i) Delay_ms(1000) next i loop until false end.

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

Dgito Seg. h Seg. g Seg. f Seg. e Seg. d Seg. c Seg. b Seg. a

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)

' Contar desde 0 a 99 ' Preparar digito de unidades

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.

7.3 Display LCD, Interfaces de 4-bit y 8-bit


Una de las mejores soluciones para dispositivos que requieren visualizar datos es el Display de Cristal Lquido (LCD) inteligente. Este tipo de display consiste en segmentos de puntos de 7x5 ordenados en filas. Una fila puede consistir de 8, 16, 20, 40 segmentos, y el display LCD puede tener 1, 2, 4 filas.

Ejemplo de conexin a un display LCD

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

' Imprimir texto en el LCD

7.4 LCD Grfico


El LCD grfico (GLCD) ms comnmente usado tiene una resolucin de 128x64 pixeles. Esto permite crear mensajes visuales ms elaborados que los que puede proveer un LCD, involucrando dibujos y mapas de bits. La siguiente figura muestra la conexin en hardware del GLCD con la inicializacin por omisin (usando la rutina GLCD_LCD_Init); si requieres una configuracin de pines diferente, refirete a la rutina GLCD_LCD_Config.

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

' Para microcontroladores PIC18 ' Libreria requerida

= = = = = =

0 0 0 0 0 0 ' configuracion por omision

GLCD_LCD_Init(PORTC, PORTD) GLCD_Set_Font(FONT_NORMAL1) while true GLCD_Clear_Screen

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.

7.5 Sealizacin por Sonido


Algunas aplicaciones requieren la sealizacin por sonido en adicin a la visual o en vez de esta. Se usa comnmente para alertar o anunciar la culminacin de algn proceso de largo consumo de tiempo. La informacin presentada por este medio es relativamente simple, pero aliviana al usuario el tener que estar monitoreando constantemente el display o los sintonizadores. La librera de sonido de BASIC facilita la generacin y salida de seales sonoras por un puerto especfico. Presentaremos una demostracin simple utilizando un parlante piezo-mtrico conectado al puerto del microcontrolador.

program Sound

' Los siguientes 3 tonos son calculados de un cristal de 4MHz

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)

' Periodo = 2ms <=> 500Hz, Duracion = 200 periodos

' Period0 = 1.8ms <=> 555Hz

' Periodo = 1.6ms <=> 625Hz

' Tocar una melodia

' Conectar parlante entre los pins RB2 y GND

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 boton en RB7 ' se toca el Tono1

' Esperar a que el boton sea liberado

' Si se presiona el botn RB4 ' se toca la melodia ' Esperar a que el boton sea liberado

Capitul 8: Ejemplos con Memoria y Medios de Almacenamiento


Introduccin 8.1 Memoria EEPROM 8.2 Memoria Flash 8.3 Flash compacta

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.

8.1 Memoria EEPROM


Los datos usados por el microcontrolador son almacenados en la memoria RAM mientras la fuente de energa est presente. Si necesitamos mantener los datos para un uso posterior, debe ser almacenada en una memoria permanente. Un dispositivo EEPROM (E2PROM) (Electrically Erasable Programmable Read-Only Memory) es un chip de almacenamiento no-voltil, comnmente usado en los microcontroladores PIC para ese propsito. Una EEPROM puede ser programada y borrada muchas veces de manera elctrica puede ser borrada y reprogramada una cierta cantidad de veces, dentro de un rango de 100 000 a 1 000 000, pero puede ser leda un nmero ilimitado de veces.

8.1.1 EEPROM interna


Algunos microcontroladores PIC poseen una EEPROM interna que les permite almacenar informacin sin ningn hardware externo adicional. BASIC tiene una librera para trabajar con la EEPROM interna que hace que la escritura y lectura de los datos sea muy sencilla. La funcin de librera EEPROM_Read lee datos desde una direccin especificada, mientras que el procedimiento EEPROM_Write escribe un dato en la direccin especificada.

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.

8.1.2 EEPROM Serial


Ocasionalmente, nuestros requerimientos excedern la capacidad de la EEPROM interna del PIC. Cuando necesitamos almacenar una cantidad mayor de datos obtenidos por el PIC, tenemos la opcin de usar una EEPROM serial externa. Serial significa que la EEPROM utiliza uno de los protocolos seriales (I2C, SPI, microwire) para la comunicacin con el microcontrolador. En nuestro ejemplo, trabajaremos con un EEPROM de la familia 24Cxx que usa dos lneas y el protocolo I2C para la comunicacin con el MCU.

Direccin I2C de la EEPROM es $A2

Ejemplo de conexin de una EEPROM SERIAL

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

8.2 Memoria Flash


La memoria Flash es una forma de EEPROM que permite que mltiples localizaciones de memoria sean borradas o escritas en una sola operacin de programacin. La EEPROM normal solo permite que una localizacin sea borrada o escrita a la vez, lo que significa que la Flash puede operar a velocidades superiores cuando el sistema requiere leer y escribir a diferentes localizaciones al mismo tiempo. La memoria Flash almacena la informacin en un chip de silicio de manera tal que no necesita alimentacin para mantener la informacin en el chip. Esto significa que si apagamos la fuente de alimentacin, la informacin es retenida en el chip sin consumir energa alguna. Adicionalmente, Flash ofrece tiempos de acceso a lectura rpidos y resistencia a vibraciones y choques de estado-slido. Estas caractersticas hacen que sea muy popular para aplicaciones con microcontroladores y tambin para aplicaciones que requieren almacenamiento en dispositivos alimentados por batera como ser los telfonos celulares. Muchos microcontroladores PIC modernos utilizan memoria Flash, usualmente en adicin al almacenaje en chip de EEPROM normal. Por lo tanto, BASIC provee una librera para acceder y trabajar

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 configurado como salida ' Inicializar arreglo

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

' Indicar que no existe error

Para la familia PIC16, el cdigo correspondiente es el siguiente:


program Prueba_flash_pic16 const FLASH_ERROR = $FF const FLASH_OK = $AA dim toRead as word dim i as word main: TRISB = 0 for i = 0 to 63 Flash_Write(i+$0A00, i) next I PORTB = 0 toRead = FLASH_ERROR for i = 0 to 63 toRead = Flash_Read($0A00+i) if toRead <> i then i = i + $0A00 PORTB = FLASH_ERROR Delay_ms(500) else PORTB = FLASH_OK end if next i end. ' Para PIC16

' 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

' Indicar que no existe error

8.3 Flash Compacta


Flash Compacta (Compact Flash) (CF) originalmente fue un tipo de dispositivo de almacenaje de datos, usado en dispositivos electrnicos porttiles. Como dispositivo de almacenaje, tpicamente utiliza memoria Flash en un encapsulado estandarizado. En la actualidad, este formato fsico es utilizado en computadores porttiles, cmaras digitales, y una gran variedad de otros dispositivos, incluyendo computadores de escritorio. Una gran capacidad (8MB ~ 8GB, y ms) y un excelente tiempo de acceso (tpicamente de algunos microsegundos) hacen que la CF sea muy atractiva para aplicaciones con microcontroladores. Los dispositivos de memoria Flash son no-voltiles y de estado slido, siendo, por lo tanto, ms robustos que los discos duros. Consumen solamente cerca del 5% de la energa requerida por los discos pequeos. Operan con 3.3 volts 5 volts, y pueden ser intercambiados de sistema a sistema. Las tarjetas CF pueden soportar cambios extremadamente rpidos en temperatura versiones industriales de tarjetas de memoria Flash pueden operar en un rango de -45C a +85C. BASIC incluye una librera para acceder y manejar datos en una tarjeta CF. En esta, los datos estn divididos en sectores. Un sector tiene usualmente 512 bytes (algunos modelos antiguos tienen sectores de 256B). Las operaciones de Lectura (Read) y Escritura (Write) no son realizadas directamente, sino sucesivamente a travs de un buffer de 512B. Estas rutinas estn configuradas para usarse con tarjetas CF que estn formateadas con un sistema de archivos FAT16 y FAT32. Nota: Las rutinas para manejo de archivos (CF_File_Write_Init, CF_File_Write_Byte, CF_File_Write_Complete ) solamente pueden ser usadas con el sistema de archivos FAT16, y nicamente con la familia PIC18!

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

sub procedure Inicio TRISC = 0

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:

program Prueba_CF dim i as word

main: TRISC = 0 CF_Init_Port(PORTB,PORTD) do nop loop until CF_Detect(PORTB) = true

'PORTC configurado como salida 'Inicializar puertos

'Esperar hasta que se inserte CF

Delay_ms(500) CF_Write_Init(PORTB, PORTD, 590, 1)

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

Capitul 9: Ejemplos de Comunicacin


Introduccin 9.1 USART y UART por Software 9.2 SPI y SPI por Software 9.3 I2C e I2C por Software 9.4 Cdigo Manchester 9.5 RS485 9.6 OneWire 9.7 CAN & CANSPI

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.

9.1 USART y UART por Software 9.1.1 USART


USART significa Transmisor/Receptor Sncrono/Asncrono Universal (Universal Synchronous/Asynchronous Receiver/Transmitter). Puede sonar misterioso, pero en realidad es el dispositivo de comunicacin ms frecuentemente usado hoy en da a travs del mundo de los computadores: Microcontroladores, celulares (algunos), lectores de cdigo de barras, PCs Primero veamos que significan cada una de esas palabras: Universal significa que puede ser usada por un amplio conjunto de dispositivos Sncrono/Asncrono indica si es que los dispositivos que desean comunicarse entre ellos requieren no, una lnea de sincronizacin externa (Reloj (Clock)). Este dispositivo presente en la mayora de los PICs, puede comunicarse de ambas formas. El modo Asncrono (sin lnea de Reloj) es ms fcil de implementar, aunque por lo general es ms lento que el modo Sncrono. Es tambin la forma ms antigua de comunicacin las primeras versiones de PICs no tenan la posibilidad de trabajar en el modo sncrono, por lo que los dispositivos se denominaban UART (sin la S) Receptor/Transmisor significa que este dispositivo puede recibir y enviar (transmitir) datos simultneamente. Tambin se denomina comunicacin de doble va dplex.

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.

9.1.2 UART por Software


Si ya has utilizado el USART en hardware y necesitas otro canal de comunicacin (por ejemplo si deseas comunicarte con dos PCs) o quizs no tienes un dispositivo USART (en lo PICs ms pequeos), entonces puedes usar el UART por software. Tal y como implica su nombre, utiliza un conjunto de rutinas en

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.

' leer dato recibido ' enviarlo de nuevo al UART

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:

9.2 SPI y SPI por software


SPI o Interface Serial de Perifricos (Serial Peripheral Interface) es probablemente el estilo de comunicacin ms simple entre tu PIC y el mundo exterior. Sin embargo est limitado a la comunicacin entre chips, lo que significa que los cables deben ser tan cortos como sea posible. La idea bsica es permitir que dos chips intercambien informacin de una manera maestro-esclavo (master-slave), el maestro inicializa la comunicacin, selecciona con que esclavo se va a comunicar, y provee un reloj (clock) para la sincronizacin. En la mayora de los casos el PIC ser el maestro y pedir datos a los otros chips menos inteligentes, les dar comandos para ejecutar, etc. El siguiente ejemplo usa las rutinas SPI del BASIC para acceder al chip max7219, el cual es usado para controlar hasta ocho displays de 7 segmentos. Todo esto se logra usando un nico pin del PIC (RC1) para la comunicacin. Para propsitos de seleccin del chip y sincronizacin de reloj, los pins SD0, SDI y SCK en ambos PICs tambin deben estar inter-conectados.
program SPI include "m7219.pbas" dim i as byte main: SPI_Init TRISC = TRISC and $FD max7219_init PORTC.1 = 0 SPI_Write(1) SPI_Write(7) PORTC.1 = 0 end.

' Configuracion estandard ' ' ' ' ' Inicializar max7219 Seleccionar max7219 Enviar direccion (1) al max7219 Enviar datos (7) al max7219 Desactivar max7219

Y el mdulo m7219.bas tiene la siguiente codificacin:


module m7219 sub procedure max7219_init PORTC = PORTC and $FD ' SPI_Write($09) ' SPI_Write($FF) PORTC = PORTC or 2 ' PORTC = PORTC and $FD ' SPI_Write($0A) SPI_Write($0F) ' PORTC = PORTC or 2 ' PORTC = PORTC and $FD ' SPI_Write($0B) SPI_Write($07) ' PORTC = PORTC or 2 ' PORTC = PORTC and $FD ' SPI_Write($0C) SPI_Write($01) ' PORTC = PORTC or 2 ' PORTC = PORTC and $FD ' SPI_Write($00) SPI_Write($FF) ' PORTC = PORTC or 2 ' end sub end.

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

9.3 I2C e I2C por software


BASIC tiene una librera para trabajar con la EEPROM interna que hace que la escritura y lectura de los datos sea muy sencilla. La funcin de librera EEPROM_Read lee datos desde una direccin especificada, mientras que el procedimiento EEPROM_Write escribe un dato en la direccin especificada. 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.

Anda mungkin juga menyukai