Anda di halaman 1dari 478

Capitulo 1: El mundo de los microcontroladores

La situacin actual en el campo de los microcontroladores se ha producido


gracias al desarrollo de la tecnologa de fabricacin de los circuitos integrados.
Este desarrollo ha permitido construir las centenas de miles de transistores en un
chip. Esto fue una condicin previa para la fabricacin de un microprocesador. Las
primeras microcomputadoras se fabricaron al aadirles perifricos externos, tales
como memoria, lneas de entrada/salida, temporizadores u otros. El incremento
posterior de la densidad de integracin permiti crear un circuito integrado que
contena tanto al procesador como perifricos. As es cmo fue desarrollada la
primera

microcomputadora

en

un

solo

chip,

denominada

ms

tarde

microcontrolador.
1.1 Introduccin
1.2 NMEROS, NMEROS, NMEROS...
1.3 DETALLES IMPORTANTES
1.4 MICROCONTROLADORES PIC
1.1 INTRODUCCIN
Los principiantes en electrnica creen que un microcontrolador es igual a un
microprocesador. Esto no es cierto. Difieren uno del otro en muchos sentidos. La
primera y la ms importante diferencia es su funcionalidad. Para utilizar al
microprocesador en una aplicacin real, se debe de conectar con componentes
tales como memoria o componentes buses de transmisin de datos. Aunque el
microprocesador se considera una mquina de computacin poderosa, no est
preparado para la comunicacin con los dispositivos perifricos que se le
conectan. Para que el microprocesador se comunique con algn perifrico, se
deben utilizar los circuitos especiales. As era en el principio y esta prctica sigue
vigente en la actualidad.

Por otro lado, al microcontrolador se le disea de tal manera que tenga


todas las componentes integradas en el mismo chip. No necesita de otros
componentes especializados para su aplicacin, porque todos los circuitos
necesarios, que de otra manera correspondan a los perifricos, ya se encuentran
incorporados. As se ahorra tiempo y espacio necesario para construir un
dispositivo.
QUE PUEDEN HACER LOS MICROCONTROLADORES?
Para entender con ms facilidad las razones del xito tan grande de los
microcontroladores, vamos a prestar atencin al siguiente ejemplo. Hace unos 10
aos, disear un dispositivo electrnico de control de un ascensor de un edificio
de varios pisos era muy difcil, incluso para un equipo de expertos. Ha pensado
alguna vez en qu requisitos debe cumplir un simple ascensor? Cmo lidiar con
la situacin cuando dos o ms personas llaman al ascensor al mismo tiempo?
Cul llamada tiene la prioridad? Cmo solucionar las cuestiones de seguridad,
de prdida de electricidad, de fallos, de uso indebido? Lo que sucede despus de
resolver estos problemas bsicos es un proceso meticuloso de disear los
dispositivos adecuados utilizando un gran nmero de los chips especializados.
Este proceso puede tardar semanas o meses, dependiendo de la complejidad del

dispositivo. Cuando haya terminado el proceso, llega la hora de disear una placa
de circuito impreso y de montar el dispositivo.Un dispositivo enorme! Es otro
trabajo difcil y tardado. Por ltimo, cuando todo est terminado y probado
adecuadamente, pasamos al momento crucial y es cuando uno se concentra,
respira profundamente y enciende la fuente de alimentacin.
Esto suele ser el punto en el que la fiesta se convierte en un verdadero
trabajo

puesto

que

los

dispositivos

electrnicos

casi

nunca

funcionan

apropiadamente desde el inicio. Preprese para muchas noches sin dormir,


correcciones, mejoras... y no se olvide de que todava estamos hablando de cmo
poner en marcha un simple ascensor.
Cuando el dispositivo finalmente empiece a funcionar perfectamente y todo
el mundo est satisfecho, y le paguen por el trabajo que ha hecho, muchas
compaas de desarrollo estarn interesadas en su trabajo. Por supuesto, si tiene
suerte, cada da le traer una oferta de trabajo de un nuevo inversionista. Sin
embargo, si lo requieren para trabajar en el control de los elevadores de un nuevo
edificio que tiene cuatro pisos ms de los que ya maneja su sistema de control.
Sabe cmo proceder? Cree acaso que se pueden controlar las demandas de sus
clientes? Pensamos que usted va a construir un dispositivo universal que se
puede utilizar en los edificios de 4 a 40 pisos, una obra maestra de electrnica.
Bueno, incluso si usted consigue construir una joya electrnica, su inversionista le
esperarar delante de la puerta pidiendo una cmara en el ascensor o una msica
relajante en caso de fallo de ascensor. O un ascensor con dos puertas.
De todos modos, la ley de Murphy es inexorable y sin duda usted no podr
tomar ventaja a pesar de todos los esfuerzos que ha hecho. Por desgracia, todo lo
que se ha dicho hasta ahora sucede en la realidad. Esto es lo que dedicarse a la
ingeniera electrnica realmente significa. Es as como se hacan las cosas hasta
aparicin de los microcontroladores diseados - pequeos, potentes y baratos.
Desde ese momento su programacin dej de ser una ciencia, y todo tom otra
direccin...

El dispositivo electrnico capaz de controlar un pequeo submarino, una


gra o un ascensor como el anteriormente mencionado, ahora est incorporado
en un slo chip. Los microcontroladores ofrecen una amplia gama de aplicaciones
y slo algunas se exploran normalmente. Le toca a usted decidir qu quiere que
haga el microcontrolador y cargar un programa en l con las instrucciones
apropiadas. Antes de encender el dispositivo es recomendable verificar su
funcionamiento con ayuda de un simulador. Si todo funciona como es debido,
incorpore el microcontrolador en el sistema. Si alguna vez necesita cambiar,
mejorar o actualizar el programa, hgalo. Hasta cundo? Hasta quedar
satisfecho. Eso puede realizarse sin ningn problema.

Saba usted que todas las personas pueden ser clasificadas en uno de 10
grupos, en los que estn familiarizados con el sistema de numeracin binario y en
los que no estn familiarizados con l. Si no entendi lo anterior significa que
todava pertenece al segundo grupo. Si desea cambiar su estado, lea el siguiente
texto que describe brevemente algunos de los conceptos bsicos utilizados ms
tarde en este libro (slo para estar seguro de que estamos hablando en los
mismos trminos).
1.2 NMEROS, NMEROS, NMEROS...

La matemtica es una gran ciencia! Todo es tan lgico y simple... El


universo de los nmeros se puede describir con slo diez dgitos. No obstante,
realmente tiene que ser as? Necesitamos exactamente esos 10 dgitos? Por
supuesto que no, es slo cuestin del hbito. Acurdese de las lecciones de la
escuela. Por ejemplo, qu significa el nmero 764? Cuatro unidades, seis
decenas y siete centenas. Muy simple! Se podra expresar de una forma ms
desarrollada? Por supuesto que s: 4 + 60 + 700. An ms desarrollado? S: 4*1
+ 6*10 + 7*100. Podra este nmero parecer un poco ms cientfico? La
respuesta es s otra vez: 4*100 + 6*101 + 7*102. Qu significa esto realmente?
Por qu utilizamos exactamente estos nmeros 100, 101 y 102 ? Por qu es
siempre el nmero 10? Es porque utilizamos 10 dgitos diferentes (0, 1, 2...8, 9).
En otras palabras, es porque utilizamos el sistema de numeracin en base 10, es
decir el sistema de numeracin decimal.

SISTEMA DE NUMERACIN BINARIO


Qu pasara si utilizramos slo dos nmeros 0 y 1? Si slo pudiramos
afirmar (1) o negar (0) que algo existe. La respuesta es nada especial,
seguiramos utilizando los mismos nmeros de la misma manera que utilizamos
hoy en da, no obstante ellos pareceran un poco diferentes. Por ejemplo:
11011010.Cuntas

son

realmente

11011010

pginas

de

un

libro?

Para

entenderlo, siga la misma lgica como en el ejemplo anterior, pero en el orden


invertido. Tenga en cuenta que se trata de aritmtica con slo dos dgitos 0 y 1, es
decir, del sistema de numeracin en base 2 (sistema de numeracin binario).

Evidentemente, se trata del mismo nmero representado en dos sistemas


de numeracin diferentes. La nica diferencia entre estas dos representaciones
yace en el nmero de dgitos necesarios para escribir un nmero. Un dgito (2) se
utiliza para escribir el nmero 2 en el sistema decimal, mientras que dos dgitos
(1 y 0) se utilizan para escribir aquel nmero en el sistema binario. Ahora est de
acuerdo que hay 10 grupos de gente? Bienvenido al mundo de la aritmtica
binaria! Tiene alguna idea de dnde se utiliza?
Excepto en las condiciones de laboratorio estrictamente controladas, los
circuitos electrnicos ms complicados no pueden especificar con exactitud la
diferencia entre dos magnitudes (dos valores de voltaje, por ejemplo), si son
demasiado pequeos (ms pequeos que unos pocos voltios). La razn son los
ruidos elctricos y fenmenos que se presentan dentro de lo que llamamos
entorno de trabajo real (algunos ejemplos de estos fenmenos son los cambios
imprevisibles de la tensin de alimentacin, cambios de temperatura, tolerancia a
los valores de los componentes etc...). Imagnese una computadora que opera
sobre nmeros decimales al tratarlos de la siguiente manera: 0=0V, 1=5V,
2=10V, 3=15V, 4=20V... 9=45V!?
Alguien dijo bateras?
Una solucin mucho ms fcil es una lgica binaria donde 0 indica la
ausencia de voltaje, mientras que 1 indica la presencia de voltaje. Simplemente,
es fcil de escribir 0 o 1 en vez de no hay voltaje o hay voltaje. Mediante el
cero lgico (0) y uno lgico (1) la electrnica se enfrenta perfectamente y realiza

con facilidad todas las operaciones aritmticas. Evidentemente, se trata de


electrnica que en realidad aplica aritmtica en la que todos los nmeros son
representados con slo dos dgitos y donde slo es importante saber si hay voltaje
o no. Por supuesto, estamos hablando de electrnica digital.
SISTEMA DE NUMERACIN HEXADECIMAL
En el principio del desarrollo de las computadoras era evidente que a la
gente le costaba mucho trabajar con nmeros binarios. Por eso, se estableci un
nuevo sistema de numeracin, que utilizaba 16 smbolos diferentes. Es llamado el
sistema de numeracin hexadecimal. Este sistema est compuesto de 10 dgitos
a los que estamos acostumbrados (0, 1, 2, 3,... 9) y de seis letras del alfabeto A,
B, C, D, E y F. Cul es el propsito de esta combinacin aparentemente extraa?
Basta con mirar cmo todo en la historia de los nmeros binarios encaja
perfectamente para lograr una mejor comprensin del tema.

El mayor nmero que puede ser representado con 4 dgitos binarios es el


nmero 1111. Corresponde al nmero 15 en el sistema decimal. En el sistema
hexadecimal ese nmero se representa con slo un dgito F. Es el mayor nmero
de un dgito en el sistema hexadecimal. Se da cuenta de la gran utilidad de estas
equivalencias? El mayor nmero escrito con ocho dgitos binarios es a la vez el
mayor nmero de dos dgitos en el sistema hexadecimal. Tenga en cuenta que
una computadora utiliza nmeros binarios de 8 dgitos. Acaso se trata de una
casualidad?
CDIGO BCD
El cdigo BCD (Binary-Coded Decimal - Cdigo binario decimal) es un cdigo
binario utilizado para representar a los nmeros decimales. Se utiliza para que los

circuitos electrnicos puedan comunicarse con los perifricos utilizando el sistema


de numeracin decimal o bien utilizando el sistema binario dentro de su propio
mundo. Consiste en nmeros binarios de 4 dgitos que representan los primeros
diez dgitos (0, 1, 2, 3...8, 9). Aunque cuatro dgitos pueden hacer 16
combinaciones posibles en total, el cdigo BCD normalmente utiliza a las primeras
diez.
CONVERSIN DE SISTEMAS DE NMERACIN
El sistema de numeracin binario es el que utilizan los microcontroladores,
el sistema decimal es el que nos resulta ms comprensible, mientras que el
sistema hexadecimal presenta un balance entre los dos. Por eso, es muy
importante aprender cmo convertir los nmeros de un sistema de numeracin a
otro, por ejemplo, cmo convertir una serie de ceros y unos a una forma de
representacin comprensible para nosotros.
CONVERSIN DE NMEROS BINARIOS A DECIMALES
Los dgitos en un nmero binario tienen ponderaciones diferentes lo que
depende de sus posiciones dentro del nmero que estn representando. Adems,
cada dgito puede ser 1 o 0, y su ponderacin se puede determinar con facilidad
al contar su posicin empezando por la derecha. Para hacer una conversin de un
nmero binario a decimal es necesario multiplicar las ponderaciones con los
dgitos correspondientes (0 o 1) y sumar todos los resultados. La magia de la
conversin de un nmero binario a decimal funciona de maravilla... Tiene duda?
Veamos el siguiente ejemplo:

Cabe destacar que es necesario utilizar slo dos dgitos binarios para
representar a todos los nmeros decimales de 0 a 3. Por consiguiente, para
representar los nmeros de 0 a 7 es necesario utilizar tres dgitos binarios, para

representar los nmeros de 0 a 15 - cuatro dgitos etc. Dicho de manera sencilla,


el mayor nmero binario que se puede representar utilizando n dgitos se obtiene
al elevar la base 2 a la potencia n. Luego, al resultado se le resta 1. Por ejemplo,
si n=4:
24 - 1 = 16 - 1 = 15
Por consiguiente, al utilizar 4 dgitos binarios, es posible representar los
nmeros decimales de 0 a 15, que son 16 valores diferentes en total.
CONVERSIN DE NMEROS HEXADECIMALES A DECIMALES
Para realizar una conversin de un nmero hexadecimal a decimal, cada
dgito hexadecimal debe ser multiplicado con el nmero 16 elevado al valor de su
posicin. Por ejemplo:

CONVERSIN DE NMEROS HEXADECIMALES A BINARIOS


No es necesario realizar ningn clculo para convertir un nmero
hexadecimal a binario. Los dgitos hexadecimales se reemplazan simplemente por
los cuatro dgitos binarios apropiados. Ya que el dgito hexadecimal mximo es
equivalente al nmero decimal 15, es necesario utilizar cuatro dgitos binarios
para representar un dgito hexadecimal. Por ejemplo:

MARCAR LOS NMEROS

El sistema de numeracin hexadecimal, junto con los sistemas binario y


decimal, se consideran los ms importantes para nosotros. Es fcil realizar una
conversin de cualquier nmero hexadecimal a binario, adems es fcil de
recordarlo. Sin obstante, estas conversiones pueden provocar una confusin. Por
ejemplo, qu significa en realidad la sentencia: Es necesario contar 110
productos en una cadena de montaje? Dependiendo del sistema en cuestin
(binario, decimal o hexadecimal), el resultado podra ser 6, 110 o 272 productos,
respectivamente. Por consiguiente, para evitar equivocaciones, diferentes prefijos
y sufijos se aaden directamente a los nmeros. El prefijo $ o 0x as como el sufijo
h marca los nmeros en el sistema hexadecimal. Por ejemplo, el nmero
hexadecimal 10AF se puede escribir as: $10AF, 0x10AF o 10AFh. De manera
similar, los nmeros binarios normalmente obtienen el sufijo % o 0B. Si un nmero
no tiene ni sufijo ni prefijo se considera decimal. Desafortunadamente, esta forma
de marcar los nmeros no es estandarizada, por consiguiente depende de la
aplicacin concreta.
La siguiente es tabla comparativa que contiene los valores de nmeros 0255 representados

en tres sistemas

de numeracin diferentes. Esto es

probablemente la manera ms fcil de entender lgica comn aplicada a todos


los sistemas de numeracin.

NMEROS NEGATIVOS
Como ya hemos visto, para escribir un nmero negativo en matemticas,
basta con aadirle el prefijo - (signo menos). Sin embargo, en la programacin,
al acabarse el proceso de la compilacin, se quedan slo los nmeros binarios,
volvindose las cosas ms complicadas. Se utilizan slo dos dgitos - 0 y 1,
mientras que todos los dems nmeros, smbolos y signos se forman por medio
de las combinaciones de estos dos dgitos. En el caso de los nmeros negativos,
la solucin es la siguiente: En los nmeros negativos, el bit ms significativo (el
bit del extremo izquierdo) representa el signo del nmero (donde 0 ser positivo y
1 negativo). En el caso de un nmero de 8 bits, para representar un valor
numrico slo quedan 7 bits. De acuerdo a este tipo de codificacin el nmero
+127 es el mayor nmero positivo con signo que se puede representar con 8 bits.
Asimismo, hay cero (0) positivo y negativo (refirase a la tabla de la derecha). La
siguiente pregunta sera: Cmo es posible saber de qu nmero se trata? Por
ejemplo, si ponemos el nmero 10000001, es -1 o 129? No se preocupe, de eso
se encarga el compilador. sta es la razn por la que se declaran variables al
escribir el programa. Bueno, de eso vamos a hablar a continuacin.

BIT
La teora dice que un bit es la unidad bsica de informacin...Vamos a
olvidarlo por un momento y demostrar qu es eso en la prctica. La respuesta es nada especial- un bit es un slo dgito binario. Similar a un sistema de numeracin
decimal en el que los dgitos de un nmero no tienen la misma ponderacin (por
ejemplo, los dgitos en el nmero 444 son los mismos pero tienen los valores
diferentes), el significado de un bit depende de la posicin que tiene en nmero
binario. En este caso no tiene sentido hablar de unidades, centenas etc. en los
nmeros binarios, sus dgitos se denominan el bit cero (el primer bit a la derecha),
el primer bit (el segundo bit a la derecha) etc. Adems, ya que el sistema binario
utiliza solamente dos dgitos (0 y 1), el valor de un bit puede ser 0 o 1.
No se confunda si se encuentra con un bit que tiene el valor 4, 16 o 64. Son
los valores representados en el sistema decimal. Simplemente, nos hemos
acostumbrado tanto a utilizar los nmeros decimales que estas expresiones
llegaron a ser comunes. Sera correcto decir por ejemplo, el valor del sexto bit en
cualquier nmero binario equivale al nmero decimal 64. Pero todos somos
humanos y los viejos hbitos mueren difcilmente. Adems, cmo le suena
nmero uno-uno-cero-uno-cero...?
BYTE
Un byte consiste en 8 bits colocados uno junto al otro. Si un bit es un dgito,
es lgico que los bytes representen los nmeros. Todas las operaciones

matemticas se pueden realizar por medio de ellos, como por medio de los
nmeros decimales comunes. Similar a los dgitos de cualquier nmero, los dgitos
de un byte no tienen el mismo significado. El bit del extremo izquierdo tiene la
mayor ponderacin, por eso es denominado el bit ms significativo (MSB). El bit
del extremo derecho tiene la menor ponderacin, por eso es denominado el bit
menos significativo (LSB). Puesto que los 8 dgitos de un byte se pueden combinar
de 256 maneras diferentes, el mayor nmero decimal que se puede representar
con un byte es 255 (una combinacin representa un cero).
Un nibble o un cuarteto representa una mitad de byte. Dependiendo de la
mitad del nmero en cuestin (izquierda o derecha), se les denomina nibbles
altos o bajos, respectivamente.

Usted seguramente ha pensado alguna vez en cmo es la electrnica


dentro de un circuito integrado digital, un microcontrolador o un microprocesador.
Cmo son los circuitos que realizan las operaciones matemticas complicadas y
toman decisiones? Saba que sus esquemas, aparentemente complicadas
consisten en slo unos pocos elementos diferentes, denominados circuitos lgicos
o compuertas lgicas?
1.3 DETALLES IMPORTANTES
El funcionamiento de estos elementos es basado en los principios
establecidos por el matemtico britnico George Boole en la mitad del siglo 19 es decir, antes de la invencin de la primera bombilla! En breve, la idea principal
era de expresar las formas lgicas por medio de las funciones algebraicas. Tal
idea pronto se transform en un producto prctico que se convirti ms tarde en
lo que hoy en da conocemos como circuitos lgicos Y (AND), O (OR) o NO (NOT).
El principio de su funcionamiento es conocido como algebra de Boole.

CIRCUITOS LGICOS
Algunas instrucciones de programa utilizadas por un microcontrolador
funcionan de la misma manera que las compuertas lgicas, pero en forma de
comandos. A continuacin vamos a explicar el principio de su funcionamiento.
COMPUERTA Y (AND)

Una compuerta lgica Y dispone de dos o ms entradas y de una salida.


En este caso la compuerta utilizada dispone de slo dos entradas. Un uno lgico
(1) aparecer en su salida slo en caso de que ambas entradas (A Y B) sean
llevadas a alto (1). La tabla a la derecha es la tabla de verdad que muestra la
relacin entre las entradas y salidas de la compuerta. El principio de
funcionamiento es el mismo cuando la compuerta disponga de ms de dos
entradas: la salida proporciona un uno lgico (1) slo si todas las entradas son
llevadas a alto (1).

Cualquier otra combinacin de voltajes de entrada proporcionar un cero


lgico (0) en su salida. Utilizada en el programa, la operacin Y lgico es realizada
por una instruccin de programa, de la que vamos a hablar ms tarde. Por ahora
basta con conocer que Y lgico en un programa se refiere a la realizacin de este
tipo de operacin sobre los bits correspondientes de dos registros diferentes.
COMPUERTA O (OR)

De manera similar, la compuerta O tambin dispone de dos o ms entradas


y de una salida. Si la compuerta dispone de slo dos entradas, es aplicable lo
siguiente: la salida proporciona un uno lgico (1) si una u otra entrada (A o B) es
llevada a alto (1). En caso de que la compuerta O disponga de ms de dos
entradas, es aplicable lo siguiente: La salida proporciona un uno lgico (1) si por
lo menos una entrada es llevada a alto (1). Si todas las entradas estn a cero
lgico (0), la salida estar a cero lgico (0) tambin.

En un programa, la operacin O lgico se realiza de la misma manera que la


operacin Y.

COMPUERTA NO (NOT)
La compuerta lgica NO dispone de una sola entrada y una sola salida, por
lo que funciona muy simplemente. Cuando un cero lgico (0) aparezca en su
entrada, la salida proporciona un uno lgico (1) y viceversa. Esto significa que
esta compuerta invierte las seales por s mismas y por eso es denominada
inversor.

En el programa la operacin lgica NO se realiza sobre un byte. El resultado


es un byte con los bits invertidos. Si los bits de un byte se consideran nmero, el
valor invertido es un complemento a ese nmero. El complemento de un nmero
es el valor que se aade al nmero hasta llegar al mayor nmero binario de 8
dgitos. En otras palabras, la suma de un dgito de 8 nmeros y de su
complemento es siempre 255.
COMPUERTA XOR (O EXCLUSIVA)

La compuerta XOR (O EXCLUSIVA) es un poco complicada en comparacin


con

las

dems.

Representa

una

combinacin

de

todas

las

compuertas

anteriormente descritas. La salida proporciona un uno lgico (1) slo si sus


entradas estn en estados lgicos diferentes.

En el programa, esta operacin se utiliza con frecuencia para comparar dos


bytes. La resta se puede utilizar con el mismo propsito (si el resultado es 0, los
bytes son iguales). A diferencia de la resta, la ventaja de esta operacin lgica es
que no es posible obtener los resultados negativos.
REGISTROS
Un registro o una celda de memoria es un circuito electrnico que puede
memorizar el estado de un byte.

REGISTROS SFR
A diferencia de los registros que no tienen ninguna funcin especial y
predeterminada, cada microcontrolador dispone de un nmero de registros de
funciones especiales (SFR), con la funcin predeterminada por el fabricante. Sus
bits estn conectados a los circuitos internos del microcontrolador tales como
temporizadores, convertidores A/D, osciladores entre otros, lo que significa que
directamente

manejan

el

funcionamiento

de

estos

circuitos,

sea

del

microcontrolador. Imagnese ocho interruptores que manejan el funcionamiento

de un circuito pequeo dentro del microcontrolador. Los registros SFR hacen


exactamente lo mismo.

En otras palabras, el estado de los bits de registros se fija dentro de


programa,

los

registros

SFR

dirigen

los

pequeos

circuitos

dentro

del

microcontrolador, estos circuitos se conectan por los pines del microcontrolador a


un dispositivo perifrico utilizado para... Bueno, depende de usted.
PUERTOS DE ENTRADA/SALIDA (E/S)
Para hacer til un microcontrolador, hay que conectarlo a un dispositivo
externo, o sea, a un perifrico. Cada microcontrolador tiene uno o ms registros
(denominados puertos) conectados a los pines en el microcontrolador. Por qu se
denominan como puertos de entrada/salida? Porque usted puede cambiar la
funcin de cada pin como quiera. Por ejemplo, usted desea que su dispositivo
encienda y apague los tres seales LEDs y que simultneamente monitoree el
estado lgico de 5 sensores o botones de presin. Uno de los puertos debe estar
configurado de tal manera que haya tres salidas (conectadas a los LEDs) y cinco
entradas (conectadas a los sensores). Eso se realiza simplemente por medio de
software, lo que significa que la funcin de algn pin puede ser cambiada durante
el funcionamiento.

Una de las caractersticas ms importantes de los pines de entrada/salida


(E/S) es la corriente mxima que pueden entregar/recibir. En la mayora de los
microcontroladores la corriente obtenida de un pin es suficiente para activar un
LED u otro dispositivo de baja corriente (10-20mA). Mientras ms pines de E/S
haya, ms baja es la corriente mxima de un pin. En otras palabras, todos los
puertos de E/S comparten la corriente mxima declarada en la hoja de
especificacin tcnica del microprocesador.
Otra caracterstica importante de los pines es que pueden disponer de los
resistores pull-up. Estos resistores conectan los pines al polo positivo del voltaje
de la fuente de alimentacin y su efecto se puede ver al configurar el pin como
una entrada conectada a un interruptor mecnico o a un botn de presin. Las
ltimas versiones de los microcontroladores tienen las resistencias pull-up
configurables por software.
Cada puerto de E/S normalmente est bajo el control de un registro SFR
especializado, lo que significa que cada bit de ese registro determina el estado del
pin correspondiente en el el microcontrolador. Por ejemplo, al escribir un uno
lgico (1) a un bit del registro de control (SFR), el pin apropiado del puerto se
configura automticamente como salida. Eso significa que el voltaje llevado a ese
pin se puede leer como 0 o 1 lgico. En caso contrario, al escribir 0 al registro
SFR, el pin apropiado del puerto se configura como salida. Su voltaje (0V o 5V)
corresponde al estado del bit apropiado del registro del puerto.
UNIDAD DE MEMORIA

La unidad de memoria es una parte del microcontrolador utilizada para


almacenar los datos. La manera ms fcil de explicarlo es compararlo con un
armario grande con muchos cajones. Si marcamos los cajones claramente, ser
fcil acceder a cualquiera de sus contenidos al leer la etiqueta en la parte
delantera del cajn.

De manera similar, cada direccin de memoria corresponde a una localidad


de memoria. El contenido de cualquier localidad se puede leer y se le puede
acceder al direccionarla. La memoria se puede escribir en la localidad o leer.
Hay varios tipos de memoria dentro del microcontrolador:
MEMORIA ROM (READ ONLY MEMORY) - MEMORIA DE SLO LECTURA
La memoria ROM se utiliza para guardar permanentemente el programa que
se est ejecutando. El tamao de programa que se puede escribir depende del
tamao de esta memoria. Los microcontroladores actuales normalmente utilizan
el direccionamiento de 16 bits, que significa que son capaces de direccionar hasta
64 Kb de memoria, o sea 65535 localidades. Por ejemplo, si usted es principiante,
su programa exceder pocas veces el lmite de varios cientos de instrucciones.
Hay varios tipos de memoria ROM.
Rom de mscara (enmascarada) - MROM

La ROM enmascarada es un tipo de ROM cuyo contenido es programado por


el fabricante. El trmino de mscara viene del proceso de fabricacin, donde las
partes del chip se plasman en las mascaras utilizadas durante el proceso de
fotolitografa. En caso de fabricacin de grandes series, el precio es muy bajo.
Olvide la idea de modificarla...

OTP ROM (One Time Programmable ROM) - ROM programable una sola
vez
La memoria programable una sola vez permite descargar un programa en el
chip, pero como dice su nombre, una sola vez. Si se detecta un error despus de
descargarlo, lo nico que se puede hacer es descargar el programa correcto en
otro chip.
UV EPROM (UV Erasable Programmable ROM) - ROM programable
borrable por rayos ultravioleta

El encapsulado de este microcontrolador tiene una ventana reconocible en


la parte alta. Eso permite exponer la superficie del chip de silicio a la luz de
ultravioleta y borrar el programa completamente en varios minutos. Luego es
posible descargar un nuevo programa en l.
La instalacin de esta ventana es complicada, lo que por supuesto afecta al
precio. Desde nuestro punto de vista, desgraciadamente, de manera negativa...
Memoria Flash
Este tipo de memoria se invent en los aos 80 en los laboratorios de la
compaa INTEL, como forma desarrollada de la memoria UV EPROM. Ya que es
posible escribir y borrar el contenido de esta memoria prcticamente un nmero
ilimitado de veces, los microcontroladores con memoria Flash son perfectos para
estudiar, experimentar y para la fabricacin en pequea escala. Por la gran
popularidad de esta memoria, la mayora de los microconroladores se fabrican

con tecnologa flash hoy en da. Si usted va a comprar un microcontrolador, ste


es en definitiva la opcin perfecta!
MEMORIA RAM (RANDOM ACCESS MEMORY) - MEMORIA DE ACCESO
ALEATORIO
Al apagar la fuente de alimentacin, se pierde el contenido de la memoria
RAM. Se utiliza para almacenar temporalmente los datos y los resultados
inmediatos creados y utilizados durante el funcionamiento del microcontrolador.
Por ejemplo, si el programa ejecuta la adicin (de cualquier cosa) es necesario
tener un registro que representa lo que se llama suma en vida cotidiana. Con tal
propsito, uno de los registros de la RAM es denominado suma y se utiliza para
almacenar los resultados de la adicin.
MEMORIA EEPROM (ELECTRICALLY ERASABLE PROGRAMMABLE ROM) ROM PROGRAMABLE Y BORRABLE ELCTRICAMENTE
El contenido de la EEPROM se puede cambiar durante el funcionamiento
(similar a la RAM), pero se queda permanentemente guardado despus de la
prdida de la fuente de alimentacin (similar a la ROM). Por lo tanto, la EEPROM
se utiliza con frecuencia para almacenar los valores creados durante el
funcionamiento, que tienen que estar permanentemente guardados. Por ejemplo,
si usted ha diseado una llave electrnica o un alarma, sera estupendo permitir
al usuario crear e introducir una contrasea por su cuenta. Por supuesto, la nueva
contrasea tiene que estar guardada al apagar la fuente de alimentacin. En tal
caso una solucin perfecta es el microcontrolador con una EEPROM embebida.
INTERRUPCIN
La mayora de programas utilizan interrupciones durante ejecucin de
programa regular. El propsito del microcontrolador generalmente consiste en
reaccionar a los cambios en su entorno. En otras palabras, cuando ocurre algo, el
microcontrolador reacciona de alguna manera... Por ejemplo, al apretar el botn
del mando a distancia, el microcontrolador lo registra y responde al comando

cambiando de canal, subiendo o bajando el volumen etc. Si el microcontrolador


pasar la mayora del tiempo comprobando varios botones sin parar - las horas,
los das, esto no sera nada prctico.
Por lo tanto, el microcontrolador aprendi un truco durante su evolucin.
En vez de seguir comprobando algn pin o bit, el microconrolador deja su trabajo
de esperar a un experto que reaccionar slo en caso de que suceda algo
digno de atencin.
La seal que informa al procesador central acerca de tal acontecimiento se
denomina INTERRUPCIN.
UNIDAD CENTRAL DE PROCESAMIENTO (CENTRAL PROCESSOR UNIT CPU)
Como indica su nombre, esto es una unidad que controla todos los procesos
dentro del microcontrolador. Consiste en varias unidades ms pequeas, de las
que las ms importantes son:
Decodificador

de

instrucciones

es

la

parte

que

descodifica

las

instrucciones del programa y acciona otros circuitos basndose en esto. El


conjunto de instrucciones que es diferente para cada familia de
microcontrolador expresa las capacidades de este circuito;
Unidad lgica aritmtica (Arithmetical Logical Unit - ALU) realiza
todas las operaciones matemticas y lgicas sobre datos; y
Acumulador o registro de trabajo. Es un registro SFR estrechamente
relacionado con el funcionamiento de la ALU. Es utilizado para almacenar
todos los datos sobre los que se debe realizar alguna operacin (sumar,
mover).

Tambin

almacena

los

resultados

preparados

para

el

procesamiento futuro. Uno de los registros SFR, denominado Registro


Status (PSW), est estrechamente relacionado con el acumulador. Muestra

el estado de un nmero almacenado en el acumulador (el nmero es


mayor o menor que cero etc.) en cualquier instante dado.

BUS
El bus est formado por 8, 16 o ms cables. Hay dos tipos de buses: el bus
de direcciones y el bus de datos. El bus de direcciones consiste en tantas lneas
como sean necesarias para direccionar la memoria. Se utiliza para transmitir la
direccin de la CPU a la memoria. El bus de datos es tan ancho como los datos, en
este caso es de 8 bits o lneas de ancho. Se utiliza para conectar todos los
circuitos dentro del microcontrolador.
COMUNICACIN EN SERIE
La conexin paralela entre el microcontrolador y los perifricos a travs de
los puertos de entrada/salida es una solucin perfecta para las distancias cortas hasta varios metros. No obstante, en otros casos cuando es necesario establecer
comunicacin entre dos dispositivos a largas distancias no es posible utilizar la
conexin paralela. En vez de eso, se utiliza la conexin en serie.
Hoy en da, la mayora de los microcontroladores llevan incorporados varios
sistemas diferentes para la comunicacin en serie, como un equipo estndar. Cul
de estos sistemas se utilizar en un caso concreto, depende de muchos factores,
de los que ms importantes son:
Con cuntos dispositivos el microcontrolador tiene que intercambiar los
datos?
Cul es la velocidad del intercambio de datos obligatoria?

Cul es la distancia entre los dispositivos?


Es necesario transmitir y recibir los datos simultneamente?

Una de las cosas ms importantes en cuanto a la comunicacin en serie es


el Protocolo que debe ser estrictamente observado. Es un conjunto de reglas que
se aplican obligatoriamente para que los dispositivos puedan interpretar
correctamente los datos que intercambian mutuamente. Afortunadamente, los
microcontroladores se encargan de eso automticamente, as que el trabajo de
programador/usuario es reducido a la escritura y lectura de datos.
VELOCIDAD DE TRANSMISIN SERIAL
La velocidad de transmisin serial (baud rate) es el trmino utilizado para
denotar el nmero de bits transmitidos por segundo [bps]. Fjese que este
trmino se refiere a bits, y no a bytes! El protocolo normalmente requiere que
cada byte se transmita junto con varios bits de control. Eso quiere decir que un
byte en un flujo de datos serial puede consistir en 11 bits. Por ejemplo, si
velocidad de transmisin serial es 300 bps un mximo de 37 y un mnimo de 27
bytes se pueden transmitir por segundo.
Los sistemas de comunicacin serial ms utilizados son:
I2C (INTER INTEGRATED CIRCUIT) - CIRCUITO INTER-INTEGRADO

Circuito inter-integrado es un sistema para el intercambio de datos serial


entre los microcontroladores y los circuitos integrados especializados de
generacin. Se utiliza cuando la distancia entre ellos es corta (el receptor y el
transmisor estn normalmente en la misma placa de circuito impreso). La
conexin se establece por medio de dos lneas - una se utiliza para transmitir los
datos, mientras que la otra se utiliza para la sincronizacin (la seal de reloj).
Como se muestra en la figura, un dispositivo es siempre el principal (master maestro), el que realiza el direccionamiento de un chip subordinado (slave esclavo) antes de que se inicie la comunicacin. De esta manera un
microcontrolador puede comunicarse con 112 dispositivos diferentes. La velocidad
de transmisin serial es normalmente 100 Kb/seg (el modo estndar) o 10 Kb/seg
(modo de velocidad de transmisin baja). Recientemente han aparecido los
sistemas con la velocidad de transmisin serial 3.4 Mb/sec. La distancia entre los
dispositivos que se comunican por el bus I2C est limitada a unos metros.

SPI (SERIAL PERIPHERAL INTERFACE BUS) - BUS SERIAL DE INTERFAZ DE


PERIFRICOS
Un bus serial de interfaz de perifricos es un sistema para la comunicacin
serial que utiliza hasta cuatro lneas (normalmente solo son necesarias tres) - para
recibir los datos, para transmitir los datos, para sincronizar y (opcional) para
seleccionar el dispositivo con el que se comunica. Esto es la conexin full duplex,
lo que significa que los datos se envan y se reciben simultneamente.
La velocidad de transmisin mxima es mayor que en el sistema de
conexin I2C.

UART

(UNIVERSAL

ASYNCHRONOUS

RECEIVER/TRANSMITTER)

TRANSMISOR-RECEPTOR ASNCRONO UNIVERSAL


Este tipo de conexin es asncrona, lo que significa que no se utiliza una lnea
especial para transmitir la seal de reloj. En algunas aplicaciones este rasgo es
crucial (por ejemplo, en mandar datos a distancia por RF o por luz infrarroja).
Puesto que se utiliza slo una lnea de comunicacin, tanto el receptor como el
transmisor reciben y envan los datos a velocidad misma que ha sido predefinida
para mantener la sincronizacin necesaria. Esto es una manera simple de
transmitir datos puesto que bsicamente representa una conversin de datos de
8 bits de paralelo a serial. La velocidad de transmisin no es alta, es hasta 1
Mbit/sec.
OSCILADOR

Los pulsos uniformes generados por el oscilador permiten el funcionamiento


armnico y sncrono de todos los circuitos del microcontrolador. El oscilador se
configura normalmente de tal manera que utilice un cristal de cuarzo o resonador
cermico para estabilizacin de frecuencia. Adems, puede funcionar como un
circuito autnomo (como oscilador RC). Es importante decir que las instrucciones

del programa no se ejecutan a la velocidad impuesta por el mismo oscilador sino


varias veces ms despacio. Eso ocurre porque cada instruccin se ejecuta en
varios ciclos del oscilador. En algunos microcontroladores se necesita el mismo
nmero de ciclos para ejecutar todas las instrucciones, mientras que en otros el
tiempo de ejecucin no es el mismo para todas las instrucciones. Por
consiguiente, si el sistema utiliza el cristal de cuarzo con una frecuencia de 20
MHZ, el tiempo de ejecucin de una instruccin de programa no es 50 nS, sino
200, 400 o 800 nS dependiendo del tipo del microcontrolador.
CIRCUITO DE ALIMENTACIN
Hay que mencionar dos cosas dignas de atencin con relacin al circuito de la
fuente de alimentacin de microcontroladores:
Brown out es un estado potencialmente peligroso que ocurre al apagar el
microcontrolador o en caso de que el voltaje de la fuente de alimentacin
salga

de

unos

mrgenes

debido

al

ruido

elctrico.

Como

el

microcontrolador dispone de varios circuitos que funcionan a niveles de


voltaje

diferentes,

ese

estado

puede

causar

un

comportamiento

descontrolado. Para evitarlo, el microcontrolador normalmente tiene un


circuito

incorporado

para

el

brown

out

reset.

El

circuito

reinicia

inmediatamente el microcontrolador si el voltaje de alimentacin cae por


debajo del lmite.
El pin de reset (reinicio), marcado frecuentemente con MCLR (Master
Clear Reset), sirve para el reinicio externo del microcontrolador al aplicar
un cero (0) o un uno (1) lgico dependiendo del tipo del microcontrolador.
En caso de que el circuito brown out no est incorporado, un simple circuito
externo para el brown out reset se puede conectar al pin MCLR.
TEMPORIZADORES/CONTADORES
El

oscilador

del

microcontrolador

utiliza

cristal

de

cuarzo

para

su

funcionamiento. Aunque no se trata de la solucin ms simple, hay muchas

razones para utilizarlo. La frecuencia del oscilador es definida con precisin y muy
estable, as que siempre genera los pulsos del mismo ancho, lo que los hace
perfectos para medicin de tiempo. Tales osciladores se utilizan en los relojes de
cuarzo. Si es necesario medir el tiempo transcurrido entre dos eventos, basta con
contar los pulsos generados por este oscilador. Esto es exactamente lo que hace
el temporizador.

La mayora de los programas utiliza estos cronmetros electrnicos en


miniatura. Generalmente son registros SFR de 8 o 16 bits cuyo contenido se
aumenta automticamente con cada pulso. Una vez que se llena el registro, se
genera una interrupcin!
Si

el

temporizador

utiliza

el

oscilador

de

cuarzo

interno

para

su

funcionamiento, es posible medir el tiempo entre dos eventos (el valor de registro
en el momento de iniciar la medicin es T1, en el momento de finalizar la
medicin es T2, el tiempo transcurrido es igual al resultado de la resta T2 - T1). Si
los registros se aumentan con los pulsos que vienen de la fuente externa, tal
temporizador se convierte en un contador.
Esto es una explicacin simple de su funcionamiento. Es un poco ms
complicado en prctica.
CMO FUNCIONAN LOS TEMPORIZADORES?
En prctica, los pulsos generados por el oscilador de cuarzo son llevados al
circuito una vez por cada ciclo de mquina directamente o por el pre-escalador, lo

que aumenta el nmero en el registro del temporizador. Si una instruccin (un


ciclo de mquina) dura cuatro perodos del oscilador de cuarzo, este nmero ser
cambiado un milln de veces por segundo (cada microsegundo) al incorporar al
cuarzo que oscila con una frecuencia de 4 MHz.

Es fcil de medir los intervalos de tiempo cortos de la manera descrita


anteriormente (hasta 256 microsegundos porque es el mayor nmero que un
registro puede contener). Esta obvia desventaja se puede superar de varias
maneras: al utilizar el oscilador ms lento, por medio de registros con ms bits,
del pre-escalador o de la interrupcin. Las primeras dos soluciones tienen algunas
debilidades as que se recomienda utilizar el pre-escalador y/o la interrupcin.
UTILIZAR

UN

PREESCALADOR

EN

EL

FUNCIONAMIENTO

DEL

TEMPORIZADOR
Un pre-escalador es un dispositivo electrnico utilizado para dividir la
frecuencia por un factor predeterminado. Esto quiere decir que se necesita llevar
1, 2, 4 o ms pulsos a su entrada para generar un pulso a la salida. La mayora de
los microcontroladores disponen de uno o ms pre-escaladores incorporados y su
tasa de divisin puede ser cambiada dentro del programa. El pre-escalador se
utiliza cuando es necesario medir los perodos de tiempo ms largos. Si el
temporizador y el temporizador perro guardin comparten un pre-escalador, ste
no se puede utilizar por los dos simultneamente.

UTILIZAR

UNA

INTERRUPCIN

EN

EL

FUNCIONAMIENTO

DEL

TEMPORIZADOR
Si el registro del temporizador es de 8 bits, el mayor nmero que se puede
escribir en l es 255 (en los registros de 16 bits es el nmero 65.535). Si se
excede este nmero, el temporizador se reinicia automticamente y el conteo
comienza de nuevo en cero. Esto es denominado desbordamiento o sobreflujo
(overflow). Permitido por el programa, el desbordamiento puede provocar una
interrupcin, lo que abre completamente nuevas posibilidades. Por ejemplo, el
estado de registros utilizados para contar segundos, minutos o das puede ser
implementado en una rutina de interrupcin. El proceso entero (excepto la rutina
de interrupcin) se lleva a cabo internamente, lo que permite que los circuitos
principales del microcontrolador funcionen regularmente.

La figura anterior describe el uso de una interrupcin en el funcionamiento


del temporizador. Al asignarle un pre-escalador al temporizador, se producen
retrasos de duracin arbitraria con mnima interferencia en la ejecucin del
programa principal.
CONTADORES
Si un temporizador se suministra por los pulsos ingresados por el pin de
entrada en el microcontrolador, se produce un contador. Evidentemente, es el
mismo circuito electrnico. La nica diferencia es que los pulsos para contar se
ingresan por el pin de entrada y que su duracin (anchura) no es definida. Por
eso, no se pueden utilizar para medicin de tiempo, sino que se utilizan para otros
propsitos, por ejemplo: contar los productos en la cadena de montaje, nmero de
rotaciones del eje de un motor, pasajeros etc. (dependiendo del sensor utilizado.
TEMPORIZADOR PERRO GUARDIN (WATCHDOG)
El perro guardin es un temporizador conectado a un oscilador RC
completamente independiente dentro del microcontrolador.
Si el perro guardin est habilitado, cada vez que cuenta hasta el mximo
valor en el que ocurre el desbordamiento del registro se genera una seal de
reinicio del microcontrolador y la ejecucin de programa inicia en la primera
instruccin. El punto es evitar que eso ocurra al utilizar el comando adecuado.
La idea se basa en el hecho de que cada programa se ejecuta en varios
bucles, ms largos o cortos. Si las instrucciones que reinician el temporizador
perro guardin se colocan en lugares estratgicos del programa, aparte los
comandos que se ejecutan regularmente, el funcionamiento del perro guardin no
afectar a la ejecucin del programa. Si por cualquier razn (ruidos elctricos
frecuentes en la industria) el contador de programa se queda atrapado dentro
de un bucle infinito, el valor del registro continuar aumentado por el
temporizador perro guardin alcanzar el mximo valor, el registro se desbordar
y, aleluya! Ocurre el reinicio!

CONVERTIDOR A/D

Las seales del mundo real son muy diferentes de las que entiende el
microcontrolador (ceros y unos), as que deben ser convertidas para que el
microcontrolador pueda entenderlas. Un convertidor analgico-digital es un
circuito electrnico encargado de convertir las seales continuas en nmeros
digitales discretos. En otras palabras, este circuito convierte un nmero real en un
nmero binario y se lo enva a la CPU para ser procesado. Este mdulo se utiliza
para medir el voltaje en el pin de entrada.
El resultado de esta medicin es un nmero (el valor digital) utilizado y
procesado ms tarde en el programa.

ARQUITECTURA INTERNA
Todos los microcontroladores actuales utilizan uno de dos modelos bsicos
de arquitectura denominados Harvard y von-Neumann.
Son dos maneras diferentes del intercambio de datos entre la CPU y la
memoria.
Arquitectura de von-Neumann

Los microcontroladores que utilizan la arquitectura von- Neumann disponen


de un solo bloque de memoria y de un bus de datos de 8 bits. Como todos los
datos se intercambian por medio de estas 8 lneas, este bus est sobrecargado, y
la comunicacin por si misma es muy lenta e ineficaz. La CPU puede leer una
instruccin o leer/escribir datos de/en la memoria. Los dos procesos no pueden
ocurrir a la vez puesto que las instrucciones y los datos utilizan el mismo bus. Por
ejemplo, si alguna lnea de programa dice que el registro de la memoria RAM

llamado SUM debe ser aumentado por uno (instruccin: incf SUMA), el
microcontrolador har lo siguiente:
1. Leer la parte de la instruccin de programa que especifica QU es lo que debe
realizar (en este caso es la instruccin para incrementar incf)
2. Seguir leyendo la misma instruccin que especifica sobre CUL dato lo debe
realizar (en este caso es el contenido del registro SUMA)
3. Despus de haber sido incrementado, el contenido de este registro se debe
escribir en el registro del que fue ledo (direccin del registro SUMA)
El mismo bus de datos se utiliza para todas estas operaciones intermedias.
ARQUITECTURA DE HARVARD

Los microcontroladores que utilizan esta arquitectura disponen de dos buses


de datos diferentes. Uno es de 8 bits de ancho y conecta la CPU con la memoria
RAM. El otro consiste en varias lneas (12, 14 o 16) y conecta a la CPU y la
memoria ROM. Por consiguiente, la CPU puede leer las instrucciones y realizar el
acceso a la memoria de datos a la vez. Puesto que todos los registros de la
memoria RAM son de 8 bits de ancho, todos los datos dentro del microcontrolador
que se intercambian son de la misma anchura. Durante el proceso de la escritura
de programa, slo se manejan los datos de 8 bits. En otras palabras, todo lo que
usted podr cambiar en el programa y a lo que podr afectar ser de 8 bits de
ancho. Todos los programas escritos para estos microcontroladores sern
almacenados en la memoria ROM interna del microcontrolador despus de haber

sido compilados a cdigo mquina. No obstante, estas localidades de memoria


ROM no tienen 8, sino 12, 14 o 16 bits. 4, 6 o 8 bits adicionales representan una
instruccin que especifica a la CPU qu hacer con los datos de 8 bits.
Las ventajas de este diseo son las siguientes:
Todos los datos en el programa son de un byte (8 bits) de ancho. Como un
bus de datos utilizado para lectura de programa tiene unas lneas ms (12,
14 o 16), tanto la instruccin como el dato se pueden leer simultneamente
al utilizar estos bits adicionales. Por eso, todas las instrucciones se ejecutan
en un ciclo salvo las instrucciones de salto que son de dos ciclos.
El hecho de que un programa (la ROM) y los datos temporales (la RAM)
estn separados, permite a la CPU poder ejecutar dos instrucciones
simultneamente. Dicho de manera sencilla, mientras que se realiza la
lectura o escritura de la RAM (que marca el fin de una instruccin), la
siguiente instruccin se lee por medio de otro bus.
En los microcontroladores que utilizan la arquitectura de von-Neumann,
nunca se sabe cunta memoria ocupar algn programa. Generalmente, la
mayora de las instrucciones de programa ocupan dos localidades de
memoria (una contiene informacin sobre QU se debe realizar, mientras
que la otra contiene informa cin sobre CUL dato se debe realizar). Sin
embargo, esto no es una frmula rgida, sino el caso ms frecuente. En los
microcontroladores que utilizan una arquitectura Harvard, el bus de la
palabra de programa es ms ancho que un byte, lo que permite que cada
palabra de programa est compuesto por una instruccin y un dato. En
otras palabras, una localidad de memoria - una instruccin de programa.

JUEGO DE INSTRUCCIONES

El nombre colectivo de todas las instrucciones que puede entender el


microcontrolador es llamado Juego de Instrucciones. Cuando se escribe un
programa en ensamblador, en realidad se especifican instrucciones en el orden en
el que deben ser ejecutadas. La restriccin principal es el nmero de instrucciones
disponibles. Los fabricantes aceptan cualquiera de los dos enfoques descritos a
continuacin:
RISC (Reduced Instruction Set Computer) - Computadora con Juego de
Instrucciones Reducidas
En este caso la idea es que el microcontrolador reconoce y ejecuta slo
operaciones

bsicas

(sumar,

restar,

copiar

etc...)

Las

operaciones

ms

complicadas se realizan al combinar stas (por ejemplo, multiplicacin se lleva a


cabo al realizar adicin sucesiva). Es como intentar explicarle a alguien con pocas
palabras cmo llegar al aeropuerto en una nueva ciudad. Sin embargo, no todo es
tan oscuro. Adems, el microcontrolador es muy rpido as que no es posible ver
todas las acrobacias aritmticas que realiza. El usuario slo puede ver el
resultado final de todas las operaciones. Por ltimo, no es tan difcil explicar
dnde est el aeropuerto si se utilizan las palabras adecuadas tales como: a la
derecha, a la izquierda, el kilmetro etc.
CISC (Complex Instruction Set Computer) - Computadoras con un juego
de instrucciones complejo

CISC es opuesto a RISC! Los microcontroladores diseados para reconocer


ms de 200 instrucciones diferentes realmente pueden realizar muchas cosas a
alta velocidad. No obstante, uno debe saber cmo utilizar todas las posibilidades
que ofrece un lenguaje tan rico, lo que no es siempre tan fcil...
CMO ELEGIR UN MICROCONTROLADOR?
Bueno, si usted es principiante, y ha tomado decisin de trabajar con los
microcontroladores. Felicitaciones por la eleccin! No obstante, a primera vista,
no es fcil la eleccin del microcontrolador ms adecuado como parece a la
primera vista. El problema no es el pequeo rango de dispositivos a elegir, sino
todo lo contrario!
Antes de empezar a disear un dispositivo basado en un microcontrolador,
tome en cuenta lo siguiente: cuntas entradas/lneas son necesarias para su
funcionamiento,

realizara

el

dispositivo

otras

operaciones

adems

encender/apagar un rel, necesita algn modulo especializado tal como el de


comunicacin en serie, convertidor A/D etc. Cuando usted tiene una clara imagen
de lo que quiere, el rango de seleccin se reduce considerablemente, y le queda
pensar en el precio. Va a tener varios dispositivos? Varios cientos? Un milln?
De todos modos ahora es ms claro.
Si est pensando en todas estas cosas por primera vez, todo le parecer un
poco confuso. Por esa razn, vaya paso a paso. Antes que nada, seleccione al
fabricante, es decir, la familia de microcontroladores que ofrece. Luego, aprenda a
trabajar con un modelo particular. Slo aprenda lo que necesite aprender, no
entre demasiado en detalles. Resuelva el problema especfico y le pasar una
cosa increble - ser capaz de manejar cualquier modelo del mismo fabricante...
Ms o menos, todo se parece a montar en bicicleta: despus de varias
cadas inevitables en el principio, ser capaz de mantener el equilibrio y montar
en cualquier otra bicicleta. Por supuesto, nunca se olvida tanto de montar en
bicicleta, como de la destreza de programacin!

1.4 MICROCONTROLADORES PIC


Los microcontroladores PIC desarrollados por Microchip Technology son
probablemente la mejor opcin si es principiante. Hay varias razones por lo que
esto es verdadero...
El nombre verdadero de este microcontrolador es PICmicro (Peripheral
Interface Controller), conocido bajo el nombre PIC. Su primer antecesor fue creado
en 1975 por la compaa General Instruments. Este chip denominado PIC1650 fue
diseado para propsitos completamente diferentes. Diez aos ms tarde, al
aadir una memoria EEPROM, este circuito se convirti en un verdadero
microcontrolador PIC. Hace unos pocos aos la compaa Microchip Technology
fabric la 5 billonsima muestra. Si est interesado en aprender ms sobre eso,
siga leyendo.
If you are interested in learning more about it, just keep on reading.
La idea principal de este libro es proporcionar la informacin necesaria al
usuario para que sea capaz de utilizar los microcontroladores en la prctica
despus de leerlo. Para evitar explicaciones pesadas y las historias infinitas sobre
las caractersticas tiles de los microcontroladores diferentes, este libro describe
el funcionamiento de un modelo particular que pertenece a la clase media alta.
Es PIC16F887 - bastante poderoso para ser digno de atencin y bastante simple
para poder ser utilizado por cualquiera. As, los siguientes captulos describen
este microcontrolador en detalle y tambin se refieren a la familia PIC entera.
Frec

Famili
a

RO

RA

uenc
Pi

ia de

[Kb [b

ne reloj

yte

yt

s]

es]

.
[MH
z]

Reso
Ent
rad
as
A/D

luci

Tempo

n del Comp

rizador

conv

arado

es

ertid

res

8/16

or

bits

de

Comu
nicaci
n
serial

Sal
ida
s
PW

Otr
os

A/D

Arquitectura de la gama baja de 8 bits, palabra de instruccin de 12

bits
0.3
PIC10F 75 XXX

0.7

XXX

PIC16F
XXX

0.7
5

- -

4-8

0-2 8

0-1

1x8

25

0.7
-

13
4

1.5

25

EEP
8

4-8

0-3 8

0-1

1x8

38

PIC16
HVXX

6 -

25

1.5

24

5
PIC12F

16

RO
M

14
-

EEP
20

0-3 8

0-2

1x8

RO

44

18

Vdd

20

1x8

20

=
15V

Arquitectura de la gama media de 8 bits, palabra de instruccin de 14


bits
PIC12F
XXX
PIC12
HVXX
X
PIC16F
XXX

64

1.7
5

3.5

64

64

1.7
-

14

PIC16

1.7

HVXX

3.5

12

20

0 - 4 10

1 - 2 x
8 1 x 16

0 1

1.7

36
8
64

12
8

20

14
-

20

64
14
20

20

0 - 4 10

- 8

13

0
12

10

10

or

0-2

1 - 2 x
8 1 x 16

1 - 2 x USART

0 1

0 -

8 1 x 16 I2C SPI 3

2 x 8 1 USART
x 16

I2C SPI

EEP
RO
M

Arquitectura de la gama alta de 8 bits, palabra de instruccin de 16


bits
USB2.
25
PIC18F 4
XXX

- 6 -

128 39
36

18
80

32
48

- 4

- 10 or

16

12

0 - 2 x
0-3

8 2 - 3
x 16

0
CAN2.

0 -

USART
I2C SPI

10
PIC18F 8
XXJXX

128

24
39
36
76

PIC18F 8
XXKXX 64

- 8 39
36

USB2.
28
-

40

10 48

- 10 16

0 - 2 x
10

8 2 - 3
x 16

0
USART

2 -

Ethern

et

I2C

SPI
28
44

64

10 13

10

1 x 8 3 USART
x 16

I2C SPI

Todos los microcontroladores PIC utilizan una arquitectura Harvard, lo que


quiere decir que su memoria de programa est conectada a la CPU por ms de 8
lneas. Hay microcontroladores de 12, 14 y 16 bits, dependiendo de la anchura del
bus. La tabla anterior muestra las caractersticas principales de estas tres
categoras.
Como se puede ver en la tabla de la pgina anterior, salvo los monstruos
de 16 bits PIC 24FXXX y PIC 24HXXX - todos los microcontroladores tienen la
arquitectura Harvard de 8 bits y pertenecen a una de las tres grandes grupos. Por
eso, dependiendo del tamao de palabra de programa existen la primera, la
segunda y la tercera categora de microcontroladores, es decir microcontroladores
de 12, 14 o 16 bits. Puesto que disponen del ncleo similar de 8 bits, todos
utilizan el mismo juego de instrucciones y el esqueleto bsico de hardware
conectado a ms o menos unidades perifricas.

Los microcontroladores PIC con palabras de programa de 14 bits parecen


ser la mejor opcin para los principiantes. Aqu est el porqu...
JUEGO DE INSTRUCCIONES
El juego de instrucciones para los microcontroladores 16F8XX incluye 35
instrucciones en total. La razn para un nmero tan reducido de instrucciones
yace en la arquietectura RISC. Esto quiere decir que las instrucciones son bien
optimizadas desde el aspecto de la velocidad operativa, la sencillez de la
arquitectura y la compacidad del cdigo. Lo malo de la arquitectura RISC es que
se espera del programador que haga frente a estas instrucciones. Por supuesto,
esto es relevante slo si se utiliza el lenguaje ensamblador para la programacin.
Este libro se refiere a la programacin en el lenguaje de alto nivel C, lo que
significa que la mayor parte del trabajo ya fue hecho por alguien ms. As, slo se
tienen que utilizar instrucciones relativamente simples.
TIEMPO DE EJECUCIN DE INSTRUCCIONES
Todas las instrucciones se ejecutan en un ciclo. La nicas excepciones
pueden ser las instrucciones de ramificacin condicional o las instrucciones que
cambian el contenido del contador de programa. En ambos casos, dos ciclos de
reloj son necesarios para la ejecucin de la instruccin, mientras que el segundo
ciclo se ejecuta como un NOP (No operation). Las instrucciones de un ciclo
consisten en cuatro ciclos de reloj. Si se utiliza un oscilador de 4 MHz, el tiempo
nominal para la ejecucin de la instruccin es 1S. En cuanto a las instrucciones
de ramificacin, el tiempo de ejecucin de la instruccin es 2S.
Juego de instrucciones de los microcontroladores PIC de 14 bits:
INSTRUCCI
N

DESCRIPCIN

OPERACIN

BANDER
A

CLK

Instrucciones para la transmisin de datos


MOVLW k

Mover literal a W

k -> w

MOVWF f

Mover el contenido W -> f

de W a f
MOVF f,d
CLRW
CLRF f
SWAPF f,d

Mover el contenido
de f a d
Borrar el contenido
de W
Borrar el contenido
de f
Intercambiar

f -> d

0 -> W

0 -> f

de f(7:4),(3:0)

nibbles en f

->

f(3:0),(7:4)

1,
2

2
1,
2

Instrucciones aritmtico - lgicas


ADDLW k
ADDWF f,d

Sumar literal a W
Sumar el contenido
de W y f

W+k -> W

C, DC, Z

W+f -> d

C, DC ,Z

SUBLW k

Restar W de literal

k-W -> W

C, DC, Z

SUBWF f,d

Restar W de f

f-W -> d

C, DC, Z

ANDLW k

AND W con literal

W AND k -> W

ANDWF f,d

AND W con f

W AND f -> d

W OR k -> W

W OR f -> d

W XOR k -> W

W XOR f -> d

IORLW k
IORWF f,d
XORWF f,d
XORLW k

OR inclusivo de W
con literal
OR inclusivo de W
con f
OR exclusivo de W
con literal
OR exclusivo de W
con f

INCF f,d

Sumar 1 a f

f+1 -> f

DECF f,d

Restar 1 a f

f-1 -> f

RLF f,d

Rotar

la

1,
2
1,
2
1,
2

1,
2
1,
2

1,
2
1,
2
1,

izquierda a travs

del bit de Acarreo


Rotar F a la derecha
RRF f,d

a travs del bit de

Acarreo
COMF f,d

Complementar f

f -> d

1,
2
1,
2

Instrucciones orientadas a bit


BCF f,b
BSF f,b

Poner a 0 el bit b
del registro f
Poner a 1 el bit b
del registro f

0 -> f(b)

1 -> f(b)

1,
2
1,
2

Instrucciones de control de programa


BTFSC f,b
BTFSS f,b

Saltar si bit b de
registro f es 0
Saltar si bit b de
reg. f es 1
Disminuir f en 1.

DECFSZ f,d

Saltar

si

el

resultado es 0
Incrementar f en 1.
INCFSZ f,d

Saltar

si

el

resultado es 1
GOTO k
CALL k
RETURN
RETLW k
RETFIE

Saltar

Skip if f(b) = 1

1 (2)

f-1 -> d skip if


Z=1
f+1 -> d skip if
Z=0

una

una PC -> TOS, k ->

subrutina
Retornar

1 (2)

direccin
Llamar

Skip if f(b) = 0

k -> PC

PC
de

subrutina

una

TOS -> PC

Retornar con literal k -> W, TOS ->


en W
Retornar

PC
de

una TOS -> PC, 1 ->

1,
1 (2)

2,
3
1,

1 (2)

2,
3

2
2
2
2
2

interupcin

GIE

Otras instrucciones
NOP

TOS -> PC, 1 ->

No operacin
Reiniciar

CLRWDT

el

temporizador perro
guardin

0 -> WDT, 1 ->


TO, 1 -> PD

Poner en estado de 0 -> WDT, 1 ->

SLEEP

reposo

GIE

TO, 0 -> PD

TO, PD

TO, PD

*1 Si un registro de E/S est modificado, el valor utilizado ser el valor presentado


en

los

pines

del

microcontrolador.

*2 Si la instruccin se ejecuta en el registro TMR y si d=1, el pre-escalador ser


borrado.
*3 Si la instruccin se ejecuta en el registro TMR y si d=1, el pre-escalador ser
borrado.

Arquitectura de los microcontroladores PIC de 8 bits. Cules de estos


mdulos

pertenecern

microcontrolador.

al

microcontrolador,

depender

del

tipo

de

Capitulo 2 - Programacin de los microcontroladores


Usted

seguramente

sabe

que

no

es

suficiente

slo

conectar

el

microcontrolador a los otros componentes y encender una fuente de alimentacin


para hacerlo funcionar, verdad? Hay que hacer algo ms. Se necesita programar
el microcontrolador. Si cree que esto es complicado, est equivocado. Todo el
procedimiento es muy simple. Basta con leer el texto para entender de lo que
estamos hablando.
2.1 LENGUAJES DE PROGRAMACIN
2.2 CARACTERSTICAS PRINCIPALES DEL MIKROC
2.3 TIPOS DE DATOS EN MIKROC
2.4 VARIABLES Y CONSTANTES
2.5 OPERADORES
2.6 ESTRUCTURAS DE CONTROL
2.7 TIPOS DE DATOS AVANZADOS
2.8 FUNCIONES
2.9 CARACTERSTICAS PRINCIPALES DEL PREPROCESADOR
2.10 MIKROC PRO FOR PIC
2.11 PROGRAMAR LOS PIC UTILIZANDO MIKROC PRO FOR PIC
2.1 LENGUAJES DE PROGRAMACIN

El microcontrolador ejecuta el programa cargado en la memoria Flash. Esto


se denomina el cdigo ejecutable y est compuesto por una serie de ceros y unos,
aparentemente

sin

significado.

Dependiendo

de

la

arquitectura

del

microcontrolador, el cdigo binario est compuesto por palabras de 12, 14 o 16


bits de anchura. Cada palabra se interpreta por la CPU como una instruccin a ser
ejecutada durante el funcionamiento del microcontrolador. Todas las instrucciones
que

el

microcontrolador

puede

reconocer

ejecutar

se

les

denominan

colectivamente Conjunto de instrucciones. Como es ms fcil trabajar con el


sistema de numeracin hexadecimal, el cdigo ejecutable se representa con
frecuencia como una serie de los nmeros hexadecimales denominada cdigo
Hex. En los microcontroladores PIC con las palabras de programa de 14 bits de
anchura, el conjunto de instrucciones tiene 35 instrucciones diferentes.
LENGUAJE ENSAMBLADOR

Como el proceso de escribir un cdigo ejecutable era considerablemente


arduo, en consecuencia fue creado el primer lenguaje de programacin
denominado ensamblador (ASM). Siguiendo la sintaxis bsica del ensamblador,
era ms fcil escribir y comprender el cdigo. Las instrucciones en ensamblador
consisten en las abreviaturas con significado y a cada instruccin corresponde
una localidad de memoria. Un programa denominado ensamblador compila
(traduce) las instrucciones del lenguaje ensamblador a cdigo mquina (cdigo
binario).
HEste programa compila instruccin a instruccin sin optimizacin. Como
permite controlar en detalle todos los procesos puestos en marcha dentro del
chip, este lenguaje de programacin todava sigue siendo popular.
Ventajas de lenguajes de programacin de alto nivel
A pesar de todos los lados buenos, el lenguaje ensamblador tiene algunas
desventajas:
Incluso una sola operacin en el programa escrito en ensamblador consiste
en muchas instrucciones, hacindolo muy largo y difcil de manejar.
Cada tipo de microcontrolador tiene su propio conjunto de instrucciones que
un programador tiene que conocer para escribir un programa
Un programador tiene que conocer el hardware del microcontrolador para
escribir un programa
Programa escrito en C (El mismo programa compilado al cdigo ensamblador):

Los lenguajes de programacin de alto nivel (Basic, Pascal, C etc.) fueron


creados con el propsito de superar las desventajas del ensamblador. En
lenguajes de programacin de alto nivel varias instrucciones en ensamblador se
sustituyen por una sentencia. El programador ya no tiene que conocer el conjunto
de instrucciones o caractersticas del hardware del microcontrolador utilizado. Ya
no es posible conocer exactamente cmo se ejecuta cada sentencia, de todas
formas ya no importa. Aunque siempre se puede insertar en el programa una
secuencia escrita en ensamblador.
Si alguna vez ha escrito un programa para un microcontrolador PIC en
lenguaje ensamblador, probablemente sepa que la arquitectura RISC carece de
algunas instrucciones. Por ejemplo, no hay instruccin apropiada para multiplicar
dos nmeros. Por supuesto, para cada problema hay una solucin y ste no es
una excepcin gracias a la aritmtica que permite realizar las operaciones
complejas al descomponerlas en un gran nmero operaciones ms simples. En
este caso, la multiplicacin se puede sustituir con facilidad por adicin sucesiva (a
x b = a + a + a + ... + a). Ya estamos en el comienzo de una historia muy larga...

No hay que preocuparse al utilizar uno de estos lenguajes de programacin de


alto nivel como es C, porque el compilador encontrar automticamente la
solucin a ste problema y otros similares. Para multiplicar los nmeros a y b,
basta con escribir a*b.
Lenguaje C
El lenguaje C dispone de todas las ventajas de un lenguaje de programacin
de alto nivel (anteriormente descritas) y le permite realizar algunas operaciones
tanto sobre los bytes como sobre los bits (operaciones lgicas, desplazamiento
etc.). Las caractersticas de C pueden ser muy tiles al programar los
microcontroladores. Adems, C est estandarizado (el estndar ANSI), es muy
portable, as que el mismo cdigo se puede utilizar muchas veces en diferentes
proyectos. Lo que lo hace accesible para cualquiera que conozca este lenguaje sin
reparar en el propsito de uso del microcontrolador. C es un lenguaje compilado,
lo que significa que los archivos fuentes que contienen el cdigo C se traducen a
lenguaje mquina por el compilador. Todas estas caractersticas hicieron al C uno
de los lenguajes de programacin ms populares.

La figura anterior es un ejemplo general de lo que sucede durante la


compilacin de programa de un lenguaje de programacin de alto nivel a bajo
nivel.

2.2 CARACTERSTICAS PRINCIPALES DEL MIKROC


A continuacin vamos a presentar a los elementos principales del lenguaje
mikroC desarrollado por Mikroelektronika. Este lenguaje es muy similar al C
estndar, no obstante en determinados aspectos difiere del ANSI estndar en
algunas caractersticas. Algunas de estas diferencias se refieren a las mejoras,
destinadas a facilitar la programacin de los microcontroladores PIC, mientras que
las dems son la consecuencia de la limitacin de la arquitectura del hardware de
los PIC. Aqu vamos a presentar caractersticas especficas del lenguaje mikroC en
la programacin de los microcontroladores PIC. El trmino C se utilizar para
referirse a las caractersticas comunes de los lenguajes C y mikroC.

Este

libro

describe

una

aplicacin

muy

concreta

del

lenguaje

de

programacin C utilizado en el compilador mikroC PRO for PIC. En este caso, el


compilador se utiliza para la programacin de los microcontroladores PIC.
FASES DE COMPILACIN
El proceso de compilacin consiste en varios pasos y se ejecuta
automticamente por el compilador. Por con, un conocimiento bsico del
funcionamiento puede ser til para entender el concepto del lenguaje mikroC.
El archivo fuente contiene el cdigo en mikroC que usted escribe para
programar el microcontrolador. El preprocesador se utiliza automticamente por el
compilador al iniciarse el proceso de la compilacin. El compilador busca las

directivas del preprocesador (que siempre empiezan por #) dentro del cdigo y
modifica el cdigo fuente de acuerdo con las directivas. En esta fase se llevan a
cabo inclusin de archivos, definicin de constantes y macros etc, lo que facilita el
proceso. Ms tarde vamos a describir estas directivas en detalle. El analizador
sintctico (parser) elimina toda la informacin intil del cdigo (comentarios,
espacios en blanco). Luego, el compilador traduce el cdigo a un archivo binario
denominado archivo .mcl. El enlazador (linker) recupera toda la informacin
requerida para ejecutar el programa de los archivos externos y la agrupa en un
solo archivo (.dbg). Adems, un proyecto puede contener ms de un archivo
fuente y el programador puede utilizar funciones predefinidas y agrupadas dentro
de los archivos denominados libreras. Por ltimo, el generador .hex produce un
archivo .hex. Es el archivo que se va a cargar en el microcontrolador.

El proceso entero de la compilacin que incluye todos los pasos


anteriormente descritos se le denomina building.
ESTRUCTURA DE PROGRAMA
La idea principal de escribir un programa en C es de romper un problema
mayor en varios trozos ms pequeos. Supongamos que es necesario escribir un
programa para el microcontrolador para medir la temperatura y visualizar los
resultados en un LCD. El proceso de medicin se realiza por un sensor que
convierte temperatura en voltaje. El microcontrolador utiliza el convertidor A/D
para convertir este voltaje (valor analgico) en un nmero (valor digital) que
luego se enva al LCD por medio de varios conductores. En consecuencia, el
programa se divide en cuatro partes, de las que cada una corresponde a una
accin especfica:

1. Activar y configurar el convertidor A/D incorporado;


2. Medir el valor analgico;
3. Calcular temperatura; y
4. Enviar los datos en el formato apropiado al LCD;
Los lenguajes de programacin de alto nivel como es C le permiten
solucionar este problema con facilidad al escribir cuatro funciones que se
ejecutarn cclicamente sin parar.
La idea general es de dividir el problema en varios trozos, de los que cada
uno se puede escribir como una sola funcin. Todos los programas escritos en
mikroC contienen por lo menos una funcin llamada main() que encierra entre
llaves {} las sentencias a ser ejecutadas. Esto es la primera funcin a ser
ejecutada al iniciarse la ejecucin de programa. Las otras funciones se pueden
llamar dentro de la funcin main. En otras palabras, podemos decir que la funcin
main() es obligatoria, mientras que las dems son opcionales. Si todava no ha
escrito un programa en C, es probable que todo le resulte confuso. No se
preocupe, acptelo tal como es por el momento y ms tarde entender la sintaxis.

Y ahora, su primer programa real! La figura muestra la estructura de


programa, sealando las partes en las que consiste.

La manera de escribir el cdigo en C es muy importante. Por ejemplo, C difiere


entre minsculas y maysculas, as que la funcin main() no se puede escribir
MAIN() o Main(). Adems, note que dos lneas del cdigo dentro de la funcin
terminan con un punto y coma. En C todas las sentencias deben terminar con un
punto y coma ;, as el compilador puede aislarlas y traducirlas a cdigo mquina.

COMENTARIOS
Los comentarios son las partes del programa utilizados para aclarar las
instrucciones de programa o para proporcionar ms informacin al respecto. El
compilador no hace caso a los comentarios y no los compila al cdigo ejecutable.
Dicho de manera sencilla, el compilador es capaz de reconocer los caracteres
especiales utilizados para designar dnde los comentarios comienzan y terminan
y no hace nada de caso al texto entre ellos durante la compilacin. Hay dos tipos
de tales caracteres. Unos designan los comentarios largos que ocupan varias
lneas de programa marcados por la secuencia especial /*...*/, mientras que otros
designan los comentarios cortos que caben en una sola lnea //. Aunque los
comentarios no pueden afectar a la ejecucin de programa, son tan importantes
como cualquier otra parte de programa. Aqu est el porqu... Con frecuencia es
necesario mejorar, modificar, actualizar, simplificar un programa... No es posible
interpretar incluso los programas simples sin utilizar los comentarios.

2.3 TIPOS DE DATOS EN MIKROC


En el lenguaje C, los datos tienen un tipo, o sea, cada dato utilizado en el
programa debe tener su tipo especificado. Esto permite al compilador conocer el
tamao de dato (nmero de bytes requerido en la memoria) y su representacin.
Hay varios tipos de datos que se pueden utilizar en el lenguaje de programacin
mikroC dependiendo del tamao de dato y del rango de valores. La tabla muestra
el rango de valores que los datos pueden tener cuando se utilizan en su forma
bsica.
TIPO
DE

TA M A O
DESCRIPCIN

D AT O

(NMERO
BITS)

DE

RANGO

DE

VA LO R E S

char

Texto (caracteres)

de 0 a 255

int

Valores enteros

16

de -32768 a 32767
de

Valores

float

en

punto

flotante

32

1.1754943508210-38
a
6.805647744071038

double

Valores

en

punto

flotante

de

doble 32

precisin

de
1.1754943508210-38
a
6.805647744071038

*Debido a las limitaciones impuestas por el hardware del microcontrolador, es


imposible alcanzar una mayor precisin de datos que la del tipo float. Por eso, el
tipo double en mikroC equivale al tipo float.
Al aadir un prefijo (calificador) a cualquier tipo de dato entero o carcter, el
rango de sus posibles valores cambia as como el nmero de los bytes de
memoria necesarios. Por defecto, los datos de tipo int son con signo, mientras que
los de tipo char son sin signo. El calificador signed (con signo) indica que el dato

puede ser positivo o negativo. El prefijo unsigned indica que el dato puede ser
slo positivo. Note que el prefijo es opcional.

TIPO

DE

TIPO

DE

D AT O

TA M A O
(NMERO

DE

RANGO

D AT O

CON PREFIJO

char

signed char

de -128 a 128

unsigned int

16

de 0 a 65535

short int

de 0 a 255

signed short int

de -128 a 127

long int

32

signed long int

32

int

BITS)

DE

VA LO R E S

de

4294967295
de

-2147483648

a 2147483647

Tipo entero (int)


Un entero es un nmero sin parte fraccionaria que puede estar expresado en
los siguientes formatos:
Hexadecimal (base 16): el nmero empieza con 0x (o 0X). Los enteros
hexadecimales consisten en los dgitos (de 0 a 9) y/o las letras (A, B, C,D, E,
F). Por ejemplo: 0x1A.
Decimal (base 10): el nmero consiste en los dgitos (de 0 a 9). El primer
dgito no puede ser 0. En este formato, se puede introducir el signo de
nmero (+ o -). Por ejemplo: 569, -25, +1500.
Octal (base 8): los nmeros se representan a base 8 utilizando slo 8 dgitos
(de 0 a 7). Los enteros octales empiezan con 0. Por ejemplo: 056.
Binario: cuando un entero empieza con 0b (o 0B) se representan como una
serie de bits (0 y 1). Por ejemplo: 0B10011111

0x11 // formato hexadecimal equivale a decimal 17


11 // formato decimal
-152 // formato decimal
011 // formato octal equivale a decimal 9
0b11 // formato binario equivale a decimal 3

Tipo punto flotante (float)


El tipo punto flotante (float) se utiliza para los nmeros reales con el punto
decimal. Los datos de tipo float se pueden representar de varias maneras. Un
dato float es siempre consigno (signed).

0.

// = 0.0

-1.23 // = -1.23
23.45e6 // = 23.45 * 10^6
2e-5

// = 2.0 * 10^-5

3E+10 // = 3.0 * 10^10


.09E34 // = 0.09 * 10^34

Tipo carcter (char)


El tipo char es considerado como un entero por el compilador. No obstante,
se utiliza normalmente para los datos de tipo carcter. Un dato de tipo carcter
est encerrado entre comillas y codificado en un carcter ASCII.

59 // entero
'p' // carcter ASCII 'p'

Una secuencia de caracteres es denominada cadena (string). Las cadenas


estn encerradas entre comillas dobles, por ejemplo:

"Presione el botn RA0"

2.4 VARIABLES Y CONSTANTES

Definiciones
Una variable es un objeto nombrado capaz de contener un dato que puede
ser modificado durante la ejecucin de programa. En C, las variables tienen tipo,
que significa que es necesario especificar el tipo de dato que se le asigna a una
variable (int, float etc.). Las variables se almacenan en la memoria RAM y el
espacio de memoria que ocupan (en bytes) depende de su tipo.

/* dos lneas de programa consecutivas. En la primera lnea del programa


se define el tipo de variable */

int a = 1000; // Variable a es de tipo int y equivale a 1000


a = 15;

// a equivale a 15

Una constante tiene las mismas caractersticas que una variable excepto el
hecho de que su valor asignado no puede ser cambiado durante la ejecucin de
programa. A diferencia de las variables, las constantes se almacenan en la
memoria Flash del microcontrolador para guardar el mayor espacio posible de
memoria RAM. El compilador las reconoce por el nombre y el prefijo const. En
mikroC, el compilador reconoce automticamente el tipo de dato de una
constante, as que no es necesario especificar el tipo adicionalmente.

/* dos lneas de programa consecutivas */

const A = 1000 // el valor de la constante A est definido


A = 15;

// ERROR! no se puede modificar el valor de la constante

Cada variable o constante debe tener un identificador que lo distingue de


otras variables y constantes. Refirase a los ejemplos anteriores, a y A son
identificadores.

Reglas para nombrar


En mikroC, los identificadores pueden ser tan largos como quiera. Sin
embargo, hay varias restricciones:
Los identificadores pueden incluir cualquiera de los caracteres alfabticos AZ (a-z), los dgitos 0-9 y el carcter subrayado '_'. El compilador es sensible
a la diferencia entre minsculas y maysculas. Los nombres de funciones y
variables se escriben con frecuencia con minsculas, mientras que los
nombres de constantes se escriben con maysculas.
Los identificadores no pueden empezar con un dgito.
Los identificadores no pueden coincidir con las palabras clave del lenguaje
mikroC, porque son las palabras reservadas del compilador.
El compilador mikroC reconoce 33 palabras clave:
M I K R O C - PA L A B R A S C L AV E
absolute

data

if

return

typedef

asm

default

inline

rx

typeid

at

delete

int

sfr

typename

auto

do

io

short

union

bit

double

long

signed

unsigned

bool

else

mutable

sizeof

using

break

enum

namespace

static

virtual

case

explicit

operator

struct

void

catch

extern

org

switch

volatile

char

false

pascal

template

while

class

float

private

this

code

for

protected

throw

const

friend

public

true

continue

goto

register

try

Ejemplos de los identificadores vlidos e invlidos:

temperatura_V1
Presin

// OK

no_corresponder
dat2string

// OK

// OK

// OK

SuM3

// OK

_vtexto

// OK

7temp

// NO -- no puede empezar con un nmero

%ms_alto
if
j23.07.04

// NO -- no pueden contener caracteres especiales


// NO -- no puede coincidir con una palabra reservada
// NO -- no puede contener caracteres especiales (punto)

nombre de variable // NO -- no puede contener espacio en blanco

Declaracin de variables
Cada variable debe ser declarada antes de ser utilizada en el programa.
Como las variables se almacenan en la memoria RAM, es necesario reservar el
espacio para ellas (uno, dos o ms bytes). Al escribir un programa, usted sabe
qu tipo de datos quiere utilizar y qu tipo de datos espera como resultado de
una operacin, mientras que el compilador no lo sabe. No se olvide de que el
programa maneja las variables con los nombres asignados. El compilador las
reconoce como nmeros en la memoria RAM sin conocer su tamao y formato.
Para mejorar la legibilidad de cdigo, las variables se declaran con frecuencia al
principio de las funciones:

<tipo> variable;

Es posible declarar ms de una variable de una vez si tienen el mismo tipo.

<tipo> variable1, variable2, variable3;

Aparte del nombre y del tipo, a las variables se les asignan con frecuencia
los valores iniciales justamente enseguida de su declaracin. Esto no es un paso
obligatorio, sino una cuestin de buenas costumbres. Se parece a lo siguiente:

unsigned int peso; // Declarar una variable llamada peso


peso = 20;

// Asignar el valor 20 a la variable peso

Un mtodo ms rpido se le denomina declaracin con inicializacin


(asignacin de los valores iniciales):

unsigned int peso = 20; // peso est declarado y su valor es 20

Si hay varias variables con el mismo valor inicial asignado, el proceso se


puede simplificar:

unsigned int peso1 = peso2 = peso3 = 20;


int valor_inicial = un_mnimo_de_petrleo = 0;

Tenga cuidado de no declarar la misma variable otra vez dentro de la misma


funcin.
Puede modificar el contenido de una variable al asignarle un nuevo valor
tantas veces que quiera
Al declarar una variable, siempre piense en los valores que la variable
tendr que contener durante la ejecucin de programa. En el ejemplo
anterior, peso1 no se puede representar con un nmero con punto decimal
o un nmero con valor negativo.
Declaracin de constantes
Similar a las variables, las constantes deben ser declaradas antes de ser
utilizadas en el programa. En mikroC, no es obligatorio especificar el tipo de
constante al declararla. Por otra parte, las constantes deben ser inicializadas a la
vez que se declaran. El compilador reconoce las constantes por su prefijo const
utilizado en la declaracin. Dos siguientes declaraciones son equivalentes:

const int MINIMUM = -100; // Declarar constante MINIMUM


const MINIMUM = -100;

// Declarar constante MINIMUM

Las constantes pueden ser de cualquier tipo, incluyendo cadenas:

const T_MAX = 3.260E1;


const I_CLASS = 'A';

// constante de punto flotante T_MAX


// constante carcter I_CLASS

const Mensaje = "Presione el botn IZQUIERDA"; // constante de cadena


Mensaje

Las constantes de enumeracin son un tipo especial de constantes enteras


que hace un programa ms comprensible al asignar los nmeros ordinales a las
constantes. Por defecto, el valor 0 se asigna automticamente a la primera
constante entre llaves, el valor 1 a la segunda, el valor 2 a la tercera etc.

enum surtidores {AGUA,GASLEO,CLORO}; // AGUA = 0; GASLEO = 1; CLORO


=2

Es posible introducir directamente el valor de una constante dentro de la


lista de enumeraciones. El incremento se detiene al asignar un valor a un
elemento de matriz, despus se reinicia a partir del valor asignado. Vea el
siguiente ejemplo:

enum surtidores {AGUA,GASLEO=0,CLORO}; // AGUA = 0; GSOLEO = 0;


CLORO = 1

Las constantes de enumeracin se utilizan de la siguiente manera:

int Velocidad_de_ascensor
enum motor_de_ascensor {PARADA,INICIO,NORMAL,MXIMO};

Velocidad_de_ascensor = NORMAL; // Velocidad_de_ascensor = 2

Definir los nuevos tipos de datos


La palabra clave typedef le permite crear con facilidad los nuevos tipos de
datos.

typedef unsigned int positivo; // positivo es un sinnimo para el tipo sin signo
int
positivo a,b;
a = 10;
b = 5;

// Variables a y b son de tipo positivo


// Variable a equivale a 10
// Variable b equivale a 5

mbito de variables y constantes


Una variable o una constante es reconocida por el compilador en base de su
identificador. Un identificador tiene significado si el compilador lo puede
reconocer. El mbito de una variable o una constante es el rango de programa en
el que su identificador tiene significado. El mbito es determinado por el lugar en
el que se declara una variable o una constante. Intentar acceder a una variable o
una constante fuera de su mbito resulta en un error. Una variable o una
constante es invisible fuera de su mbito. Todas las variables y constantes que
pensamos utilizar en un programa deben ser declaradas anteriormente en el
cdigo. Las variables y constantes pueden ser globales o locales. Una variable
global se declara en el cdigo fuente, fuera de todas las funciones, mientras que
una variable local se declara dentro del cuerpo de la funcin o dentro de un
bloque anidado en una funcin.

A las variables globales se les puede acceder de cualquiera parte en el


cdigo, an dentro de las funciones con tal de que sean declaradas. El mbito de
una variable global est limitado por el fin del archivo fuente en el que ha sido
declarado.
El mbito de variables locales est limitado por el bloque encerrado entre
llaves {} en el que han sido declaradas. Por ejemplo, si estn declaradas en el
principio del cuerpo de funcin (igual que en la funcin main) su mbito est
entre el punto de declaracin y el fin de esa funcin. Refirase al ejemplo anterior.
A las variables locales declaradas en main() no se les puede acceder desde la
Funcin_1 y al revs.
Un bloque compuesto es un grupo de declaraciones y sentencias (que
pueden ser bloques tambin) encerradas entre llaves. Un bloque puede ser una
funcin, una estructura de control etc. Una variable declarada dentro de un
bloque se considera local, o sea, existe slo dentro del bloque. Sin embargo, las
variables declaradas fuera del mbito todava son visibles.
Aunque las constantes no pueden ser modificadas en el programa, siguen las
mismas reglas que las variables. Esto significa que son visibles dentro de su
bloque a excepcin de las constantes globales (declaradas fuera de cualquier
funcin). Las constantes se declaran normalmente en el inicio del cdigo fuera de
cualquier funcin (como variables globales).
Clases de almacenamiento

Las clases de almacenamiento se utilizan para definir el mbito y la vida de


variables, constantes y funciones dentro de un programa. En mikroC se pueden
utilizar diferentes clases de almacenamiento:
auto es una clase de almacenamiento por defecto para las variables
locales, as que se utiliza raramente. Se utiliza para definir que una variable
local tiene duracin local. La clase de almacenamiento auto no se puede
utilizar con variables globales.

static es una clase de almacenamiento por defecto para las variables


globales. Especifica que una variable es visible dentro del archivo. A las
variables locales declaradas con el prefijo static se les puede acceder
dentro del archivo fuente (o sea se comportan como variables globales).
extern: la palabra clave extern se utiliza cuando el programa est
compuesto por diferentes archivos fuente. Esto le permite utilizar una
variable, una constante o una funcin declarada en otro archivo. Por
supuesto, para compilar y enlazar este archivo correctamente, el mismo
debe ser incluido en su proyecto. En los siguientes ejemplos, el programa
consiste en dos archivos: File_1 y File_2. El File_1 utiliza una variable y una
funcin declaradas en File_2.
File 1:

extern int cnt;

// Variable cnt es visible en File_1

extern void hello(); // Funcin hello()se puede utilizar en File_1

void main(){
PORTA = cnt++;

// Cualquier modificacin de cnt en File_1 ser visible en

File_2
hello();

// Funcin hello()se puede llamar desde aqu

File 2:

int cnt = 0;
void hello();

void hello(){ // Modificaciones que afectan a la


.

// cnt en File_1 son visibles aqu

.
.
}

2.5 OPERADORES
Un operador es un smbolo que denota una operacin aritmtica, lgica u
otra

operacin

particular.

Dicho

de

manera

sencilla,

varias

operaciones

aritmticas y lgicas se realizan por medio de los operadores. Hay ms de 40


operaciones disponibles en el lenguaje C, pero se utiliza un mximo de 10-15 de

ellas en prctica. Cada operacin se realiza sobre uno o ms operandos que


pueden ser variables o constantes. Adems, cada operacin se caracteriza por la
prioridad de ejecucin y por la asociatividad.
OPERADORES ARITMTICOS
Los operadores aritmticos se utilizan en las operaciones aritmticas y
siempre devuelven resultados numricos. Hay dos tipos de operadores, los
unitarios y los binarios. A diferencia de las operaciones unitarias que se realizan
sobre un operando, las operaciones binarias se realizan sobre dos operandos. En
otras palabras, se requieren dos nmeros para ejecutar una operacin binaria. Por
ejemplo: a+b o a/b.

OPERADOR

OPERACIN

Adicin

Resta

Multiplicacin

Divisin

Resto de la divisin

int a,b,c; // Declarar 3 enteros a, b, c


a = 5;

// Inicializar a

b = 4;

// Inicializar b

c = a + b; // c = 9
c = c%2; // c = 1. Esta operacin se utiliza con frecuencia
// para comprobar la paridad. En este caso, el
// resultado es 1 lo que significa que la variable
// es un nmero imparo

OPERADORES DE ASIGNACIN
Hay dos tipos de asignacin en el lenguaje C:
Los operadores simples asignan los valores a las variables utilizando el
carcter comn '='. Por ejemplo: a =8
Las asignaciones compuestas son especficas para el lenguaje C. Consisten
en dos caracteres como se muestra en la tabla a la derecha. Se utilizan
para simplificar la sintaxis y habilitar la ejecucin ms rpida.

OPERADOR

E J E M P LO
Expresin

Equivalente

+=

a += 8

a=a+8

-=

a -= 8

a=a-8

*=

a *= 8

a=a*8

/=

a /= 8

a=a/8

%=

a %= 8

a=a%8

int a = 5; // Declarar e inicializar la variable a


a += 10; // a = a + 10 = 15

OPERADORES DE INCREMENTO Y DECREMENTO


Las operaciones de incremento y decremento por 1 se denotan con "++" y
"--". Estos caracteres pueden preceder o seguir a una variable. En primer caso (+
+x), la variable x ser incrementada por 1 antes de ser utilizada en la expresin.
De lo contrario, la variable se utilizar en la expresin antes de ser aumentada
por 1. Lo mismo se aplica a la operacin de decremento.
OPERADOR
++
--

int a, b, c;
a = b = 5;
c = 1 + a++; // c = 6

E J E M P LO
++a
a++
--b
b--

DESCRIPCIN
Variable "a" es incrementada por 1
Variable "a" es decrementada por 1

b = ++c + a // b = 7 + 6 = 13

OPERADORES RELACIONALES
Los operadores relacionales se utilizan en comparaciones con el propsito
de comparar dos valores. En mikroC, si una expresin es evaluada como falsa
(false), el operador devuelve 0, mientras que si una oracin es evaluada como
verdadera (true), devuelve 1. Esto se utiliza en expresiones tales como si la
expresin es evaluada como verdadera, entonces...
OPERADO

DESCRIPCI

EJEMPL

CONDICIN

VERACIDAD

>

mayor que

b>a

si b es mayor que a

a >= 5

si a es mayor o igual que 5

a<b

si a es menor que b

a <= b

si a es menor o igual que b

mayor

>=

igual

que

<

menor que
menor

<=

igual

que

==

igual que

a == 6

si a es igual que 6

!=

desigual que

a != b

si a es desigual que b

DE

int prop;
int var = 5;
prop = var < 10; // Expresin es evaluada como verdadera, prop = 1

OPERADORES LGICOS
Hay tres tipos de operaciones lgicas en el lenguaje C: Y (AND) lgico, O
(OR) lgico y negacin - NO (NOT) lgico. Los operadores lgicos devuelven
verdadero (1 lgico) si la expresin evaluada es distinta de cero. En caso

contrario, devuelve falso (0 lgico) si la expresin evaluada equivale a cero. Esto


es muy importante porque las operaciones lgicas se realizan generalmente sobre
las expresiones, y no sobre las variables (nmeros) particulares en el programa.
Por lo tanto, las operaciones lgicas se refieren a la veracidad de toda la
expresin.
Por ejemplo: 1 && 0 es igual a (expresin verdadera) && (expresin
falsa)
El resultado 0, o sea - Falso en ambos casos.
OPERADOR

FUNCIN

&&

||

NO

OPERADORES DE MANEJO DE BITS


A diferencia de las operaciones lgicas que se realizan sobre los valores o
expresiones, las operaciones de manejo de bits se realizan sobre los bits de un
operando. Se enumeran en la siguiente tabla:
OPERADO
R
~
<<

>>
&

EJEMPL

DESCRIPCIN

Complemento a uno
Desplazamiento

a = ~b
a

la

izquierda
Desplazamiento
derecha

R E S U LTA D O
b=5
b

a = -5
=

a = b << 2 1111001
1

la

a = b >> 2 1111001
1

Y lgico para manejo de c = a & b

bits

1110001
1

11001100
a

00011110

= c

11000000

1100110
0
a

1110001
O lgico para manejo de

bits

c=a|b

1
b

= 11101111

1100110
0
a

1110001
EXOR lgico para manejo

de bits

c=a^b

1
b

= 00101111

1100110
0
Note que el resultado de la operacin de desplazamiento a la derecha
depende del signo de la variable. En caso de que el operando se aplique a una
variable sin signo o positiva, se introducirn los ceros en el espacio vaco creado
por desplazamiento. Si se aplica a un entero con signo negativo, se introducir un
1 para mantener el signo correcto de la variable.
CMO UTILIZAR LOS OPERADORES?
Aparte de los operadores de asignacin, dos operadores no deben estar
escritos uno junto al otro.

x*%12; // esta expresin generar un error

Cada operador tiene su prioridad y asociatividad como se muestra en la


tabla:

Similar a las expresiones aritmticas, los operadores se agrupan juntos por


medio de parntesis. Primero se calculan las expresiones encerradas entre
parntesis. Si es necesario, se pueden utilizar los parntesis mltiples
(anidados).
PRIORIDA
D
Alta

OPERADORES
() [] -> .

A S O C I AT I V I D A
D
de

*/%
+<>
< <= > >=
== !=
&
^
|
&&
||
?:

derecha

! ~ ++ -- +(unitario) -(unitario) *Puntero de


&Puntero

izquierda
derecha

izquierda
de

izquierda

derecha
de

izquierda

derecha
de

izquierda

derecha
de

izquierda

derecha
de

izquierda

derecha
de

izquierda

derecha
de

izquierda

derecha
de

izquierda

derecha
de

izquierda

derecha
de

derecha

izquierda
de

derecha

izquierda
Baja

= += -= *= /= /= &= ^= |= <= >=

int a, b, res;
a = 10;
b = 100;
res = a*(a + b); // resultado = 1100
res = a*a + b; // resultado = 200

de

izquierda

derecha

CONVERSIN DE TIPOS DE DATOS


Algunas operaciones implican conversin de datos. Por ejemplo, si divide
dos valores enteros, hay una alta posibilidad de que el resultado no sea un entero.
El mikroC realiza una conversin automtica cuando se requiera.
Si dos operandos de tipo diferente se utilizan en una operacin aritmtica,
el tipo de operando de la prioridad ms baja se convierte automticamente en el
tipo de operando de la prioridad ms alta. Los tipos de datos principales se
colocan segn el siguiente orden jerrquico:

La autoconversin se realiza asimismo en las operaciones de asignacin. El


resultado de la expresin de la derecha del operador de la asignacin siempre se
convierte en el tipo de la variable de la izquierda del operador. Si el resultado es
de tipo de la prioridad ms alta, se descarta o se redondea para coincidir con el
tipo de la variable. Al convertir un dato real en un entero, siempre se descartan
los nmeros que siguen al punto decimal.

int x;

// A la variable x se le asigna el tipo integer (un entero)

x = 3;

// A la variable x se le asigna el valor 3

x+ = 3.14; // El valor 3.14 se agrega a la variable x al


// realizar la operacin de asignacin

/* El resultado de la adicin es 6 en vez de 6.14, como era de esperar.


Para obtener el resultado esperado sin descartar los nmeros que siguen al
punto decimal, se debe declarar x como un punto flotante. */

Para realizar una conversin explcita, antes de escribir una expresin o una
variable hay que especificar el tipo de resultado de operacin entre parntesis.

double distancia, tiempo, velocidad;


distancia = 0.89;
tiempo = 0.1;
velocidad = (int)(a/b); // c = (int)8.9 = 8.0
velocidad = ((int)a)/b; // c = 0/0.1 = 0.0

2.6 ESTRUCTURAS DE CONTROL


ESTRUCTURAS CONDICIONALES
Las condiciones son ingredientes comunes de un programa. Las condiciones
permiten ejecutar una o varias sentencias dependiendo de validez de una
expresin. En otras palabras, Si se cumple la condicin (...), se debe hacer (...).
De lo contrario, si la condicin no se cumple, se debe hacer (...). Los operandos
condicionales if-else y switch se utilizan en las operaciones condicionales. Una
sentencia condicional puede ser seguida por una sola sentencia o por un bloque
de sentencias a ser ejecutadas.
OPERADOR CONDICIONAL if-else

El operador if se puede utilizar solo o asociado al operador else (if-else).


Ejemplo del operador if:

if(expresin) operacin;

Si el resultado de la expresin encerrada entre parntesis es verdadero


(distinto de 0) la operacin se realiza y el programa contina con la ejecucin. Si
el resultado de la expresin es falso (0), la operacin no se realiza y el programa
contina inmediatamente con la ejecucin.
Como hemos mencionado, la otra forma combina tanto el operador if como
el else:

if(expresin) operacin1 else operacin2;

Si el resultado de la expresin es verdadero (distinto de 0), se realiza


operacin1, de lo contrario se realiza la operacin2. Despus de realizar una de
las operaciones, el programa contina con la ejecucin.
La sentencia if-else se parece a lo siguiente:

if(expresin)
operacin1
else
operacin2

Si operacin1 u operacin2 est compuesta, escriba una lista de sentencias


encerradas entre llaves. Por ejemplo:

if(expresin) {
... //
... // operacin1
...} //
else
operacin2

El operador if-else se puede sustituir por el operador condicional '?:':

(expresin1)? expresin2 : expresin3

Si el valor de la expresin1 es distinto de 0 (verdadero), el resultado de la


expresin entera ser equivalente al resultado obtenido de la expresin2. De lo
contrario, si la expresin1 es 0 (falso), el resultado de la expresin entera ser
equivalente al resultado obtenido de la expresin3. Por ejemplo:

maximum = (a>b)? a : b // A la variable maximum se le asigna el


// valor de la variable mayor(a o b)

Operador Switch
A diferencia de la sentencia if-else que selecciona entre dos opciones en el
programa, el operador switch permite elegir entre varias opciones. La sintaxis de
la sentencia switch es:

switch (selector) // Selector es de tipo char o int


{
case constante1:
operacin1 // El grupo de operadores que se ejecutan si
...

// el selector y la constante1 son equivalentes

break;

case constante2:

operacin2 // El grupo de operadores se ejecuta si


...

// el selector y la constante2 son equivalentes

break;
...
default:

operacin_esperada // El grupo de operadores que se ejecuta si

...

// ninguna constante equivale al selector

break;
}

La operacin switch se ejecuta de la siguiente manera: primero se ejecuta el


selector y se compara con la constante1. Si coinciden, las sentencias que
pertenecen a ese bloque se ejecutan hasta llegar a la palabra clave break o hasta
el final de la operacin switch. Si no coinciden, el selector se compara con la
constante2. Si coinciden, las sentencias que pertenecen a ese bloque se ejecutan
hasta llegar a la palabra clave break etc. Si el selector no coincide con ninguna
constante, se ejecutarn las operaciones que siguen al operador default.
Tambin es posible comparar una expresin con un grupo de constantes. Si
coincide con alguna de ellas, se ejecutarn las operaciones apropiadas:

switch (das) // La variable das representa un da de la semana.


{ // Es necesario determinar si es un da laborable o no lo es
case1:case2:case3:case4:case5: LCD_message = 'Da laborable'; break;
case6:case7: LCD_message = 'Fin de semana'; break;
default:LCD_message_1 = 'Elija un da de la semana'; break;
}

La palabra clave de C break se puede utilizar en cualquier tipo de bloques.


Al utilizar break, es posible salir de un bloque aunque la condicin para su final

no se haya cumplido. Se puede utilizar para terminar un bucle infinito, o para


forzar un bucle a terminar antes de lo normal.
BUCLES
A menudo es necesario repetir una cierta operacin un par de veces en el
programa. Un conjunto de comandos que se repiten es denominado un bucle de
programa. Cuntas veces se ejecutar, es decir cunto tiempo el programa se
quedar en el bucle, depende de las condiciones de salir del bucle.
Bucle While
El bucle while se parece a lo siguiente:

while(expresin){
comandos
...
}

Los comandos se ejecutan repetidamente (el programa se queda en el


bucle) hasta que la expresin llegue a ser falsa. Si la expresin es falsa en la
entrada del bucle, entonces el bucle no se ejecutar y el programa continuar
desde el fin del bucle while.
Un tipo especial del bucle de programa es un bucle infinito. Se forma si la
condicin sigue sin cambios dentro del bucle. La ejecucin es simple en este caso
ya que el resultado entre llaves es siempre verdadero (1=verdadero), lo que
significa que el programa se queda en el mismo bucle:

while(1){ // En vez de "while(1)", se puede escribir "while(true)"

...

// Expresiones encerradas entre llaves se ejecutarn

...

// repetidamente (bucle infinito)

Bucle For
El bucle for se parece a lo siguiente:

for(expresin_inicial; expresin_de_condicin; cambiar_expresin) {


operaciones
...
}

La ejecucin de esta secuencia de programa es similar al bucle while, salvo


que en este caso el proceso de especificar el valor inicial (inicializacin) se realice
en la declaracin. La expresin_ inicial especifica la variable inicial del bucle, que
ms tarde se compara con la expresin_ de_condicin antes de entrar al bucle.
Las operaciones dentro del bucle se ejecutan repetidamente y despus de cada
iteracin el valor de la expresin_inicial se incrementa de acuerdo con la regla
cambiar_expresin. La iteracin contina hasta que la expresin_de_condicin
llegue a ser falsa.

for(k=0; k<5; k++) // La variable k se incrementa 5 veces (de 1 a 4) y


operacin
...

// cada vez se repite la expresin operacin

La operacin se ejecutar cinco veces. Luego, al comprobar se valida que la


expresin k<5 sea falsa (despus de 5 iteraciones k=5) y el programa saldr del
bucle for.
Bucle Do-while
El bucle do-while se parece a lo siguiente:

do
operacin
while (cambiar_condicin);

La expresin cambiar_condicin se ejecuta al final del bucle, que significa


que operacin se ejecuta como mnimo una vez sin reparar en que si la condicin
es verdadera o falsa. Si el resultado es distinto de 0 (verdadero), el procedimiento
se repite.
Todos los siguientes ejemplos son equivalentes. Esta parte del cdigo
visualiza "hello" en un LCD 10 veces con un retardo de un segundo. Note que en
este ejemplo se utilizan funciones predefinidas, que se encuentran en las libreras
del compilador mikroC PRO for PIC. No obstante le aconsejamos que no trate de
entenderlas en detalle. Su comportamiento general dentro del bucle se explica
por medio de los comentarios.

i = 0; // Inicializacin del contador

while (i<10) {

// Condicin

Lcd_Out(1,3,"hello"); // Visualizar hello en el LCD

Delay_ms(1000);

// Retardo de 1000 ms

Lcd_Cmd(_LCD_CLEAR); // Borrar el LCD


Delay_ms(500);
i++;

// Retardo de 500ms
// Contador se incrementa

}
for(i=0; i<10; i++) {

// Inicializacin, condicin, incremento

Lcd_Out(1,3,"hello"); // Visualizar hello en el LCD


Delay_ms(1000);

// Retardo de 1000 ms

Lcd_Cmd(_LCD_CLEAR);
Delay_ms(500);

// Borrar el LCD

// Retardo de 500ms

}
i = 0;

// Inicializacin del contador

do {
Lcd_Out(1,3,"hello"); // Visualizar hello en el LCD
Delay_ms(1000);

// Retardo de 1000 ms

Lcd_Cmd(_LCD_CLEAR); // Borrar LCD


Delay_ms(500);
i++;

// Retardo de 500ms
// Contador se incrementa

}
while (i<10);

// Condicin

SENTENCIAS DE SALTO
SENTENCIA BREAK
A veces es necesario detener y salir de un bucle dentro de su cuerpo. La
sentencia break se puede utilizar dentro de cualquier bucle (while, for, do while) y
en las sentencias switch tambin. En stas la sentencia break se utiliza para salir
de las sentencias switch si la condicin case es verdadera. En este ejemplo,
Esperar est parpadeando en la pantalla LCD hasta que el programa detecte un
uno lgico en el pin 0 del puerto PORTA.

while(1){ // Bucle infinito


if(PORTA.F0 == 1)
break;

// Probar si el estado lgico del pin 0 del puerto

// PORTA es 1; si equivale, salir del bucle

Lcd_Out(1,3,"Esperar"); // Visualizar Esperar en el LCD


Delay_ms(1000);

// Retardo de 1000 ms

Lcd_Cmd(_LCD_CLEAR);
Delay_ms(500);

// Borrar LCD

// Retardo de 500ms

SENTENCIA CONTINUE

La sentencia continue colocada dentro de un bucle se utiliza para saltar una


iteracin. A diferencia de la sentencia break, el programa se queda dentro del
bucle y las iteraciones continan.

// Si x=7, puede ocurrir una divisin por 0.


// continue se utiliza aqu para evitar esta situacin.
x=1;
while (x<=10) {
if (x == 7) { // saltar x=7 para evitar divisin por 0
Lcd_Cmd(_LCD_CLEAR);
Lcd_Out(1,3,"Division by 0");
Delay_ms(1000);
x++;
continue; // Despus de esta lnea, saltar a la sentencia while con x=8
}

a = 1/(x-7); // Esta divisin generar un error si x=7

/* Muchas operaciones pueden ocurrir aqu */

Lcd_Out(1,3,"Division is OK"); // Poner este mensaje en el LCD


Delay_ms(1000);
x++;
}

SENTENCIA GOTO
La sentencia goto le permite hacer un salto absoluto al otro punto en el
programa. Esta caracterstica se debe utilizar con precaucin ya que su ejecucin
puede causar un salto incondicional sin hacer caso a todos los tipos de
limitaciones de anidacin. El punto destino es identificado por una etiqueta,
utilizada como un argumento para la sentencia goto. Una etiqueta consiste en un
identificador vlido seguido por un colon (:).

...
if(CO2_sensor) goto aire acondicionado; // Si se consta que el valor
...

// de la variable CO2_sensor =1
// hacer salto a la lnea de programa
// Aire acondicionado

...
Aire acondicionado:
ejecutar

// Desde aqu sigue la parte del cdigo que se

// en caso de una concentracin de CO2 demasiado


alta
...

// en el ambiente

2.7 TIPOS DE DATOS AVANZADOS


MATRICES
Una matriz es una lista de elementos del mismo tipo colocados en
localidades de memoria contiguas. Cada elemento es referenciado por un ndice.
Para declarar una matriz, es necesario especificar el tipo de sus elementos
(denominado tipo de matriz), su nombre y el nmero de sus elementos
encerrados entre corchetes. Todos los elementos de una matriz tienen el mismo
tipo.

tipo_de_matriz nombre_de_matriz [n_de_elementos];

Los elementos de una matriz se identifican por su posicin. En C, el ndice


va desde 0 (el primer elemento de una matriz) a N-1 (N es el nmero de
elementos contenidos en una matriz). El compilador tiene que saber cuntas
localidades de memoria debe alojar al declarar una matriz. El tamao de una
matiz no puede ser una variable. Por eso, se pueden utilizar dos mtodos:

// mtodo 1
int display [3]; // Declaracin de la matriz display capaz de contener 3 enteros
// mtodo 2
const DGITOS = 5;

char Matriz_nueva[DGITOS]; // Declaracin de la matriz Matriz_nueva


// capaz de contener 5 enteros

Una matriz se puede inicializar a la vez que se declara, o ms tarde en el


programa. En ambos casos, este paso se realiza al utilizar llaves:

int array_1[3] = {10,1,100};

Para leer o modificar un elemento de matriz del ejemplo anterior, basta con
introducir su ndice encerrado entre corchetes:

/* Se supone que a ha sido declarado anteriormente como un entero */

a = array_1[0]; // A la variable a se le asigna el valor del miembro de matriz

// con ndice 0 (a = 10)


array_1[2] = 20; // Miembro de matriz array_1[2] es modificado (nuevo valor es
20)

El siguiente programa cambia el orden de los elementos de una matriz. Note


que el ndice se puede expresar mediante variables y operaciones bsicas.

void main() {
const MUESTRAS_DE_AGUA = 4; // Valor de la constante MUESTRAS_DE_AGUA
es 4
int i, temp; // Variables i y temp son de tipo int
int profunidad_de_sonda [MUESTRAS_DE_AGUA] = {24,25,1,1987};// Todos

// los miembros de la matriz profundidad


// de sonda son de tipo int

for(i=0;i<(MUESTRAS_DE_AGUA/2);i++){ // Bucle se ejecuta 2 veces


temp = profundiad_de_sonda [i];

// temp se utiliza para guardar un valor

// temporalmente
profundiad_de_sonda [i] = profundiad_de_sonda [MUESTRAS_DE_AGUA-1-i];
profundiad_de_sonda [MUESTRAS_DE_AGUA-1-i] = temp;
}

//

Aqu

{1987,1,25,24}
}

tenemos:

profundidad_de_sonda

[MUESTRAS_DE_AGUA]

MATRICES BIDIMENSIONALES
Aparte de las matrices unidimensionales que se pueden interpretar como
una

lista

de

valores,

multidimensionales.
bidimensionales,

En

el
esta

tambin

lenguaje
parte

vamos

denominadas

le

permite

declarar

matrices

describir

slo

matrices

tablas

matrices.

las
Una

matriz

bidimensional se declara al especificar el tipo de dato de matriz, el nombre de


matriz y el tamao de cada dimensin.

tipo_de_matriz nombre_de_matriz [nmero_de_filas] [nmero_de_columnas];

En la declaracin de esta matriz nmero_de_filas y nmero_de_columnas


representan el nmero de filas y columnas en las que consiste una tabla,
respectivamente. Vea la siguiente matriz bidimensional:

int Tabla [3][4]; // Tabla se define de modo que tenga 3 filas y 4 columnas

Esta matriz se puede representar en la forma de una tabla.


tabla[0][0]

tabla[0][1]

tabla[0][2]

tabla[0][3]

tabla[1][0]

tabla[1][1]

tabla[1][2]

tabla[1][3]

tabla[2][0]

tabla[2][1]

tabla[2][2]

tabla[2][3]

Similar a las matrices unidimesionales, es posible asignar los valores a los


elementos de una tabla en la lnea de declaracin. La asignacin debe ser
realizada lnea a lnea como en el siguiente ejemplo. Como hemos visto
anteriormente, esta matriz tiene dos filas y tres columnas:

int Tabla [2][3]= { {3,42,1},{7,7,19} };

La matriz anterior se puede representar tambin en la forma de una tabla de


valores:
3

42

19

PUNTEROS
Un puntero es una variable destinada a recibir una direccin. Un puntero
apunta a una localidad de memoria, referenciada por una direccin. En C, la
direccin de un objeto se puede obtener por medio un operador unitario &. Para
acceder al contenido de la memoria en una direccin especfica (tambin llamado
objeto apuntado), se utiliza un operador de indireccin (*).

'&n' es la direccin de la localidad de memoria 'n'.


'*(&n)' es el contenido de la direccin '(&n)', o sea de 'n'.
Para declarar un puntero, se debe que especificar el tipo de la variable
apuntada:

tipo_de_variable *puntero;

En esta etapa, el puntero mi_puntero apunta al valor almacenado en esta


localidad de memoria, o sea, a un valor desconocido. As que, una inicializacin es
muy recomendable:

puntero = &variable;

Ahora, puntero contiene la direccin de variable.

Para acceder al contenido de la variable apuntada, debe utilizar *. El


siguiente ejemplo muestra el contenido de memoria dependiendo de la accin
realizada por medio del puntero.

Los punteros son muy tiles para manejar las matrices. En este caso, un
puntero se utilizar para apuntar al primer elemento de una matriz. Debido al
hecho de que es posible realizar operaciones bsicas sobre los punteros
(aritmtica de punteros), es fcil manejar los elementos de una matriz.
Fjese en la diferencia entre *v+1 y *(v+1) en el siguiente ejemplo:

short int voltio[3] = {0,5,10};


short int *v;
v = &(voltio[0]); // v contiene la direccin de voltio[0]
*(v+1) = 2;

// voltio[1] = 2

voltio[2] = *v+1; // tab[2] = 1 (tab[0] + 1)


*(v+2) = *(v+1); // voltio[2] = 2

v++;

// v contiene la direccin de voltio[1]

*v = 1;

// voltio[1] = 1

Los punteros tambin pueden ser declarados con el prefijo const. En este
caso, su valor no puede ser modificado despus de la inicializacin, similar
a una constante.
A diferencia de C, el mikroC no admite alojamiento dinmico.
ESTRUCTURAS
Ya hemos visto cmo agrupar los elementos dentro de matrices. No
obstante, al utilizar este mtodo todos los elementos deben ser del mismo tipo. Al
utilizar estructuras, es posible agrupar diferentes tipos de variables bajo el mismo
nombre. Las variables dentro de una estructura se le denominan los miembros de
la estructura. Las estructuras de datos se declaran al utilizar la siguiente sintaxis:

struct nombre_de_estructura {
tipo1_de_miembro1 miembro1;
tipo2_de_miembro2 miembro2;
tipo3_de_miembro3 miembro3;
..
};

No es posible inicializar variables dentro de la declaracin de la estructura


de datos:

struct generador {
int voltaje;
char corriente;
};

Entonces, podr definir los objetos denominados turbina en el cdigo. A


cada uno de estos tres objetos (turbinas) se le asignan las variables corriente y
voltaje.

struct generadores turbina_1, turbina_2, turbina_3;

Para acceder a las variables, es preciso utilizar el operador '.'

turbina_3.voltaje = 150;
turbina_3.corriente = 12;

Por supuesto, igual que al utilizar los punteros, todava se le permite realizar
operaciones por medio de operadores y sentencias definidos en las partes
anteriores.
Si est familiarizado con el lenguaje C, recuerde que mikroC no admite la
inicializacin de los miembros de estructura por medio de las llaves. Por ejemplo,
conjunto_1 ={15,m}; devuelve un error en mikroC.
2.8 FUNCIONES
Una funcin es una subrutina que contiene una lista de sentencias a
realizar. La idea principal es dividir un programa en varias partes utilizando estas

funciones para resolver el problema inicial con ms facilidad. Adems, las


funciones nos permiten utilizar las destrezas y el conocimiento de otros
programadores. Una funcin se ejecuta cada vez que se llame dentro de otra
funcin. En C, un programa contiene como mnimo una funcin, la funcin main(),
aunque el nmero de funciones es normalmente mayor. Al utilizar funciones el
cdigo se hace ms corto ya que es posible llamar una funcin tantas veces como
se necesite. En C, el cdigo normalmente consiste en muchas funciones. No
obstante, en caso de que su programa sea muy corto y simple, puede escribir
todas las sentencias dentro de la funcin principal.
FUNCIN PRINCIPAL
La funcin principal main() es una funcin particular puesto que es la que se
ejecuta al iniciar el programa. Adems, el programa termina una vez completada
la ejecucin de esta funcin. El compilador reconoce automticamente esta
funcin y no es posible llamarla por otra funcin. La sintaxis de esta funcin es la
siguiente:

void main (void) {

/* el primer 'void' significa que main no devuelve ningn valor. El segundo


'void' significa que no recibe ningn valor. Note que el compilador
tambin admite la siguiente sintaxis: 'main()' o 'void main()' o
'main(void)' */

..

/* --- Introduzca su programa aqu --- */

.
};

Esto significa que f es una funcin que recibe un nmero real x como
parmetro y devuelve 2*x-y.
La misma funcin en C se parece a lo siguiente:

float f (float x, float y) // variables flotantes x y y se pueden utilizar en f


{
float r;

// declarar r para almacenar el resultado

r = 2*x - y; // almacenar el resultado del clculo en r


return r;

// devolver el valor de r

Cada funcin debe ser declarada apropiadamente para poder interpretarla


correctamente durante el proceso de compilacin. La declaracin contiene los
siguientes elementos:
Tipo de resultado (valor devuelto): tipo de dato del valor devuelto

Nombre de funcin: es un identificador que hace posible llamar a una


funcin.
Declaracin de parmetros se parece a la declaracin de variable regular
(por ejemplo: float x). Cada parmetro consiste en una variable, constante,
puntero o matriz, precedidos por la etiqueta de tipo de dato. Se utilizan
para pasar la informacin a la funcin al llamarla. Los parmetros
diferentes estn delimitados por comas.
Cuerpo de funcin: bloque de sentencias dentro de llaves
Una funcin se parece a lo siguiente:

tipo_de_resultado nombre_de_funcin (tipo argumento1, tipo argumento2,...)


{
Sentencia;
Sentencia;
...
return ...
}

Note que una funcin no necesita parmetros (funcin main() por ejemplo),
pero

debe

estar

entre

parntesis.

En

caso

contrario,

el

compilador

malinterpretara la funcin. Para hacerlo ms claro, puede sustituir el espacio en


blanco encerrado entre parntesis por la palabra clave void: main (void).
VALOR DEVUELTO

Una funcin puede devolver un valor (esto no es obligatorio) por medio de


la palabra clave return. Al llegar a return, la funcin evala un valor (puede ser
una expresin) y lo devuelve a la lnea de programa desde la que fue llamada.

return r;

// Devolver el valor contenido en r

return (2*x - y); // Devolver el valor de la expresin 2*x-y

Una funcin no puede devolver ms de un valor, pero puede devolver un


puntero o una estructura. Tenga cuidado al utilizar matrices y punteros. El
siguiente ejemplo es un error tpico:

int *reverse(int *tab) // Esta funcin debe devolver una matriz r


{

// cuyo contenido est en orden inverso con


// respecto a la matriz tab
int r[DIM]; // Declaracin de una nueva matriz denominada r
int i;
for(i=0;i<DIM;i++)

// Bucle que copia el contenido de tab en r

r[i] = tab[DIM-1-i]; // al invertir el orden

return r; // Devolver el valor r


}

En realidad, el compilador reserva memoria para el almacenamiento de


variables de la funcin reverse slo durante su ejecucin. Una vez completada la
ejecucin de reverse, la localidad de memoria para la variable i o para la matriz r
ya no est reservada. Esto significa que la direccin que contiene los valores de i
o r[] est libre para introducir datos nuevos. Concretamente, la funcin devuelve
slo el valor &r[0], as que slo el primer elemento de la matriz tab ser
almacenado en la memoria. Las dems localidades de memoria, tales como
&tab[1], &tab[2], etc. sern consideradas por el compilador como espacios en
blanco, o sea, estarn listas para recibir los nuevos valores.
Para escribir esta funcin es necesario pasar la matriz r [] como parmetro
(vea la subseccin Pasar los parmetros).
La funcin puede contener ms de una sentencia return. En este caso, al
ejecutar la primera sentencia return, la funcin devuelve el valor correspondiente
y se detiene la ejecucin de la funcin.

float abs (float x, float y) // Devolver el valor absoluto de 2*x-y


{
if ((2*x - y) >= 0)
return (2*x - y);
else
return (-2*x + y);
}

Si la funcin no devuelve ningn valor, la palabra void debe ser utilizada


como un tipo de resultado en la declaracin. En este caso, la sentencia return no

debe ser seguida por ninguna expresin. Puede ser omitida como en el siguiente
ejemplo:

void wait_1 (unsigned int a)


{
cnt ++;

// Incremento de una variable global cnt

Delay_ms(a) ; // Ejecucin de la funcin Delay_ms


}

// Note que Delay_ms no devuelve nada

DECLARAR PROTOTIPOS DE FUNCIONES


Para utilizar una funcin, el compilador debe ser consciente de su presencia
en el programa. En la programacin en C, los programadores normalmente
primero escriben la funcin main() y luego las funciones adicionales. Para avisar al
compilador de la presencia de las funciones adicionales, se requiere declarar los
prototipos de funciones en el principio de programa antes de la funcin main(). Un
prototipo de funcin est compuesto por:
tipo de resultado
nombre de funcin
tipos de parmetros
un punto y coma (;)
El prototipo de la funcin main no necesita ser declarado.

float f (float, float);

/* no es obligatorio escribir los nombres de los parmetros. Este prototipo


informa al compilador: en el programa se utilizar la funcin f,
que utiliza dos parmetros de tipo float y devuelve el resultado del tipo
float. */

LLAMAR UNA FUNCIN


Mientras una funcin es definida y su prototipo declarado, se puede utilizar
en culquier parte de programa. Sin embargo, como la funcin main es 'raiz' del
programa, no puede ser llamada de ninguna parte de programa. Para ejecutar
una funcin, es necesario escribir su nombre y los parmetros asociados. Vea los
siguientes ejemplos:

float resultado,a,b; // resultado,a,b,time deben coincidir con los tipos


// definidos
int time = 100;

// en la declaracin de las funciones f y wait_1

a = 10.54;
b = 5.2;
resultado = f(a,b); // Ejecutar la funcin f por medio de los parmetros a y b

// El valor devuelto se le asigna a la variable resultado

pausa_1(tiempo);

// Ejecutar la funcin pausa_1 por medio de la variable

tiempo
funcinX();

// Ejecutar la funcin funcinX (sin parmetros)

Cuando se llama una funcin, el programa salta a la funcin llamada, la


ejecuta, despus vuelve a la lnea desde la que fue llamada.
PASAR LOS PARMETROS
Al llamar una funcin, se le pasan los parmetros. En C existen dos formas
diferentes para pasar parmetros a una funcin.
El primer mtodo, denominado paso por valor, es el ms fcil. En este
caso, los parmetros se pueden considerar como variables locales de la funcin.
Cuando se llama una funcin, el valor de cada parmetro se copia a un nuevo
espacio de memoria reservado durante la ejecucin de la funcin. Como los
parmetros se consideran como variables locales por el compilador, sus valores
pueden ser modificados dentro de la funcin, pero sus modificaciones no se
quedan en la memoria una vez completada la ejecucin de la funcin.
Tenga en cuenta de que la funcin devuelve un valor, y no una variable.
Adems, se crean copias de los valores de los parmetros, por lo que sus nombres
en la funcin f pueden ser diferentes de los parmetros utilizados en la main(). La
mayor desventaja del paso por el valor es que la nica interaccin que una
funcin tiene con el resto del programa es el valor devuelto de un solo resultado
(o la modificacin de las variables globales).
El otro mtodo, denominado 'paso por direccin' le permite sobrepasar este
problema. En vez de enviar el valor de una variable al llamar a funcin, se debe
enviar la direccin de memoria del valor. Entonces, la funcin llamada ser capaz
de modificar el contenido de esta localidad de memoria.

// Funcin 'sort'ordena los miembros de la matriz por valor ascendente


// y devuelve el miembro con mximo valor

int sort(int *); // Prototipo de funcin


const SIZE = 5; // Nmero de miembros a ordenar

void main() {
int maximum, input[SIZE] = {5,10,3,12,0}; // Declaracin de variables en la
matriz
maximum = sort(input);

// Llamar a funcin y asignarle el mximo

// valor a la variable maximum


}

int sort(int *sequence) {


int i, temp, permut;
permut = 1;

while(permut!=0) {

// Declaracin de variables
// Bandera de bit indica que se ha hecho una permutacin

// Quedarse en el bucle hasta reinicar la bandera

permut = 0;

// Bandera reiniciada

for(i=0;i<SIZE-1;i++) { // Comparar y oredenar los miembros de la


// matriz (dos a dos)

if(sequence [i] > sequence[i+1]){


temp = sequence [i];
sequence[i] = sequence[i+1];
sequence[i+1] = temp;
permut = 1; // Se ha hecho una permutacin, bandera de bit
//se pone a uno
}
}
}

return sequence[SIZE-1]; // Devolver el valor del ltimo miembro

} // que es al mismo tiempo el miembro con el mximo valor

En este ejemplo, por medio de una funcin se realizan dos operaciones:


ordena los miembros de la matriz por valor asdendente y devuelve el mximo
valor.
Para utilizar una matriz en una funcin es necesario asignar la direccin a la
matriz (o a su primer miembro). Vea el siguiente ejemplo:

float mtodo_1(int[]);

// Declaracin de prototipo de la funcin Mtodo_1

float mtodo_2(int*);

// Declaracin de prototipo de la funcin Mtodo_2

const NMERO_DE_MEDICIONES = 7; // Nmero de los miembros de la matriz

void main()
{
double promedio1, promedio2; // Declaracin de las variables promedio1
// y promedio2
int voltaje [NMERO_DE_MEDICIONES] = {7,8,3,5,6,1,9}; // Declaracin de la
// matriz voltaje
promedio1 = mtodo_1(&voltaje[0]); // Parmetro de la funcin es la direccin
// del primer miembro
promedio2 = mtodo_2(voltaje); // Parmetro de la funcin es la direccin de

// la matriz
}

//

float mtodo_1(int voltaje[])

// Inicio de la funcin mtodo_1

{
int i, suma;

// Declaracin de las variables locales i y suma

for(i=0;i<NMERO_DE_MEDICIONES;i++) // Clculo del valor promedio de


voltaje
suma += voltaje[i];

// Es posible utilizar *(voltaje+i)en vez de

voltaje[i]

return(suma/NMERO_DE_MEDICIONES);
}

//

float mtodo_2 (int *voltaje) //Inicio de la funcin mtodo_2


{
int i, suma;

// Declaracin de las variables locales i y suma

for(i=0;i<NMERO_DE_MEDICIONES;i++) // Clculo del valor promedio de


voltaje
suma += *(voltaje+i);

// Es posible utilizar voltaje[i] en vez de

*(voltaje+i)

return(suma/NMERO_DE_MEDICIONES);
}

Las funciones 'mtodo_1' y 'mtodo_2' son completamente equivalentes.


Las dos devuelven el valor promedio de la matriz 'voltaje[]'. Despus de
declararla, la direccin del primer miembro se puede escribir como 'voltaje' o
'&voltaje[0]'.
2.9 CARACTERSTICAS PRINCIPALES DEL PREPROCESADOR
El preprocesador es un programa que procesa el cdigo antes de que pase
por el compilador. Funciona bajo el control de las lneas de comando del
preprocesador denominadas directivas. Las directivas del preprocesador se
colocan en el cdigo fuente, normalmente en el principio del archivo. Antes de
pasar por el compilador, el cdigo fuente se examina por el preprocesador que
detecta y ejecuta todas las directivas del preprocesador. Las directivas del

preprocesador siguen a una regla de la sintaxis especial, empiezan por un smbolo


# y no requieren ningn punto y coma al final (;).
DIRECTIVAS DEL PREPROCESADOR
La siguiente tabla contiene un conjunto de directivas del preprocesador
frecuentemente utilizadas:
Las directivas del preprocesador se pueden dividir en tres categoras:
D I R E C T I VA S

FUNCIONES

#include

Define una sustitucin de macro

#undef

Quita una definicin de nombre de macro

#define

Especifica un archivo a ser incluido

#ifdef

Prueba para definicin de macro

#endif

Especificar el final de #if

#ifndef

Prueba si una macro no est definida

#if

Prueba las condiciones de compilar

#else

Especifica alternativas cuando la prueba de #if falla


Especifica alternativas cuando ms de dos condiciones se

#elif

necesitan

Definiciones de macro
Inclusiones de archivos
Control de compilacin
Ahora, vamos a presentar slo las directivas del preprocesador utilizadas con
ms frecuencia. Sin embargo, no es necesario saber todas ellas para programar
microcontroladores. Slo tenga en cuenta que el preprocesador es una
herramienta

muy

poderosa

para

los

programadores

avanzados

especialmente para el control de compilacin.


DIRECTIVAS DEL PREPROCESADOR PARA DEFINIR MACROS

en

C,

Por medio de los macros es posible definir las constantes y ejecutar


funciones bsicas. Una sustitucin de macro es un proceso en el que un
identificador del

programa

se sustituye

por

una

cadena

predefinida.

El

preprocesador sustituye cada ocurrencia del identificador en el cdigo fuente por


una cadena. Despus de la sustitucin, el cdigo ser compilado normalmente.
Esto significa que el cdigo sustituido debe respetar la sintaxis del mikroC.
La accin se realiza por medio de la directiva '#define'.

#define PI 3.14159 // Sustitucin simple, PI ser sustituido por


// el valor 3.14159 en todas las partes del programa

Tambin puede utilizar los parmetros para realizar substituciones ms


complejas:

#define VOLUMEN (D,H) (((D/2)*(D/2)*PI))*H // Macro con parmetros

Entonces, en el cdigo, la siguiente sentencia:

Tanque_1 = VOLUMEN (Dimetro,altura);

ser sustituida por:

Tanque_1 = (((Dimetro/2)*(Dimetro/2)*PI)*altura;

Por medio de la directiva #undef es posible quitar una definicin de nombre


de macro. As se especifica que la substitucin que se ha definido anteriormente
ya no va ocurrir en el siguiente cdigo. Esto es til cuando usted quiere restringir
la definicin slo a una parte particular del programa.

#undef TANQUE // Quitar la definicin del macro VOLUMEN

INCLUSIN DE ARCHIVOS
La directiva de preprocesador #include copia un archivo especfico en el
cdigo fuente. El cdigo incluido debe observar la sintaxis de C para ser
compilado correctamente.
Hay dos formas de escribir estas directivas. En el primer ejemplo, slo el
nombre de archivo se especifica, as que el preprocesador lo buscar dentro del
archivo include. En el segundo ejemplo, se especifica la ruta entera, as que el
archivo estar directamente incluido (este mtodo es ms rpido).

#include <nombre_de_archivo>

// Se especifica slo el nombre del

archivo
#include "C:\Ruta\nombre_de_archivo.h"

// Se especifica la localidad

// exacta del archivo

2.10 MIKROC PRO FOR PIC


Como ya hemos visto, hay varias divergencias entre los lenguajes mikroC y
ANSI C. En este captulo vamos a presentar las caractersticas especficas del
mikroC con el propsito de facilitar la programacin de los microcontroladores PIC.
ACCESO A LOS REGISTROS DE FUNCIONES ESPECIALES (SFR)
Como todos los microcontroladores, los de familia PIC tienen los registros de
funciones especiales (SFR). Para programar un PIC, es necesario acceder a estos
registros (para leerlos o escribir en ellos). Al utilizar el compilador mikroC PRO for
PIC es posible de acceder a cualquier SFR del microcontrolador de cualquier parte
del cdigo (los SFR se consideran como variables globales) sin necesidad de
declararlo anteriormente. Los registros de funciones especiales se definen en un

archivo externo e incluido dentro del compilador (archivo .def). Este archivo
contiene todos los SFR del microcontrolador PIC a programar.

TRISB = 0; // todos los pines del puerto PORTB se configuran como salidas
PORTB = 0; // todos los pines del PORTB se ponen a 0

ACCESO A LOS BITS INDIVIDUALES


El compilador mikroC PRO for PIC le permite acceder a los bits individuales
de variables de 8 bits por su nombre o su posicin en byte:

INTCON.B0 = 0; // Poner a 0 el bit 0 del registro INTCON


ADCON0.F5 = 1; // Poner a 1 el bit 5 del registo ADCON0
INTCON.GIE = 0; // Poner a 0 el bit de interrupcin global (GIE)

Para acceder a un bit individual, se puede utilizar '.FX' as como '.BX' (X es


un entero entre 0 y 7 que representa la posicin de bit).
TIPO SBIT
Si quiere declarar una variable que corresponde a un bit de un SFR, hay que
utilizar el tipo sbit. Una variable de tipo sbit se comporta como un puntero y se
debe declarar como una variable global:

sbit Botn_PARADA at PORTA.B7; // Botn_PARADA est definido


...

void main() {

// Cualquier modificacin de Botn_PARADA afectar a

PORTA.B7
...

// Cualquier modificacin de PORTA.B7 afectar a

Botn_PARADA
}

En este ejemplo, El Botn_PARADA es una variable declarada por el usuario,


mientras que PORTA.B7 (bit 7 del puerto PORTA) ser automticamente
reconocido por el compilador.
TIPO BIT
El compilador mikroC PRO for PIC proporciona un tipo de datos bit que se
puede utilizar para declarar variables. No se puede utilizar en las listas de
argumentos, punteros y los valores devueltos de funciones. Adems, no es posible
declarar e inicializar una variable de tipo bit en la misma lnea. El compilador
determina el bit en uno de los registros disponibles para almacenar las variables.

bit bf;

// Variable de tipo bit vlida

bit *ptr; // Varibale de tipo bit invlida.


// No hay punteros a una variable de tipo bit
bit bg = 0; // ERROR ; declaracin con inicializacin no est permitida
bit bg;
bg = 0;

// Declaracin e inicializacin vlidas

INSERTAR CDIGO ASM EN C

A veces el proceso de escribir un programa en C requiere las partes del


cdigo escritas en ensamblador. Esto permite ejecutar las partes complicadas del
programa de una forma definida con precisin en un perodo de tiempo exacto.
Por ejemplo, cuando se necesita que los pulsos muy cortos (de unos
microsegundos) aparezcan peridicamente en un pin del microcontrolador. En
tales casos la solucin ms simple sera utilizar el cdigo ensamblador en la parte
del programa que controla la duracin de pulsos.

Una o ms instrucciones en ensamblador estn insertadas en el programa


escrito en C, utilizando el comando asm:

asm
{
instrucciones en ensamblador
...
}

Los cdigos escritos en ensamblador pueden utilizar constantes y variables


anteriormente definidos en C. Por supuesto, como el programa entero est escrito
en C, sus reglas se aplican al declarar estas constantes y variables.

unsigned char maximum = 100; // Declarar variables: maximum = 100


asm
{

// Inicio del cdigo ensamblador


MOVF maximum,W

// W = maximum = 100

...
}

// Final del cdigo ensamblador

FUNCIN DE INTERRUPCIN
Una interrupcin detiene la ejecucin normal de un programa para ejecutar
las operaciones especficas. Una lista de sentencias a ejecutar debe estar escrita
dentro de una funcin particular denominada interrupt(). La sintaxis de una
interrupcin en mikroC se parece a lo siguiente:

void interrupt() {
cnt++ ;

// Al producirse una interrupcin


// la cnt se incrementa en 1

PIR1.TMR1IF = 0; // Poner a 0 el bit TMR1IF


}

A diferencia de las funciones estndar, no es necesario declarar el prototipo


de la funcin interrupt(). Adems, como la ejecucin de esta funcin no forma
parte de la ejecucin de programa regular, no se debe llamar de ninguna parte
de programa (se ejecutar automticamente dependiendo de las condiciones
que el usuario ha definido en el programa). En el siguiente captulo vamos a dar
una clara explicacin de la ejecucin y definicin de subrutinas de interrupcin.
LIBRERAS
Usted probablemente ha notado que en los ejemplos anteriores hemos
utilizado algunas funciones como son 'Delay_ms', 'LCD_out', 'LCD_cmd' etc. Estas
funciones estn definidas en las libreras contenidas en el compilador mikroC.
Una librera representa un cdigo compilado, anteriormente escrito en
mikroC, que contiene un conjunto de variables y funciones. Cada librera tiene un
propsito especfico. Por ejemplo, la librera LCD contiene funciones de
visualizacin de la pantalla LCD, mientras que C_math proporciona algunas
funciones matemticas.
Antes de utilizar alguna de ellas en el programa, es necesario comunicrselo
al compilador al marcarlas en la lista de las libreras del compilador existentes. Si
el compilador encuentra una funcin desconocida durante la ejecucin de
programa, primero va a buscar su declaracin en las libreras marcadas.

Aparte de las libreras existentes, es posible crear las libreras y luego


utilizarlas en el programa. El procedimiento de cmo crear libreras se describe en
detalles en Help (Ayuda) del compilador.
El compilador mikroC incluye tres tipos de libreras:
- libreras ANSI C estndar:
LIBRARA
ANSI

DESCRIPCIN

Ctype Utilizada principalmente para probar o para convertir los

Library
ANSI

datos
C

Math

Stdlib

String Utilizada para realizar las operaciones de cadenas y de

Library
ANSI
Library
ANSI
Library

Utilizada para las operaciones matemticas de punto flotante


Contiene las funciones de libreras estndar

manipulacin de memoria

- libreras miscelneas:
LIBRARA

DESCRIPCIN

Button Library

Utilizada para desarrollar los proyectos

Conversion
Library

Utilizada para la conversin de tipos de datos

Sprint Library

Utilizada para formatear los datos con facilidad

PrintOut Library

Utilizada para formatear los datos e imprimirlos

Time Library

Utilizada para clculos de tiempo (formato UNIX time)

Trigonometry

Utilizada

Library

trigonomtricas fundamentales

Setjmp Library

Utilizada para los saltos de programa

para

la

- libreras para el hardware:


LIBRARA

DESCRIPCIN

implementacin

de

funciones

ADC Library

Utilizada para el funcionamiento del convertidor A/D

CAN Library

Utilizada para las operaciones con el mdulo CAN


Utilizada para las operaciones con el mdulo CAN

CANSPI Library

externo (MCP2515 o MCP2510)

Compact Flash Library

Utilizada para las operaciones con las tarjetas de


memoria Compact Flash
Utilizada para las operaciones con la memoria EEPROM

EEPROM Library

incorporada

EthernetPIC18FxxJ60

Utilizada para las operaciones con el mdulo Ethernet

Library

incorporado

Flash Memory Library

grfico con resolucin 128x64


Utilizada para las operaciones con el mdulo de

I2C Library

comunicacin serial I2C incorporado


Utilizada para las operaciones con el teclado (botones

Keypad Library

de presin 4x4)
Utilizada para las operaciones con el LCD (de 2x16

Lcd Library

caracteres)
Code Utilizada para la comunicacin utilizando el cdigo

Library
Multi

incorporada
Utilizada para las operaciones con el mdulo LCD

Graphic Lcd Library

Manchester

Utilizada para las operaciones con la memoria Flash

Manchester
Media

Card Utilizada

Library
One Wire Library
Port Expander Library
PS/2 Library
PWM Library

para

las

operaciones

con

las

tarjetas

operaciones

con

los

circuitos

multimedia MMC flash


Utilizada

para

las

utilizando la comunicacin serial One Wire


Utilizada para las operaciones con el extensor de
puertos MCP23S17
Utilizada para las operaciones con el teclado estndar
PS/2
Utilizada para las operaciones con el mdulo PWM
incorporado

RS-485 Library
Software I2C Library
Software SPI Library
Software UART Library
Sound Library
SPI Library
SPI Ethernet Library
SPI Graphic Lcd Library
SPI LCD Library
SPI Lcd8 Library
SPI T6963C Graphic Lcd
Library
UART Library
USB Hid Library

Utilizada

para

las

operaciones

con

los

mdulos

utilizando la comunicacin serial RS485


Utilizada

para

simular

la

comunicacin

I2C

con

para

simular

la

comunicacin

SPI

con

software
Utilizada
software
Utilizada para simular la comunicacin UART con
software
Utilizada para generar las seales de audio
Utilizada para las operaciones con el mdulo SPI
incorporado
Utilizada para la comunicacin SPI con el mdulo
ETHERNET (ENC28J60)
Utilizada para la comunicacin SPI de 4 bits con el LCD
grfico
Utilizada para la comunicacin SPI de 4 bits con el LCD
(de 2x16 caracteres)
Utilizada para la comunicacin SPI de 8 bits con el LCD
Utilizada para la comunicacin SPI con el LCD grfico
Utilizada para las operaciones con el mdulo UART
incorporado
Utilizada para las operaciones con el mdulo USB
incorporado

2.11 PROGRAMAR LOS PIC UTILIZANDO MIKROC PRO FOR PIC


En las secciones anteriores hemos presentado el lenguaje mikroC,
especialmente diseado para programar los PIC. Ahora, lo que hemos revisado es
suficiente para empezar a programar, es hora de presentar el software que
utilizar para desarrollar y editar los proyectos. Este software se le denomina
Entorno de desarrollo integrado (Integrated Developement Environment - IDE) e
incluye todas las herramientas necesarias para desarrollar los proyectos (editor,
depurador etc.). Por extensin, IDE es a veces llamado compilador. En esta
seccin le ensearemos lo bsico que debe saber para empezar a desarrollar su
primer proyecto en mikroC utilizando el IDE del compilador mikroC PRO for PIC.
Aparte de todas las caractersticas comunes de cualquier IDE, mikroC PRO
for PIC contiene las informaciones de arquitectura de los microcontroladores PIC
(registros, mdulos de memoria, funcionamiento de circuitos particulares etc.)
para compilar y generar un archivo legible por un microcontrolador PIC. Adems,
incluye las herramientas especficas para programar los microcontroladores PIC.
El proceso de crear y ejecutar un proyecto contiene los siguientes pasos:
1. Crear un proyecto (nombre de proyecto, configuracin de proyecto, dependencias
entre archivos)
2. Editar un programa
3. Compilar el programa y correccin de errores
4. Depurar (ejecutar el programa paso a paso para asegurarse de que se ejecutan
las operaciones deseadas).
5. Programar un microcontrolador (cargar el archivo .hex generado por el compilador
en el microcontrolador utilizando el programador PICflash).
INSTALAR MIKROC PRO FOR PIC

Antes que nada, usted debe instalar el compilador (con su IDE) en la PC. La
instalacin del mikroC PRO for PIC es similar a la instalacin de cualquier
programa en Windows. Todo el procedimiento se lleva a cabo por medio de los
wizards (asistentes de instalacin):

Basta con seguir las instrucciones y pulsar sobre Next, OK, Next, Next... En
general, es el mismo procedimiento menos la ltima opcin: 'Do you want to
install PICFLASH v7.11 programmer?'. Para qu sirve este software? De eso
vamos a hablar ms tarde. Por ahora, basta con saber que es un software
autnomo utilizado para cargar el programa en el microcontrolador.
Una vez ms: Next, OK, Next, Next...

Una vez completada la instalacin del PICflash, el sistema operativo le preguntar


a instalar otro programa similar, un software para programar un grupo especial de
los microcontroladores PIC que funcionan en modo de bajo consumo (3.3 V). Salte
este paso...
El ltimo paso - la instalacin del controlador (driver)!

Pulse sobre Yes.


Un controlador es un programa que permite al sistema operativo comunicar
con un perifrico. En este caso, este dispositivo es el programador (hardware) del
sistema de desarrollo.

El controlador a instalar depende del sistema operativo utilizado. Seleccione


el controlador correspondiente al SO (sistema operativo) utilizado (por medio de
abrir la carpeta correspondiente) e inicie la instalacin. Otra vez, Next, OK, Next,
Next... Bueno, todo est instalado para iniciar a programar!

CARACTERSTICAS PRINCIPALES DEL MIKROC PRO FOR PIC


Al iniciar el IDE del compilador mikroC PRO for PIC por primera vez,
aparecer una ventana como se muestra a continuacin:

Desgraciadamente, una descripcin detallada de todas las opciones


disponibles de este IDE nos tomara mucho tiempo. Por eso vamos a describir slo

lo ms importante del compilador mikroC PRO for PIC. De todos modos, para
obtener ms informacion presione el botn de Ayuda (Help) [F1].
MANEJAR LOS PROYECTOS
Antes de empezar a escribir el cdigo, usted debe crear un proyecto. Un
programa escrito en el compilador mikroC PRO for PIC no es un archivo fuente
autnomo, sino que forma parte de un proyecto que incluye un cdigo hex, un
cdigo ensamblador, cabecera y otros archivos. Algunos de ellos se requieren
para compilar el programa, mientras que otros se crean durante el proceso de
compilacin. Un archivo con extensin .mcppi le permite abrir cualquiera de estos
proyectos.
Para crear un proyecto, basta con seleccionar la opcin Project/New Project,
y un wizard aparecer automticamente. Qu hacer entonces? Siga las
instrucciones...
PROJECT MANAGER (ADMINISTRADOR DEL PROYECTO)
Una vez creado el proyecto, es posible manejar todos los archivos que
contiene al utilizar la ventana Project Manager. Basta con pulsar con el botn
derecho del ratn sobre una carpeta y seleccionar la opcin que necesita para su
proyecto.

PROJECT SETTINGS (CONFIGURACIN DE PROYECTOS)


Al compilar un proyecto, el compilador genera el archivo .hex que se
cargar en el microcontrolador. Estos archivos sern diferentes lo que depende
del tipo del microcontrolador as como del propsito de la compilacin. Por esta
razn es necesario ajustar algunos parmetros de proyectos utilizando la ventana
Project Settings.

Device (dispositivo):
Al seleccionar el tipo de microcontrolador a utilizar permite al compilador
extraer el archivo de definicin (archivo .def) asociado. El archivo de definicin de
un microcontrolador contiene las informaciones especficas de sus registros SFR,
de sus direcciones de memoria y algunas variables de programacin especficas a
ese tipo del microcontrolador. Es obligatorio crear un archivo .hex compatible.
Oscillator (oscilador):
Se debe especificar la velocidad de operacin del microcontrolador. Por
supuesto, este valor depende del oscilador utilizado. El compilador la necesita
para compilar rutinas, lo que requiere informacin del tiempo (por ejemplo, la
funcin Delay_ms). Ms tarde, el programador necesitar esta informacin

tambin. La velocidad de operacin se configura de modo que permita al


oscilador interno del microcontrolador funcionar a una frecuencia seleccionada.
Build/Debugger Type:
Todo el proceso de compilar (building) est compuesto por anlisis sintctico
(parsing), compilar, enlazar (linking) y generar los archivos .hex. El tipo de
compilacin le permite ajustar el modo de compilacin. Dependiendo del modo
seleccionado, difieren los archivos generados a cargar en el microcontrolador.
Release: Al elegir esta opcin , el compilador no puede afectar ms a la
ejecucin de programa despus de la compilacin. El programa a cargar en el
microcontrolador no ser modificado de ninguna manera.
ICD debug: Al elegir esta opcin, una vez completado el proceso de la
compilacin y cargado el programa en la memoria del microcontrolador, el
compilador se queda conectado al microcontrolador por medio del cable USB y el
programador, y todava puede afectar a su funcionamiento. El archivo .hex
generado contiene los datos adicionales que permiten el funcionamiento del
depurador. Una herramienta denominada mikroICD (Depurador en circuito - In
Circuit Debugger) permite ejecutar el programa paso a paso y proporcionar un
acceso al contenido actual de todos los registros de un microcontrolador real.
El simulador no utiliza los dispositivos reales para simular el funcionamiento
del microcontrolador, as que algunas operaciones no pueden ser reproducidas
(por ejemplo, interrupcin). De todos modos, resulta ms rpido depurar un
programa por medio de un simulador. Adems, no se requiere ningn dispositivo
destino.
Note que es posible modificar cualquier configuracin en cualquier
momento mientras se edita el programa. No se olvide de recompilar y
reprogramar su dispositivo despus de modificar una configuracin.

LIBRARY MANAGING (EDITOR DE LIBRERAS)


El compilador tiene que conocer todas las dependencias de su archivo
fuente en mikroC para compilarlo apropiadamente. Por ejemplo, si las libreras
forman parte de su proyecto, debe especificar cules de ellas se utilizan.
Las libreras contienen un gran nmero de funciones listas para ser
utilizadas. Las libreras en mikroC proporcionan muchas facilidades para escribir
programas para los microcontroladores PIC. Abra la ventana Library Manager, y
marque las que quiere utilizar en el programa. Al marcar una librera, se aade
automticamente al proyecto y se enlaza durante el proceso de la compilacin.
As, no necesita incluir las libreras manualmente en sus archivos del cdigo
fuente por medio de la directiva del preprocesador #include.

Por ejemplo, si su programa utiliza un LCD no hace falta escribir nuevas


funciones ya que al seleccionar la librera Lcd, usted podr utilizar funciones listas
para ser utilizadas de la librera LCD (Lcd_Cmd, LCD_Init...) en su programa. Si
esta librera no est seleccionada en la ventana Library Manager, cada vez que
intente utilizar una funcin de la librera LCD, el compilador le informar de un
error. Una descripcin de cada librera est disponible al pulsar con el botn
derecho del ratn sobre su nombre y seleccionar la opcin Help.

EDITAR Y COMPILAR PROGRAMAS


CODE EDITOR (EDITOR DE CDIGO)
El proceso de editar programas se debe realizar dentro de la ventana
principal del IDE denominada Code Editor. Al escribir el programa no se olvide de
los comentarios. Los comentarios son muy importantes para depurar y mejorar el
programa. Adems, aunque el compilador no tenga las restricciones de formateo,
siempre debe seguir a las mismas reglas de editar (como en los ejemplos
proporcionados en este libro). Como no hay limitaciones de tamao, no vacile en
utilizar los espacios en blanco para hacer su cdigo ms legible.

Al escribir un programa, no espere que termine la redaccin del programa


para compilarlo. Compile su cdigo de forma regular con el propsito de corregir
cunto ms errores de sintaxis. Asimismo usted puede compilar su programa cada
vez que se complete la redaccin de una nueva funcin as como probar su
comportamiento al utilizar modo de depuracin (ver la prxima seccin). De este
modo, resulta ms fcil solucionar los errores de programa para no tomar un
camino errneo en redactar su programa. De lo contrario, usted tendr que
editar el programa entero.

CODE EXPLORER (EXPLORADOR DEL CDIGO)


La ventana Code Explorer le permite localizar funciones y procedimientos
dentro de los programas largos. Por ejemplo, si usted busca una funcin utilizada
en el programa, basta con pulsar dos veces sobre su nombre en esta ventana, y el
cursor estar automticamente posicionado en la lnea apropiada en el programa.
COMPILAR Y SOLUCIONAR LOS ERRORES
Para compilar su cdigo, pulse sobre la opcin Build en el men Project. En
realidad, el proyecto entero se ha compilado, y si la compilacin se ha realizado
con xito, se generarn los archivos de salida (asm, .hex etc.). Una compilacin se
ha realizado con xito si no se ha encontrado ningn error. Durante el proceso de
compilacin se generan muchos mensajes que se visualizan en la ventana
Messages. Estos mensajes consisten en informacin, advertencia y errores. Cada
error encontrado se asocia con su lnea de programa y su descripcin.
Como un error en su cdigo puede generar mucho ms errores,
simplemente debe intentar solucionar el primer error en la lista y despus
recompile su programa. En otras palabras, es recomendable solucionar los errores
uno a uno.

En el ejemplo anterior hay dos errores y una advertencia: faltan un punto y


coma y una declaracin de variable La advertencia le informa que falta el tipo del
valor devuelto de la funcin main.

La compilacin le permite corregir su programa por medio de solucionar


todos los errores en mikroC. Cuando todos los errores se solucionen, su programa
est listo para ser cargado en el microcontrolador. De todas formas, su tarea
todava no est terminada, porque an no sabe si su programa se comporta como
se esperaba o no.
DEPURAR EL PROGRAMA
La depuracin es un paso muy importante ya que permite probar el
programa despus de una compilacin realizada con xito, o solucionar los errores
descubiertos mientras se ejecuta el programa. Como ya hemos visto, hay dos
modos de depurar: un depurador software que simula el funcionamiento del
microcontrolador (modo por defecto) y depurador hardware (mikroICD) que lee
directamente el contenido de la memoria del microcontrolador. El procedimiento
de depuracin es el mismo sin reparar en el modo elegido. En caso de elegir la
opcin ICD debug, hay que cargar el programa en el microcontrolador antes de
depurarlo.
Para iniciar la depuracin, pulse sobre la opcin Start debugger del men
Run. El editor del cdigo ser ligeramente modificado automticamente y
aparecer una ventana denominada Watch Values. El principio de depuracin se
basa en ejecutar el programa paso a paso y monitorear el contenido de los
registros y los valores de las variables. De este modo, es posible comprobar el
resultado de un clculo y ver si algo inesperado ha ocurrido. Al ejecutar el
programa paso a paso, podr localizar los problemas con facilidad.
Durante una depuracin el programa ser modificado, por lo que usted
siempre debe recompilar el programa despus de cada correccin, y reiniciar el
depurador para comprobar qu ha sido modificado.
COMANDOS DEL DEPURADOR
Hay varios comandos disponibles para depurar el cdigo:

Step Into - Ejecuta una sola instruccin. Cuando la instruccin es una


llamada a una rutina, el depurador har un salto a la rutina y se detendr
despus de ejecutar la primera instruccin dentro de la rutina.
Step Over - Se ejecuta una sola instruccin. Cuando la instruccin es una
llamada a una rutina, el depurador no har un salto a la rutina, sino que se
ejecutar toda la rutina. El depurador se detiene a la primera instruccin
despus de la llamada a la rutina.
Run To Cursor - El programa se ejecuta hasta la lnea en la que se
encuentre el cursor.
Step out - Se ejecutan las dems instrucciones dentro de la rutina. El
depurador se detiene inmediatamente al salir de la rutina.

PUNTOS DE RUPTURA (BREAKPOINTS)


Los puntos de ruptura hacen el proceso de depurar los programas de una
manera ms eficiente, puesto que permiten ejecutar el programa a toda velocidad
y detenerlo automticamente en una lnea especfica (punto de ruptura). Eso
resulta muy til, permitindole comprobar slo las partes crticas del programa y
no perder el tiempo probando todo el programa lnea a lnea. Para aadir o quitar
un punto de ruptura basta con pulsar sobre la lnea apropiada en el lado izquierdo
del editor del cdigo, o presionar [F5]. Una pequea ventana denominada
Breakpoints muestra dnde estn los puntos de ruptura. Note que las lneas
designadas como puntos de ruptura estn marcadas en rojo.
La lnea que se est ejecutando actualmente est marcada en azul. Es
posible leer el contenido de registros y variables seleccionados en la ventana

Watch Values en cualquier momento. Para ejecutar la parte de programa desde la


lnea en la que est el cursor hasta el punto de ruptura, utilice el comando
Run/Pause Debugger.

VENTANA WATCH VALUES


El depurador software y hardware tienen la misma funcin de monitorear el
estado de los registros durante la ejecucin del programa. La diferencia es que el
depurador software simula ejecucin de programa en una PC, mientras que el
depurador ICD (depurador hardware) utiliza un microcontrolador real. Cualquier
cambio de estado lgico de los pines se indica en el registro (puerto) apropiado.
Como la ventana Watch Values permite monitorear el estado de todos los
registros, resulta fcil comprobar si un pin est a cero o a uno. La ltima
modificacin est marcada en rojo en la ventana Watch Values. Esto le permite
localizar la modificacin en la lista de variables y registros durante el proceso de
la depuracin.

Para visualizar esta ventana es necesario seleccionar la opcin View/Debug


Windows/Watch

Values.

Entonces

usted

puede

hacer

una

lista

de

registros/variables que quiere monitorear y la manera de visualizarlos.


STOPWATCH (CRONMETRO)
Si quiere saber cunto tiempo tarda un microcontrolador en ejecutar una
parte del programa, seleccione la opcin Run/View Stopwatch. Aparecer una
ventana como se muestra en la figura a la derecha. Cmo funciona un
cronmetro? Eso es pan comido... El tiempo que tarda un comando (step into,
step

over,

run/pause

etc.)

en

ejecutarse

por

el

depurador

se

mide

automticamente y se visualiza en la ventana Stopwatch. Por ejemplo, se mide


tiempo para ejecutar un programa, tiempo para ejecutar el ltimo paso etc.

PROGRAMAR EL MICROCONTROLADOR
Si ha solucionado todos los errores en su cdigo y cree que su programa est
listo para ser utilizado, el siguiente paso es cargarlo en el microcontrolador. El

programador PICflash se utiliza para este propsito. Es una herramienta diseada


para programar todos los tipos de microcontroladores PIC. Est compuesto por
dos partes:
La parte hardware se utiliza para introducir un cdigo hexadecimal (el
programa a ser cargado en el microcontrolador) y para programar el
microcontrolador por medio de niveles de voltaje especficos. Durante el
proceso de la programacin, un nuevo programa se escribe en la memoria
flash del microcontrolador, mientras que el programa anterior se borra
automticamente.
La parte de software se encarga de enviar el programa (archivo .hex ) a la
parte hardware del programador por medio de un cable USB. A la interfaz
de usuario de este software se le puede acceder desde IDE al pulsar sobre
la opcin mE_Programmer del men Tools o al pulsar [F11]. Por
consiguiente,

es

posible

modificar

algunas

configuraciones

del

programador y controlar el funcionamiento de la parte hardware (Cargar,


Escribir, Verificar...).

Se puede reprogramar el microcontrolador tantas veces como se necesite.


OTRAS HERRAMIENTAS DEL COMPILADOR

El compilador mikroC PRO for PIC proporciona herramientas que en gran


medida simplifican el proceso de escribir el programa. Todas estas herramientas
se encuentran en el men Tools. En la siguiente seccin vamos a darle una breve
descripcin de todas ellas.
TERMINAL USART
El terminal USART representa una sustitucin para la estndar Windows
Hyper

Terminal.

Se

puede

utilizar

para

controlar

el

funcionamiento

del

microcontrolador que utiliza la comunicacin USART. Tales microcontroladores


estn incorporados en un dispositivo destino y conectados al conector RS232 de
la PC por medio de un cable serial.
La ventana USART terminal dispone de opciones para configurar la
comunicacin serial y visualizar los datos enviados/ recibidos.

EDITOR EEPROM
Al seleccionar la opcin EEPROM Editor del men Tools, aparecer una
ventana como se muestra en la siguiente figura. As es cmo funciona la memoria
EEPROM del microcontrolador. Si quiere cambiar de su contenido despus de
cargar el programa en el microcontrolador, sta es la forma correcta de hacerlo. El
nuevo contenido es un dato de un tipo especfico (char, int o double), primero

debe seleccionarlo, introducir el valor en el campo Edit Value y pulsar sobre Edit.
Luego, pulse sobre el botn Save para guardarlo como un documento con
extensin .hex. Si la opcin Use EEPROM in Project est activa, los datos se
cargarn automticamente en el microcontrolador durante el proceso de la
programacin.

VENTANA ASCII CHART


Si necesita representar numricamente un carcter ASCII, seleccione la
opcin ASCII chart del men Tools. Aparecer una tabla, como se muestra en la
figura que est a continuacin. Usted probablemente sabe que cada tecla de
teclado est asociada con un cdigo (cdigo ASCII). Como se puede ver, los
caracteres que representan los nmeros tienen valores diferentes. Por esta razn,
la instruccin de programa para visualizar el nmero 7 en un LCD no visualizar
este nmero, sino el equivalente a la instruccin BEL. Si enva el mismo nmero
en forma de un carcter a un LCD, obtendr el resultado esperado - nmero 7. Por
consiguiente, si quiere visualizar un nmero sin convertirlo en un carcter
apropiado, es necesario aadir el nmero 48 a cada dgito en el que consiste el
nmero a visualizar.

EDITOR DE SIETE SEGMENTOS


Un editor de siete segmentos le permite determinar con facilidad el nmero
a poner en un puerto de salida con el propsito de visualizar un smbolo deseado.
Por supuesto, se da por entendido que los pines del puerto deben estar
conectados a los segmentos del visualizador de manera apropiada. Basta con
colocar el cursor en cualquier segmento del visualizador y pulsar sobre l. Se
visualizar inmediatamente el nmero a introducir en el programa.

LCD

CUSTOM

CHARACTER

(CARACTERES

LCD

DEFINIDOS

POR

EL

USUARIO)
Adems de los caracteres estndar, el microcontrolador tambin puede
visualizar los caracteres creados por el programador. Al seleccionar la herramienta
LCD custom character, se evitar un pesado trabajo de crear funciones para
enviar un cdigo apropiado a un visualizador. Para crear un smbolo, pulse sobre
los cuadros pequeos en la ventana LCD custom character, luego seleccione la
posicin y la fila y pulse sobre el botn GENERATE. El cdigo apropiado aparece en
otra ventana. No es necesita pulsar ms. Copy to Clipboard (copiar al
portapapeles) - Paste (pegar)...

GENERADOR DE MAPA DE BITS PARA UN LCD GRFICO


El generador de mapa de bits para un LCD grfico es una herramienta
insustituible en caso de que el programa que escribe utilice el visualizador LCD
(GLCD). Esta herramienta le permite visualizar un mapa de bits con facilidad.
Seleccione la opcin Tools/Glcd Bitmap Editor aparecer la ventana apropiada.
Para utilizarlo, seleccione el tipo de visualizador a utilizar y cargue un mapa de
bits. El mapa de bits debe ser monocromtico y tener la resolucin apropiada del
visualizador (128 x 64 pxeles en este ejemplo). El procedimiento a seguir es igual
que en el ejemplo anterior: Copy to Clipboard...

Un

cdigo

generado

que

utiliza

herramientas

para

controlar

los

visualizadores LCD y GLCD contiene funciones de la librera Lcd. Si las utiliza en el


programa, no se olvide de marcar la caja de chequeo junto a esta librera en la
ventana Library Manager. As el compilador ser capaz de reconocer estas
funciones correctamente.

Capitulo 3: Microcontrolador PIC16F887


El PIC16F887 es un producto conocido de la compaa Microchip. Dispone
de todos los componentes disponibles en la mayora de los microcontroladores
modernos. Por su bajo precio, un rango amplio de aplicaciones, alta calidad y
disponibilidad, es una solucin perfecta aplicarlo para controlar diferentes
procesos en la industria, en dispositivos de control de mquinas, para medir
variables de procesos etc. Algunas de sus caractersticas principales se enumeran
a continuacin.
3.1 CARACTERSTICAS BSICAS DEL PIC16F887
3.2 PRINCIPALES REGISTROS SFR
3.3 PUERTOS DE ENTRADA/SALIDA
3.4 TEMPORIZADOR TIMER0
3.5 TEMPORIZADOR TIMER1
3.6 TEMPORIZADOR TIMER2
3.7 MDULOS CCP
3.8 MDULOS DE COMUNICACIN SERIE
3.9 MDULOS ANALGICOS
3.10 OSCILADOR DE RELOJ
3.11 MEMORIA EEPROM
3.12 REINICIO! BLACK-OUT, BROWN-OUT O RUIDOS?
3.1 CARACTERSTICAS BSICAS DEL PIC16F887

arquitectura RISC
o El microcontrolador cuenta con solo 35 instrucciones diferentes
o Todas las instrucciones son uni-ciclo excepto por las de ramificacin
Frecuencia de operacin 0-20 MHz
Oscilador interno de alta precisin
o Calibrado de fbrica
o Rango de frecuencia de 8MHz a 31KHz seleccionado por software
Voltaje de la fuente de alimentacin de 2.0V a 5.5V
o Consumo: 220uA (2.0V, 4MHz), 11uA (2.0 V, 32 KHz) 50nA (en modo
de espera)
Ahorro de energa en el Modo de suspensin
Brown-out Reset (BOR) con opcin para controlar por software
35 pines de entrada/salida
o alta corriente de fuente y de drenador para manejo de LED
o resistencias pull-up programables individualmente por software
o interrupcin al cambiar el estado del pin
memoria ROM de 8K con tecnologa FLASH
o El chip se puede re-programar hasta 100.000 veces
Opcin de programacin serial en el circuito

o El chip se puede programar incluso incorporado en el dispositivo


destino.
256 bytes de memoria EEPROM
o Los datos se pueden grabar ms de 1.000.000 veces
368 bytes de memoria RAM
Convertidor A/D:
o 14 canales
o resolucin de 10 bits
3 temporizadores/contadores independientes
Temporizador perro guardin
Mdulo comparador analgico con
o Dos comparadores analgicos
o Referencia de voltaje fija (0.6V)
o Referencia de voltaje programable en el chip
Mdulo PWM incorporado
Mdulo USART mejorado
o Soporta las comunicaciones seriales RS-485, RS-232 y LIN2.0
o Auto deteccin de baudios
Puerto Serie Sncrono Maestro (MSSP)

o Soporta los modos SPI e I2C

DESCRIPCIN DE PINES
La mayora de los pines del microcontrolador PIC16F887 son multipropsito
como

se

muestra

en

la

figura

anterior.

Por

ejemplo,

la

asignacin

RA3/AN3/Vref+/C1IN+ para el quinto pin del microcontrolador indica que ste


dispone de las siguientes funciones:
RA3 Tercera entrada/salida digital del puerto A
AN3 Tercera entrada analgica
Vref+ Referencia positiva de voltaje
C1IN+ Entrada positiva del comparador C1
La funcionalidad de los pines presentados anteriormente es muy til puesto
que permite un mejor aprovechamiento de los recursos del microcontrolador sin
afectar a su funcionamiento. Estas funciones de los pines no se pueden utilizar
simultneamente, sin embargo se pueden cambiar en cualquier instante durante
el funcionamiento.
Las siguientes tablas se refieren al microcontrolador DIP de 40 pines.

UNIDAD CENTRAL DE PROCESAMIENTO (CPU)


Con el propsito de explicar en forma clara y concisa, sin describir
profundamente el funcionamiento de la CPU, vamos a hacer constar que la CPU
est fabricada con la tecnologa RISC ya que esto es un factor importante al
decidir qu microcontrolador utilizar.

RISC es un acrnimo derivado del ingls Reduced Instruction Set Computer, lo


que proporciona al PIC16F887 dos grandes ventajas:
La CPU cuenta con slo 35 instrucciones simples. Cabe decir que para poder
programar otros microcontroladores en lenguaje ensamblador es necesario
saber ms de 200 instrucciones
El tiempo de ejecucin es igual para casi todas las instrucciones y tarda 4
ciclos de reloj. La frecuencia del oscilador se estabiliza por un cristal de
cuarzo. Las instrucciones de salto y de ramificacin tardan ocho ciclos de
reloj en ejecutarse. Esto significa que si la velocidad de operacin del
microcontrolador es 20 MHz, el tiempo de ejecucin de cada instruccin
ser 200nS, o sea, el programa ejecutar 5millones de instrucciones por
segundo!

MEMORIA
El PIC16F887 tiene tres tipos de memoria: ROM, RAM y EEPROM. Como cada
una tiene las funciones, caractersticas y organizacin especficas, vamos a
presentarlas por separado.
MEMORIA ROM
La memoria ROM se utiliza para guardar permanente el programa que se
est ejecutando. Es la razn por la que es frecuentemente llamada memoria de
programa. El PIC16F887 tiene 8Kb de memoria ROM (en total 8192 localidades).

Como la memoria ROM est fabricada con tecnologa FLASH, su contenido se


puede cambiar al proporcionarle un voltaje de programacin especial (13V).
No obstante, no es necesario explicarlo en detalles puesto que se realiza
automticamente por un programa especial en la PC y un simple dispositivo
electrnico denominado programador.

MEMORIA EEPROM
Similar a la memoria de programa, el contenido de memoria EEPROM est
permanentemente guardado al apagar la fuente de alimentacin. Sin embargo, a
diferencia de la ROM, el contenido de la EEPROM se puede cambiar durante el
funcionamiento del microcontrolador. Es la razn por la que esta memoria (256
localidades) es perfecta para guardar permanentemente algunos resultados
creados y utilizados durante la ejecucin del programa.
MEMORIA RAM
Es la tercera y la ms compleja parte de la memoria del microcontrolador.
En este caso consiste en dos partes: en registros de propsito general y en los
registros de funciones especiales (SFR). Todos estos registros se dividen en cuatro
bancos de memoria de los que vamos a hablar ms tarde en este captulo.
A unque los dos grupos de registros se ponen a cero al apagar la fuente de
alimentacin, adems estn fabricados de la misma forma y se comportan de la
manera similar, sus funciones no tienen muchas cosas en comn.

REGISTROS DE PROPSITO GENERAL


Los registros de propsito general se utilizan para almacenar los datos
temporales y los resultados creados durante el funcionamiento. Por ejemplo, si el
programa realiza el conteo (de los productos en una cadena de montaje), es
necesario tener un registro que representa lo que en la vida cotidiana llamamos
suma. Como el microcontrolador no es nada creativo, es necesario especificar la
direccin de un registro de propsito general y asignarle esa funcin. Se debe
crear un programa simple para incrementar el valor de este registro por 1,
despus de que cada producto haya pasado por el sensor.
Ahora el microcontrolador puede ejecutar el programa ya que sabe qu es y
dnde est la suma que se va a incrementar. De manera similar, a cada variable
de programa se le debe pre-asignar alguno de los registros de propsito general.

/* En esta secuencia, la variable en el registro sum se aumenta cada vez que se


lleve un uno (1) lgico en el pin de entrada RB0. */

...

if (PORTB.0 = 1) // Comprobar si el pin RB0 est a uno


sum++ ;
...

// Si est, el valor de la variable se aumenta por 1


// Si no est, el programa sale de la sentencia if

...

REGISTROS DE FUNCIONES ESPECIALES (SFR)


Los registros de funciones especiales son tambin parte de la memoria RAM.
A diferencia de los registros de propsito general, su propsito es predeterminado
durante el proceso de fabricacin y no se pueden cambiar. Como los bits estn
conectados a los circuitos particulares en el chip (convertidor A/D, mdulo de
comunicacin serial, etc), cualquier cambio de su contenido afecta directamente
al funcionamiento del microcontrolador o de alguno de los circuitos.
Por ejemplo, el registro ADCON0 controla el funcionamiento del convertidor
A/D. Al cambiar los bits se determina qu pin del puerto se configurar como la
entrada del convertidor, el momento del inicio de la conversin as como la
velocidad de la conversin.
Otra caracterstica de estas localidades de memoria es que tienen nombres
(tanto los registros como sus bits), lo que simplifica considerablemente el proceso
de escribir un programa. Como el lenguaje de programacin de alto nivel puede
utilizar la lista de todos los registros con sus direcciones exactas, basta con
especificar el nombre de registro para leer o cambiar su contenido.

// En esta secuencia, el contenido de los registros TRISC y PORTC ser


modificado

...
TRISC = 0x00

// un cero lgico (0) se escribe en el registro TRISC (todos

// los pines del puerto PORTC se configuran como salidas)


PORTC = 0b01100011 // cambio de estado lgico de todos los pines del puerto
PORTC
...

BANCOS DE LA MEMORIA RAM


La memoria RAM est dividida en cuatro bancos. Antes de acceder a un
registro al escribir un programa (para leer o cambiar su contenido), es necesario
seleccionar el banco que contiene ese registro. Ms tarde vamos a tratar dos bits
del registro STATUS utilizados para seleccin del banco. Para simplificar el
funcionamiento, los SFR utilizados con ms frecuencia tienen la misma direccin
en todos los bancos, lo que permite accederlos con facilidad.

Trabajar con bancos puede ser difcil slo si se escribe un programa en


lenguaje ensamblador. Al utilizar el lenguaje de programacin de alto nivel como
es C y el compilador como es mikroC PRO for PIC, basta con escribir el nombre del
registro. A partir de esa informacin, el compilador selecciona el banco necesario.
Las instrucciones apropiadas para la seleccin del banco sern incorporadas en el
cdigo durante el proceso de la compilacin. Hasta ahora usted ha utilizado slo
el lenguaje ensamblador y esta es la primera vez que utiliza el compilador C,
verdad? Es una noticia maravillosa, no lo cree?

PILA
Una parte de la RAM utilizada como pila consiste de ocho registros de 13
bits. Antes de que el microcontrolador se ponga a ejecutar una subrutina
(instruccin CALL) o al ocurrir una interrupcin, la direccin de la primera
siguiente instruccin en ser ejecutada se coloca en la pila (se apila), o sea, en uno
de los registros. Gracias a eso, despus de ejecutarse una subrutina o una
interrupcin, el microcontrolador sabe dnde continuar con la ejecucin de
programa. Esta direccin se borra (se desapila) despus de volver al programa, ya
que no es necesario guardarla, disponiendo automticamente esas localidades de
la pila para un uso futuro.
Cabe tener en mente que el dato se apila circularmente. Esto significa que
despus de que se apile ocho veces, la novena vez se sobrescribe el valor que se
almacen al apilar el dato por primera vez. La dcima vez que se apile, se
sobrescribe el valor que se almacen al apilar el dato por segunda vez etc. Datos
sobrescritos de esta manera no se pueden recuperar. Adems, el programador no
puede acceder a estos registros para hacer escritura/lectura. No hay ningn bit de
estado para indicar el estado de desbordamiento o subdesbordamiento de pila.
Por esta razn hay que tener un especial cuidado al escribir un programa.
Vamos a hacerlo en mikroC...

/* Al entrar o al salir de la instruccin en ensamblador del programa, el


compilador
no va a guardar los datos en el banco de la RAM actualmente activo. Esto
significa
que en esta seccin de programa la seleccin de banco depende de los
registros SFR

utilizados. Al volver a la seccin de programa escrito en C, los bits de control


RP0 y RP1 deben devolver el estado que tenan antes de la ejecucin del cdigo
en
lenguaje ensamblador. En este ejemplo, el problema se soluciona al utilizar la
variable auxiliar saveBank que guarda el estado de estos dos bits*/

saveBank = STATUS & 0b01100000; // Guardar el estado de los bits RP0 y RP1
// (bits 5 y 6 del registro STATUS)
asm {

// Inicio de la secuencia en ensamblador

...
...

// Cdigo ensamblador

...
}

// Final de la secuencia en ensamblador

STATUS &= 0b10011111; // Bits RP0 y RP1 devuelven su estado original


STATUS |= saveBank;
...
...

SISTEMA DE INTERRUPCIONES

Al

aparecer

una

peticin

de interrupcin lo primero

que hace el

microcontrolador es ejecutar la instruccin actual despus de que se detiene el


proceso de ejecucin de programa. Como resultado, la direccin de memoria de
programa actual se apila automticamente y la direccin por defecto (predefinida
por el fabricante) se escribe en el contador de programa. La localidad en la que el
programa contina con la ejecucin se le denomina vector de interrupcin. En el
caso del microcontrolador PIC16F887 esta direccin es 0x0004h. Como se
muestra en la siguiente figura la localidad que contiene el vector de interrupcin
se omite durante la ejecucin de programa regular.
Una parte de programa que se ejecutar al hacer una peticin de
interrupcin se le denomina rutina de interrupcin. Su primera instruccin se
encuentra en el vector de interrupcin. Cunto tiempo tardar en ejecutar esta
subrutina y cmo ser depende de la destreza del programador as como de la
fuente de interrupcin. Algunos microcontroladores tienen ms de un vector de
interrupcin (cada peticin de interrupcin tiene su vector), pero en este caso slo
hay uno. En consecuencia, la primera parte da la rutina de interrupcin consiste
en detectar la fuente de interrupcin.
Por fin, al reconocer la fuente de interrupcin y al terminar de ejecutar la
rutina de interrupcin el microcontrolador alcanza la instruccin RETFIE, toma la
direccin de la pila y contina con la ejecucin de programa desde donde se
interrumpi.

mikroC reconoce una rutina de interrupcin que se ejecutar como la funcin


void interrupt(). El cuerpo de la funcin, o sea, rutina de interrupcin, debe ser
escrito por el usuario.

void interrupt() { // Interrupt routine


cnt++ ;

// Interrupt causes variable cnt to be incremented by 1

Cmo utilizar los registros SFR


Supongamos que usted ha comprado ya un microcontrolador y que tiene
una buena idea de cmo utilizarlo... La lista de los registros SFR as como de sus
bits es muy larga. Cada uno controla algn proceso. En general, parece como una
gran tabla de control con un gran nmero de instrumentos e interruptores. Ahora
est preocupado de cmo conseguir aprender acerca de todos ellos? Es poco
probable,

pero

no

se

preocupe,

Usted

no

tiene

que

hacerlo!

Los

microcontroladores son tan potentes que se parecen a los supermercados:


ofrecen tantas cosas a bajos precios y a usted solo le toca elegir las que necesita.
Por eso, seleccione el campo en que est interesado y examine slo lo que
necesita. Cuando entienda completamente el funcionamiento de hardware,
examine los registros SFR encargados de controlarlo (normalmente son unos
pocos).
Como todos los dispositivos tienen un tipo de sistema de control el
microcontrolador tiene sus "palancas" con las que usted debe estar familiarizado
para ser capaz de utilizarlos correctamente. Por supuesto, estamos hablando de
los registros SFR desde los que el proceso de programacin se inicia y en los que
el mismo termina.
3.2 PRINCIPALES REGISTROS SFR

El siguiente texto describe los principales registros SFR del microcontrolador


PIC16F887. Los bits de cada registro controlan los circuitos diferentes dentro del
chip, as que no es posible clasificarlos en grupos especiales. Por esta razn, se
describen junto con los procesos que controlan.
Registro STATUS

registro STATUS contiene: el estado aritmtico de datos en el registro W, el


estado RESET, los bits para seleccionar el banco para los datos de la memoria.
IRP - Registro de seleccin de Banco (usado para direccionamiento
indirecto)
o 1 - Bancos 0 y 1 son activos (localidades de memoria 00h-FFh)
o 0 - Bancos 2 y 3 son activos (localidades de memoria 100h-1FFh)
RP1,RP0 - Registro de seleccin de banco (usado para direccionamiento
directo).
RP1

RP0

BANCO ACTIVO

Banco 0

Banco 1

Banco 2

Banco 3

TO - Time-out bit (bit de salida del temporizador perro guardin)

o 1 - Despus de encender el microcontrolador, despus de ejecutarse


la instruccin CLRWDT que reinicia al WDT (temporizador perro
guardin) o despus de ejecutarse la instruccin SLEEP que pone al
microcontrolador en el modo de bajo consumo.
o 0 - Despus de acabarse el tiempo del WDT.
PD - Power-down bit (bit de apagado)
o 1 - Despus de encender el microcontrolador, despus de ejecutar la
instruccin CLRWDT que reinicia al WDT.
o 0 - Despus de ejecutarse la instruccin SLEEP que pone al
microcontrolador en el modo de bajo consumo.
Z - Zero bit (bit cero)
o 1 - El resultado de una operacin lgica o aritmtica es 0.
o 0 - El resultado de una operacin lgica o aritmtica es distinto de 0.
DC - Digit carry/borrow bit (bit de acarreo/prstamo de dgito) cambia al
sumar o al restar si ocurre un "desbordamiento" o un "prstamo" en el
resultado.
o 1 - Hubo acarreo del cuarto bit de orden bajo (nibble bajo) en el
resultado.
o 0 - No hubo acarreo del cuarto bit de orden bajo (nibble bajo) en el
resultado.
C - Carry/Borrow bit (bit de acarreo/prstamo) cambia al sumar o al restar
si ocurre un "desbordamiento" o un "prstamo" en el resultado, o sea si el
resultado es mayor de 255 o menor de 0.

o 1 - Ocurri acarreo en el bit ms significativo (MSB) del resultado.


o 0 - No ocurri acarreo en el bit ms significativo (MSB) del resultado.
Registro OPTION_REG

El registro OPTION_REG contiene varios bits de control para configurar el pre


- escalador del Temporizador 0/WDT, el temporizador Timer0, la interrupcin
externa y las resistencias pull-up en el puerto PORTB.

RBPU - Port B Pull up Enable bit (resistencia Pull Up Puerto B)


o 1 - Desactivadas.
o 0 - Activadas.

INTEDG - Interrupt Edge Select bit (bit selector de flanco activo de


la interrupcin externa)
o 1 - Interrupcin por flanco ascendente en el RB0/INT.
o 0 - Interrupcin por flanco descendente en el RB0/INT.

T0CS - TMR0 Clock Source Select bit (bit selector de tipo de reloj
para el Timer0)
o 1 - Pulsos introducidos a travs del TOCKI (contador).
o 0 - Pulsos de reloj internos Fosc/4 (temporizador).

T0SE - TMR0 Source Edge Select bit (bit selector de tipo de flanco en
TOCKI) selecciona el flanco (ascendente o descendente) contado por el
temporizador Timer0 por el pin RA4/T0CKI.
o 1 - Incrementa en flanco descendente en el pin TOCKI.
o 0 - Incrementa en flanco ascendente en el pinTOCKI.

PSA - Prescaler Assignment bit asigna el pre-escalador (hay slo uno) al


temporizador o al WDT.
o 1 - Pre - escalador se le asigna al WDT.
o 0 - Pre - escalador se le asigna al temporizador Timer0.
PS2, PS1, PS0 Prescaler Rate Select bits (bit selector del valor del
divisor de frecuencia)

El valor del divisor de frecuencia se selecciona al combinar estos tres bits.


Como se muestra en la siguiente tabla, el valor del divisor de frecuencia se le
asigna al temporizador (Timer0) o al temporizador perro guardin (WDT).
PS2

PS1

PS0

TMR0

WDT

1:2

1:1

1:4

1:2

1:8

1:4

1:16

1:8

1:64

1:32

1:128

1:64

1:256

1:128

Para conseguir el valor del divisor de frecuencia 1:1 cuando el temporizador


Timer0

cuenta

pulsos,

el

preescalador

debe

ser

asignado

al

WDT.

En

consecuencia, el temporizador Timer0 no utiliza el pre-escalador, sino que cuenta


directamente los pulsos generados por el oscilador, lo que era el objetivo.
Vamos a hacerlo en mikroC...

/* Si el comando CLRWDT no se ejecuta,


el WDT va a reiniciar al microcontrolador cada 32.768 uS (f=4 MHz) */

void main() {
OPTION_REG = 0b00001111; // Pre-escalador est asignado al WDT (1:128)
asm CLRWDT; // Comando en ensamblador para reiniciar al WDT
...

...// El tiempo entre estos dos comandos CLRWDT no debe exceder 32.768
microsegundos (128x256)
...
asm CLRWDT; // Comando en ensamblador para reiniciar al WDT
...
...// El tiempo entre estos dos comandos CLRWDT no debe exceder 32.768
microsegundos (128x256)
...
asm CLRWDT; // Comando en ensamblador para reiniciar al WDT
}

REGISTROS DEL SISTEMA DE INTERRUPCIN


Al llegar la peticin de interrupcin, no significa que una interrupcin
ocurrir automticamente, puesto que debe ser habilitada por el usuario (por el
programa) tambin. Por esta razn, hay bits especiales utilizados para habilitar o
deshabilitar interrupciones. Es fcil de reconocerlos por las letras IE contenidas en
sus

nombres

(Interrupt

Enable

Interrupcin

habilitada).

Adems,

cada

interrupcin se asocia con otro bit denominado bandera que indica que una
peticin de interrupcin ha llegado sin verificar si est habilitada. Asimismo, se
reconocen con facilidad por las dos ltimas letras contenidas en sus nombres - IF
(Interrupt Flag - Bandera de interrupcin).

Como hemos visto, toda la idea es muy simple y eficiente. Al llegar la


peticin de interrupcin, primero el bit de bandera se pone a uno.
Si el bit IE apropiado est a cero (0), esta condicin ser ignorada
completamente. De lo contrario, ocurre una interrupcin. Si varias fuentes de
interrupcin estn habilitadas, es necesario detectar la activa antes de que la
rutina de interrupcin se ponga a ejecutar. La deteccin de la fuente se realiza al
comprobar los bits de las banderas.
Cabe destacar que los bits de cada bandera no se ponen a cero
automticamente, sino por el software, mientras que la ejecucin de la rutina de
interrupcin contina ejecutndose. Si no hacemos caso a este detalle, ocurrir
otra interrupcin inmediatamente despus de volver al programa principal,
aunque no hay ms peticiones de ejecucin. Simplemente, la bandera, as como
el bit IE, se quedan en uno.
Todas las fuentes de interrupcin tpicas para el microcontrolador PIC16F887
se muestran en la siguiente pgina. Fjese en lo siguiente:
El bit GIE habilita/deshabilita simultneamente las interrupciones no
enmascaradas.
El PEIE bit habilita/deshabilita las interrupciones no enmascaradas de
perifricos. Esto no se refiere al temporizador Timer0 y a las fuentes de
interrupcin del puerto PORTB.
Para habilitar una interrupcin causada por el cambio del estado lgico en el
puerto PORTB, es necesario habilitarla para cada bit por separado. En este caso,
los bits del registro IOCB se comportan como los bits IE de control.

Registro INTCON
El registro INTCON contiene varios bits de habilitacin y de bandera para el
desbordamiento en el registro TMR0, e interrupciones por el cambio del estado en
el puerto PORTB y las interrupciones externas en el pin INT.

GIE - Global Interrupt Enable bit - (bit de habilitacin de interrupciones


globales) controla simultneamente todas las fuentes de interrupciones
posibles.

o 1 - Habilita las interrupciones no enmascaradas.


o 0 - Deshabilita las interrupciones no enmascaradas.
PEIE

Peripheral

Interrupt

Enable

bit

(bit

de

habilitacin

de

interrupciones perifricas) es similar al bit GIE, sin embargo controla


interrupciones habilitadas por los perifricos. Eso significa que no influye en
interrupciones causadas por el temporizador Timer0 o por el cambio del
estado en el puerto PORTB o por el cambio en el pin RB0/INT.
o 1 - Habilita las interrupciones perifricas no enmascaradas.
o 0 - Deshabilita las interrupciones perifricas no enmascaradas.
T0IE - TMR0 Overflow Interrupt Enable bit (bit de habilitacin de
interrupciones por el desbordamiento del temporizador Timer0) controla
interrupciones causadas por el desbordamiento del Timer0.
o 1 - Habilita interrupciones por Timer0.
o 0 - Deshabilita interrupciones por Timer0.
INTE - RB0/INT External Interrupt Enable bit (bit de habilitacin de la
interrupcin externa en RB0) controla interrupciones causadas por el
cambio del estado lgico en el pin de entrada RB0/INT (interrupcin
externa).
o 1 - Habilita interrupciones externas INT.
o 0 - Deshabilita interrupciones externas INT.
RBIE - RB Port Change Interrupt Enable bit (bit de habilitacin de
interrupciones por cambios en el puerto PORTB). Cuando se configuran
como entradas, los pines en el puerto PORTB pueden causar una
interrupcin al cambiar el estado lgico (no importa si se produce bajada o

subida de tensin, lo que importa es que se produce un cambio). Este bit


determina si una interrupcin va a ocurrir.
o 1 - Habilita interrupciones por cambio en el puerto PORTB.
o 0 - Deshabilita interrupciones por cambio en el puerto PORTB.
T0IF - TMR0 Overflow Interrupt Flag bit (bit de bandera de interrupcin
por el desbor damiento del Timer0) detecta el desbordamiento en el
registro del temporizador Timer0, o sea el contador se pone a cero.
o 1 - En el registro del Timer0 ha ocurrido desbordamiento (esta
bandera debe volverse a 0 por software).
o 0 - En el registro del Timer0 no ha ocurrido desbordamiento.
INTF - RB0/INT External Interrupt Flag bit (bit de bandera de
interrupcin externa en INT) detecta el cambio en el estado lgico en el pin
INT.
o 1 - Ha ocurrido una interrupcin externa por INT (esta bandera debe
volverse a 0 por software)
o 0 - No ha ocurrido una interrupcin externa por INT.
RBIF - RB Port Change Interrupt Flag bit (bit de bandera de
interrupcin por cambio en el puerto RB) detecta cualquier cambio del
estado lgico de alguno de los pines de entrada en el puerto PORTB.
o 1 - Al menos uno de los pines de E/S de propsito general en el puerto
PORTB ha cambido de valor. Despus de leer el puerto PORTB, el bit
RBIF debe volverse a 0 por software).
o 0 - Ninguno de los pines de E/S de propsito general en el puerto
PORTB ha cambiado de valor.

Vamos a hacerlo en mikroC...

// El pin PORTB.4 se configura como una entrada sensible al cambio del estado
lgico.

void initMain() {
ANSEL = ANSELH = 0; // Todos los pines de E/S se configuran como digitales
PORTB = 0;

// Todos los pines del puerto PORTB se ponen a cero

TRISB = 0b00010000; // Todos los pines del puerto PORTB menos PORTB.4 se
// configuran como salidas

RBIE = 1;

// Se habilitan las interrupciones por el cambio en el puerto

PORTB
IOCB4 = 1;

// Se habilita la interrupcin por el cambio en el pin 4 en el


// puerto PORTB

GIE = 1;

// Se habilita la interrupcin global

...

// Desde este punto, se produce una interrupcin con cualquier

cambio
...
...

// del estado lgico en el pin PORTB.4

Registro PIE1
El registro PIE1 contiene los bits de habilitacin de interrupciones
perifricas.

ADIE - A/D Converter Interrupt Enable bit (bit de habilitacin de


interrupciones del convertidor A/D).
o 1 - Habilita la interrupcin ADC.
o 0 - Deshabilita la interrupcin ADC.
RCIE - EUSART Receive Interrupt Enable bit (bit de habilitacin de
interrupciones de recepcin del EUSART).
o 1 - Habilita la interrupcin de recepcin del EUSART.
o 0 - Deshabilita la interrupcin de recepcin del EUSART.
TXIE - EUSART Transmit Interrupt Enable bit (bit de habilitacin de
interrupciones de transmisin del EUSART).
o 1 - Habilita la interrupcin de transmisin del EUSART.
o 0 - Deshabilita la interrupcin de transmisin del EUSART.
SSPIE - Master Synchronous Serial Port (MSSP) Interrupt Enable bit
- (bit de habilitacin de la interrupcin del puerto serie sncrono maestro
(MSSP) habilita generar una peticin de interrupcin despus de cada

transmisin de datos por el mdulo de comunicacin serie sncrona (modo


SPI o I2C).
o 1 - Habilita la interrupcin del MSSP.
o 0 - Deshabilita la interrupcin del MSSP.
CCP1IE - CCP1 Interrupt Enable bit (bit de habilitacin de la interrupcin
del mdulo 1 de Comparacin/Captura/PWM - CCP1) permite generar una
peticin de interrupcin en el mdulo CCP1 utilizado para procesamiento de
la seal PWM.
o 1 - Habilita la interrupcin CCP1.
o 0 - Deshabilita la interrupcin CCP1.
TMR2IE

TMR2

to

PR2

Match

Interrupt

Enable

bit

(bit

de

habilitacin de la interrupcin de igualdad entre TMR2 y PR2)


o 1 - Habilita la interrupcin de igualdad entre TMR2 y PR2.
o 0 - Deshabilita la interrupcin de igualdad entre TMR2 y PR2.
TMR1IE - TMR1 Overflow Interrupt Enable bit (bit de habilitacin de la
interrupcin de desbordamiento del temporizador Timer1) habilita generar
una peticin de interrupcin despus de cada desbordamiento en el
registro del temporizador Timer1, o sea el contador se pone a cero.
o 1 - Habilita la interrupcin de desbordamiento del temporizador
Timer1.
o 0 - Deshabilita la interrupcin de desbordamiento del temporizador
Timer1.
Vamos a hecerlo en mikroC...

/* Se produce una interrupcin con cada desbordamiento en el registro del


temporizador1
que consiste en TMR1H y TMR1L. En cada rutina de interrucpiones, la variable
cnt ser incrementada por 1 */

unsigned short cnt;


void interrupt()
cnt++ ;

// Definir la variable cnt

// Inicio de la rutina de interrupcin


// Al producirse una interrupcin, la cnt se

// incrementa por 1
PIR1.TMR1IF = 0;

// El bit TMR1IF se reinicia

TMR1H = 0x80;

// A los registros del temporizador TMR1H y TMR1L se les

TMR1L = 0x00;

// devuelven sus valores iniciales

// Final de la rutina de interrupcin

void main() {
ANSEL = ANSELH = 0; // Todos los pines de E/S se configuran como digitales
T1CON = 1;
PIR1.TMR1IF = 0;

// Encender el temporizador Timer


// El bit TMR1IF se pone a cero

TMR1H = 0x80;

// Establecer los valores iniciales para el temporizador

Timer1
TMR1L = 0x00;
PIE1.TMR1IE = 1;

// Habilitar la interrupcin al producirse un

// desbordamiento en el Timer1
cnt = 0;
INTCON = 0xC0;

// Reiniciar la variable cnt


// Habilitar la interrupcin (los bits GIE y PEIE)

...

Registro PIE2
El

registro

PIE2

tambin

contiene

varios

bits

de

habilitacin

de

interrupciones.

OSFIE - Oscillator Fail Interrupt Enable bit (bit de habilitacin de la


interrupcin de fallo en el oscilador)
o 1 - Habilita la interrupcin de fallo en el oscilador.
o 0 - Deshabilita la interrupcin de fallo en el oscilador.
C2IE - Comparator C2 Interrupt Enable bit (bit de habilitacin de la
interrupcin del comparador C2)

o 1 - Habilita la interrupcin del comparador C2.


o 0 - Deshabilita la interrupcin del comparador C2.
C1IE - Comparator C1 Interrupt Enable bit (bit de habilitacin de la
interupcin del comparador C1)
o 1 - Habilita la interrupcin del comparador C1
o 0 - Deshabilita la interrupcin del comparador C1.
EEIE - EEPROM Write Operation Interrupt Enable bit (bit de
habilitacin de la interrupcin de escritura en la memoria EEPROM)
o 1 - Habilita la interrupcin de escritura en la memoria EEPROM.
o 0 - Deshabilita la interrupcin de escritura en la memoria EEPROM.
BCLIE - Bus Collision Interrupt Enable bit (bit de habilitacin de la
interrupcin de colisin de bus)
o 1 - Habilita la interrupcin de colisin de bus.
o 0 - Deshabilita la interrupcin de colisin de bus.
ULPWUIE - Ultra Low-Power Wake-up Interrupt Enable bit (bit de
habilitacin de la interrupcin para salir del modo de ultra bajo
consumo - la reactivacin)
o 1 - Habilita la interrupcin para salir del modo de ultra bajo consumo.
o 0 - Deshabilita la interrupcin para salir del modo de ultra bajo
consumo.
CCP2IE - CCP2 Interrupt Enable bit (bit de habilitacin de la
interrupcin del mdulo 2 de Comparacin/Captura/PWM (CCP2)

o 1 - Habilita la interrupcin del CCP2.


o 0 - Deshabilita la interrupcin del CCP2.
Vamos a hacerlo en mikroC...

/* El comparador C2 se configura para utilizar los pines RA0 y RA2 como


entradas. Al producirse
un cambio en la salida del comparador, el pin de salida PORTB.1 cambia el
estado lgico en la
rutina de interrupcin.*/

void interrupt() {

// Inicio de la rutina de interrupcin

PORTB.F1 = ~PORTB.F1 ; // La interrupcin invertir el estado lgico del


// pin PORTB.1
PIR2.C2IF = 0;
}

// Bit de bandera de interrupcin C2IF se pone a cero


// Final de la rutina de interrupcin

void main() {
TRISB = 0;

// Todos los pines del puerto PORTB se configuran


// como salidas

PORTB.F1 = 1;

// El pin PORTB.1 se pone a uno

ANSEL = 0b00000101;;

// Los pines RA0/C12IN0- y RA2/C2IN+ son las

// entradas analgicas
ANSELH = 0;

// Todos los pines de E/S se configuran como

digitales
CM2CON0.C2CH0 = CM2CON0.C2CH1 = 0; // El pin RA0 se selecciona para ser
una
// entrada invertida del C2
PIE2.C2IE = 1;

// Habilita la interrupcin del comparador C2INT

CON.GIE = 1;

// Interrupcin global est habilitada

CM2CON0.C2ON = 1;

// Comparador C2 est habilitado

...
...

Registro PIR1
El registro PIR1 contiene los bits de banderas de interrupcin.

ADIF - A/D Converter Interrupt Flag bit (bit de bandera de la


interrupcin del convertidor A/D)
o 1 - Se ha completado una conversin A/D (el bit debe volverse a 0 por
software)
o 0 - No se ha completado una conversin A/D o no ha empezado
RCIF - EUSART Receive Interrupt Flag bit (bit de bandera de la
interrupcin de recepcin del EUSART)
o 1 - El bfer de recepcin del EUSART est lleno. El bit se pone a cero
al leer el registro RCREG.
o 0 - El bfer de recepcin del EUSART no est lleno.
TXIF - EUSART Transmit Interrupt Flag bit (bit de la interrupcin de
transmisin del EUSART)
o 1 - El bfer de transmisin del EUSART est vaco. El bit se pone a
cero al esribir un dato en el registro TXREG.
o 0 - El bfer de transmisin del EUSART est lleno.
SSPIF - Master Synchronous Serial Port (MSSP) Interrupt Flag bit
(bit de bandera de la interrupcin de puerto serie sncrono
maestro)
o 1 - Se ha cumplido la condicin de ocurrir una interrupcin del MSSP
al transmitir/ recibir los datos. Difieren dependiendo del modo de
operacin del MSSP (SPI o I2C). El bit debe ponerse a cero por
software antes de volver de la rutina de servicio de interrupciones)
o 0 - No se ha cumplido ninguna condicin de ocurrir una interrupcin
del MSSP.

CCP1IF - CCP1 Interrupt Flag bit (bit de bandera de la interrupcin


del mdulo 1 de Comparacin/Captura/PWM (CCP1).
o 1 - Se ha cumplido la condicin de la interrupcin del CCP1 (CCP1 es
una unidad para captar, comparar y generar una seal PWM).
Dependiendo del modo de operacin (modo captura o modo
comparacin),

se

produce

una

captura

la

igualdad

en

la

comparacin. En ambos casos, el bit debe volverse a cero por


software. El bit no se utiliza en el modo PWM.
o 0 - No se ha cumplido la condicin de la interrupcin del CCP1.
TMR2IF - Timer2 to PR2 Interrupt Flag bit (bit de bandera de la
interrupcin de igual dad entre el temporizador Timer2 y el
registro PR2)
o 1 - Se ha producido igualdad con el valor del TMR2 (registro de 8 bits
del temporizador) y el valor del PR2. El bit debe ponerse a cero por
software antes de volver de la rutina de servicio de interrupciones).
o 0 - No se ha producido igualdad con el valor del TMR2 y el valor del
PR2.
TMR1IF - Timer1 Overflow Interrupt Flag bit (bit de bandera de la
interrupcin de desbordamiento del temporizador Timer1)
o 1 - Se ha producido desbordamiento del Timer1. El bit debe ponerse a
cero por software.
o 0 - No se ha producido desbordamiento del Timer1.
Registro PIR2
El registro PIR2 contiene los bits de banderas da la interrupcin.

OSFIF - Oscillator Fail Interrupt Flag bit (bit de bandera de la


interrupcin de fallo en el oscilador)
o 1 - Se ha producido un fallo en el oscilador del sistema. La entrada de
reloj ha sido conmutada al oscilador interno INTOSC. El bit debe
ponerse a cero por software.
o 0 - El oscilador del sistema funciona correctamente.
C2IF - Comparator C2 Interrupt Flag bit (bit de bandera de la
interrupcin del comparador C2)
o 1 - La salida del comparador analgico C2 ha sido cambiada (el bit
C2OUT). El bit debe ponerse a cero por software.
o 0 - La salida del comparador analgico C2 no ha sido cambiada.
C1IF - Comparator C1 Interrupt Flag bit (bit de bandera de la
interrupcin del comparador C1)
o 1 - La salida del comparador analgico C1 ha sido cambiada (el bit
C1OUT). El bit debe ponerse a cero por software.
o 0 - La salida del comparador analgico C1 no ha sido cambiada.
EEIF - EE Write Operation Interrupt Flag bit (bit de bandera de la
interrupcin de la operacin de escritura en la memoria EEPROM)
o 1 - La operacin de escritura en la memoria EEPROM se ha
completado. El bit debe ponerse a cero por software.

o 0 - La operacin de escritura en la memoria EEPROM no se ha


completado o todava no se ha iniciado.
BCLIF - Bus Collision Interrupt Flag bit (bit de bandera de la
interrupcin de colisin de bus en el MSSP)
o 1 - Se ha producido una colisin de bus en el MSSP al ser configurado
para el modo maestro I2C. El bit debe ponerse a cero por software.
o 0 - No se ha producido colisin de bus en el MSSP.
ULPWUIF - Ultra Low-power Wake-up Interrupt Flag bit (bit de
bandera de la interrupcin para salir del modo de ultra bajo
consumo - la reactivacin)
o 1 - Se ha cumplido la condicin de salir del modo de ultra bajo
consumo. El bit debe ponerse a cero por software.
o 0 - No se ha cumplido la condicin de salir del modo de ultra bajo
consumo.
CCP2IF - CCP2 Interrupt Flag bit (bit de la interrupcin del mdulo 2
de Comparacin/Captura/PWM - CCP2)
o 1 - Se ha cumplido la condicin de la interrupcin del CCP2 (CCP2 es
una unidad para captar, comparar y generar una seal PWM).
Dependiendo del modo de operacin (modo captura o modo
comparacin),

se

produce

una

captura

la

igualdad

en

la

comparacin. En ambos casos, el bit debe volverse a cero por


software. El bit no se utiliza en el modo PWM.
o 0 - No se ha cumplido la condicin de la interrupcin del CCP2.
Vamos a hacerlo en mikroC...

// Secuencia de activacin del mdulo ULPWU

void main() {
PORTA.F0 = 1;
ANSEL = ANSELH = 0;

// Pin PORTA.0 se pone a uno


// Todos los pines de E/S se configuran como

digitales
TRISA = 0;

// Los pines del puerto PORTA se configuran como

salidas
Delay_ms(1);
PIR2.ULPWUIF = 0;
PCON.ULPWUE = 1;
TRISA.F0 = 1;
PIE2.ULPWUIE = 1;

// Cargar el capacitor
// Bandera ULPWUIF se pone a cero
// Habilitar el funcionamiento del mdulo ULPWU
// PORTA.0 se configura como entrada
// Habilitar la interrupcin por el mdulo ULPWU

INTCON.GIE = INTCON.PEIE = 1; // Habilitar todas las interrupciones


asm SLEEP;
...
...

Registro PCON

// Pasar al modo de bajo consumo

El registro PCON contiene solamente dos bits de banderas utilizados para


diferenciar entre un Power-on reset (POR), un Brown-out reset (BOR), un reinicio
por el temporizador perro guardin (WDT) y un reinicio externo por el pin MCLR.

ULPWUE - Ultra Low-Power Wake-up Enable bit (bit de habilitacin


para salir del modo de ultra bajo consumo - la reactivacin)
o 1 - Se habilita salir del modo de ultra bajo consumo.
o 0 - No se habilita salir del modo de ultra bajo consumo.
SBOREN - Software BOR Enable bit (bit de habilitacin del BOR por
software)
o 1 - Se habilita Brown-out reset.
o 0 - Se deshabilita Brown-out reset.
POR - Power-on Reset Status bit (bit de estado Power - on reset)
o 1 - No se ha producido Power - on reset.
o 0 - Se ha producido Power - on reset. El bit debe ponerse a uno por
software despus de que se haya producido un Power - on reset.
BOR - Brown-out Reset Status bit (bit de estado Brown - out reset)
o 1 - No se ha producido Brown - out reset.

o 0 - Se ha producido Brown - out reset. El bit debe ponerse a uno por


software despus de que se haya producido Brown - out reset.
REGISTROS PCL Y PCLATH
La memoria de programa del PIC16F887 es de 8K y tiene 8192 localidades
para el almacenamiento de programa. Por esta razn, el contador de programa
debe de ser de 13 bits de anchura (213 = 8192). Para habilitar el acceso a una
localidad

de

memoria

de

programa

durante

el

funcionamiento

del

microcontrolador , es necesario acceder a su direccin por medio de los registros


SFR. Como todos los registros SFR son de 8 bits de anchura, este registro de
direccionamiento es creado artificialmente al dividir los 13 bits en dos registros
independientes, PCLATH y PCL. Si la ejecucin de programa no afecta al contador
de programa, el valor de este registro va incrementndose automtica y
constantemente: +1, +1, +1, +1... De esta manera, el programa se ejecuta como
est escrito - instruccin a instruccin, seguido por un incremento de direccin
constante.

Si el contador de programa ha sido cambiado por software, debe tomar en


cuenta lo siguiente para evitar problemas:
Los ocho bits inferiores (el byte inferior) del registro PCL son de
lectura/escritura, mientras que los cinco bits superiores del registro PCLATH
son de slo escritura.
El registro PCLATH se borra con cada reinicio.
En el lenguaje ensamblador, el valor del contador de programa est
marcado con PCL y se refiere slo a los ocho bits. Usted debe tener cuidado
al utilizar la instruccin "ADDWF PCL". Esto es una instruccin de salto que

especifica la localidad destino al aadir un nmero a la direccin actual. Se


utiliza con frecuencia para saltar a la tabla de bsqueda o a la tabla de
ramificacin de programa y leerlas. Un problema surge si la direccin actual
es de tal tamao que al sumar se produce un cambio en un bit que
pertenece
La

al

ejecucin

de

byte
una

superior
instruccin

del
sobre

registro
el

registro

PCLATH.
PCL

causa

simultneamente la sustitucin de los bits del contador de programa por


los contenidos en el registro PCLATH. De todos modos, el registro PCL
puede acceder slo a 8 bits inferiores del resultado de la instruccin, pues
el siguiente salto ser completamente incorrecto. La solucin a este
problema es poner estas instrucciones en las direcciones que terminan en
xx00h. De esta manera se habilitan los saltos de programa hasta 255
localidades. Si se ejecutan los saltos ms largos por medio de esta
instruccin, el registro PCLATH debe ser incrementado por 1 cada vez que
se produce desbordamiento en el registro PCL.
Al llamar una subrutina o al ejecutarse un salto (instrucciones CALL y
GOTO),

el

microcontrolador

es

capaz

de

proporcionar

solamente

direccionamiento de 11 bits. Similar a la RAM que est dividida en


bancos, la ROM est dividida en las cuatro pginas de 2K cada una. Las
instrucciones dentro de estas pginas se ejecutan regularmente. Dicho de
manera sencilla, como el procesador est proporcionado con una direccin
de 11 bits del programa, es capaz de direccionar cualquier localidad dentro
de 2KB. La siguiente figura muestra el salto a la direccin del subprograma
PP1.

Sin embargo, si una subrutina o una direccin de salto no est en la misma


pgina que la localidad de salto, se deben proporcionar dos bits superiores que
faltan al escribir en el registro PCLATH. La siguiente figura muestra el salto a la
direccin de la subrutina PP2.
En ambos casos, cuando la subrutina llega a las instrucciones RETURN,
RETLW o RETFIE (vuelta al programa principal), el microcontrolador continuar
con la ejecucin de programa desde donde se interrumpi, ya que la direccin de
retorno se empuja y se guarda en la pila que consiste en registros de 13 bits,
como hemos mencionado.
REGISTROS DE DIRECCIONAMIENTO INDIRECTO
Adems del direccionamiento directo, que es lgico y claro (basta con
especificar

la

direccin

de

un

registro

para

leer

su

contenido),

este

microcontrolador es capaz de realizar el direccionamiento indirecto por los


registros INDF y FSR. A veces esto facilita el proceso de escribir un programa. El
procedimiento entero est habilitado ya que el registro INDF no es real (no existe
fsicamente), sino que solamente especifica el registro cuya direccin est situada
en el registro FSR. Por esta razn, escribir o leer los datos del registro INDF
realmente significa escribir o leer del registro cuya direccin est situada en el
registro FSR. En otras palabras, direcciones de registros se especifican en el
registro FSR, y su contenido se almacena en el registro INDF. La diferencia entre el
direccionamiento directo e indirecto se muestra en la siguiente figura:

Como hemos visto, el problema con "los bits de direccionamiento que


faltan" se soluciona con un "prstamo" del otro registro. Esta vez, es el sptimo
bit, denominado bit IRP del registro STATUS.

Una de las caractersticas ms importantes del microcontrolador es el


nmero de los pines de entrada/ salida, que permite conectarlo con los
perifricos. El PIC16F887 tiene en total 35 pines de E/S de propsito general, lo
que es suficiente para la mayora de las aplicaciones.
3.3 PUERTOS DE ENTRADA/SALIDA
Con el propsito de sincronizar el funcionamiento de los puertos de E/S con
la organizacin interna del microcontrolador de 8 bits, ellos se agrupan, de
manera similar a los registros, en cinco puertos denotados con A, B, C, D y E.
Todos ellos tienen las siguientes caractersticas en comn:
Por las razones prcticas, muchos pines de E/S son multifuncionales. Si un
pin re aliza una de estas funciones, puede ser utilizado como pin de E/S de
propsito general.

Cada puerto tiene su propio registro de control de flujo, o sea el registro


TRIS correspondiente: TRISA, TRISB, TRISC etc. lo que determina el
comportamiento de bits del puerto, pero no determina su contenido.
Al poner a cero un bit del registro TRIS (pin=0), el pin correspondiente del
puerto se configurar como una salida. De manera similar, al poner a uno un bit
del registro TRIS (bit=1), el pin correspondiente del puerto se configurar como
una entrada. Esta regla es fcil de recordar: 0 = Entrada 1 = Salida.

Puerto PORTA y registro TRISA


El puerto PORTA es un puerto bidireccional, de 8 bits de anchura. Los bits de
los registros TRISA y ANSEL controlan los pines del PORTA. Todos los pines del
PORTA se comportan como entradas/salidas digitales. Cinco de ellos pueden ser
entradas analgicas (denotadas por AN):

RA0 = AN0 (determinado por el bit ANS0 del registro ANSEL)


RA1 = AN1 (determinado por el bit ANS1 del registro ANSEL)
RA2 = AN2 (determinado por el bit ANS2 del registro ANSEL)
RA3 = AN3 (determinado por el bit ANS3 del registro ANSEL)
RA5 = AN4 (determinado por el bit ANS4 del registro ANSEL)
Similar a que los bits del registro TRISA determinan cules pines sern
configurados como entradas y cules sern configurados como salidas, los bits
apropiados del registro ANSEL determinan si los pines sern configurados como
entradas analgicas o entradas/salidas digitales.
Cada bit de este puerto tiene una funcin adicional relacionada a algunas
unidades perifricas integradas, que vamos a describir en los siguientes captulos.
Este captulo cubre slo la funcin adicional del pin RA0, puesto que est
relacionado al puerto PORTA y a la unidad ULPWU.
Vamos a hacerlo en mikroC...

// El pin PORTA.2 se configura como una entrada digital. Todos los dems pines
del puerto
// PORTA son salidas digitales

...

ANSEL = ANSELH = 0; // Todos los pines de E/S se configuran como digitales


PORTA = 0;

// Todos los pines del puerto PORTA se ponen a cero

TRISA = 0b00000100; // Todos los pines del puerto PORTA excepto el


// PORTA.2 se configuran como salidas

...

UNIDAD ULPWU
El microcontrolador se utiliza generalmente en los dispositivos que
funcionan peridicamente y completamente independiente utilizando una fuente
de alimentacin de batera. En tal caso, el consumo de corriente mnimo es una
de las prioridades. Los ejemplos tpicos de tales aplicaciones son: termmetros,
sensores de deteccin del fuego y similar. Es conocido que al reducir frecuencia
de reloj se reduce el consumo de corriente, pues una de las soluciones ms
convenientes a este problema es bajar la frecuencia de reloj, o sea utilizar el
cristal de cuarzo de 32KHz en vez de el de 20MHz.

Al poner el microcontrolador en el modo de reposo es otro paso en la misma


direccin. An ha quedado el problema de salir de este modo y poner el
microcontrolador en modo normal de funcionamiento. Es obviamente necesario
tener una seal externa en alguno de los pines. Esta seal debe ser generada por
componentes electrnicos adicionales, lo que resulta en un consumo de energa
ms alto del dispositivo completo...
La solucin perfecta sera que el microcontrolador saliera del modo de
reposo peridicamente por si mismo, lo que no es imposible. El circuito que lo
habilita se muestra en la figura a la izquierda.
El principio de funcionamiento es simple:
Un pin se configura como salida y se le lleva un uno lgico (1). Esto causa
una carga del capacitor. Inmediatamente despus, el mismo pin se configura
como entrada. El cambio de estado lgico habilita una interrupcin y el
microcontrolador entra en modo de reposo. Slo ha quedado esperar que se
descargue el capacitor por la corriente de fuga fluyendo por el pin de entrada.
Despus de la descarga, se produce una interrupcin y el microcontrolador
contina con la ejecucin de programa en modo normal. Todo el procedimiento se
repite.

En teora, esto es una solucin perfecta. El problema es que todos los pines
capaces de causar una interrupcin son digitales y tienen una corriente de fuga
relativamente alta cuando el voltaje sobre ellos no est cerca de los valores
lmites de Vdd (1) o VSS (0). En este caso, el condensador se descarga en poco
tiempo ya que la corriente es de varias centenas de microamperios. Por esta
razn se dise el circuito ULPWU, capaz de indicar una lenta cada de voltaje con
un consumo de corriente mnimo.
La salida genera una interrupcin, mientras que la entrada est conectada a
uno de los pines del microcontrolador. Es el pin RA0. Refirindose a la Figura
(R=200 ohms, C=1nF), el tiempo de descarga es aproximadamente 30mS,
mientras que un consumo total de corriente del microcontrolador es 1000 veces
ms bajo (de varias centenas de nanoamperios).
Puerto PORTB y registro TRISB
El puerto PORTB es un puerto bidireccional, de 8 bits de anchura. Los bits
del registro TRISB determinan la funcin de sus pines.

Similar al puerto PORTA, un uno lgico (1) en el registro TRISB configura el


pin apropiado en el puerto PORTB y al revs. Los seis pines de este puerto se
pueden comportar como las entradas analgicas (AN). Los bits del registro
ANSELH determinan si estos pines sern configurados como entradas analgicas o
entradas/salidas digitales:
RB0 = AN12 (determinado por el bit ANS12 del registro ANSELH)
RB1 = AN10 (determinado por el bit ANS10 del registro ANSELH)
RB2 = AN8 (determinado por el bit ANS8 del registro ANSELH)
RB3 = AN9 (determinado por el bit ANS9 del registro ANSELH)
RB4 = AN11 (determinado por el bit ANS11del registro ANSELH)
RB4 = AN11 (determinado por el bit ANS11del registro ANSELH)
Cada bit de este puerto tiene una funcin adicional relacionada a algunas
unidades perifricas integradas, que vamos a describir en los siguientes captulos.
Este puerto dispone de varias caractersticas por las que se distingue de
otros puertos y por las que sus pines se utilizan con frecuencia:
Todos los pines del puerto PORTB tienen las resistencias pull-up integradas,
que los hacen perfectos para que se conecten con los botones de presin
(con el teclado), interruptores y optoacopladores. Con el propsito de
conectar las resisitencias a los puertos del microcontrolador, el bit
apropiado del registro WPUB debe estar a uno.*

Al tener un alto nivel de resistencia (varias decenas de kiloohmios), estas


resistencias "virtuales" no afectan a los pines configurados como salidas, sino que
sirven de un complemento til a las entradas. Estas resistencias estn conectados
a las entradas de los circuitos lgicos CMOS. De lo contrario, se comportaran
como si fueran flotantes gracias a su alta resistencia de entrada.

Adems de los bits del registro WPUB, hay otro bit que afecta a la
instalacin de las resistencias pull-up. Es el bit RBPU del registro OPTION_REG.
Al estar habilitado, cada bit del puerto PORTB configurado como una
entrada puede causar una interrupcin al cambiar su estado lgico. Con el
propsito de habilitar que los termi nales causen una interrupcin, el bit
apropiado del registro IOCB debe estar a uno.

Gracias a estas caractersticas, los pines del puerto PORTB se utilizan con
frecuencia para comprobar los botones de presin en el teclado ya que detectan
cada apretn de botn infaliblemente. Por eso, no es necesario examinar todas las
entradas una y otra vez.

Cuando los pines X,Y y Z se configuran como entradas de puesta a uno (1),
slo se necesita esperar una peticin de interrupcin que aparece al apretar un
botn. Ms tarde, se comprueba cul botn fue activado al combinar ceros y unos
en las entradas.
Vamos a hacerlo en mikroC...

/* El pin PORTB.1 se configura como entrada digital. Se produce una


interrupcin con cualquier
cambio de su estado lgico. Tambin tiene una resistencia pull-up. Todos los
dems pines del
puerto PORTB son entradas digitales. */

...
ANSEL = ANSELH = 0; // Todos los pines de E/S se configuran como digitales

PORTB = 0;

// Todos los pines del puerto PORTB se ponen a cero

TRISB = 0b00000010; // Todos los pines del puerto PORTB excepto PORTB.1
// se configuran como salidas
RBPU = 0;

// Se habilitan las resistencias pull-up

WPUB1 = 1;

// La resistencia pull-up se conecta al pin PORTB.1

IOCB1 = 1;

// El pin PORTB.1 puede causar una interrupcin por el


// cambio del estado lgico

RBIE = GIE = 1;

// Se habilita una interrupcin

...

PIN RB0/INT
El pin RB0/INT es la nica fuente verdadera de la interrupcin externa. Se
puede configurar de manera que reaccione al borde ascendente de seal
(transicin de cero a uno) o al borde descendente de seal (transicin de uno a
cero). El bit INTEDG del registro OPTION_REG selecciona la seal apropriada.
PINES RB6 Y RB7
El PIC16F887 no dispone de ningn pin especial para la programacin (el
proceso de escribir un programa en la ROM). Los pines que generalmente estn
disponibles como los pines de E/S de propsito general, se utilizan para este
propsito. Para decir con ms precisin, son los pines del puerto PORTB utilizados
para la transmisin de seal de reloj (RB6) y de datos (RB7) al cargar el programa.
Adems, es necesario suministrar el voltaje de alimentacin Vdd (5V) as como el
voltaje apropiado Vpp (12-14V) para la programacin de memoria FLASH. Durante

la programacin, el voltaje Vpp se aplica al pin MCLR. No se preocupe de los


detalles relacionados a este proceso, tampoco se preocupe de cul voltaje se
aplica primero puesto que los componentes del programador se encargan de eso.
Lo

que

es

muy

importante

es

que

el

programa

se

puede

cargar

al

microcontrolador an despus de haber sido soldado en el dispositivo destino. Por


supuesto, el programa cargado se puede cambiar de la misma manera. Esta
funcin se le denomina ICSP (In-Circuit Serial Programming - Programacin serial
en circuito)
Para utilizarlo correctamente es necesario planificar con antelacin. Es pan
comido! Slo es necesario instalar un conector miniatura de 5 pines en el
dispositivo

destino

para

suministrar

al

microcontrolador

un

voltaje

de

programacin necesario. Para evitar la interferencia entre los voltajes y los


componentes del dispositivo conectados a los pines del microcontrolador, todos
los perifricos adicionales deben estar desconectados durante la programacin
(utilizando las resistencias o los puentes).

Como hemos visto, los voltajes aplicados a los pines del zcalo del
programador son los mismos que los utilizados durante la programacin ICSP.
Puerto PORTC y registro TRISC
El puerto PORTC es un puerto bidireccional, de 8 bits de anchura. Los bits
del registro TRISC determinan la funcin de sus pines. Similar a otros puertos, un
uno lgico (1) en el registro TRISC configura el pin apropiado del puerto PORTC
como entrada.

Todas las funciones adicionales del puerto PORTC se describen en los


siguientes captulos.
Puerto PORTD y registro TRISD
El puerto PORTD es un puerto bidireccional de 8 bits de anchura. Los bits del
registro TRISD determinan la funcin de sus pines. Similar a otros puertos, un uno
lgico (1) en el registro TRISD configura el pin apropiado del puerto PORTD como
entrada.

Puerto PORTE y registro TRISE


El puerto PORTE es un puerto bidireccional, de 4 bits de anchura. Los bits
del registro TRISE determinan la funcin de sus pines. Similar a otros puertos, un
uno lgico (1) en el registro TRISE configura el pin apropiado del puerto PORTE
como entrada.

La excepcin es el pin RE3, que siempre est configurado como entrada.


Similar a los puertos PORTA y PORTB, en este caso los tres pines se pueden
configurar como entradas analgicas. Los bits del registro ANSEL determinan si
estos pines sern configurados como entradas analgicas (AN) o entradas/salidas
digitales:
RE0 = AN5 (determinado por el bit ANS5 del registro ANSEL);
RE1 = AN6 (determinado por el bit ANS6 del registro ANSEL); y
RE2 = AN7 (determinado por el bit ANS7 del registro ANSEL).
Vamos a hacerlo en mikroC...

/* El pin PORTE.0 se configura como una entrada analgica mientras que los
dems tres
pines del mismo puerto se configuran como digitales */

...
ANSEL = 0b00100000; // El pin PORTE.0 se configura como analgico

ANSELH = 0;

// Todos los pines de E/S se configuran como digitales

TRISE = 0b00000001; // Todos los pines del puerto PORTE excepto el


// PORTE.0 se configuran como salidas
PORTE = 0;

// Todos los bits del puerto PORTE se ponen a cero

...

Registros ANSEL y ANSELH


Los registros ANSEL y ANSELH se utilizan para configurar el modo de
entrada de un pin de E/S como analgico o como digital.

La regla es la siguiente:
Para configurar un pin como una entrada analgica, el bit apropiado de los
registros ANSEL o ANSELH se debe poner a uno (1). Para configurar un pin como
una entrada/salida digital, el bit apropiado se debe poner a cero (0).
El estado lgico de los bits del registro ANSEL no tiene influencia en las
funciones de salidas digitales. Al intentar a leer un pin de puerto configurado
como una entrada analgica, el resultado es siempre 0.

Es probable que usted nunca vaya a escribir un programa que no utilice


puertos, as que el esfuerzo para aprender todo sobre ellos en definitiva vale la
pena. De todos modos, los puertos son probablemente los mdulos ms simples
dentro del microcontrolador. Se utilizan de la siguiente manera:
Al

disear

un

dispositivo,

seleccione

un

puerto

por

el

que

el

microcontrolador comunicar al entorno perifrico. Si usted utiliza slo


entradas/salidas digitales, seleccione cualquier puerto. Si utiliza alguna de
las entradas analgicas, seleccione los puertos apropiados que soportan tal
configuracin de los pines (AN0-AN13).
Cada pin del puerto se puede configurar como salida o como entrada. Los
bits de los registros TRISA,TRISB, TRISC, TRISD y TRISE determinan cmo se
com portarn los pines apropiados de los puertos PORTA, PORTB, PORTC,
PORTD y PORTE. Simplemente...
Si utiliza alguna de las entradas analgicas, primero es necesario poner a
uno los bits apropiados de los registros ANSEL y ANSELH en el principio de
programa.
Si utiliza resistencias o botones de presin como una fuente de seal de en
trada, conctelos a los pines del puerto PORTB, ya que tienen las
resistencias pull-up. El uso de estos registros est habilitado por el bit RBPU
del registro OPTION_REG, mientras que la instalacin de las resistencias
individuales est habilitada por los bits del registro WPUB.

Con frecuencia se necesita responder tan pronto como los pines de entrada
cambien su estado lgico. Sin embargo, no es necesario escribir un
programa para comprobar el estado lgico de los pines. Es mucho ms
simple conectar estas entradas a los pines del puerto PORTB y habilitar que
ocurra una interrupcin con cada cambio de voltaje. Los bits de los
registros IOCB e INTCON se encargan de eso.
El microcontrolador PIC16F887 dispone de tres temporizadores/contadores
independientes, denominados Timer0, Timer1 y Timer2. En este captulo se
presenta una descripcin detallada de los mismos.
3.4 TEMPORIZADOR TIMER0
El temporizador Timer0 tiene una amplia gama de aplicaciones en la
prctica. Slo unos pocos programas no lo utilizan de alguna forma. Es muy
conveniente y fcil de utilizar en programas o subrutinas para generar pulsos de
duracin arbitraria, en medir tiempo o en contar los pulsos externos (eventos)
casi sin limitaciones.
El mdulo del temporizador Timer0 es un temporizador/contador de 8 bits
con las siguientes caractersticas:
Temporizador/contador de 8 bits;
Pre-escalador de 8 bits (lo comparte con el temporizador perro guardin);
Fuente de reloj interna o externa programable;
Generacin de interrupcin por desbordamiento; y
Seleccin del flanco de reloj externo programable.
La siguiente figura muestra el esquema del temporizador Timer0 con todos
los bits que determinan su funcionamiento. Estos bits se almacenan en el registro
OPTION_REG.

Registro OPTION_REG

RBPU - PORTB Pull-up enable bit (resistencia Pull Up del puerto


PORTB)
o 0 - Resistencias pull-up del puerto PORTB estn deshabilitadas.
o 1 - Pines del puerto PORTB pueden estar conectados a las resistencias
pull-up.
INTEDG - Interrupt Edge Select bit (bit selector de flanco activo de
la interrupcin externa)
o 0 - Interrupcin por flanco ascendente en el pin INT (0-1).
o 1 - Interrupcin por flanco descendente en el pin INT (1-0).

T0CS - TMR0 Clock Select bit (bit selector de tipo de reloj para el
Timer0)
o 0 - Los pulsos se llevan a la entrada del temporizador/contador Timer0
por el pin RA4.
o 1 - El temporizador utiliza los pulsos de reloj internos (Fosc/4).
T0SE - TMR0 Source Edge Select bit (bit selector de tipo de flanco)
o 0 - Incrementa en flanco descendente en el pin TMR0.
o 1 - Incrementa en flanco ascendente en el pin TMR0.
PSA

- Prescaler Assignment bit (bit de asignacin del pre-

escalador)
o 0 - Pre-escalador se le asigna al WDT.
o 1 - Pre-escalador se le asigna al temporizador/contador Timer0.
PS2, PS1, PS0 - Prescaler Rate Select bit (bit selector del valor del
divisor de frecuencias)
o El valor del divisor de frecuencias se ajusta al combinar estos bits.
Como se muestra en la tabla a la derecha, la misma combinacin de
bits proporciona los diferentes valores del divisor de frecuencias para
el

temporizador/contador

el

temporizador

perro

respectivamente.
PS2

PS1

PS0

TMR0

WDT

1:2

1:1

1:4

1:2

1:8

1:4

1:16

1:8

guardin,

1:32

1:16

1:64

1:32

1:128

1:64

1:256

1:128

Cuando

el

bit

PSA

est

0,

el

pre-escalador

se

le

asigna

al

temporizador/contador Timer0, como se muestra en la siguiente figura.

Vamos a hacerlo en mikroC...

// En este ejemplo, Timer0 se configura como un temporizador y se le asigna un


pre-escalador.

unsigned cnt;

// Declarar la variable cnt

void interrupt() { // Rutina de interrupcin


cnt++;

// Interrupcin causa el incremento de cnt por 1

TMR0 = 155;
INTCON = 0x20;

// Temporizador (o contador) Timer0 devuelve su valor inicial


// Bit T0IE est a 1, bit T0IF est a 0

void main() {
OPTION_REG = 0x04;

// Pre-escalador (1:32) se le asigna al temporizador

Timer0
TMR0 = 155;

// Temporizador T0 cuenta de 155 a 255

INTCON = 0xA0;

// Habilitada la generacin de interrupcin para el

// temporizador Timer0
...
...
// En el siguiente ejemplo, Timer0 se configura como un
temporizador
// y se le asigna un pre-escalador.
OPTION_REG = 0x20; // Pre-escalador (1:2) se le asigna al contador Timer0
TMR0 = 155;
INTCON = 0xA0;

// Contador T0 cuenta de 155 a 255


// Habilitada la generacin de interrupcin por el

// temporizador Timer0
...
...

Cuando el bit PSA est a 1, el pre-escalador se le asigna al temporizador


perro guardin como se muestra en la siguiente figura.

Vamos a hacerlo en mikroC...

// En este ejemplo, el pre-escalador (1:64) se le asigna al temporizador perro


guardin.

void main() {
OPTION_REG = 0x0E; // Pre-escalador se le asigna al WDT (1:64)

asm CLRWDT;

// Comando en ensamblador para reiniciar el WDT

...
...
asm CLRWDT;

// Comando en ensamblador para reiniciar el WDT

...

Aparte de lo dicho anteriormente, cabe destacar lo siguiente:


Al asignarle el pre-escalador al temporizador/contador, el pre-escalador se
pondr a 0 con cualquier escritura en el registro TMR0.
Al asignar el pre-escalador al temporizador perro guardin, tanto el WDT
como el preescalador se pondrn a 0 con la instruccin CLRWDT.
Al escribir en el registro TMR0, utilizado como un temporizador, no se inicia
el conteo de los pulsos inmediatamente, sino con retraso de dos ciclos de
instrucciones. Por consiguiente, es necesario ajustar el valor escrito en el
registro TMR0.
Al poner el microcontrolador en el modo de reposo se apaga el oscilador de
reloj. No puede ocurrir el desbordamiento ya que no hay pulsos a contar. Es
la razn por la que la interrupcin por el desbordamiento del TMR0 no
puededespertar al procesador del modo de reposo.
Si se utiliza como un contador de reloj externo sin pre-escalador, la longitud
de pulso mnima o tiempo muerto entre dos pulsos deber ser 2 Tosc + 20
nS (Tosc es el perodo de seal de reloj del oscilador).
Si se utiliza como un contador de reloj externo con pre-escalador, la longitud
de pulso mnima o tiempo muerto entre dos pulsos es slo 10nS.

El registro del pre-escalador de 8 bits no est disponible al usuario, lo que


significa que no es posible leerlo o escribir en l directamente.
Al cambiar de asignacin del pre-escalador del Timer0 al temporizador perro
guardin, es necesario ejecutar la siguiente secuencia de instrucciones
escritas en ensamblador para impedir reiniciar el microcontrolador:

BANKSEL TMR0

CLRWDT

CLRF TMR0

BANKSEL OPTION_REG

BSF OPTION_REG,PSA ;ASIGNARLE EL PRE-ESCALADOR AL WDT

CLRWDT

MOVLW b'11111000' ;SELECCIONAR LOS BITS PS2,PS1,PS0 Y PONERLOS

ANDWF OPTION_REG,W ;A CERO POR LA INSTRUCCIN 'Y LGICO'

IORLW b'00000101' ;BITS PS2, PS1, Y PS0 PONEN EL VALOR

;PONER A CERO WDT


;PONER A CERO TMR0 Y PRE-ESCALADOR

;PONER A CERO WDT

MOVWF OPTION_REG ;DEL DIVISOR DE FRECUENCIAS A 1:32

De manera similar, al cambiar de asignacin del pre-escalador del WDT al


Timer0, es necesario ejecutar la siguiente secuencia de instrucciones,
tambin escritas en ensamblador:

BANKSEL TMR0

CLRWDT

BANKSEL OPTION_REG

MOVLW b'11110000' ;SELECCIONAR SLO LOS BITS PSA,PS2,PS1,PS0

ANDWF OPTION_REG,W ;Y PONERLOS A CERO POR LA INSTRUCCIN 'Y

;PONER A CERO WDT Y PRE-ESCALADOR

LGICO'

IORLW b'00000011' ;VALOR DEL DIVISOR DE FRECUENCIAS ES 1:16

MOVWF OPTION_REG

Para utilizar el Timer0 apropiadamente, es necesario:


Paso 1: Seleccionar el modo:
El modo de temporizador se selecciona por el bit TOSC del registro
OPTION_REG (TOSC: 0=temporizador, 1=contador).
Cuando se asigna el pre-escalador al temporizador/contador se debe poner
a cero el bit PSA del registro OPTION_REG. El valor del divisor de
frecuencias se configura al utilizar los bits PS2-PS0 del mismo registro.
Al utilizar una interrupcin, los bits GIE y TMR0IE del registro INTCON deben
estar a uno.
Paso 2: Medir y contar
Para medir tiempo:

Reiniciar el registro TMR0 o escribir un valor conocido en l.


El tiempo transcurrido(en microsegundos al utilizar el oscilador de 4MHz) se
mide al leer el registro TMR0.
El

bit

de

bandera

TMR0IF

del

registro

INTCON

se

pone

uno

automticamente siempre que ocurra el desbordamiento del registro TMR0.


Si est habilitada, ocurre una interrupcin.
Para contar pulsos:
La polaridad de pulsos a contar en el pin RA4 se selecciona por el bit TOSE
del registro OPTION_REG (T0SE: 0=pulsos positivos, 1=pulsos negativos).
Varios pulsos se pueden leer del registro TMR0. El pre-escalador y la
interrupcin se utilizan de la misma forma que en el modo de temporizador.
3.5 TEMPORIZADOR TIMER1
El mdulo del temporizador Timer1 es un temporizador/contador de 16 bits,
lo que significa que consiste en dos registros (TMR1L y TMR1H). Puede contar
hasta 65535 pulsos en un solo ciclo, o sea, antes de que el conteo se inicie desde
cero.

Similar al temporizador Timer0, estos registros se pueden leer o se puede


escribir

en

ellos

en

cualquier

momento.

En

caso

de

desbordamiento, se genera una interrupcin si est habilitada.

que

ocurra

un

El mdulo del temporizador Timer1 puede funcionar en uno o dos modos


bsicos, eso es como un temporizador o como un contador. A diferencia del
temporizador Timer0, cada uno de estos dos modos tiene funciones adicionales.
El temporizador Timer1 tiene las siguientes caractersticas:
Temporizador/contador de 16 bits compuesto por un par de registros;
Fuente de reloj interna o externa programable;
Pre-escalador de 3 bits;
Oscilador LP opcional;
Funcionamiento sncrono o asncrono;
Compuerta para controlar el temporizador Timer1 (conteo habilitado) por
medio del comparador o por el pin T1G;
Interrupcin por desbordamiento;
"Despierta"

al

microcontrolador

(salida

del

modo

desbordamiento (reloj externo); y


Fuente de reloj para la funcin de Captura/Comparacin.

de

reposo)

por

SELECCIN DE LA FUENTE DE RELOJ DEL TEMPORIZADOR TIMER1


El bit TMR1CS del registro T1CON se utiliza para seleccionar la fuente de
reloj para este temporizador:
F U E N T E D E R E LO J

TMR1CS

Fosc/4

T1CKI pin

Al seleccionar la fuente de reloj interna, el par de registros TMR1H-TMR1L


ser incrementado con varios pulsos Fosc como es determinado por el preescalador.
Al seleccionar la fuente de reloj externa, este temporizador puede funcionar
como un temporizador o un contador. Los pulsos en el modo temporizador pueden
estar sincronizados con el reloj interno del microcontrolador o funcionar
asncronamente. En caso de que se necesite un oscilador del reloj externo y el
microcontrolador PIC16F887 utilice el oscilador interno INTOSC con el pin
RA6/OSC2/CLIKOUT, el temporizador Timer1 puede utilizar el oscilador LP como
una fuente de reloj.

PRE-ESCALADOR DEL TEMPORIZADOR TIMER1


El temporizador Timer1 tiene un escalador completamente separado que
permite dividir la frecuencia de entrada de reloj por 1,2,4 o 8. No es posible leer el
pre-escalador o escribir en l directamente. De todas formas, el contador del preescalador se pone a 0 automticamente despus de escribir en los registros
TMR1H o TMR1L.
OSCILADOR DEL TEMPORIZADOR TIMER1
Los pines RC0/T1OSO y RC1/T1OSI se utilizan para registrar los pulsos que
vienen de los dispositivos perifricos, pero tambin tienen una funcin adicional.
Como se puede ver en la siguiente figura, se configuran simultneamente como
entrada (pin RC1) y salida (pin RC0) del oscilador de cuarzo LP (Low Power - de
bajo consumo) adicional. Este circuito est principalmente diseado para
funcionar a bajas frecuencias (hasta 200 KHz), exactamente para el uso de cristal
de cuarzo de 32.768 KHz. Este cristal se utiliza en los relojes de cristal puesto que
es fcil de obtener un pulso de duracin de un segundo al dividir esta frecuencia.
Como el oscilador no depende del reloj interno, puede funcionar incluso en
el modo de reposo. Se habilita al poner a uno el bit de control T1OSCEN del
registro T1CON. El usuario debe proporcionar tiempo muerto por medio de
software (unos pocos milisegundos) para habilitar que el oscilador se inicie
apropiadamente.

La siguiente tabla muestra los valores recomendados de los capacitores


convenientes con el oscilador de cuarzo. No es necesario que estos valores sean
exactos. De todas formas, la regla general es: cunto ms alta sea la capacidad,
tanto ms alta ser la estabilidad, lo que a la vez prolonga el tiempo necesario
para la estabilizacin del oscilador.
OSCILADOR

LP

FRECUENCIA

C1

C2

32 kHz

33 pF

33 pF

100 kHz

15 pF

15 pF

200 kHz

15 pF

15 pF

El consumo de corriente del microcontrolador se reduce a nivel ms bajo en


el modo de reposo ya que el consumidor de corriente principal - el oscilador - no
funciona. Es fcil de poner al microcontrolador en este modo - al ejecutar la
instruccin SLEEP. El problema es cmo despertar al microcontrolador porque slo
una interrupcin puede producirlo. Como el microcontrolador duerme, se debe
usar una interrupcin causada por dispositivos perifricos para despertarlo. Se
pone muy complicado si es necesario despertar al microcontrolador a intervalos
de tiempo regulares...
Para resolver el problema, un oscilador de cuarzo LP (de bajo consumo de
corriente) completamente independiente, capaz de funcionar en el modo de
reposo, est integrado en el microcontrolador PIC16F887. Simplemente, un
circuito anteriormente separado ahora est integrado en el microcontrolador y
asignado al temporizador Timer1. El oscilador est habilitado al poner a 1 el bit
T1OSCEN del registro T1CON. El bit TMR1CS del mismo registro se utiliza para
habilitar que el temporizador Timer1 utilice secuencias de pulsos de ese oscilador.

Una seal generada por este oscilador de cuarzo est sincronizada con el
reloj del microcontrolador al poner a 0 el bit T1SYNC. En este caso, el
temporizador no puede funcionar en modo de reposo porque el circuito
para sincronizacin utiliza el reloj del microcontrolador.
La interrupcin por desbordamiento en el registro del temporizador Timer1
puede estar habilitada. Si el bit T1SYNC se pone a 1, tales interrupciones se
producirn en el modo de reposo tambin.
COMPUERTA DEL TEMPORIZADOR TIMER1
El pin TG1 o la salida del comparador C2 pueden ser una fuente de los
pulsos que pasan por la compuerta del temporizador Timer1. Se configuran por
software. Esta compuerta permite que el temporizador mida directamente la
duracin de los eventos externos al utilizar el estado lgico del pin T1G o los
eventos analgicos al utilizar la salida del comparador C2. Refirase a la Figura en
la pgina anterior. Para medir duracin de seal, basta con habilitar esta
compuerta y contar los pulsos que pasan por ella.

TIMER1 EN EL MODO TEMPORIZADOR


Para seleccionar este modo, es necesario poner a 0 el bit TMR1CS. Despus
de eso, el registro de 16 bits ser incrementado con cada pulso generado por el
oscilador interno. Si se utiliza el cristal de cuarzo de 4 MHZ, el registro ser
incrementado cada microsegundo.
En este modo, el bit T1SYNC no afecta al temporizador porque cuenta los
pulsos de reloj interno. Como todos los dispositivos utilizan estos pulsos, no hace
falta sincronizarlos.

El oscilador de reloj del microcontrolador no funciona durante el modo de


reposo as que el desbordamiento en el registro del temporizador no puede causar
interrupcin.
Vamos a hacerlo en mikroC...

// En este ejemplo, el TMR1 est configurado como un temporizador con el valor


// del preescalador 1:8. Cada vez que ocurra un desbordamiento de los registros
TMR1H y
// TMR1L, se solicitar una interrupcin.

void main() {
PIR1.TMR1IF = 0;

// Poner a 0 la bandera de bit del TMR1IF

TMR1H = 0x22;

// Poner el valor inicial para el temporizador Timer1

TMR1L = 0x00;
TMR1CS = 0;

// Temporizador1 cuenta los pulsos del oscilador interno

T1CKPS1 = T1CKPS0 = 1; // El valor del pre-escalador asignada es 1:8


PIE1.TMR1IE = 1;

// Interrupcin habilitada por desbordamiento

INTCON = 0xC0;

// Interrupcin habilitada (bits GIE y PEIE)

TMR1ON = 1;

// Encender el temporizador Timer1

...

TIMER1 EN EL MODO CONTADOR


El temporizador Timer1 se pone a funcionar como un contador al poner a 1
el bit TMR1CS. Este bit cuenta los pulsos llevados al pin PC0/T1CKI y se
incrementa en el flanco ascendente de la entrada del reloj externo T1CKI. Si el bit
de control T1SYNC del registro T1CON se pone a 0, las entradas del reloj externo
se sincronizarn en su camino al temporizador Timer1. En otras palabras, el
temporizador Timer1 se sincroniza con el reloj interno del microcontrolador y se le
denomina contador sncrono.
Al poner en modo de reposo el microcontrolador que funciona de esta
manera, los registros del temporizador Timer1H y TMR1L no sern incrementados

aunque los pulsos de reloj aparezcan en los pines de entrada. Como el reloj
interno del microcontrolador no funciona en este modo, no hay entradas de reloj
que se utilicen para la sincronizacin. De todas formas, el pre-escalador sigue
funcionando siempre que haya pulsos de reloj en los pines, porque es un simple
divisor de frecuencias.

Este contador detecta un uno lgico (1) en los pines de entrada. Cabe
destacar que al menos un flanco ascendente debe ser detectado antes de
empezar a contar los pulsos. Refirase a la Figura a la izquierda. Las flechas en la
figura indican los incrementos del contador.

Registro T1CON

T1GINV - Timer1 Gate Invert bit (Bit inversor de la compuerta del temporizador1)
se comporta como un inversor del estado lgico en la compuerta formada por el
pin T1G o la salida (C2OUT) del comparador C2. Este bit habilita al temporizador
para con tar los pulsos cuando la compuerta est a alto o a bajo.
1 - Temporizador 1 cuenta los pulsos cuando el pin T1G o el bit C2OUT estn
a alto (1).
0 - Temporizador 1 cuenta los pulsos cuando el pin T1G o el bit C2OUT estn
a bajo (0).
TMR1GE - Timer1 Gate Enable bit (Bit de habilitacin de la compuerta del
temporizador1) determina si la compuerta formada por el pin T1G o salida del
comparador C2 (C2OUT) estar activa o no. Este bit es funcional slo en caso de
que el temporizador Timer1 est encendido (el bit TMR1ON = 1). De lo contrario,
este bit se ignora.
1 - Temporizador Timer1 est encendido slo si la compuerta no est activa.
0 - Compuerta no afecta al temporizador Timer1.
T1CKPS1, T1CKPS0 - Timer1 Input Clock Prescale Select bits (Bits de seleccin
del preescalador de seal de reloj del Temporizador1) determina el valor del
divisor de frecuen cias asignada al temporizador Timer1.
T1CKPS1

T1CKPS0

VA LO R D E L P R E - E S C A L A D O R

1:1

1:2

1:4

1:8

T1OSCEN - LP Oscillator Enable Control bit (bit de habilitacin del oscilador LP del
Timer1)
1 - Oscilador LP est habilitado para el reloj del Timer1 (oscilador de bajo
consumo y de frecuencia de 32.768 kHz)
0 - Oscilador LP est apagado.
T1SYNC - Timer1 External Clock Input Synchronization Control bit (Bit de control
de sincronizacin de la seal de entrada) habilita la sincronizacin de la entrada
del oscilador LP o de la entrada del pin T1CKI con el reloj interno del
microcontrolador. Este bit se ignora al contar los pulsos desde el oscilador
principal (el bit TMR1CS = 0).
1 - Entrada de reloj externa no est sincronizada.
0 - Entrada de reloj externa est sincronizada.
TMR1CS - Timer TMR1 Clock Source Select bit (bit de seleccin de la fuente de
reloj del temporizador Timer1)
1 - Cuenta los pulsos por el pin T1CKI (por el flanco ascendente 0-1)
0 - Cuenta los pulsos del reloj interno del microcontrolador
TMR1ON - Timer1 On bit (TMR activo, hace entrar o no en funcionamiento el
Timer1).
1 - Habilita el temporizador Timer1.
0 - Deshabilita el temporizador Timer1.

Para utilizar el Timer1 apropiadamente, es necesario hacer lo siguiente:


Como no es posible apagar el pre-escalador, su valor debe estar ajustado a
los bits T1CKPS1 y T1CKPS0 del registro T1CON (Refirase a la tabla).
Seleccionar el modo por el bit TMR1CS del registro T1CON. (TMR1CS: 0=la
fuente de reloj es oscilador de cuarzo interno, 1= la fuente de reloj es
oscilador de cuarzo externo).
Al configurar el bit T1OSCEN del mismo registro, el oscilador est habilitado
y los registros TMR1H y TMR1L se incrementan con cada pulso de reloj. Al
poner este bit a 0, se detiene el conteo.
Al reiniciar los registros del contador o al escribir en ellos, se reinicia el preescalador.
Al llenar ambos registros del temporizador, se configura la bandera TMR1IF
y el conteo empieza desde cero.

3.6 TEMPORIZADOR TIMER2


El mdulo del temporizador Timer2 es un temporizador de 8 bits.

Los pulsos que vienen del oscilador de cuarzo primero pasan por el preescalador cuyo valor puede ser modificado al combinar los bits T2CKPS1 y
T2CKPS0. La salida del preescalador se utiliza para incrementar el registro TMR2
empezando

por

00h.

Los

valores

del

TMR2

del

PR2

se

comparan

constantemente y el registro TMR2 va incrementndose hasta alcanzar el valor


del registro PR2. Cuando se igualan los valores de los registros, lo que ser
registrado por el comparador, el TMR2 se reinicia a 00h automticamente. El
postescalador del temporizador Timer2 se incrementa y su salida se utiliza para
generar una interrupcin si est habilitada.
Los ambos registros TMR y PR2 son de lectura y escritura. El conteo se
puede detener al poner a 0 el bit TMR2ON, lo que resulta en un ahorro de energa.
El momento de reinicio del TMR2 se puede utilizar para determinar la
velocidad de transmisin en baudios de la comunicacin serie sncrona.
Varios bits del registro T2CON estn en control del temporizador Timer2.

Registro T2CON

TOUTPS3 - TOUTPS0 - Timer2 Output Postcaler Select bits (bits de seleccin del
rango del divisor del post-escalador para el Timer2) se utilizan para determinar el
valor del post-escalador segn la siguiente tabla:
TOUTPS

TOUTPS

TOUTPS

TOUTPS

VA LO R

DEL

ESCALADOR

1:1

1:2

1:3

1:4

1:5

1:6

1:7

1:8

1:9

1:10

1:11

1:12

1:13

1:14

1:15

1:16

P O S T-

TMR2ON Timer2 On bit - (bit de activacin del TIMR2) hace entrar en


funcionamiento el temporizador Timer2.

1 - Habilita el funcionamiento del Timer2.


0 - Deshabilita el funcionamiento del Timer2.
T2CKPS1, T2CKPS0 - Timer2 Clock Prescaler bits (seleccin del rango del divisor
del preescalador del Timer2) determina el valor del divisor de frecuencias:
T2CKPS1

T2CKPS0

VA LO R D E L P R E - E S C A L A D O R

1:1

1:4

1:16

Al utilizar el temporizador Timer2 hay que saber varios detalles relacionados


con sus registros:
En el momento de encender una fuente de alimentacin, el registro PR2
contiene el valor FFh.
Tanto el pre-escalador como el post-escalador se borran al escribir en el
registro TMR2.
Tanto el pre-escalador como el post-escalador se borran al escribir en el
registro T2CON.
Al producirse cualquier reinicio, como puede anticiparse, tanto el preescalador como el post-escalador se borran.
Los mdulos CCP pueden funcionar en muchos modos diferentes, por lo que
se consideran los ms complicados. Si usted intenta analizar su funcionamiento a
base de tablas que describen las funciones de bits, comprender mejor de lo qu
le estamos hablando. Si utiliza alguno de los mdulos CCP, primero seleccione el
modo que necesita, analice la figura apropiada y entonces pngase a modificar
los bits de registros. Si no...
3.7 MDULOS CCP

El mdulo CCP (Captura/Comparacin/PWM) es un perifrico que le permite


medir y controlar diferentes eventos.
El modo de captura proporciona el acceso al estado actual de un registro
que cambia su valor constantemente. En este caso, es el registro del
temporizador Timer1.
El modo de comparacin compara constantemente valores de dos
registros. Uno de ellos es el registro del temporizador Timer1. Este circuito
tambin le permite al usuario activar un evento externo despus de que haya
expirado una cantidad de tiempo predeterminada.
PWM (Pulse Width Modulation - modulacin por ancho de pulsos) puede
generar seales de frecuencia y de ciclo de trabajo variados por uno o ms pines
de salida.
El microcontrolador PIC16F887 dispone de dos mdulos CCP - CCP1 y CCP2.
Ambos son idnticos en modo normal de funcionamiento, mientras que las
caractersticas del PWM mejorado estn disponibles slo en el modo CCP1. sta es
la razn por la que en este captulo se describe detalladamente el funcionamiento
del mdulo CCP1. Con respecto al CCP2, se presentarn slo las caractersticas
que lo distinguen del CCP1.
MDULO CCP1
Una parte central de este circuito es un registro CCPR1 de 16 bits que
consiste en registros CCPR1L y CCOR1H. Se utiliza para capturar y comparar sus
valores con los nmeros almacenados en el registro del temporizador Timer1
(TMR1H y TMR1L).

Si est habilitado por software, puede ocurrir el reinicio del temporizador


Timer1 al igualarse los valores en modo de Comparacin. Adems, el mdulo
CCP1 puede generar seales PWM de frecuencia y de ciclo de trabajo variados.
Los bits del registro CCP1CON estn en control del mdulo CCP1.
CCP1 EN MODO DE CAPTURA
En este modo, el registro del temporizador Timer1 (que consiste en los
TMR1H y TMR1L) se copia al registro CCP1 (que consiste en los CCPR1H y CCPR1L)
en las siguientes situaciones:
Cada flanco ascendente (1 -> 0) en el pin RC2/CCP;
Cada flanco descendente (0 -> 1) en el pin RC2/CCP1;
Cada cuarto flanco ascendente (0 -> 1) en el pin RC2/CCP1; y
Cada decimosexto flanco descendente (0 -> 1) en el pin RC2/CCP1.
Una combinacin de cuatro bits (CCP1M3 - CCP1M0) del registro de control
determina cul de estos eventos causar transmisin de dato de 16 bits. Adems,
se deben cumplir los siguientes requisitos::
El pin RC2/CCP1 debe estar configurado como entrada; y
El Timer1 debe funcionar como temporizador o contador sncrono.

El bit de bandera CCP1IF se pone a uno despus de acabar la captura. Si se


pone a 1 el bit CCP1IE del registro PIE1, se producir una interrupcin.
En caso de que el mdulo CCP1 est en modo de captura, puede producirse
una interrupcin no deseada. Para evitarlo, antes de que ocurra un cambio en el
registro de control se deben poner a 0 tanto el bit que habilita la interrupcin
CCP1IE, como el bit de bandera CCP1IF.
Las interrupciones no deseadas pueden producirse al cambiar el valor del
pre-escalador. Para evitarlo, el mdulo CCP1 debe estar apagado temporalmente
antes de cambiar el valor del pre-escalador.
Se recomienda la siguiente secuencia de programa, escrita en ensamblador:

BANKESEL CCP1CON

CLRF

CCP1CON ;REGISTRO DE CONTROL BORRADO


;MDULO CCP1 EST APAGADO

MOVLW
MOVWF

XX

;NUEVO MODO DEL PRE-ESCALADOR EST SELECCIONADO

CCP1CON ;EN EL REGISTRO DE CONTROL SE INTRODUCE UN NUEVO

VALOR
;MDULO CCP1 SE ENCIENDE SIMULTNEAMENTE

Vamos a hacerlo en mikroC...

...

ASM {
BANKESEL CCP1CON
CLRF CCP1CON

// REGISTRO DE CONTROL BORRADO

// MDULO CCP1 EST APAGADO


MOVLW XX

// NUEVO MODO DEL PRE-ESCALADOR EST SELECCIONADO

MOVWF CCP1CON

// EN EL REGISTRO DE CONTROL SE INTRODUCE NUEVO

VALOR
}

// MDULO CCP1 SE ENCIENDE SIMULTNEAMENTE

...

CCP1 EN MODO DE COMPARACIN


En este modo, el valor almacenado en el registro CCP1 se compara
constantemente al valor almacenado en el registro del temporizador Timer1. Al
igualarse los valores, el estado lgico en el pin de salida puede ser cambiado, lo
que depende del estado de bits en el registro de control (CCP1M3 - CCP1M0). El
bit de bandera CCP1IF se pone a uno simultneamente.

Para poner el mdulo CCP1 en este modo de funcionamiento, se deben


cumplir dos condiciones:
El pin RC2/CCP1 debe estar configurado como salida; y
El temporizador Timer1 debe estar sincronizado con el reloj interno.
CCP1 EN MODO PWM
Las seales de frecuencia y de ciclo de trabajo variados tienen una amplia
gama de aplicaciones en automatizacin. Un ejemplo tpico es un circuito de
control de potencia. Refirase a la siguiente figura. Si un cero lgico (0) indica un
interruptor abierto y un uno lgico (1) indica un interruptor cerrado, la potencia
elctrica que se transmite a los consumidores ser directamente proporcional a la
duracin del pulso. Esta relacin se le denomina Ciclo de Trabajo.

El otro ejemplo, comn en la prctica, es el uso de seales PWM en un


circuito para generar seales de forma de onda arbitraria como una onda
sinusoidal. Vea la siguiente figura:

Los dispositivos que funcionan segn este principio se utilizan con


frecuencia en la prctica como variadores de frecuencia ajustable que controlan
motores elctricos (velocidad, aceleracin, desaceleracin etc.)

La Figura anterior muestra el diagrama de bloques del mdulo CCP1 puesto


en el modo PWM. Para generar un pulso de forma arbitraria en el pin de salida, es
necesario ajustar el perodo de pulsos (frecuencia) y la duracin de pulsos.

PERODO DE PWM
El perodo de pulso de salida (T) se determina por el registro PR2 del
temporizador Timer2. El perodo de PWM se puede calcular por la siguiente
ecuacin:
Perodo PWM = (PR2 +1) * 4Tosc * Valor de pre-escala del Timer2
Si el perodo de PWM (T) es conocido, es fcil determinar la frecuencia de
seal F, porque estos dos valores estn relacionados por la ecuacin F=1/T.
CICLO DE TRABAJO DE PWM
El ciclo de trabajo de PWM se especifica al utilizar en total 10 bits: los ocho
bits ms significativos del registro CCPR1L y los dos bits menos significativos
adicionales del registro CCP1CON (DC1B1 y DC1B0). El resultado es un nmero de
10 bits dado por la siguiente frmula:
Ancho de pulsos = (CCPR1L,DC1B1,DC1B0) * Tosc * Valor de pre-escala del
Timer2
La siguiente tabla muestra cmo generar las seales PWM de diferentes
frecuencias cuando el microcontrolador utiliza un cristal de cuarzo de 20 MHz
(Tosc=50nS).

FRECUENCIA [KHZ]

1.2
2

4.88

19.5

78.1

156.

208.3

Pre-escalador del TMR2

16

Registro PR2

FFh

FFh

FFh

3Fh

1Fh

17h

Notas adicionales:

El pin de salida se va a poner a 1 constantemente, si por error el ancho de


pulso generado es ms largo que el perodo de PWM.
En esta aplicacin, no se puede utilizar el post-escalador del temporizador
Timer2 para generar perodos de PWM largos.
RESOLUCIN DE PWM
Una seal PWM no es nada ms que una secuencia de pulsos que varan su
ciclo de trabajo. Para una frecuencia especfica (nmero de pulsos por segundo),
hay un nmero limitado de combinaciones de ciclos de trabajo. Este nmero
representa una resolucin medida en bits. Por ejemplo, si una resolucin es de 10
bits estarn disponibles 1024 ciclos de trabajo discretos; si una resolucin es de 8
bits

estarn

disponibles

256

ciclos

de

trabajo

disretos

etc.

En

este

microcontrolador la resolucin es determinada por el registro PR2. El mximo


valor se obtiene al usar el nmero FFh.
Frecuencias y resoluciones de PWM (Fosc = 20MHz):
FRECUEN
CIA

DE

PWM
Pre-escala del
temporizador
Valor del PR2
Resolucin
mxima

1.22K

4.88K

19.53K

78.12K

156.3K

208.3K

HZ

HZ

HZ

HZ

HZ

HZ

16

FFh

FFh

FFh

3Fh

1Fh

17h

10

10

10

Frecuencias y resoluciones de PWM (Fosc = 8MHz):


FRECUEN
CIA

DEL

PWM
Pre-escala

1.22K

4.90K

19.61

76.92K

153.85

200.0K

HZ

HZ

KHZ

HZ

KHZ

HZ

16

del
temporizador
Valor del PR2
Resolucin
mxima

65h

65h

65h

19h

0Ch

09h

Vamos a hacerlo en mikroC...

/* En este ejemplo, el mdulo PWM est inicializado y ajustado para producir


una secuencia
de pulsos de ciclo de trabajo del 50%. Para este propsito, se utilizan las
funciones
PWM1_Init(), PWM1_Start() y PWM1_Set_Duty(). Todas las funciones las contiene
la librera
PWM del mikroC PRO for PIC. Slo es necesario copiarlas al programa */

unsigned short duty_c; // Definir la variable duty_c

void initMain() {
ANSEL = ANSELH = 0;
PORTC = TRISC = 0;
PWM1_Init(5000);
}

// Todos los pines de E/S se configuran como digitales


// Estado inicial de los pines de salida del puerto PORTC

// Inicializacin del mdulo PWM (5KHz)

void main() {
initMain();
duty_c = 127;

// Valor inicial del ciclo de trabajo

PWM1_Start();

// Iniciar el mdulo PWM1

PWM1_Set_Duty(duty_c); // Ajustar el ciclo de trabajo de PWM al 50%


...
...

Registro CCP1CON

P1M1, P1M0 - PWM Output Configuration bits (bits de configuracin del


modo PWM) - El pin P1A es la entrada del mdulo de Captura/Comparacin en
todos los modos, menos en modo PWM. Los pines P1B, P1C y P1D actan como
los pines de E/S del puerto D.
En modo PWM estos bits afectan al funcionamiento del mdulo CCP1 como
se muestra en la siguiente tabla:
P1M1

P1M0

MODO
PWM con una sla salida

Por

el

pin

P1A

sale

una

seal

modulada.

Pines P1B, P1C y P1D son entradas/salidas del puerto D.


Configuracin

Full

Bridge

Forward

(puente completo con salida directa)


0

Por

el

pin

P1D

sale

una

seal

modulada.

Por

el

pin

P1D

sale

una

seal

modulada.

Pines P1B y P1C estn inactivos.


Configuracin Half Bridge (medio-puente)
1

Por los pines P1A y P1B sale una seal modulada.


Pines P1C y P1D son entradas/salidas del puerto D.
Configuracin

Full

Bridge

Reverse

(puente completo con salida inversa)


1

Por
Pin

el

pin

P1B

sale

P1C

Pines P1A y P1D estn inactivos.

una
est

seal

modulada.
activo.

DC1B1, DC1B0 - PWM Duty Cycle Least Significant bits (bits menos
significativos del ciclo de trabajo de PWM) - Se utilizan slo en el modo PWM y
representan dos bits menos significativos de un nmero de 10 bits. Este nmero
determina el ciclo de trabajo de la seal PWM. Los dems 8 bits se almacenan en
el registro CCPR1L.
CCP1M3 - CCP1M0 - (bits de seleccin de modo del mdulo CCP1)
determina el modo del mdulo CCP1.
CCP1M

CCP1M

CCP1

CCP1M

M1

Mdulo est deshabilitado (reinicio).

No utilizado.

MODO

Modo de comparacin
0

El bit CCP1IF bit se pone a 1 al


ocurrir una coincidencia.

No utilizado.
Modo de captura

Cada flanco descendente en el pin


CCP1.
Modo de captura

Cada flanco ascendente en el pin


CCP1.
Modo de captura

Cada cuarto flanco ascendente en


el pin CCP1.
Modo de captura

Cada

decimosexto

flanco

ascendente en el pin CCP1.


Modo de comparacin
1

La salida y el bit CCP1IF se ponen a


1 al ocurrir una coincidencia

Modo de comparacin

La salida se pone a 0 y el bit CCP1IF


se

pone

al

ocurrir

una

coincidencia.
Modo de comparacin
1

Llega la solicitud de interrupcin y


el bit CCP1IF se pone a 1 al ocurrir
una coincidencia
Modo de comparacin
El bit CCP1IF se pone a 1, y los

registros de temporizadores 1 o 2
se

borran

al

ocurrir

una

coincidencia
Modo PWM
Pines P1A y P1C estn activos a
1

nivel

alto.

Pines P1B y P1D estn activos a


nivel alto.
Modo PWM
Pines P1A y P1C estn activos a
1

nivel

alto.

Pines P1B y P1D estn activos a


nivel bajo.
Modo PWM
Pines P1A y P1C estn activos a
1

nivel

bajo.

Pines P1B y P1D estn activos a


nivel alto.
Modo PWM
Pines P1A y P1C estn activos a
1

nivel

bajo.

Pines P1B y P1D estn activos a


nivel bajo.

MDULO CCP2
Con exclusin de los nombres diferentes de los registros y de los bits, este
mdulo es una muy buena copia del mdulo CCP1 puesto en modo normal. La
nica diferencia significativa entre ellos es el funcionamiento en modo de
comparacin del mdulo CCP2. La diferencia se refiere a la seal de reinicio del
temporizador T1. Concretamente, si el convertidor A/D est habilitado, al
igualarse los valores de los registros TMR1 y CCPR2, la seal de reinicio del
temporizador T1 iniciar automticamente la conversin A/D. Similar al mdulo
anterior, este circuito tambin est bajo el control de los bits del registro de
control. Esta vez es el registro CCP2CON.

Registro CCP2CON

DC2B1, DC2B0 - PWM Duty Cycle Least Significant bits (bits menos
significativos del ciclo de trabajo de PWM) - Se utilizan slo en modo PWM y
representan dos bits menos significativos de un nmero de 10 bits. Este nmero
determina el ciclo de trabajo de la seal PWM. Los dems 8 bits se almacenan en
el registro CCPR2L.

CCP2M3 - CCP2M0 - CCP2 Mode Select bits (bits de seleccin de modo del
mdulo CCP2) determina el modo del mdulo CCP2.
CCP2M

CCP2M

CCP2M

CCP2M

No utilizado.

No utilizado.

No utilizado.

MODO
Mdulo

est

deshabilitado

(reinicio).

Modo de Captura
0

Cada flanco descendente en el pin


CCP2.
Modo de Captura

Cada flanco ascendente en el pin


CCP2.
Modo de Captura

Cada cuarto flanco ascendente en


el pin CCP2.
Modo de Captura

Cada

decimosexto

flanco

ascendente en el pin CCP2.


Modo de comparacin
1

La salida y el bit CCP2IF se ponen a


1 al ocurrir una coincidencia.
Modo de comparacin

La salida se pone a 0 y el bit


CCP2IF se pone a 1 al ocurrir una
coincidencia

Modo de comparacin
Se produce una interrupcin, el bit
CCP2IF se pone a 1 y no hay

cambio el pin CCP2 pin al ocurrir


una coincidencia.
Modo de comparacin
Al ocurrir una coincidencia, el bit
1

CCP2IF se pone a 1, los registros


del temporizador 1 se borran y la
conversin

A/D

se

inicia

si

el

convertidor A/D est habilitado.


1

Modo PWM

Cmo configurar e iniciar el mdulo CCP1 para funcionar en modo PWM?


Para configurar e iniciar el mdulo CCP1 para funcionar en modo PWM, siga
los siguientes pasos:
Deshabilitar el pin de salida del CCP1. Deber estar configurado como
entrada.
Seleccionar el perodo de seal PWM al introducir el valor en el registro PR2.
Configurar el mdulo CCP1 para funcionar en modo PWM al combinar los
bits del registro CCP1CON.
Ajustar el ciclo de trabajo de seal PWM al introducir el valor en el registro
CCPR1L y al utilizar los bits DC1B1 y DC1B0 del registro CCP1CON.
Configurar e iniciar el temporizador Timer2:
o Poner a cero el bit de bandera de interrupcin TMR2IF en el registro
PIR1
o Ajustar el valor de divisin de frecuencia del temporizador Timer2 por
los bits
o T2CKPS1 y T2CKPS0 del registro T2CON.

o Iniciar el temporizador Timer2 al poner a uno el bit TMR2ON del


registro T2CON.
Habilitar los pines de salida de PWM despus de que haya sido acabado un
ciclo de PWM:
o Esperar el desbordamiento del temporizador Timer2 (el bit TMR2IF del
registro PIR1 se pone a uno)
o Configurar el pin apropiado como salida al poner a cero el bit en el
registro TRIS.
MDULO CCP1 EN MODO MEJORADO
El mdulo CCP1 es el nico que se puede poner en modo mejorado. Este
modo bsicamente no difiere del modo normal del CCP1 y la mejora se refiere a la
transmisin de la seal PWM a los pines de salida. Por qu es eso tan
importante? Por el uso cada vez ms frecuente de los microcontroladores en los
sistemas de control de motores elctricos. Aqu no vamos a describir estos
dispositivos, sin embrago si tiene la oportunidad de trabajar en el desarrollo de los
dispositivos similares, reconocer los elementos que se utilizaban hasta hace
poco como los perifricos. Decimos &se utilizaban& porque todos estos elementos
ahora estn integrados en el microcontrolador y pueden funcionar en varios
modos diferentes.
MODO PWM CON UNA SALIDA
El modo PWM con una salida est habilitado slo en el caso de que se
pongan a cero los bits P1M1 y P1M0 en el registro CCP1CON. En tal caso, una
seal PWM puede estar disponible simultneamente en como mximo cuatro
diferentes pines de salida. Adems, la secuencia de seales PWM puede aparecer
en forma de onda bsica o invertida. La distribucin de seales depende de los
bits del registro PSTRCON, mientras que su polaridad depende de los bits CCP1M1
y CCP1M0 del registro CCP1CON.

Si se utiliza una salida invertida, los pines activos a nivel bajo y los pulsos
que tienen la misma forma de onda se generan siempre en parejas: en los pines
P1A y P1C as como en los pines P1B y P1D, respectivamente.

MODO DE MEDIO-PUENTE
En cuanto al modo de medio-puente, la seal PWM es una salida en el pin
P1A, mientras que a la vez la seal complementaria PWM es una salida en el pin
P1B. Estos pulsos activan a los controladores MOSFET en modo de Medio-Puente
que habilitan/deshabilitan el flujo de corriente por el dispositivo.

En este modo es muy peligroso encender los controladores MOSFET


simultneamente (el cortocircuito producido en aquel momento sera fatal). Para
evitarlo, es necesario proporcionar un tiempo muerto entre encender y apagar los

controladores. Este tiempo muerto est marcado con 'td' (time delay) en la
siguiente figura. El problema se resuelve al utilizar los bits PDC0-PDC6 del registro
PWM1CON.

Como se muestra en la siguiente figura, el modo de medio-puente se puede


utilizar para activar los controladores MOSFET en la configuracin Puente
completo:

MODO PUENTE-COMPLETO
Todos los cuatro pines se utilizan como salidas en el modo Puente completo.
En la prctica, este modo es utiliza con frecuencia para activar los motores, lo que
proporciona un control simple y completo de velocidad y direccin de rotacin.
Hay dos configuraciones de este modo: Full Bridge-Forward (puente completo con
salida directa) y Full Bridge-Reverse (puente completo con salida inversa).

CONFIGURACIN PUENTE COMPLETO - DIRECTO


En modo Directo ocurre lo siguiente:
Un uno lgico (1) aparece en el pin P1A (pin est activo a nivel alto);
Secuencia de pulsos aparece en el pin P1D; y
Un cero lgico (0) en los pines P1B y P1C (pines estn activos a nivel bajo).
La siguiente figura muestra el estado de los pines P1A-P1D durante un ciclo
PWM completo:

CONFIGURACIN PUENTE COMPLETO - INVERSO


Lo similar ocurre en modo Inverso, a menos que estos pines dispongan de
funciones diferentes:

Un uno lgico (1) aparece en el pin P1C (pin est activo a nivel alto);
Secuencia de pulsos aparece en el pin P1B; y
Un cero lgico (0) aparece en los pines P1A y P1D (pines estn activos a
nivel bajo).

Registro PWM1CON

STRC PWM Restart Enable bit (Bit de habilitacin del reinicio automtico
del PWM)
1 - Despus de un apagado automtico, el mdulo PWM se reinicia
automticamente, y el bit ECCPASE del registro ECCPAS se pone a cero.
0 - Para iciar el mdulo PWM despus de un apagado automtico, el bit
ECCPASE debe ponerse a cero por software.
PDC6 - PDC0 PWM Delay Count bits (Bits de configuracin del tiempo
muerto en el modo PWM) - El nmero binario de 7 dgitos determina el nmero
de ciclos de in strucciones (4Tosc) aadidos como tiempo muerto al activar los
pines de entrada PWM.

Registro PSTRCON

STRSYNC - Steering Sync bit (bit de sincronizacin de direccin)


determina el momento de la direccin de los pulsos de PWM:
1 - La direccin ocurre despus de que el registro PSTRCION haya sido
cambiado, slo si se ha completado la forma de onda del PWM.
0 - La direccin ocurre despus de que el registro PSTRCION haya sido
cambiado.

La

seal

PWM

en

la

salida

del

pin

ser

cambiada

inmediatamente sin reparar en si el ciclo anterior ha sido completado. Este

procedimiento es til cuando es necesario detener la transmisin de una


seal PWM del pin.
STRD - Steering Enable bit D (bit D de habilitacin de direccin)
determina la funcin del pin P1D.
1 - El pin P1D tiene la forma de onda del PWM con polaridad determinada
por los bits CCP1M0 y CCP1M1.
0 - Pin est configurado como entrada/salida general del puerto PORTD.
STRC Steering Enable bit C (bit C de habilitacin de direccin) determina
la funcin del pin P1C.
1 - El pin P1C tiene la forma de onda del PWM con polaridad determinada
por los bits CCP1M0 y CCP1M1.
0 - Pin est configurado como entrada/salida general del puerto PORTD.
STRB - Steering Enable bit B (bit B de habilitacin de direccin)
determina la funcin del pin P1B.
1 - El pin P1B tiene la forma de onda del PWM con polaridad determinada
por los bits CCP1M0 y CCP1M1.
0 - Pin est configurado como entrada/salida general del puerto PORTD.
STRA - Steering Enable bit A (bit A de habilitacin de direccin)
determina la funcin del pin P1A.
1 - El pin P1A tiene la forma de onda del PWM con polaridad determinada
por los bits CCP1M0 y CCP1M1.
0 - Pin est configurado como entrada/salida general del puerto PORTC.
Registro ECCPAS

ECCPASE - ECCP Auto-Shutdown Event Status bit (bit de estado del


apagado automtico) indica si ha ocurrido el apagado automtico del mdulo CCP
(estado de Apagado):
1 - Mdulo CCP est en estado de Apagado.
0 - Mdulo CCP funciona normalmente.
ECCPAS2 - ECCPAS0 - ECCP Auto-Shutdown Source Select bits (Bits
de seleccin de la fuente de apagado automtico) selecciona la fuente de
apagado automtico.
E C C PA S

E C C PA S

E C C PA S

FUENTE

DEL

E S TA D O

A PA G A D O

Estado del apagado deshabilitado

Cambio de salida del comparador C1

Cambio de salida del comparador C2

DE

Cambio de salidas de los comparadores C1


y C2
Cero lgico (0) en el pin INT
Cero lgico (0) en el pin INT o cambio de
salida del comparador C1
Cero lgico (0) en el pin INT o cambio de
salida del comparador C2
Cero lgico (0) en el pin INT o cambio de
salidas de los comparadores C1 y C2

PSSAC1, PSSAC0 - Pins P1A, P1C Shutdown State Control bits (Bits
de configuracin de los pines P1A y P1C en modo de apagado) define el estado
lgico de los pines P1A y P1C cuando el mdulo CCP est en el estado de
apagado.
P SS A C 1

P SS A C 0

E S TA D O L G I C O D E LO S P I N E S

Alta impedancia (Tri-estado)

PSSBD1, PSSBD0 - Pins P1B, P1D Shutdown State Control bits (Bits
de configuracin de los pines P1B y P1D en modo de apagado) define el estado
lgico de los pines P1B y P1D cuando el mdulo CCP est en el estado de
apagado.
P SS B D 1

P SS B D 0

E S TA D O L G I C O D E LO S P I N E S

Alta impedancia (Tri-estado)

El microcontrolador PIC 16F887 dispone de varios mdulos de comunicacin


serie independientes, adems cada uno se puede configurar a funcionar en
modos diferentes. Eso es lo que los hace insustituibles en muchos casos.
Acurdese de lo que hemos dicho sobre los mdulos CCP ya que lo mismo se
aplica aqu. No se preocupe de los detalles del funcionamiento de todos los
mdulos, solo seleccione uno y utilice lo que realmente necesita.
3.8 MDULOS DE COMUNICACIN SERIE
El USART es uno de los primeros sistemas de comunicacin serie. Las
versiones nuevas de este sistema estn actualizadas y se les denomina un poco
diferente - EUSART.
EUSART

El mdulo Transmisor/Receptor Universal Sncrono/Asncrono mejorado


(Enhanced Universal Synchronous Asynchronous Receiver Transmitter - EUSART)
es un perifrico de comunicacin serie de entrada/salida. Asimismo es conocido
como Interfaz de comunicacin serie (Serial Communications Interface - SCI).
Contiene todos los generadores de seales de reloj, registros de desplazamiento y
bfers de datos necesarios para realizar transmisin de datos serie de
entrada/salida, independientemente de la ejecucin de programa del dispositivo.
Como indica su nombre, aparte de utilizar el reloj para la sincronizacin, este
mdulo puede establecer la conexin asncrona, lo que lo hace nico para algunas
aplicaciones. Por ejemplo, en caso de que sea difcil o imposible proporcionar
canales especiales para transmisin y recepcin de datos y seales de reloj (por
ejemplo, mando a distancia de radio o infrarrojas), el mdulo EUSART es
definitivamente la mejor opcin posible.
El EUSART integrado en el PIC16F887 posee las siguientes caractersticas:
Transmisin y recepcin asncrona en modo Full-duplex;
Caracteres de anchura de 8 9 bits programables;
Deteccin de direccin en modo de 9 bits;
Deteccin de errores por saturacin del bfer de entrada; y
Comunicacin Half Duplex en modo sncrono.
EUSART EN MODO ASNCRONO

El EUSART transmite y recibe los datos utilizando la codificacin de no


retorno a cero - NRZ (non-return-to-zero). Como se muestra en la siguiente figura,
no se utiliza una seal de reloj y los datos se transmiten de forma muy simple:

Cada dato se transmite de la siguiente forma:


En estado inactivo la lnea de datos permanece en estado alto (1);
Cada transmisin de datos comienza con un bit de arranque (START), el
cual, siempre es cero (0);
Cada dato tiene un ancho de 8 o 9 bits (primero se transmite el bit menos
significativo - LSB); y
Cada transmisin de datos termina con un bit de parada (STOP), el cual,
siempre es uno (1) La siguiente figura muestra cmo conectar de manera
habitual un microcontrolador PIC que utiliza el mdulo EUSART. El circuito
RS-232 se utiliza como un convertidor de nivel de voltaje.
Figure below shows a common way of connecting PIC microcontroller that
uses EUSART module. The RS-232 circuit is used as a voltage level converter.

EUSART EN MODO DE TRANSMISOR ASNCRONO

Para habilitar la transmisin de datos por medio del mdulo EUSART, es


necesario configurarlo para que funcione como un transmisor. En otras palabras,
es necesario definir el estado de los siguientes bits:
TXEN = 1 - El transmisor EUSART se habilita al poner a uno el bit TXEN del
registro TXSTA.
SYNC = 0 - El EUSART se configura a funcionar en modo asncrono al poner
a cero el bit SYNC del registro TXSTA.
SPEN = 1 - Al poner a uno el bit SPEN del registro RCSTA, el EUSART est
habilitado y el pin TX/CK se configura automticamente como salida. Si el
bit se utiliza simultneamente para alguna funcin analgica, se debe
deshabilitar al poner a cero el bit correspondiente del registro ANSEL.
La parte central del transmisor EUSART ocupa el registro de desplazamiento
TSR que no est directamente disponible al usuario. Para iniciar la transmisin de
datos, el mdulo debe estar habilitado al poner a uno el bit TXEN del registro

TXSTA. Los datos a enviar se deben escribir en el registro TXREG, lo que resultar
en la siguiente secuencia de eventos:
Byte ser transmitido inmediatamente al registro de desplazamiento TSR;
El registro TXREG permanece vaco, lo que indica la bandera de bit TXIF del
registro PIR1. Si se pone a uno el bit TXIE del registro PIE1, se generar una
interrupcin. De todos modos, la bandera se pone a uno sin reparar en si
una interrupcin est habilitada o no y no se puede poner a cero por
software, sino al escribir un dato nuevo en el registro TXREG.
Dispositivos electrnicos de control "empujan" el dato hacia el pin TX en
sincronizacin con seal de reloj interna: bit de arranque (START)
(1).....datos....bit de parada (STOP) (1).
Cuando el ltimo bit abandona el registro TSR, el bit TRMT en el registro
TXSTA se pone a cero automticamente.
Si mientras tanto se escribe un dato nuevo en el registro TXREG, todo el
procedimiento se repite inmediatamente despus de la transmisin del bit
de parada del dato anterior.
Para transmitir un dato de 9 bits es necesario poner a uno el bit TX9 del
registro TXSTA. El bit TX9D del registro TXSRTA es el noveno bit y el ms
significativo. Al transmitir un dato de 9 bits, el bit de datos TX9D deber estar
escrito antes de que de se escriban los 8 bits menos significativos en el registro
TXREG. Todos los nueve bits de datos se transmiten al registro de desplazamiento
TFR inmediatamente despus de que se acabe la escritura en el registro TXREG.
EUSART EN MODO DE RECEPTOR ASNCRONO

Similar al poner en marcha el transmisor del EUSART, para habilitar el


receptor es necesario configurar los siguientes bits:
CREN = 1 - El receptor EUSART se habilita al poner a uno el bit CREN del
registro RCSTA;
SYNC = 0 - El EUSART se configura a funcionar en modo asncrono al poner
a cero el bit SYNC del registro TXSTA; y
SPEN = 1 - Al poner a uno el bit SPEN del registro RCSTA, el EUSART est
habilitado y el pin RX/DT se configura automticamente como salida. Si el
bit se utiliza simultneamente para alguna funcin analgica, se debe
desha bilitar al poner a cero el bit correspondiente del registro ANSEL.
Despus de que se haya terminado el primer paso necesario y se haya
detectado el bit de arranque (START), el dato se transmite al registro de
desplazamiento RSR por el pin RX. Al haber recibido el bit de parada (STOP),
ocurre lo siguiente:
El dato se transmite automticamente al registro RCREG (si est vaco);
El bit de bandera RCIF se pone a uno y ocurre una interrupcin si est
habilita da por el bit RCIE en el registro PIE1. Similar al transmisor, el bit de
bandera se pone a cero slo por software, o sea, al leer el registro RCREG.

Tenga en cuenta que esto es un doble registro de tipo FIFO (primero en


entrar, primero en salir - first-in, first-out), lo que permite almacenamiento
de dos caracteres simultneamente);
Si el registro RCREG est ocupado (contiene dos bytes) y el registro de
desplazamiento detecta el nuevo bit de parada (STOP), el bit de
sobrescritura OERR se pondr a uno. En tal caso se pierde un dato nuevo
que viene, y el bit OERR debe ponerse a cero por software al poner a cero y
luego

al

poner

uno

el

bit

CREN;

Nota: No es posible recibir un dato nuevo sino hasta que el bit


OERR est a uno.
Si el bit de parada (STOP) est a cero (0), el bit FERR del registro RCSTA
estar a uno, lo que indica un error en recepcin; y
Para habilitar la recepcin de un dato de 9 bits, es necesario poner a uno el
bit RX9 del registro RCSTA.
DETECCIN DE ERRORES EN RECEPCIN
El microcontrolador puede detectar automticamente dos tipos de errores.
El primero es denominado error de encuadre (Framing error). Ocurre cuando el
receptor no detecta el bit de parada en un intervalo predeterminado de tiempo.
Este error se indica mediante el bit FERR del registro RCSTA. Si el bit est a uno, el
ltimo dato recibido puede ser incorrecto. Cabe destacar lo siguiente:
El error de encuadre no genera por si mismo una interrupcin;
Si el bit est a uno, el ltimo dato recibido contiene un error;
El error de encuadre (bit est a uno) no impide la recepcin de un dato
nuevo;
El bit FERR se pone a cero al leer el dato recibido, lo que significa que se
debe hacer una verificacin antes de leer el dato; y

El bit FERR no se puede poner a cero por software. Si es necesario, se puede


borrar al poner a cero al bit SPEN del registro RCSTA, lo cual,
simultneamente causa una reinicializacin del sistema EUSART.
Otro tipo de error es denominado error de sobrescritura (Overrun Error).
Como hemos mencionado anteriormente, el registro de tipo FIFO puede
almacenar slo dos caracteres. Un error de sobrescritura ocurre cuando el registro
recibe el tercer carcter. Simplemente no hay espacio para almacenar un byte
ms, por lo que un error es inevitable. Cuando ocurre este error, el bit OERR del
registro RCSTA se pone a uno. Las consecuencias son las siguientes:
Los datos almacenados en los registros FIFO (2 bytes) se pueden leer
normalmente;
No se recibirn ms datos hasta que el bit OERR est puesto a cero; y
A este bit no se le puede acceder directamente. Para borrarlo, es necesario
poner a cero el bit CREN del registro RCSTA o reiniciar el sistema EUSART al
poner a cero al bit SPEN del registro RCSTA.
RECEPCIN DE DATOS DE 9 BITS
Aparte de recibir los datos de forma estndar de 8 bits, el sistema EUSART
soporta la recepcin de datos de 9 bits. En el lado del transmisor, el noveno bit
se adjunta al byte original directamente antes del bit de parada. En el lado del
receptor, al poner a uno el bit RX9 del registro RCSTA, el noveno bit de datos ser
automticamente escrito en el bit RX9D del mismo registro. Despus de
almacenar este byte, es necesario tener cuidado en como leer estos bits - primero
se debe leer el bit RX9D y luego los ocho (8) bits menos significativos del registro
RCREG. De otra forma, el noveno bit ser puesto a cero antes de ser ledo.

DETECCIN DE DIRECCIN
Cuando el bit ADDEN del registro RCSTA est a uno, el modulo EUSART es
capaz de recibir slo los datos de 9 bits, mientras que se ignoran todos los datos
de 8 bits. Aunque parece una restriccin, este modo habilita la comunicacin
serial entre varios microcontroladores. El principio de funcionamiento es muy
simple. El dispositivo maestro enva un dato de 9 bits que representa la direccin
de un microcontrolador esclavo. No obstante, todos deben tener el bit ADDEN
puesto a uno, ya que de esta manera se habilita la deteccin de direccin. Todos
los microcontroladores esclavos que comparten la misma lnea de transmisin,
reciben este dato (direccin) y verifican automticamente si coincide con su
propia direccin. El software, en el que ocurre la coincidencia de direccin, debe
deshabilitar la deteccin de direccin, poniendo a cero el bit ADDEN.

El

dispositivo

maestro

sigue

enviando

los

datos

de

bits

al

microcontrolador. Todos los datos que pasan por la lnea de transmisin sern
recibidos slo por el mdulo EUSART direccionado. Una vez recibido el ltimo
byte, el microcontrolador esclavo debe poner a uno el bit ADDEN para habilitar de
nuevo la deteccin de direccin.

Registro TXSTA

CSRC - Clock Source Select bit - (bit de seleccin de la fuente de reloj)


determina la fuente del reloj. Se utiliza slo en modo sincrnico.
1 - Modo Maestro. Reloj generado internamente por el generador de tasa de
baudios.
0 - Modo Esclavo. Reloj proveniente de una fuente externa.
TX9 - 9-bit Transmit Enable bit (bit de habilitacin del modo de 9
bits en transmisin)
1 - Se habilita el modo de 9 bits en transmisin por el sistema EUSART.
0 - Se habilita el modo de 8 bits en transmisin por el sistema EUSART.

TXEN - Transmit Enable bit (Bit de habilitacin de transmisin)


1 - Transmisin habilitada.
0 - Transmisin deshabilitada.
SYNC - EUSART Mode Select bit (Bit de seleccin del modo EUSART)
1 - El EUSART funciona en modo sncrono.
0 - El EUSART funciona en modo asncrono.
SENDB - Send Break Character bit (Bit de envo de carcter Break en
modo asncrono) se utiliza slo en modo asncrono y cuando se requiere obedecer
el estndar de bus LIN.
1 - Se enviar un carcter Break en la prxima transmisin (se pone a 0 por
hardware cuando finaliza el envo).
0 - Envo del carcter de transmisin Break completado.
BRGH - High Baud Rate Select bit (bit de seleccin de modo de alta
velocidad en modo asncrono). Determina la velocidad de transmisin en modo
sncrono. No afecta al EUSART en modo sncrono.
1 - EUSART funciona a alta velocidad.
0 - EUSART funciona a baja velocidad.
TRMT - Transmit Shift Register Status bit (bit de estado de registro de
desplazamiento de transmisin)
1 - Registro TSR est vaco.
0 - Registro TSR est lleno.

TX9D - Ninth bit of Transmit Data (Valor del noveno bit en transmisin)
Puede ser utilizado como direccin o bit de paridad o para distinguir entre
direccin o dato en los buses maestro-esclavo).

Registro RCSTA

SPEN - Serial Port Enable bit (bit de habilitacin del puerto serie)
1 - Puerto serie habilitado. Los pines RX/DT y TX/CK se configuran
automticamente como entrada y salida, respectivamente.
0 - Puerto serie deshabilitado.
RX9 - (bit de habilitacin del modo de 9 bits en recepcin):

1 - Se habilita la recepcin de datos de 9 bits por medio del sistema


EUSART.
0 - Se habilita la recepcin de datos de 8 bits por medio del sistema
EUSART.
SREN - Single ReceiveEnable bit (bit de habilitacin de la recepcin
simple). Es utilizado slo en modo sincrnico y en funcionamiento como Maestro.
1 - Recepcin simple habilitada.
0 - Recepcin simple deshabilitada.
CREN - Continuous Receive Enable bit (bit de habilitacin de la
recepcin continua) acta dependiendo del modo EUSART.
Modo asncrono:
1 - Recepcin habilitada.
0 - Recepcin deshabilitada.
Modo sncrono:
1 - Se habilita la recepcin continua hasta que el bit CREN est a cero.
0 - No se habilita la recepcin en forma continua.
ADDEN - Address Detect Enable bit (bit de habilitacin de la deteccin de
direccin) se utiliza slo en modo de detectar la direccin.
1 - Habilita la deteccin de direccin (slo se procesa un byte recibido en el
registro de desplazamiento de recepcin si el noveno bit est a uno)
0 - Deteccin de direccin deshabilitada (todos los bytes recibidos en el
registro

de

desplazamiento

de

recepcin

son

procesados

independientemente del valor del noveno bit recibido). El noveno bit se


utiliza como bit de paridad.
FERR - Framing Error bit (bit de error de encuadre)
1 - Se ha producido un error de encuadre en recepcin.
0 - No se ha producido un error de encuadre.
OERR - Overrun Error bit (bit de error de sobrescritura).
1 - Se ha producido un error de sobrescritura en recepcin.
0 - No se ha producido un error de sobrescritura.
RX9D - Ninth bit of Received Data No se ha producido un error de
sobrescritura.

GENERADOR DE BAUDIOS DEL EUSART (BRG)


Si mira atentamente al diagrama del receptor o transmisor EUSART
asncrono, ver que los ambos utilizan seal de reloj del temporizador local BRG
para la sincronizacin. La misma fuente de reloj se utiliza tambin en modo
sncrono.

El temporizador BRG consiste en dos registros de 8 bits haciendo un registro


de 16 bits.

El valor de un nmero escrito en estos dos registros determinar la


velocidad de transmisin en baudios. Adicionalmente, el bit BRGH del registro
TXSTA y el bit BRGH16 del registro BAUDCTL, afectan la frecuencia de reloj
utilizada para el clculo de los baudios.
El valor de un nmero escrito en estos dos registros determinar la
velocidad de transmisin en baudios. Adicionalmente, el bit BRGH del registro
TXSTA y el bit BRGH16 del registro BAUDCTL, afectan la frecuencia de reloj
utilizada para el clculo de los baudios.
BITS
SYN

BRG1 BRG

MODO BRG /

F R M U L A D E V E LO C I D A D D E

E U S A RT

TRANSMISIN EN BAUDIOS

de

bits

/asncrono
de

bits

bits

bits

bits

bits

asncrono
de

16

asncrono
de

16

asncrono
de

sncrono
de

16

sncrono

Fosc / [64 (n + 1)]


Fosc / [16 (n + 1)]
Fosc / [16 (n + 1)]
Fosc / [4 (n + 1)]
Fosc / [4 (n + 1)]
Fosc / [4 (n + 1)]

Las tablas en las siguientes pginas contienen los valores que deben estar
escritos en el registro de 16 bits SPBRG y asignados a los bits SYNC, BRGH y
BRGH16 para obtener algunos valores de la velocidad de transmisin en baudios
estndar. La frmula para hacer el clculo de la velocidad de transmisin en
baudios:

Registro BAUDCTL

ABDOVF - Auto-Baud Detect Overflow bit (bit de desbordamiento de


auto-deteccin de la velocidad de transmisin) se utiliza slo en modo asncrono
durante la deteccin de la velocidad de transmisin.
1 - Se ha producido desbordamiento durante la auto-deteccin.
0 - No se ha producido desbordamiento durante la auto-deteccin.

RCIDL - Receive Idle Flag bit No se ha producido desbordamiento durante


la auto-deteccin.
1 - Receptor en estado inactivo. No hay operacin de recepcin en marcha.
0 - Se ha recibido el bit de arranque (START) y hay una operacin de
recepcin en marcha.
SCKP - Synchronous Clock Polarity Select bit. (bit de seleccin de
polaridad de la seal de reloj en modo sncrono). El estado lgico de este bit
difiere dependiendo de cul modo de EUSART est activo
Modo asncrono:
1 - El dato invertido se transmite al pin RC6/TX/CK.
0 - El dato no invertido se transmite al pin RC6/TX/CK.
Modo sncrono:
1 - Sincronizacin en el flanco ascendente de la seal de reloj.
0 - Sincronizacin en el flanco descendente de la seal de reloj.
BRG16 16-bit Baud Rate Generator bit - (bit de habilitacin del
generador de velocidad de transmisin de 16 bits) determina si el registro
SPBRGH se utilizar, o sea si el temporizador BGRG tendr 8 o 16 bits.
1 - Se utiliza el generador de velocidad de transmisin de 16 bits
0 - Se utiliza el generador de velocidad de transmisin de 8 bits
WUE Wake-up Enable bit (bit de habilitacin del modo de auto-activacin
en modo asncrono):

1 - Modo de auto-activacin habilitado. El receptor espera a que el flanco


descendente aparezca en el pin RC7/RX/DT para que el microcontrolador se
despierte del modo de reposo.
0 - Modo de auto-activacin habilitado. El receptor funciona normalmente.
ABDEN - Auto-Baud Detect Enable bit (bit de habilitacin de autodeteccin de velocidad de transmisin) se utiliza slo en modo asncrono.
1 - Modo de auto-deteccin habilitado. Al detectar la velocidad de
transmisin, el bit se pone a uno automticamente.
0 - Modo de auto-deteccin deshabilitado.
Vamos a hacerlo en mikroC...

/* En este ejemplo, el mdulo EUSART interno se inicializa y se ajusta para enviar


el
mensaje inmediatamente despus de recibirlo. La velocidad de transmisin en
baudios se
ajusta a 9600 bps. El programa utiliza las siguientes rutinas de librera UART:
UART1_init(), UART1_Write_Text(), UART1_Data_Ready(), UART1_Write() y
UART1_Read().*/

char uart_rd;

void main() {

ANSEL = ANSELH = 0;

// Todos los pines se configuran como digitales

C1ON_bit = C2ON_bit = 0;

// Deshabilitar los comparadores

UART1_Init(9600);

// Inicializar el mdulo UART a 9600 bps

Delay_ms(100);

// Esperar a que seal de reloj del mdulo UART se


// ponga estable

UART1_Write_Text("Start");
while (1) {

// Bucle infinito

if (UART1_Data_Ready()) {
uart_rd = UART1_Read();
UART1_Write(uart_rd);

// Si el dato se ha recibido,
// lea el dato recibido
// y envelo atrs por el UART

}
}
}

Transmisin serial asncrona a travs de los registros del mdulo EUSART


1. La velocidad de transmisin deseada deber estar ajustada a travs de los bits
BRGH (del registro TXSTA) y BRG16 (del registro BAUDCTL) y de los registros
SPBRGH y SPBRG.
2. La velocidad de transmisin deseada deber estar ajustada a travs de los bits
BRGH (del registro TXSTA) y BRG16 (del registro BAUDCTL) y de los registros
SPBRGH y SPBRG.

3. La velocidad de transmisin deseada deber estar ajustada a travs de los bits


BRGH (del registro TXSTA) y BRG16 (del registro BAUDCTL) y de los registros
SPBRGH y SPBRG.
4. La transmisin de datos es habilitada poniendo a uno el bit TXEN del registro
TXSTA. El bit TXIF del registro PIR1 est automticamente puesto a uno.
5. Para que el bit TXEN cause una interrupcin, tanto el bit TXIE del registro PIE1
como los bits GIE, PEIE del registro INTCON debern estar puestos a uno.
6. En una transmisin de datos de 9 bits, el valor del noveno bit deber estar escrito
en el bit TX9D del registro TXSTA.
7. La transmisin comienza cuando se escribe el dato de 8 bits sobre el registro de
recepcin TXREG.
Recepcin serial asncrona a travs de los registros del mdulo EUSART:
1. La velocidad de transmisin deseada deber estar ajustada a travs de los bits
BRGH (del registro TXSTA) y BRG16 (del registro BAUDCTL) y de los registros
SPBRGH y SPBRG.
2. El bit SYNC (del registro TXSTA) deber estar puesto a cero y el bit SPEN (del
registro RCSTA) deber estar puesto a uno a fin de habilitar el puerto serie.
3. Tanto el bit RCIE del registro PIE1 como los bits GIE y PEIE del registro INTCON
debern estar puestos a uno si se necesita habilitar que la recepcin de dato
cause una interrupcin.
4. Para una recepcin de datos de 9 bits, el bit RX9 (del registro RCSTA) deber estar
puesto a uno
5. La recepcin de datos es habilitada poniendo a uno el bit CREN del registro
RCSTA.
6. El registro RCSTA deber leerse para obtener informacin acerca de la ocurrencia
de errores durante la recepcin. El valor del noveno bit ser almacena do en este
registro en la recepcin de datos de 9 bits.

7. El dato de 8 bits recibido ser almacenado en el registro RCREG y deber leerse


para obtener dicho dato.
Ajustar el modo de deteccin de direccin:
1. La velocidad de transmisin deseada deber estar ajustada a travs de los bits
BRGH (del registro TXSTA) y BRG16 (del registro BAUDCTL) y de los registros
SPBRGH y SPBRG.
2. El bit SYNC (del registro TXSTA) deber estar puesto a cero y el bit SPEN (del
registro RCSTA) deber estar puesto a uno (1) a fin de habilitar el puerto serie.
3. Tanto el bit RCIE del registro PIE1 como los bits GIE y PEIE del registro INTCON
debern estar puestos a uno si se necesita habilitar que la recepcin de dato
cause una interrupcin.
4. El bit RX9 del registro RCSTA debe estar a uno.
5. El bit ADDEN del registro RCSTA debe estar a uno, lo que habilita que un dato sea
reconocido como direccin.
6. La recepcin de datos es habilitada poniendo a uno el bit CREN del registro
RCSTA.
7. Tan pronto como se reciba un dato de 9 bits, el bit RCIF del registro PIR1 estar
automticamente puesto a uno. Si est habilitada se produce una interrupcin.
8. El registro RCSTA deber leerse para obtener informacin acerca de la ocurrencia
de errores durante la transmisin. El noveno bit RX9D siempre estar a uno.
9. El dato de 8 bits recibido ser almacenado en el registro RCREG y deber leerse.
Se deber comprobar si la combinacin de estos bits coincide con la direccin
predefinida. Si coincide, es necesario poner a cero el bit ADDEN del registro
RCSTA, lo que habilita la recepcin de datos de 8 bits.
MDULO PUERTO SERIE SNCRONO MAESTRO (MSSP)

El MSSP (Puerto serie sncrono maestro - Master Synchronous Serial Port) es


un mdulo muy til, y a la vez uno de los circuitos ms complejos dentro del
microcontrolador. Este mdulo permite la comunicacin de alta velocidad entre un
microcontrolador y otros perifricos u otros microcontroladores al utilizar varias
lneas de E/S (como mximo dos o tres lneas). Por eso, se utiliza con frecuencia
para conectar el microcontrolador a los visualizadores LCD, los convertidores A/D,
las memorias EEPROM seriales, los registros de desplazamiento etc. La
caracterstica principal de este tipo de comunicacin es que es sncrona y
adecuada para ser utilizada en sistemas con un slo maestro y uno o ms
esclavos. Un dispositivo maestro contiene un circuito para generacin de baudios
y adems, suministra seales de reloj a todos los dispositivos del sistema. Los
dispositivos esclavos no disponen de un circuito interno para generacin de
seales de reloj. El mdulo MSSP puede funcionar en uno de dos modos:
modo SPI (Interfaz perifrica serial - Serial Peripheral Interface); y
modo I2C (Circuito inter-integrado - Inter-Integrated Circuit).
Como se muestra en la siguiente figura, un mdulo MSSP representa slo
una mitad de un hardware necesario para establecer una comunicacin serial,
mientras que la otra mitad se almacena en el dispositivo con el que intercambia
los datos. Aunque los mdulos en ambas puntas de lnea son los mismos, sus
modos de funcionamiento difieren esencialmente dependiendo de si el mdulo
funciona como Maestro o como Esclavo:
Si el microcontrolador a ser programado controla otro dispositivo o circuito
(perifricos), deber funcionar como un dispositivo maestro. Este mdulo
generar seal de reloj cuando sea necesario, o sea slo cuando se requiera
recibir y transmitir los datos por software. Por consiguiente, el establecimiento de
conexin depende nicamente del dispositivo maestro.

De lo contrario, si el microcontrolador a ser programado est integrado en


un dispositivo ms complejo (por ejemplo en una PC), deber funcionar como un
dispositivo esclavo. Como tal, un esclavo siempre tiene que esperar a que un
dispositivo maestro enve la solicitud de transmisin de datos.
MODO SPI
El modo SPI permite la transmisin y recepcin simultnea de datos de 8
bits al utilizar tres lneas de entrada/salida
SDO - Serial Data Out (salida de datos serie )- lnea de transmisin;
SDI - Serial Data In (entrada de datos serie) - lnea de recepcin; y
SCK - Serial Clock (reloj de comunicacin) - lnea de sincronizacin.
Adicionalmente, hay una cuarta lnea (SS) que se puede utilizar si el
microcontrolador intercambia los datos con varios dispositivos perifricos.
Refirase a la siguiente figura.
SS - Slave Select (Seleccin de esclavo) - Es una lnea adicional utilizada
para la seleccin de un dispositivo especfico. Esta lnea est activa slo si el
microcontrolador funciona como esclavo, o sea cuando el dispositivo externo maestro requiere intercambiar los datos. Al funcionar en modo SPI, el mdulo
MSSP utiliza 4 registros en total:

SSPSTAT - registro de estado


SSPCON - registro de control
SSPBUF - bfer serie de transmisin/recepcin
SSPSR - registro de desplazamiento (no es accesible directamente)
Los primeros tres registros son de lectura/escritura y se pueden modificar en
cualquier momento, mientras que el cuarto, como no es accesible, se utiliza para
convertir datos en formato serial.

Como se muestra en la siguiente figura, la parte central del mdulo SPI


consiste de dos registros conectados a los pines para recepcin, transmisin y
sincronizacin.

El registro de desplazamiento (SSPRS) est directamente conectado a los


pines del microcontrolador y es utilizado para transmisin de datos en formato
serie. El registro SSPRS dispone de la entrada y salida para desplazar los datos
hacia dentro y hacia fuera del dispositivo. En otras palabras, cada bit que aparece

en la entrada (lnea de recepcin) desplaza simultneamente otro bit hacia la


salida (lnea de transmisin).
El registro SSPBUF (Bfer) es una parte de memoria utilizada para
almacenar

temporalmente

los

datos

antes

de

que

se

enven,

sea

inmediatamente despus de que se reciban. Despus de que todos los 8 bits


hayan sido recibidos, el byte se mueve del registro SSPRS al registro SSPBUF. Este
proceso de crear un doble bfer para recibir los datos permite iniciar la recepcin
del prximo byte antes de leer los datos que se acaban de recibir. Durante la
transmisin/recepcin de datos se ignora un intento de escribir un dato en el
registro SSBUF. Desde el punto de vista de un programador, este registro se
considera el ms importante por haber sido accedido con ms frecuencia.
Concretamente, si dejamos aparte el ajuste del modo de funcionamiento, la
transmisin de datos por el mdulo SPI no es nada ms que escritura y lectura de
datos de este registro, mientras que las dems acrobacias como mover los
registros, se llevan a cabo automticamente por el hardware.
Vamos a hacerlo en mikroC...

/* En este ejemplo, el microcontrolador PIC (maestro) enva un byte de datos a


un chip
perifrico (esclavo) por el mdulo SPI. El programa utiliza las funciones de
librera
SPI SPI1_init() y SPI1_Write. */

sbit Chip_Select at RC0_bit;

// Pin RC0 es un pin de seleccionar el chip

// perifrico Seleccin_de_chip
sbit Chip_Select_Direction at TRISC0_bit; // Bit TRISC0 define el pin RC0 como
entrada o salida
unsigned int value;

// Dato a ser enviado es de tipo unsigned int

void main() {
ANSEL = ANSELH = 0;

// Todos los pines de E/S son digitales

TRISB0_bit = TRISB1_bit = 1; // Configurar los pines RB0, RB1 como entradas


Chip_Select = 0;

// Seleccionar el chip perifrico

Chip_Select_Direction = 0; // Configurar el pin CS# como salida


SPI1_Init();
SPI1_Write(value);

// Inicializar el mdulo SPI


// Envar el valor al chip perifrico

...

Comunicacin serial sncrona SPI


Antes de inicializar el mdulo SPI, es necesario especificar varias opciones:
Modo maestro TRISC.3=0 (pin SCK es salida de seal de reloj);
Modo de esclavo TRISC.3=1 (pin SCK es entrada de seal de reloj);
Fase de datos de entrada - la mitad o el final del tiempo de salida (bit SMP
del registro SSPSTAT );

Flanco de reloj (bit CKE del registro SSPSTAT);


Velocidad de transmisin en baudios, los bits SSPM3-SSPM0 del registro
SSPCON (slo en modo Maestro);
Seleccin de modo esclavo, bits SSPM3-SSPM0 del registro SSPCON (slo en
modo Esclavo)
El mdulo se pone en marcha al poner a uno el bit SSPEN:

Paso 1.
Los datos a ser transmitidos debern ser escritos en el registro del
bfer SSPBUF. Si el mdulo SPI funciona en modo maestro, el
microcontrolador ejecutar automticamente la secuencia de los siguientes
pasos 2,3 y 4. Si el mdulo SPI funciona en modo esclavo, el
microcontrolador no ejecutar la secuencia de los siguientes pasos hasta
que el pin SCK detecte seal de reloj.

Paso 2.

El dato se mueve al registro SSPSR y el contenido del registro SSPBUF no se


borra.

Paso 3.
El dato se desplaza hacia el pin de salida (primero se desplaza el bit ms
significativo - MSB), mientras que a la vez el registro se carga con los bits por el
pin de entrada. En modo maestro el microcontrolador en si mismo genera seal
de reloj, mientras que el modo esclavo utiliza seal de reloj externa (pin SCK).

Paso 4.
El registro SSPSR est lleno despus de que hayan sido recibidos 8 bits de
datos, lo que se indica al poner a uno el bit BF del registro SSPSTAT y el bit SSPIF
del registro PIR1. Los datos recibidos (un byte) son automticamente movidos del
registro SSPSR al registro SSPBUF. Como la transmisin de datos serial se realiza
automticamente, el resto de programa se ejecuta normalmente mientras que la
transmisin de datos est en progreso. En este caso, la funcin del bit SSPIF es de
generar una interrupcin al acabar la transmisin de un byte.

Paso 5.
Por ltimo, el dato almacenado en el registro SSPBUF est listo para su uso
y debe moverse al registro deseado.
Modo I2C
El modo I2C (Bus de circuito inter-integrado) es adecuado para ser utilizado
cuando el microcontrolador debe intercambiar los datos con un circuito integrado
dentro

de

un

mismo

dispositivo.

stos

son

con

frecuencia

otros

microcontroladores, o los circuitos integrados especializados y baratos que


pertenecen a la nueva generacin de as llamados "perifricos inteligentes"
(memorias, sensores de temperatura, relojes de tiempo real etc.)
Similar a la comunicacin serie en modo SPI, la transmisin de datos en
modo I2C es sncrona y bidireccional. Esta vez slo dos pines se utilizan para
transmisin de datos. stos son los pines de SDA (Datos seriales) y SCL (Reloj
serial). El usuario debe configurar estos pines como entradas o salidas por los bits
TRISC.
Al observar las reglas particulares (protocolos), este modo habilita conectar
simultneamente de una manera simple hasta 112 diferentes componentes al
utilizar slo dos valiosos pines de E/S. Vamos a ver cmo funciona el sistema:
El reloj, necesario para sincronizar el funcionamiento de ambos dispositivos,
siempre es generado por un dispositivo maestro (un microcontrolador) y su
frecuencia directamente afecta a la velocidad de transmisin de datos. Aunque
hay un protocolo que permite como mximo una frecuencia de reloj de 3,4 MHz
(as llamado bus I2C de alta velocidad), este libro cubre slo el protocolo utilizado

con ms frecuencia, con una frecuencia de reloj limitada a 100 KHz. La frecuencia
mnima no est limitada.
Cuando los componentes maestro y esclavo estn sincronizados por el reloj,
el maestro siempre inicia cada intercambio de datos. Una vez que el mdulo MSSP
se ha habilitado, espera que ocurra una condicin de arranque (Start condition). El
dispositivo maestro primero enva el bit de arranque (est a cero) por el pin SDA,
luego la direccin de 7 bits del dispositivo esclavo seleccionado, y por ltimo, el
bit que requiere al dispositivo escribir (0) o leer (1) el dato enviado. En otras
palabras, los ocho bits se desplazan al registro SSPSR despus de ocurrir una
condicin de arranque. Todos los dispositivos esclavos que comparten la misma
lnea de transmisin recibirn simultneamente el primer byte, pero slo el que
contiene la direccin coincidente recibir el dato entero.

Una vez que el primer byte se ha enviado (slo se transmiten datos de 8


bits), el maestro se pone en modo de recepcin y espera el reconocimiento del
dispositivo receptor acerca de la direccin coincidente.
Si el dispositivo esclavo enva un bit de reconocimiento (1) la transmisin de
datos continuar hasta que el dispositivo maestro (microcontrolador) enve el bit
de parada (Stop).

Esto es una explicacin simple de cmo se comunican dos componentes.


Este microcontrolador es capaz de controlar las situaciones ms complicadas
cuando estn conectados 1024 diferentes componentes (direccin de 10 bits),
compartidos por varios dispositivos maestros diferentes. Por supuesto, estos
dispositivos se utilizan pocas veces en la prctica por lo que no es necesario
hablar de ellos detalladamente.
La siguiente figura muestra el diagrama de bloques del mdulo MDSSP en
modo I2C.

En una operacin I2C con el mdulo MSSP intervienen seis registros. Algunos
de ellos se muestran en la Figura anterior.
SSPCON

SSPCON2
SSPSTAT
SSPBUF
SSPSR
SSPADD
Registro SSPSTAT

SMP Sample bit (Bit de muestra)


Modo maestro SPI - Este bit determina fase de datos de entrada.
1 - Estado lgico se lee al final del tiempo de salida.
0 - Estado lgico se lee en la mitad del tiempo de salida.
Modo esclavo SPI - Este bit debe ser borrado cuando SPI se emplea en modo
esclavo.
Modo IC (maestro o esclavo)
1 - Deshabilita control de variaciones para velocidad estndar (100kHz).
0 - Habilita control de variaciones para velocidad alta (400k Hz).

CKE - Clock Edge Select bit (bit de seleccin del flanco de reloj)
selecciona el modo de sincronizacin.
CKP = 0:
1 - Dato transmitido en flanco ascendente de pulso de reloj (0 - 1).
0 - Dato transmitido en flanco descendente de pulso de reloj (1 - 0).
CKP = 1:
1 - Dato transmitido en flanco descendente de pulso de reloj (1 - 0).
0 - Dato transmitido en flanco ascendente de pulso de reloj (0 - 1).
D/A - Data/Address bit (bit de direcciones/datos) se utiliza slo en modo I2C.
1 - Indica que el ltimo byte recibido o transmitido es un dato.
0 - Indica que el ltimo byte recibido o transmitido es una direccin.
P - Stop bit (bit de parada) se utiliza slo en modo IC.
1 - Bit de parada (STOP) se ha detectado.
0 - Bit de parada (STOP) no se ha detectado.
S - Start bit (bit de arranque) se utiliza slo en modo I2C.
1 - Bit de arranque (START) se ha detectado.
0 - Bit de arranque (START) no se ha detectado.
R/W - Read Write bit (bit de informacin Lectura/Escritura) se utiliza slo
en modo I2C. Este bit contiene la informacin del bit de L/E despus de la ltima

direccin coin cidente. Este bit es vlido slo desde la direccin coincidente hasta
el siguiente bit de arranque, bit de parada o bit no ACK.
Modo IC en modo esclavo
1 - Lectura de dato.
0 - Escritura de dato.
Modo IC en modo esclavo
1 - Transmisin en progreso.
0 - Transmisin no est en progreso.
UA - Update Address bit (bit de activacin de direccin) se utiliza slo en
modo I2C de 10 bits.
1 - Indica que es necesario actualizar la direccin en el registro SSPADD.
0 - Indica que la direccin es correcta y que no se necesita actualizarla.
BF Buffer Full Status bit (bit de estado de bfer lleno)
Durante la recepcin de dato (en modos SPI e IC)
1 - Recepcin completa. El registro SSPBUF est lleno.
0 - Recepcin no completa. El registro SSPBUF est vaco.
Durante la transmisin de dato (slo en modo IC)
1 - Transmisin de dato en progreso (no incluye el bit ACK y bits de parada).
0 - Transmisin de dato completa (no incluye el bit ACK y bits de parada).

Registro SSPSTAT

WCOL Write Collision Detect bit (bit detector de colisin)


1 - Colisin detectada. En el registro SSPBUF se ha escrito cuando no se han
cumplido las condiciones para iniciar una transmisin.
0 - No hay colisin.
SSPOV Receive Overflow Indicator bit (bit detector de desbordamiento
en recepcin)
1 - Se recibe un nuevo byte cuando el registro SSPBUF an mantiene los
datos ante riores. Como no hay espacio para recibir datos nuevos, uno de
estos dos bytes debe ser borrado. En este caso, los datos almacenados en
el registro SSPSR se pierden irremediablemente.
0 - Dato serial es recibido correctamente.
SSPEN - Synchronous Serial Port Enable bit (bit de habilitacin del
mdulo SSP - puerto serie sncrono) determina la funcin de los pines del
microcontrolador e inicializa el mdulo MSSP:
En modo SPI
1 - Habilita el mdulo MSSP y configura los pines SCK, SDO, SDI y SS como
una fuente de pines del puerto serie.

0 - Deshabilita el mdulo MSSP y configura estos pines como pines del


puerto de E/S.
En modo IC
1 - Habilita el mdulo MSSP y configura los pines SDA y SCL como una
fuente de pines del puerto serie.
0 - Deshabilita el mdulo MSSP y configura estos pines como pines del
puerto de E/S.
CKP - Clock Polarity Select bit (bit de seleccin de polaridad de reloj) no
se utiliza en modo IC maestro.
En modo SPI
1 - Para una seal de reloj, el estado inactivo es un nivel alto.
0 - Para una seal de reloj, el estado inactivo es un nivel bajo.
En modo IC esclavo
1 - Seal de reloj habilitada.
0 - Mantiene la salida de seal de reloj en estado bajo. Se utiliza para
proporcionar ms tiempo para estabilizacin de datos.
SSPM3-SSPM0 - Synchronous Serial Port Mode Select bits. (bit de
seleccin del modo del SSP (puerto serie sncrono). El modo SSP se determina al
combinar los siguientes bits:
SS P M

SS P M

SS P M

SS P M

Modo maestro del SPI, reloj = Fosc/4.

Modo maestro del SPI, reloj = Fosc/16.

MODO

Modo maestro del SPI, reloj = Fosc/64.


Modo maestro del SPI, reloj = (TMR
output)/2.
Modo esclavo del SPI, habilitado el pin de
control SS.
Modo esclavo del SPI, deshabilitado el pin

de control SS, SS se puede utilizar como


pin de E/S.
Modo esclavo I2C, direccin de 7 bits

Mscara utilizada en modo esclavo I2C.

No utilizado.

Modo maestro I2C controlado.

No utilizado.

No utilizado.

utilizada.
Modo esclavo I2C, direccin de 10 bits
utilizada.
Modo

maestro

I2C,

reloj

Fosc

[4(SSPAD+1)].

Modo esclavo I2C, direccin de 7 bits


1

utilizada, los bits de arranque (START) y


de parada (STOP) habilitan interrupcin.
Modo esclavo I2C, direccin de 10 bits

utilizada, los bits de arranque (START) y


de parada (STOP) habilitan interrupcin.

Registro SSPCON2

GCEN - General Call Enable bit (bit de habilitacin general)


Slo en modo esclavo IC
1 - Habilita interrupcin cuando una direccin de llamada general es
recibida en el SSPST (0000h).
0 - Deshabilita direccin de llamada general.
ACKSTAT - Acknowledge Status bit (bit de estado de reconocimiento)
Slo en modo de transmisin maestro IC
1 - Reconocimiento del esclavo no recibido.
0 - Reconocimiento del esclavo recibido.
ACKDT - Acknowledge data bit (bit de recepcin)
Slo en modo de recepcin maestro IC
1 - No reconocimiento.
0 - Reconocimiento.
ACKEN - Acknowledge Sequence Enable bit (bit de habilitacin de
secuencia de reconocimiento)
En modo de recepcin maestro IC
1 - Indica una secuencia de reconocimiento en los pines SDA y SCL y
transmite el bit ACKDT. Automticamente borrado por hardware.
0 - Secuencia de reconocimiento en reposo.
RCEN - Receive Enable bit (bit de habilitacin de recepcin)

Slo en modo maestro IC


1 - Habilita recepcin en modo I2C.
0 - Recepcin deshabilitada.
PEN - STOP condition Enable bit (bit de habilitacin de condicin de
Parada)
Slo en modo maestro IC
1 - Indica una condicin de Parada en los pines SDA y SCL. Luego, este bit
es automticamente borrado por hardware.
0 - Condicin de Parada en reposo.
RSEN - Repeated START Condition Enabled bit (bit de habilitacin de
repetir condicin de Arranque)
Slo en modo maestro IC
1 - Indica repeticin de condicin de Arranque en los pines SDA y SCL.
Luego, este bit es automticamente borrado por hardware.
0 - Condicin de repeticin de Arranque en reposo.
SEN - START Condition Enabled/Stretch Enabled bit (bit de habilitacin
de condicin de Arranque)
Slo en modo maestro IC
1 - Indica condicin de Arranque en los pines SDA y SCL. Luego, este bit es
automticamente borrado por hardware.
0 - Condicin de Arranque en reposo.

IC en Modo Maestro
El caso ms comn es que un microcontrolador funciona como maestro y un
perifrico como esclavo. Es la razn por la que este libro slo trata este modo. Se
da por entendido que la direccin consiste en 7 bits y el dispositivo contiene un
solo microcontrolador (dispositivo con maestro nico).
Para habilitar el mdulo MSSP en este modo, siga las siguientes
instrucciones:

Ajuste la velocidad de transmisin (registro SSPADD), desactive el control de


velocidad de rotacin (al poner a uno el bit SMP del registro SSPSTAT) y seleccione
el modo maestro (registro SSPCON). Despus de finalizar todos los ajustes y
habilitar el mdulo (registro SSPCON: bit SSPEN), es necesario esperar a que los
circuitos de control internos indiquen con una seal que todo est preparado para
transmisin de datos: o sea, que el bit SSPIF del registro PIR1 se haya puesto a
uno.
Despus de poner este bit a cero por software, el microcontrolador est listo
para intercambiar los datos con los perifricos.

Transmisin de datos en Modo Maestro IC


La transmisin de datos en el pin SDA se inicia con un cero lgico (0) que
aparece al poner a uno el bit SPEN del registro SSPCON2. Sin embargo, aunque
est habilitado, el microcontrolador tiene que esperar cierto tiempo antes de
iniciar la comunicacin. Se le denomina 'Condicin de Inicio' durante la que se
realizan las preparaciones y verificaciones internas. Si se cumplen con todas la
condiciones, el bit SSPIF del registro PIR1 se pone a uno y la transmisin de datos
se inicia en cuanto se cargue el registro SSPBUF.

Como mximo 112 circuitos integrados (dispositivos esclavos) pueden


compartir simultneamente la misma lnea de transmisin. El primer byte de
datos enviado por el dispositivo maestro contiene la direccin que coincide con
una sola direccin del dispositivo esclavo. Todas las direcciones se enumeran en
las hojas de datos respectivas. El octavo bit del primer byte de datos especifica la
direccin de transmisin de datos, o sea si el microcontrolador va a enviar o
recibir los datos. En este caso, como se trata de transmisin de datos, el octavo
bit se pone a cero (0).

Cuando ocurre la coincidencia de direcciones, el microcontrolador tiene que


esperar a que el dispositivo esclavo enve el bit de reconocimiento, o sea que se
ponga a cero el bit ASKSTAT del registro SSPCON2. Una vez que la coincidencia de
direcciones ha ocurrido apropiadamente, todos los bytes de datos se transmiten
de la misma manera.
La transmisin de datos termina al poner a uno el bit SEN del registro
SSPCON2. Ocurre la condicin de parada (STOP), lo que habilita que el pin SDA
reciba una secuencia de pulsos:
Inicio - Direccin - Reconocimiento - Dato - Reconocimiento .... Dato Reconocimiento - Parada!
Recepcin de datos en Modo Maestro IC
Las preparaciones para recibir los datos son similares a las de transmitir los
datos, con excepcin de que el ltimo bit del primer byte enviado (el que contiene
la direccin) se ponga a uno lgico (1). Eso especifica que el dispositivo maestro
espera recibir los datos del dispositivo esclavo direccionado. Con respecto al
microcontrolador, ocurre lo siguiente:

Despus de hacer las pruebas internas y poner a uno el bit de arranque


(START), el dispositivo esclavo enva byte por byte. Estos bytes se almacenan en
el registro serial SSPSR. Despus de recibir el ltimo - octavo bit, cada dato se
carga en el registro SSPBUF del que se puede leer. Al leer este registro, se enva
automticamente el bit de reconocimiento, lo que significa que el dispositivo
maestro est listo para recibir los nuevos datos.
Al igual que en el caso de la transmisin, la recepcin de datos termina al
poner a uno el bit de parada (STOP):

Inicio - Direccin - Reconocimiento - Dato - Reconocimiento .... Dato Reconocimiento - Parada!


En esta secuencia de pulsos, el bit de reconocimiento se enva al dispositivo
esclavo.
Generador de baudios
Para sincronizar la transmisin de datos, todos los eventos que ocurren en el pin
SDA deben estar sincronizados con la seal de reloj generada en el dispositivo
maestro. Esta seal de reloj se genera por un simple oscilador cuya frecuencia
depende de la frecuencia del oscilador principal del microcontrolador, del valor

que se introduce al registro SSPADD y as como del modo SPI actual. La frecuencia
de seal de reloj del modo descrito en este libro depende del cristal de cuarzo
seleccionado y del registro SPADD. La frmula utilizada para hacer el clculo de
frecuencia de reloj es:

Vamos a hacerlo en mikroC...

/* En este ejemplo, el microcontrolador PIC est conectado a la memoria


EEPROM 24C02
por los pines SCL y SDA. El programa enva un byte de dato a la direccin 2 de
la EEPROM.
Entonces, el programa lee este dato por el modo I2C de la EEPROM y lo enva al
puerto PORTB para comprobar si el dato se ha escrito con xito. El byte para
direccionar
la EEPROM est compuesto por 7 bits de la direccin (1010001) y el bit que
determina
lectura o escritura del dato (LSB - bit menos significativo).*/

void main(){
ANSEL = ANSELH = PORTB = TRISB = 0; // Todos los pines son digitales. Los
pines del
// puerto PORTB son salidas.
I2C1_Init(100000);

// Inicializar I2C con reloj deseado

// Incio del bloque de sentencias para escribir un byte en la memoria EEPROM.

I2C1_Start();
I2C1_Wr(0xA2);

// Seal de inicio de I2C


// Enviar byte por I2C (direccin de dispositivo +

W)
I2C1_Wr(2);
I2C1_Wr(0xF0);
I2C1_Stop();

// Enviar byte (direccin de la localidad EEPROM)


// Enviar los datos a escribir
// Seal de parada de I2C

Delay_100ms();

// En el siguiente bloque de sentencias se determina la direccin 2 de la que se


leer el dato

I2C1_Start();
I2C1_Wr(0xA2);

// Seal de inicio de I2C


// Enviar byte por I2C (direccin de dispositivo +

W)
I2C1_Wr(2);

// Enviar byte (direccin de dato)

// La direccin est determinada y el dato est listo para ser ledo

I2C1_Repeated_Start();
I2C1_Wr(0xA3);
PORTB = I2C1_Rd(0u);
I2C1_Stop();

// Se vuelve a generar el inicio de seal I2C


// Enviar byte (direccin de dispositivo + R)
// Leer el dato (reconocimiento NO)
// Seal de parada de I2C

NOTAS TILES...
Cuando el microcontrolador se comunica con un perifrico, puede ocurrir un
fallo en la transmisin de datos por alguna razn. En este caso, es recomendable
comprobar el estado de algunos bits que pueden aclarar el problema. En la
prctica, el estado de estos bits se comprueba al ejecutar una pequea subrutina
despus de transmisin y recepcin de cada byte (por si acaso).
WCOL (SPCON,7) - Si intenta escribir un dato nuevo al registro SSPBUF
mientras que otra transmisin/recepcin de datos est en progreso, el bit WCOL

se pone a uno y el contenido del registro SSBUF se queda sin cambios. No hay
escritura. Luego, el bit WCOL debe ser borrado por el software.
BF (SSPSTAT,0) - Al transmitir los datos, este bit se pone a uno durante la
escritura en el registro SSPBUF y se queda puesto a uno hasta que el byte en
formato serial se desplace del registro SSPRS. En modo de recepcin, este bit se
pone a uno al cargar un dato o una direccin al registro SSPBUF. Se pone a cero
despus de leer el registro SSPBUF.

SSPOV (SSPCON,6) - En modo de recepcin, este bit se pone a uno al


recibir un nuevo byte en el registro SSPSR por medio de la comunicacin serial,
todava sin haber ledo el dato anteriormente recibido del registro SSPBUF.
Pines SDA y SCL - Cuando el mdulo SSP est habilitado, estos pines se
vuelven a las salidas de Drenaje Abierto. Esto significa que deben estar
conectados a resistencias conectados a la otra punta al polo positivo de la fuente
de alimentacin.
Para establecer la comunicacin serial en modo I2C, se debe realizar lo
siguiente:
Ajustar el mdulo y enviar la direccin:
Introducir en el registro SSPADD el valor para definir la velocidad de
transmisin en baudios.
Poner a uno el bit SMP del registro SSPSTAT para desactivar el control de la
velocidad de rotacin.

Introducir el valor binario 1000 a los bits SSPM3-SSPM0 del registro


SSPCON1 para seleccionar el modo Maestro.
Poner a uno el bit SEN del registro SSPCON2 (secuencia de Inicio - START).
El bit SSPIF se pone a uno automticamente en final de la secuencia de
Inicio cuando el mdulo est listo para funcionar. Se deber poner a cero.
Introducir la direccin de esclavo al registro SSPBUF.
Cuando se enva un byte, el bit SSPIF (interrupcin) se pone a uno
automticamente despus de haber recibido el bit de reconocimiento del
dispositivo esclavo.
Transmitir los datos:
Introducir en el registro SSPBUF los datos a enviar.
Cuando se enva un byte, el bit SSPIF (interrupcin) se pone a uno
automticamente despus de haber recibido el bit de reconocimiento del
dispositivo esclavo.
La condicin de Parada (STOP) se debe iniciar al poner a uno el bit PEN del
registro SSPCON para informar al dispositivo Esclavo que la transmisin de
datos se acab.
Recibir los datos:
Poner a uno el bit RSEN del registro SSPCON2 para habilitar la recepcin.
El bit SSPIF indica con su estado lgico la recepcin de datos. Despus de
leer los datos del registro SSPBUF, el bit ACKEN del registro SSPCON2 debe
ponerse a uno para habilitar el envo del bit de reconocimiento.

La condicin de Parada (STOP) se debe iniciar al poner a uno el bit PEN del
registro SSPCON para informar al dispositivo Esclavo que la transmisin se
acab.
Aparte de disponer de un gran nmero de lneas digitales de E/S utilizadas
para la comunicacin con los perifricos, el PIC16F887 contiene 14 entradas
analgicas. Debido a stas, el microcontrolador no slo puede reconocer si un pin
es llevado a bajo o alto (0 o +5V), sino que puede medir con precisin el voltaje y
convertirlo en un valor numrico, o sea, en formato digital.

3.9 MDULOS ANALGICOS


El mdulo del convertidor A/D dispone de las siguientes caractersticas:
El convertidor genera un resultado binario de 10 bits utilizando el mtodo
de aproximaciones sucesivas y almacena los resultados de conversin en
los registros ADC (ADRESL y ADRESH);
Dispone de 14 entradas analgicas separadas;
El convertidor A/D convierte una seal de entrada analgica en un nmero
binario de 10 bits;
La resolucin mnima o calidad de conversin se puede ajustar a diferentes
necesidades al seleccionar voltajes de referencia Vref- y Vref+.

CONVERTIDOR A/D
Aunque a primera vista parece muy complicado utilizar un convertidor A/D,
en realidad es muy simple. De hecho resulta ms simple utilizar un convertidor
A/D que los temporizadores o mdulos de comunicacin serie.

El funcionamiento del convertidor A/D est bajo el control de los bits de


cuatro registros:
ADRESH Registro alto del resultado de la conversin A/D;
ADRESL Registro bajo del resultado de la conversin A/D;
ADCON0 Registro de control 0; y
ADCON1 Registro de control 1.
Registros ADRESH y ADRESL
El resultado obtenido despus de convertir un valor analgico en digital es
un nmero de 10 bits que se almacenar en los registros ADRESH y ADRESL. Hay
dos maneras de manejarlo: justificacin a la izquierda y a la derecha que
simplifica en gran medida su uso. El formato del resultado de la conversin
depende del bit ADFM del registro ADCON1. En caso de que no se utilice el
convertidor A/D, estos registros se pueden utilizar como registros de propsito
general.

REQUERIMIENTOS DE ADQUISICIN A/D


Para que el convertidor A/D alcance su exactitud especificada, es necesario
proporcionar un cierto tiempo muerto entre seleccionar una entrada analgica
especfica y la medicin misma. Este tiempo se le denomina tiempo de
adquisicin y generalmente depende de la impedancia de la fuente. Se utiliza
una ecuacin para hacer clculo de tiempo de adquisicin con precisin, cuyo
valor mnimo es de 20uS aproximadamente. Por consiguiente, para realizar una
conversin con precisin, no se olvide este detalle.
RELOJ PARA LA CONVERSIN A/D
El tiempo necesario para realizar una conversin A/D cuyo resultado es 1 bit
se define en unidades de TAD. Se requiere que sea como mnimo 1,6 uS. Para
realizar una conversin completa de 10 bits se requiere un poco ms tiempo de lo
esperado, son 11 TAD. Como la frecuencia de reloj as como la fuente de
conversin A/D son determinadas por software, es necesario seleccionar una de
las combinaciones de los bits disponibles ADCS1 y ADCS0 antes de empezar a
medir voltaje en una de las entradas analgicas. Estos bits se almacenan en el
registro ADCON0.

F U E N T E D E R E LO J

ADCS

ADCS

DE ADC

Fosc/2

FRECUENCIA

DE

DISPOSITIVO (FOSC)
20 Mhz 8 Mhz

4 Mhz

1 Mhz

100 nS

500 nS

2 uS

250 nS

Fosc/8

400 nS

1 uS

2 uS

8 uS

Fosc/32

1.6 uS

4 uS

8 uS

32 uS

Frc

2 - 6 uS

2 - 6 uS 2 - 6 uS 2 - 6 uS

Cualquier cambio de la frecuencia de reloj del microcontrolador afectar a la


frecuencia de reloj de la conversin A/D, lo que puede perjudicar al resultado de la
conversin A/D. En la siguiente tabla se muestran las caractersticas de la
frecuencia del dispositivo. Los valores en las celdas sombreadas estn fuera del
rango recomendado.

CMO UTILIZAR EL CONVERTIDOR A/D?


Para llevar a cabo una conversin A/D sin problemas as como para evitar los
resultados inesperados, es necesario considerar lo siguiente:
El convertidor A/D no hace diferencia entre seales digitales y analgicas.
Para evitar errores en medicin o daar el chip, los pines se deben
configurar como en tradas analgicas antes de que empiece el proceso de
conversin. Los bits utiliza dos para este propsito se almacenan en los
registros TRIS y ANSEL (ANSELH);
Al leer el estado de puerto con las entradas analgicas, el estado de los bits
correspondientes se leer como cero lgico (0), sin reparar en el valor del
voltaje real en el pin; y

Hablando en trminos generales, la medicin de voltaje en el convertidor


est basado en comparar voltaje de entrada con una escala interna que
tiene 1023 grados (210 - 1 =1023). El grado ms bajo de esta escala
representa el voltaje Vref-, mientras que el grado ms alto se refiere al
voltaje Vref+. La siguiente figura muestra los voltajes de referencia
seleccionables as como sus valores mximos y mnimos.

Registro ADCON0

ADCS1, ADCS0 - A/D Conversion Clock Select bits (bits de seleccin de reloj
de conversin A/D) selecciona la frecuencia de reloj utilizada para sincronizacin
interna del convertidor A/D. Asimismo afecta a la duracin de la conversin.

ADCS1

ADCS2

R E LO J

Fosc/2

Fosc/8

Fosc/32

RC *

* Seal de reloj se genera por el oscilador interno RC que est integrado en el


convertidor.
CHS3-CHS0 - Analog Channel Select bits (bits de seleccin de canal
analgico) selecciona un pin o un canal analgico para la conversin A/D, o sea
para medir el voltaje:
CHS

CHS

CHS

CHS

CANA

RA0/AN0

RA1/AN1

RA2/AN2

RA3/AN3

RA5/AN4

RE0/AN5

RE1/AN6

RE2/AN7

RB2/AN8

RB3/AN9

10

RB1/AN10

11

RB4/AN11

12

RB0/AN12

13

RB5/AN13

CVref

Vref = 0.6V

PIN

GO/DONE - A/D Conversion Status bit (bit de estado de la conversin A/D)


determina el estado actual de de la conversin:
1 - La conversin A/D est en progreso.
0 - La conversin A/D ha finalizado. El bit se pone a cero automticamente
por hardware cuando la conversin A/D finaliza.
ADON - A/D On bit (bit de encendido A/D) habilita el convertidor A/D.
1 - Convertidor A/D est habilitado.
0 - Convertidor A/D est deshabilitado.
Vamos a hacerlo en mikroC...

/* Este cdigo es un ejemplo de leer el valor analgico del canal 2 y de


visualizarlo
en los puertos PORTB y PORTC como nmero binario de 10 bits. */

#include <built_in.h>
unsigned int adc_rd;

void main() {
ANSEL = 0x04;
TRISA = 0xFF;

// Configurar AN2 como pin analgico


// PORTA se configura como entrada

ANSELH = 0;

// Configurar los dems pines AN como E/S digitales

TRISC = 0x3F;

// Pines RC7 y RC6 se configuran como salidas

TRISB = 0;

// PORTB se configura como salida

do {
temp_res = ADC_Read(2); // Obtener el resultado de 10 bits de la conversin
AD
PORTB = temp_res;

// Enviar los 8 bits ms bajos al PORTB

PORTC = temp_res >> 2; // Enviar los 2 bits ms significativos a los RC7, RC6
} while(1);

// Quedarse en el bucle

Registro ADCON1

ADFM - A/D Result Format Select bit (bit de seleccin del formato del
resultado de la conversin A/D)

1 - Resultado de conversin est justificado a la derecha. No se utilizan los


seis bits ms significativos del registro ADRESH.
0 - Resultado de conversin est justificado a la izquierda. No se utilizan los
seis bits menos significativos del registro ADRESL.
VCFG1 - Voltage Reference bit (bit de configuracin de voltaje de referencia)
selecciona la fuente de voltaje de referencia bajo que se necesita para el
funcionamiento del convertidor A/D.
1 - Voltaje de referencia bajo se aplica al pin Vref 0 - Voltaje de alimentacin Vss se utiliza como una fuente de voltaje de
referencia bajo.
VCFG0 - Voltage Reference bit (bit de configuracin de voltaje de referencia)
selecciona la fuente de voltaje de referencia alto que se necesita para el
fucionamiento del convertidor A/D.
1 - Voltaje de referencia alto se aplica al pin Vref+.
0 - Voltaje de alimentacin Vdd se utiliza como una fuente de voltaje de
referencia alto.
Para medir el voltaje en un pin de entrada por medio del convertidor A/D, se debe
realizar lo siguiente:
Paso 1 - Configuracin del puerto:
Escribir un uno lgico (1) a un bit del registro TRIS, lo que resulta en
configurar el pin apropiado como una entrada.
Escribir un uno lgico (1) a un bit del registro ANSEL, lo que resulta en
configurar el pin apropiado como una entrada analgica.

Paso 2 - Configuracin del mdulo de la conversin A/D:


Configurar voltaje de referencia en el registro ADCON1.
Seleccionar una seal de reloj de la conversin A/D en el registro ADCON0.
Seleccionar uno de los canales de entrada CH0-CH13 del registro ADCON0.
Seleccionar el formato de dato por medio de ADFM del registro ADCON1.
Habilitar el convertidor A/D al poner a uno el bit ADON del registro ADCON0.
Paso 3 - Configuracin de la interrupcin (opcionalmente):
Poner a cero el bit ADIF.
Poner a uno los bits ADIE, PEIE y GIE.
Paso 4 - Tiempo de espera para que transcurra el tiempo de adquisicin
(aproximadamente 20uS).
Paso 5 - Inicio de la conversin poniendo a uno el bit GO/DONE del reg istro
ADCON0.
Paso 6 - Esperar a que la conversin A/D finalice.
Es necesario comprobar en el bucle de programa si el bit GO/DONE est a
cero

esperar

que

se

produzca

una

anteriormente habilitada).
Paso 7 - Lectura del resultado de la conversin A/D:
Leer los registros ADRESH y ADRESL.
COMPARADOR ANALGICO

interrupcin

(deber

estar

Aparte del convertidor A/D, hay otro mdulo, que hasta hace poco ha sido
incorpodo slo en los circuitos integrados que pertenecen a los llamados
componentes analgicos. Debido al hecho de que casi no hay ningn dispositivo
automtico complejo que en cierto modo no utilice estos circuitos, dos
comparadores de alta calidad, junto con los componentes adicionales estn
integrados en el microcontrolador y conectados a sus pines.
Cmo funciona un comparador? Bsicamente, el comparador analgico es un
amplificador que compara la magnitud de voltajes en dos entradas. Dispone de
dos entradas y una salida. Dependiendo de cul voltaje de entrada es ms alto
(valor analgico), un cero lgico (0) o un uno lgico (1) (valores digitales) ser la
salida.

Cuando el voltaje analgico en Vin - es ms alto que el voltaje anlogo en


Vin+, la salida del comparador estar a un nivel digital bajo.
Cuando el voltaje analgico en Vin+ es ms alto que el voltaje anlogo en
Vin-, la salida del comparador estar a un nivel digital alto.
El microcontrolador PIC16F887 dispone de dos de estos comparadores de voltaje
cuyas entradas estn conectadas a los pines de E/S RA0-RA3, mientras que las
salidas estn conectadas a los pines RA4 y RA5. Adems, hay una fuente de
voltaje de referencia interna en el chip mismo, la que vamos a discutir ms tarde.

Estos dos circuitos estn bajo el control de los bits almacenados en los siguientes
registros:
CM1CON0 est en control del comparador C1;
CM2CON0 est en control del comparador C2;
CM2CON1 est en control del comparador C2;
FUENTE INTERNA DE VOLTAJE DE REFERENCIA
Uno de dos voltajes analgicos proporcionados en las entradas del comparador es
por lo general estable e inalterable. Es denominado voltaje de referencia(Vref).
Para generarlo, se pueden utilizar tanto una fuente de voltaje externa como una
fuente de voltaje interna especial. El voltaje de referencia Vref se deriva despus
de seleccionar una fuente, por medio de una red en escalera que consiste en 16
resistencias, formando un divisor de voltaje. La fuente de voltaje es seleccionable
por el bit VRSS del registro VRCON.
Adems, la fraccin de voltaje proporcionada por la red de resistencias es
seleccionable por los bits VR0-VR3 y utilizada como voltaje de referencia. Vea la
siguiente figura:

El voltaje de referencia del comparador dispone de dos gamas con 16 diferentes


niveles de voltaje cada una. La seleccin de gama es controlada por el bit VRR del
registro VRCON. El voltaje de referencia seleccionado CVref puede ser la salida al
pin RA2/AN2 si el bit VROE se pone a uno.
Aunque la idea principal era obtener el voltaje de referencia variable para el
funcionamiento de mdulos analgicos, de ese modo se obtiene un simple
convertidor A/D. Este convertidor es muy til en algunas situaciones. Su
funcionamiento est bajo el control del registro VRCON.
COMPARADORES E INTERRUPCIN
Siempre que haya un cambio del estado lgico en la salida de un comparador, el
bit de bandera CMIF del registro PIR se pone a uno. Ese cambio tambin causar
una interrupcin si los siguientes bits se ponen a uno:

El bit CMIE del registro PIE = 1;


El bit PEIE del registro INTCON = 1; y
El bit GIE del registro INTCON = 1.
Si una interrupcin est habilitada, un cambio en la salida de un comparador
cuando el microcontrolador est en modo de reposo, puede causar que el
microcontrolador salga de reposo y vuelva a funcionar en modo normal.
FUNCIONAMIENTO EN MODO DE REPOSO (SLEEP MODE)
Si est habilitado antes de entrar en modo de reposo, el comparador se queda
activo durante el modo de reposo. Si el comparador no se utiliza para "despertar"
el dispositivo, el consumo de corriente se puede reducir en modo de reposo al
apagar el comparador. Esto se lleva a cabo al poner a cero el bit CxON del registro
CMxCON0.
Para que el comparador "despierte" al microcontrolador del modo de reposo, el bit
CxIE del registro IE2 y el bit PEIE del registro INTCON debern ponerse a uno. La
instruccin que sigue a la instruccin Sleep siempre se ejecuta al salir del modo
de reposo. Si el bit GIE del registro INTCON se pone a uno, el dispositivo ejecutar
la rutina de servicio de interrupcin.
Registro CM1CON0

Los bits de este registro estn en control del comparador C1. Eso afecta
principalmente a la configuracin de las entradas. Para explicarlo con ms
claridad, vea la siguiente figura en la que se muestran slo los componentes
directamente afectados por los bits de este registro.

C1ON - Comparator C1 Enable bit (bit de habilitacin del comparador C1)


habilita al comparador C1.
1 - Comparador C1 est habilitado.
0 - Comparador C1 est deshabilitado.
C1OUT - Comparator C1 Output bit (bit de salida del comparador C1) es la
salida del comparador C1.
Si C1POL = 1 (salida del comparador est invertida)
1 - Voltaje de entrada C1Vin+ es ms bajo que el voltaje de entrada C1Vin-.
0 - Voltaje de entrada C1Vin+ es ms alto que el voltaje de entrada C1Vin-.

If C1POL = 0 (salida del comparador no est invertida)


1 - Voltaje de entrada C1Vin+ es ms alto que el voltaje de entrada C1Vin-.
0 - Voltaje de entrada C1Vin+ es ms bajo que el voltaje de entrada C1Vin-.
C1OE Comparator C1 Output Enable bit (bit de habilitacin de salida del
comparador C1)
1 - Salida del comparador C1OUT est conectada al pin C1OUT *.
0 - Salida del comparador se utiliza internamente.
* Para habilitar que el bit C1OUT aparezca en el pin, se deben cumplir dos
condiciones:

C1ON

(el

comparador

debe estar

activado)

el bit

correspondiente TRIS = 0 (pin se debe configurar como salida).


C1POL - Comparator C1 Output Polarity Select bit (bit de seleccin de
polaridad de salida del comparador C1) habilita la inversin del estado de la salida
del comparador C1.
1 - Salida del comparador C1 est invertida.
0 - Salida del comparador C1 no est invertida.
C1R - Comparator C1 Reference Select bit (bit de seleccin de la fuente de
voltaje de referencia del comparador C1)
1 - Entrada no invertida C1Vin+ est conectada a la fuente de voltaje de
referencia C1Vref.
0 - Entrada no invertida C1Vin+ est conectada al pin C1IN+.
C1CH1, C1CH0 - Comparator C1 Channel Select bit (bit de seleccin de canal
del comparador C1)

C1CH1

C1CH0

E N T R A D A C 1 V I N - D E L C O M PA R A D O R

Entrada C1Vin- est conectada al pin C12IN0-

Entrada C1Vin- est conectada al pin C12IN1-

Entrada C1Vin- est conectada al pin C12IN2-

Entrada C1Vin- est conectada al pin C12IN3-

Registro CM2CON0

Los bits de este registro estn en control del comparador C2. Similar al caso
anterior, la siguiente figura muestra un esquema simplificado del circuito afectado
por los bits de este registro.

C2ON - Comparator C2 Enable bit (bit de habilitacin del comparador C2)


habilita el comparador C2.
1 - Comparador C2 est habilitado.
0 - Comparador C2 est deshabilitado.
C2OUT - Comparator C2 Output bit (bit de salida del comparador C2) es la
salida del comparador C2.
If C2POL = 1 (salida del comparador est invertida)
1 - Voltaje de entrada C2Vin+ es ms bajo que el voltaje de entrada C2Vin-.
0 - Voltaje de entrada C2Vin+ es ms alto que el voltaje de entrada C2Vin-.
If C2POL = 0 (salida del comparador no est invertida)
1 - Voltaje de entrada C2Vin+ es ms alto que el voltaje de entrada C2Vin-.
0 - Voltaje de entrada C2Vin+ es ms bajo que el voltaje de entrada C2Vin-.
C2OE - Comparator C2Output Enable bit (bit de habilitacin de salida del
comparador C2)
1 - Salida del comparador C2OUT est conectada al pin C2OUT*.
0 - Salida del comparador se utiliza internamente.
* Para habilitar que el bit C2OUT aparezca en el pin, se deben cumplir dos
condiciones:

C2ON

(el

comparador

debe estar

activado)

el bit

correspondiente TRIS = 0 (pin se debe configurar como salida).


C2POL - Comparator C2 Output Polarity Select bit (bit de seleccin de
polaridad de salida del comparador C2) habilita la inversin del estado de la salida
del comparador C2.

1 - Salida del comparador C2 est invertida.


0 - Salida del comparador C2 no est invertida.
C2R - Comparator C2 Reference Select bit (bit de seleccin de la fuente de
voltaje de referencia del comparador C2)
1 - Entrada no invertida C2Vin+ est conectada a la fuente de voltaje de
referencia C2Vref.
0 - Entrada no invertida C2Vin+ est conectada al pin C2IN+.
C2CH1, C2CH0 Comparator C2 Channel Select bit (bit de seleccin de canal
del comparador C2)
C2CH1

C2CH0

E N T R A D A C 2 V I N - D E L C O M PA R A D O R

Entrada C2Vin- est conectada al pin C12IN0-

Entrada C2Vin- est conectada al pin C12IN1-

Entrada C2Vin- est conectada al pin C12IN2-

Entrada C2Vin- est conectada al pin C12IN3-

Registro CM2CON1

MC1OUT Mirror Copy of C1OUT bit es una copia del bit C1OUT
MC2OUT Mirror Copy of C2OUT bit es una copia del bit C2OUT

C1RSEL Comparator C1 Reference Select bit (bit de seleccin de la fuente de


voltaje de referencia del comparador C1)
1 - Voltaje seleccionable CVref se utiliza en la fuente de voltaje de referencia
C1Vref.
0 - Voltaje de referencia fijo de 0,6V se utiliza en la fuente de voltaje de
referencia C1Vref.
C2RSEL - Comparator C2 Reference Select bit (bit de seleccin de la fuente
de voltaje de referencia del comparador C2)
1 - Voltaje seleccionable CVref se utiliza en la fuente de voltaje de referencia
C2Vref.
0 - Voltaje de referencia fijo de 0,6V se utiliza en la fuente de voltaje de
referencia C2Vref.
T1GSS - Timer1 Gate Source Select bit (bit de seleccin de la fuente de la
compuerta del temporizador Timer1)
1 - Compuerta del temporizador Timer1 utiliza seal del pin T1G.
0 - Compuerta del temporizador Timer1 utiliza seal SYNCC2OUT.
C2SYNC - Comparator C2 Output Synchronization bit (bit de sincronizacin
de salida del comparador C2)
1 - Salida del comparador C2 est sincronizada con un flanco ascendente de
seal de reloj del temporizador Timer1
0 - Salida del comparador es una seal asncrona.
Registro VRCON

VREN Comparator C1 Voltage Reference Enable bit (bit de habilitacin de la


fuente de voltaje de referencia del comparador C1)
1 - Fuente de voltaje de referencia CVref est encendido.
0 - Fuente de voltaje de referencia CVref est apagado.
VROE Comparator C2 Voltage Reference Enable bit (bit de habilitacin de la
fuente de voltaje de referencia del comparador C2)
1 - Fuente de voltaje de referencia CVref est conectada al pin.
0 - Fuente de voltaje de referencia CVref no est conectada al pin.
VRR - CVref Range Selection bit (bit de seleccin de gama de voltaje de
referencia Vref)
1 - Fuente de voltaje de referencia se ajusta a producir baja gama de
voltaje.
0 - Fuente de voltaje de referencia se ajusta a producir alta gama de voltaje.
VRSS - Comparator Vref Range selection bit (bit de seleccin de gama de
voltaje de referencia Vref del comparador)
1 - Voltaje de referencia est en la gama de Vref+ a Vref-.

0 - Voltaje de referencia est en la gama de Vdd a Vss. (voltaje de


alimentacin).
VR3 - VR0 CVref Value Selection (seleccin de valor de voltaje de referencia)
If VRR = 1 (gama baja)
El voltaje de referencia se calcula por medio de la frmula: CVref =
([VR3:VR0]/24)Vdd.
If VRR = 0 (gama alta)
El voltaje de referencia se calcula por medio de la frmula CVref = Vdd/4 +
([VR3:VR0]/32)Vdd.
Pasos a seguir para utilizar apropiadamente los comparadores integrados:
Paso 1 - Configuracin del mdulo:
Para seleccionar el modo apropiado, se deben configurar los estados de los
bits de los registros CM1CON0 y CM2CON0. La interrupcin debe estar
deshabilitada durante el cambio de modo.
Paso 2 - Configurar la fuente de voltaje de referencia Vref interna (slo si se
utiliza). En el registro VRCON es necesario realizar lo siguiente:
Seleccionar una de dos gamas de voltaje por medio del bit VRR.
Configurar el voltaje de referencia Vref necesario por medio de los bits VR3 VR0.
Poner a uno el bit VROE si es necesario.
Habilitar la fuente de voltaje de referencia Vref al poner a uno el bit VREN.
Frmula utilizada para calcular el voltaje de referencia

VRR

(gama

baja)

(gama

alta)

CVref = ([VR3:VR0]/24)VLADDER
VRR

CVref = (VLADDER/4) + ([VR3:VR0]VLADDER/32)


Vladder = Vdd or ([Vref+] - [Vref-]) or Vref+
Paso 3 - Inicio del funcionamiento:
Habilitar una interrupcin al poner a uno los bits CMIE (registro PIE), PEIE y
GIE (registro INTCON ).
Leer los bits C1OUT y C2OUT del registro CMCON.
Leer la bandera de bit CMIF del registro PIR. Despus de haber sido puesto a
uno, este bit se pone a cero por software.
Para

sincronizar

todos

los

procesos

que

se

llevan

cabo

dentro

del

microcontrolador, se debe utilizar una seal de reloj, mientras que para generar
una seal de reloj, se debe utilizar un oscilador. As de simple. El microcontrolador
dispone de varios osciladores capaces de funcionar en modos diferentes. Y aqu
es donde viene lo interesante...
3.10 OSCILADOR DE RELOJ
Como se muestra en la siguiente figura, la seal de reloj se genera por uno de los
dos osciladores integrados.

Un oscilador externo est instalado fuera del microcontrolador y conectado a


los pines OSC1 y OSC2. Es denominado 'externo' porque utiliza componentes
externos para generar una seal de reloj y estabilizar la frecuencia. Estos son:
cristal de cuarzo, resonador cermico o circuito resistor - capacitor. El modo de
funcionamiento del oscilador se selecciona por los bits, que se envan durante la
programacin, denominados Palabra de Configuracin.
El oscilador interno consiste en dos osciladores internos separados:
El HFINTOSC es un oscilador interno de alta frecuencia calibrado a 8MHz. El
microcontrolador puede utilizar una seal de reloj generada a esta frecuencia o
despus de haber sido dividida en el pre-escalador.
El LFINTOSC es un oscilador interno de baja frecuencia calibrado a 31 kHz. Sus
pulsos de reloj se utilizan para funcionamiento de los temporizadores de
encendido y perro guardin, asimismo puede utilizarse como fuente de seal de
reloj para el funcionamiento de todo el microcontrolador.

El bit System Clock Select (bit de seleccin del reloj del sistema - SCS) del registro
OSCCON determina si una fuente de seal de reloj del microcontrolador ser
interna o externa.
Registro OSCCON
El registro OSCCON gobierna el microcontrolador y las opciones de seleccin de
frecuencia. Contiene los siguientes bits: bits de seleccin de frecuencia (IRCF2,
IRCF1, IRCF0), bits de estado de frecuencia (HTS, LTS), bits de control de reloj del
sistema (OSTA, SCS).

IRCF2-0 - Internal Oscillator Frequency Select bits. (bits de seleccin de


frecuencia del oscilador interno). El valor del divisor de frecuencias depende de la
combinacin de estos tres bits. La frecuencia de reloj del oscilador interno se
determina de la misma manera.
IRCF2

IRCF1

IRCF0

FRECUENCIA

OSC.

8 MHz

HFINTOSC

4 MHz

HFINTOSC

2 MHz

HFINTOSC

1 MHz

HFINTOSC

500 kHz

HFINTOSC

250 kHz

HFINTOSC

125 kHz

HFINTOSC

OSTS

Oscillator

Start-up

31 kHz
Time-out

LFINTOSC

Status

bit

(bit de estado del

temporizador de encendido) indica cul fuente de reloj est actualmente en uso.


Es un bit de slo lectura.
1 - Se utiliza el oscilador de reloj externo.
0 - Se utiliza uno de los osciladores de reloj interno (HFINTOSC o LFINTOSC).
HTS - HFINTOSC Status bit (8 MHz - 125 kHz) (bit de estado del HFINTOSC)
indica si el oscilador interno de alta frecuencia funciona en modo estable.
1 - HFINTOSC est estable.
0 - HFINTOSC no est estable.
LTS - LFINTOSC Stable bit (31 kHz) (bit de estado del LFINTOSC) indica si el
oscilador de baja frecuencia funciona en modo estable.
1 - LFINTOSC est estable.
0 - LFINTOSC no est estable.
SCS - System Clock Select bit (bit de seleccin del reloj del sistema) determina
cul oscilador se utilizar como una fuente de reloj.
1 - Oscilador interno se utiliza como reloj del sistema.
0

Oscilador

externo

se

utiliza

como

reloj

del

sistema.

El modo del oscilador se configura por medio de los bits, denominados


Palabra

de

Configuracin,

que

se

escribe

en

microcontrolador durante el proceso de la programacin.


MODOS DE RELOJ EXTERNO

la

memoria

del

El oscilador externo se puede configurar para funcionar en uno de varios modos,


lo que habilita que funcione a diferentes velocidades y utilice diferentes
componentes para estabilizar la frecuencia. El modo de funcionamiento se
selecciona durante el proceso de escribir un programa en el microcontrolador.
Antes que nada, es necesario activar el programa en una PC que se utilizar para
programar el microcontrolador. En este caso, es el programa PICflash. Pulse sobre
la casilla del oscilador y seleccione uno de la lista desplegable. Los bits
apropiados se pondrn a uno automticamente, formando parte de varios bytes,
denominados Palabra de Configuracin.
Durante el proceso de la programacin del microcontrolador, los bytes de la
Palabra de Configuracin se escriben en la memoria ROM del microcontrolador y
se almacenan en los registros especiales no disponibles al usuario. A base de
estos bits, el microcontrolador sabe qu hacer, aunque eso no se indica
explcitamente en el programa.

Modo de funcionamiento se selecciona despus de escribir y compilar un


programa
OSCILADOR EXTERNO EN MODO EC
El modo de reloj externo (EC - external clock) utiliza un oscilador externo como
una fuente de seal de reloj. La mxima frecuencia de seal de reloj est limitada
a 20 MHz.

Las ventajas del funcionamiento del oscilador externo en modo EC son las
siguientes:
La fuente de reloj externa independiente est conectada al pin de entrada
OSC1. El pin OSC2 est disponible como pin de E/S de propsito general;
Es posible sincronizar el funcionamiento del microcontrolador con los dems
componentes incorporados en el dispositivo;
En este modo el microcontrolador se pone a funcionar inmediatamente
despus de encenderlo. No se requiere esperar para estabilizar la
frecuencia.
Al deshabilitar temporalmente la fuente de reloj externa, se detiene el
funcionamiento del dispositivo, dejando todos los datos intactos. Despus
de reiniciar el reloj externo, el dispositivo sigue funcionando como si no
hubiera pasado nada.

OSCILADOR EXTERNO EN MODO LP, XT O HS

Los modos LP, XT y HS utilizan un oscilador externo como una fuente de reloj cuya
frecuencia est determinada por un cristal de cuarzo o por resonadores cermicos
conectados a los pines OSC1 y OSC2. Dependiendo de las caractersticas de los
componentes utilizados, seleccione uno de los siguientes modos:
Modo LP - (Baja potencia) se utiliza slo para cristal de cuarzo de baja
frecuencia. Este modo est destinado para trabajar con cristales de 32.768
KHz normalmente embebidos en los relojes de cristal. Es fcil de
reconocerlos por sus dimensiones pequeas y una forma cilndrica. Al

utilizar este modo el consumo de corriente ser menor que en los dems
modos.
Modo XT se utiliza para cristales de cuarzo de frecuencias intermedias
hasta 8 MHz. El consumo de corriente es media en comparacin con los
dems modos.
Modo HS - (Alta velocidad) se utiliza para cristales de reloj de frecuencia
ms alta de 8 MHz. Al utilizar este modo el consumo de corriente ser
mayor que en los dems modos.

RESONADORES CERMICOS EN MODO XT O HS


Los resonadores cermicos son similares a los cristales de cuarzo segn sus
caractersticas, por lo que se conectan de la misma manera. A diferencia de los
cristales de cuarzo, son ms baratos y los osciladores que hacen uso de ellos son
de calidad ms baja. Se utilizan para las frecuencias de reloj entre 100 kHz y 20
MHz.

OSCILADOR EXTERNO EN MODOS RC Y RCIO


El uso de los elementos para estabilizar la frecuencia sin duda alguna tiene
muchas ventajas, pero a veces realmente no es necesario. En la mayora de casos
el oscilador puede funcionar a frecuencias que no son precisamente definidas, as
que sera una prdida de dinero embeber tales elementos. La solucin ms simple
y ms barata es estas situaciones es utilizar una resistencia y un capacitor para el
funcionamiento del oscilador. Hay dos modos:

Modo RC. Cuando el oscilador externo se configura a funcionar en modo RC, el


pin OSC1 debe estar conectado al circuito RC como se muestra en la figura a la
derecha. La seal de frecuencia del oscilador RC dividida por 4 est disponible en
el pin OSC2. Esta seal se puede utilizar para la calibracin, sincronizacin o para
otros propsitos.

Modo RCIO. De manera similar, el circuito RC est conectado al pin OSC1. Esta
vez, el pin OSC2 est disponible para ser utilizado como pin de E/S de propsito
general.
En ambos casos se le recomienda utilizar los componentes como se muestra en la
figura.
La frecuencia de este oscilador se calcula por medio de la frmula f = 1/T segn la
que:
f = frecuencia [Hz];
T = R * C = constante de tiempo [s];
R = resistencia elctrica []; y
C = capacitancia del condensador [F].
MODOS DE RELOJ INTERNO
El circuito del oscilador interno consiste en dos osciladores separados que se
pueden seleccionar como la fuente del reloj del microcontrolador:
El oscilador HFINTOSC est calibrado de fbrica y funciona a 8Mhz. La frecuencia
de este oscilador se puede configurar por el usuario por medio de software
utilizando los bits del registro OSCTUNE.
El oscilador LFINTOSC no est calibrado de fbrica y funciona a 31kHz.

Similar al oscilador externo, el interno tambin puede funcionar en varios modos.


El modo de funcionamiento se selecciona de la misma manera que en el oscilador
externo - por medio de los bits que forman Palabra de configuracin. En otras
palabras, todo se lleva a cabo dentro del software de PC antes de escribir un
programa en el microcontrolador.

OSCILADOR

INTERNO

EN

MODO

INTOSC

En este modo, el pin OSC1 est disponible para ser utilizado como pin de E/S de
propsito general. La seal de frecuencia del oscilador interno dividida por 4 est
disponible en el pin OSC2.

OSCILADOR

INTERNO

EN

MODO

INTOSCIO

En este modo, los dos pines estn disponibles como pines de E/S de propsito
general.
CONFIGURACIN DEL OSCILADOR INTERNO

El oscilador interno consiste en dos circuitos separados:


1. El oscilador interno de alta frecuencia HFINTOSC est conectado al postescalador (divisor de frecuencias). Est calibrado de fbrica y funciona a 8 Mhz. Al
utilizar el post-escalador, este oscilador puede producir una seal de reloj a una
de siete frecuencias. La seleccin de frecuencia se realiza dentro del software
utilizando los pines IRCF2, IRCF1 y IRCF0 del registro OSCCON.
El HFINTOSC est habilitado al seleccionar una de siete frecuencias (entre 8 Mhz y
125 kHz) y poner a uno el bit de la fuente de reloj del sistema (SCS) del registro
OSCCON. Como se muestra en la siguiente figura, todo el procedimiento se realiza
por medio de los bits del registro OSCCON.

2. El oscilador de baja frecuencia LFINTOSC no est calibrado de fbrica y


funciona a 31 kHz. Est habilitado al seleccionar la frecuencia (bits del registro
OSCCON) y poner a uno el bit SCS del mismo registro.
MODO DE CAMBIO AUTOMTICO DE VELOCIDAD DE RELOJ (TWO-SPEED
CLOCK START-UP MODE)

El modo de cambio automtico de velocidad de reloj se utiliza para reducir el


consumo de corriente cuando el microcontrolador funciona en modo de reposo.
De qu se trata todo esto?
Cuando se configura en modo LP, XT o HS, el oscilador externo se desactiva al
pasar a modo de reposo para reducir el consumo de corriente total del dispositivo.
Cuando se cumplen las condiciones de "despertamiento", el microcontrolador no
se pone a funcionar inmediatamente puesto que tiene que esperar a que se
estabilice la frecuencia de seal de reloj. Este tiempo muerto dura exactamente
1024 pulsos, despus de que el microcontrolador contina con la ejecucin del
programa. El caso es que se ejecutan slo unas pocas instrucciones antes de que
el microcontrolador vuelva al modo de reposo.
Eso significa que la mayora de tiempo as como la mayora de corriente de
bateras se ha perdido en vano. El caso se soluciona utilizando el oscilador interno
para ejecutar el programa durante la duracin de 1024 pulsos. Tan pronto como
se estabilice la frecuencia del oscilador externo, l retoma automticamente "el
papel principal". Todo el procedimiento se habilita al poner a uno el bit de palabra
de configuracin. Para programar el microcontrolador, es necesario seleccionar la
opcin Int-Ext Switchover (conmutacin interna/externa) por software.

MONITOR PARA DETECTAR UN FALLO DE LA FUENTE DE RELOJ (FAIL-SAFE


CLOCK MONITOR)
Como indica su nombre, el monitor para detectar un fallo de la fuente de reloj
(Fail-Safe Clock Monitor - FSCM) monitorea el funcionamiento externo y permite al
microcontrolador continuar con la ejecucin de programa en caso de que el
oscilador falle por alguna razn. En tal caso, el oscilador interno toma su funcin.

El monitor detecta un fallo al comparar las fuentes de reloj interno y externo. Si


los pulsos del oscilador externo tardan ms de 2mS en llegar, la fuente de reloj
ser automticamente cambiada por la interna. As, el oscilador interno sigue
funcionando controlado por los bits del registro OSCCON. Si el bit OSFIE del
registro PIE2 est a uno, se producir una interrupcin.
El reloj interno sigue siendo la fuente del reloj del sistema hasta que el dispositivo
reinicie con xito el oscilador externo que vuelve a ser la fuente de reloj del
sistema. De manera similar a casos anteriores, este mdulo est habilitado al
cambiar la palabra de configuracin justamente antes de que se inicie el proceso
de programar el chip. Esta vez, esto se realiza al seleccionar la opcin Fail-Safe
Clock Monitor.

Registro OSCTUNE
Los cambios del registro OSCTUNE afectan a la frecuencia del oscilador HFINTOSC,
pero no a la frecuencia del LFINTOSC. No hay ninguna indicacin de que haya
ocurrido

desplazamiento

microcontrolador.

de

frecuencia

durante

el

funcionamiento

del

TUN4 - TUN0 Frequency Tuning bits. (bits de calibrar la frecuencia). Al


combinar estos cinco bits, la frecuencia del oscilador de 8Mhz se reduce o se
aumenta. De este modo, las frecuencias obtenidas por la divisin en el postescalador cambian tambin.
TUN4

TUN3

TUN2

TUN1

TUN0

FRECUENCIA

Mxima

Calibrada

Mnima

La EEPROM es un segmento de memoria separado, que no pertenece a la


memoria de programa (ROM), tampoco a la memoria de datos (RAM). Aunque a
estas localidades de memoria no se les puede acceder fcil y rpidamente, su
propsito es insustituible. Los datos almacenados en la EEMPROM estn
permanentemente guardados incluso al apagar la fuente de alimentacin, y

pueden

ser

cambiados

en

cualquier

momento.

Por

estas

caractersticas

excepcionales cada byte de la EEPROM se considera valioso.


3.11 MEMORIA EEPROM
El microcontrolador PIC16F887 dispone de 256 localidades de memoria EEPROM
controlados por los bits de los siguientes registros:
EECON1 (registro de control);
EECON2 (registro de control);
EEDAT (almacena los datos listos para escritura y lectura); y
EEADR (almacena la direccin de la EEPROM a la que se accede).
Adems, el registro EECON2 no es un registro verdadero, no existe fsicamente en
el chip. Se utiliza slo durante la escritura de los datos en la memoria.
Los registros EEDATH y EEADRH se utilizan durante la escritura y lectura de la
EEPROM. Los dos se utilizan tambin durante la escritura y lectura de la memoria
de programa (FLASH).
Por considerar esto una zona de riesgo (por supuesto usted no quiere que el
microcontrolador borre su propio programa por casualidad), no vamos a discutirlo
aqu, no obstante le avisamos que tenga cuidado.
Registro EECON1

EEPGD - Program/Data EEPROM Select bit (bit de seleccin de memorias)


1 - Acceso a la memoria Flash de programa.
0 - Acceso a la memoria de datos EEPROM.
WRERR - EEPROM Error Flag bit (bit de error de escritura)
1 - Se produce un error de escritura de forma prematura y ha ocurrido un
error.
0 - Se ha completado la operacin de escritura.
WREN - EEPROM Write Enable bit (bit de habilitacin de escritura)
1 - Escritura de datos en la EEPROM habilitada.
0 - Escritura de datos en la EEPROM deshabilitada.
WR - Write Control bit (bit de control de escritura)
1 - Se ha iniciado una operacin de escritura de datos en la EEPROM.
0 - Se ha completado una operacin de escritura de datos en la EEPROM.
RD - Read Control bit (bit de control de lectura)

1 - Inicia una lectura de la memoria EEPROM.


0 - Lectura de la memoria EEPROM deshabilitada.
LECTURA DE LA MEMORIA EEPROM
Para leer los datos de la memoria EEMPROM, siga los siguientes pasos:
Paso 1: Escribir la direccin (00h - FFh) en el registro EEADR.
Paso 2: Seleccionar el bloque de memoria EEPROM al poner a cero el bit
EEPGD del registro EECON1.
Paso 3: Poner a uno el bit RD del mismo registro para leer el contenido de
la localidad.
Paso 4: El dato se almacena en el registro EEDAT y est listo para su uso.
El siguiente ejemplo muestra el procedimiento anteriormente descrito al escribir
un programa en lenguaje ensamblador:

BSF STATUS,RP1 ;
BCF STATUS,RP0 ; Acceder al banco 2
MOVF ADDRESS,W ; Mover la direccin al registro W
MOVWF EEADR

; Escribir la direccin

BSF STATUS,RP0 ; Acceder al banco 3


BCF EECON1,EEPGD ; Seleccionar la EEPROM
BSF EECON1,RD

; Leer los datos

BCF STATUS,RP0 ; Acceder al banco 2


MOVF EEDATA,W

; Dato se almacena en el registro W

La misma secuencia de programa escrita en C se parece a lo siguiente:

W = EEPROM_Read(ADDRESS);

Las ventajas del uso del lenguaje C se han hecho ms obvias, no lo cree?
ESCRITURA EN LA MEMORIA EEPROM
Antes de escribir los datos en la memoria EEPROM es necesario escribir la
direccin en el registro EESADR y los datos en el registro EESAT. Slo ha quedado
seguir a una secuencia especial para iniciar la escritura para cada byte. Durante
el proceso de escritura las interrupciones deben estar deshabilitadas.
El ejemplo que sigue muestra el procedimiento anteriormente descrito al escribir
un programa en lenguaje ensamblador:

BSF STATUS,RP1
BSF STATUS,RP0
BTFSC EECON,WR1 ; Esperar a que se complete la escritura anterior
GOTO $-1 ;
BCF STATUS,RP0 ; Banco 2
MOVF ADDRESS,W ; Mover la direccin a W

MOVWF EEADR
MOVF DATA,W

MOVWF EEDATA

; Escribir la direccin
; Mover los datos a W

; Escribir los datos

BSF STATUS,RP0 ; Banco 3


BCF EECON1,EEPGD ; Seleccionar la EEPROM
BSF EECON1,WREN ; Escritura a la EEPROM habilitada
BCF INCON,GIE

; Todas las interrupciones deshabilitadas

MOVLW 55h
MOVWF EECON2
MOVLW AAh
MOVWF EECON2
BSF EECON1,WR

BSF INTCON,GIE ; Interrupciones habilitadas


BCF EECON1,WREN ; Escritura a la EEPROM deshabilitada

La misma secuencia de programa escrita en C se parece a lo siguiente:

W = EEPROM_Write(ADDRESS, W);

No hace falta comentar nada.


Vamos a hacerlo en mikroC...

// El ejemplo muestra cmo utilizar la librera EEPROM en el compilador mikroC


PRO for PIC.

char ii; // La variable ii utilizada en el bucle

void main(){
ANSEL = 0;
ANSELH = 0;
PORTB = 0;
PORTC = 0;
PORTD = 0;
TRISB = 0;
TRISC = 0;
TRISD = 0;

// Configuracin de los pines AN como E/S digitales

for(ii = 0; ii < 32; ii++)

// Llenar el bfer con los datos

EEPROM_Write(0x80+ii, ii);

// Escribir los datos en la direccin 0x80+ii

EEPROM_Write(0x02,0xAA);

// Escribir un dato en la direccin 2 de la

EEMPROM
EEPROM_Write(0x50,0x55);

// Escribir un dato en la direccin 0x50

// de la EEMPROM
Delay_ms(1000);
PORTB = 0xFF;

// Diodos en los puertos PORTB y PORTC


// para indicar el comienzo de la lectura

PORTC = 0xFF;
Delay_ms(1000);
PORTB = 0x00;
PORTC = 0x00;
Delay_ms(1000);
PORTB = EEPROM_Read(0x02);
EEPROM y

// visualizarla en el puerto PORB

// Leer los datos de la direccin 2 de la

PORTC = EEPROM_Read(0x50);

// Leer los datos de la direccin 0x50 de la

EEPROM y

// visualizarla en el puerto PORC


Delay_ms(1000);

for(ii = 0; ii < 32; ii++) {

// Leer el bloque de 32 bytes de la direccin

PORTD = EEPROM_Read(0x80+ii); // 0x80 y visualizarla en el puerto PORTD

Delay_ms(250);
}
}

Aprimera vista, basta con encender una fuente de alimentacin para hacer
funcionar un microcontrolador. A primera vista, basta con apagar una fuente de
alimentacin para detenerlo. Slo a primera vista. En realidad, el arranque y el
final del funcionamiento son las fases crticas de las que se encarga una seal
especial denominada RESET.
3.12 REINICIO! BLACK-OUT, BROWN-OUT O RUIDOS?
Al

producirse

un

reinicio

el

microcontrolador

detiene

su

funcionamiento

inmediatamente y borra sus registros. Una seal de reinicio se puede generar


externamente en cualquier momento (nivel lgico bajo en el pin MCLR). Si se

necesita, una seal tambin puede ser generada por la lgica de control interna.
Al encender una fuente de alimentacin siempre se produce un reinicio. Por
muchos eventos de transicin que ocurren al encender una fuente de
alimentacin (centelleos y fogonazos de contactos elctricos en interruptores,
subida de voltaje lenta, estabilizacin de la frecuencia de seal de reloj graduada
etc.) es necesario proporcionar un cierto tiempo muerto antes de que el
microcontrolador se ponga a funcionar. Dos temporizadores internos PWRT y OST
se encargan de eso. El PWRT puede estar habilitado/ deshabilitado durante el
proceso de escribir un programa. Vamos a ver cmo funciona todo.

Cuando el voltaje de la fuente de alimentacin alcanza entre 1.2 y 1.7V, un


circuito denominado temporizador de arranque (Power-up timer) mantiene al
microcontrolador reiniciado durante unos 72mS. Tan pronto como transcurra el
tiempo, otro temporizador denominado temporizador de encendido del oscilador
(Oscillator start-up timer) genera otra seal de reinicio durante la duracin de
1024 perodos del oscilador de cuarzo. Al expirar el tiempo muerto (marcado con
Reset T en la Figura) y al poner a alto el pin MCLR, todas las condiciones se han
cumplido y el microcontrolador se pone a ejecutar la primera instruccin en el
programa.
Aparte de este reinicio "controlado" que ocurre al encender una fuente de
alimentacin, hay dos tipos de reinicio denominados Black-out y Brown-out que
pueden producirse durante el funcionamiento del microcontrolador as como al
apagar una fuente de alimentacin.

REINICIO BLACK-OUT

El reinicio black out ocurre al apagar una fuente de alimentacin correctamente.


El microcontrolador no tiene tiempo para hacer nada imprevisible puesto que el
voltaje cae muy rpidamente por debajo de su valor mnimo. En otras palabras,
se apaga la luz, las cortinas bajan y el espectculo ha terminado!
REINICIO BROWN-OUT

Cuando el voltaje de la fuente de alimentacin cae lentamente (un ejemplo tpico


es descarga de bateras, aunque el microcontrolador experimentara unas cadas
mucho ms rpidas como un proceso lento) los componentes internos detienen su
funcionamiento gradualmente y ocurre el as llamado reinicio Brownout. En tal
caso,

antes

de

que

el

microcontrolador

detenga

su

funcionamiento

completamente, hay un peligro real de que los circuitos que funcionan a


frecuencias altas se pongan a funcionar de forma imprevisible. El reinicio brown-

out puede causar cambios fatales en el programa ya que se almacena en la


memoria flash incorporada en el chip.
RUIDO ELCTRICO

Es un tipo especial del reinicio Brownout que ocurre en un ambiente industrial


cuando voltaje de alimentacin parpadea por un momento y cae por debajo del
valor mnimo. Aunque es corto, este ruido producido en una lnea de conduccin
elctrica puede afectar desfavorablemente al funcionamiento del dispositivo.
PIN MCLR

Un cero lgico (0) al pin MCLR causa un reinicio inmediato y regular. Es


recomendable conectarlo de la forma mostrada en la Figura a la derecha. La

funcin de los componentes adicionales es de mantener un uno lgico "puro"


durante el funcionamiento normal. Si sus valores se seleccionan de manera que
proporcionen un nivel lgico alto en el pin despus de que haya transcurrido el
tiempo

muerto

reset

T,

el

microcontrolador

se

pondr

funcionar

inmediatamente. Esto puede ser muy til cuando se necesita sincronizar el


funcionamiento del microcontrolador con los componentes adicionales o con el
funcionamiento de varios microcontroladores.
Para evitar posibles errores al producirse el reinicio Brown-out, el PIC 16F887 tiene
un mecanismo de proteccin incorporado. Es un circuito simple, pero eficaz que
reacciona cada vez que el voltaje de alimentacin cae por debajo de 4V (si se
utiliza un voltaje de alimentacin de 5V) y mantiene este nivel de voltaje por ms
de 100 microsegundos. Este circuito genera una seal despus de que todo el
microcontrolador funcionar como si hubiera sido encendido por primera vez.
Capitulo 4: Ejemplos
El propsito de este captulo es de proporcionar la informacin bsica que
necesita saber para ser capaz de utilizar microcontroladores con xito en la
prctica. Por eso, este captulo no contiene ningn programa muy elaborado,
tampoco dispone de un esquema de dispositivo con soluciones extraordinarias.
Por el contrario, los siguientes ejemplos son la mejor prueba de que escribir un
programa no es un privilegio ni cosa de talento, sino una habilidad de poner las
piezas juntas del rompecabezas al utilizar directivas. Tenga la seguridad de que
el diseo y el desarrollo de los dispositivos generalmente siguen al mtodo
probar-corregir-repetir. Por supuesto, cunto ms ahonde sobre el tema, ms se
complica, ya que tanto los nios como los arquitectos de primera lnea, ponen las
piezas juntas del rompecabezas.
4.1 CONEXIN BSICA
4.2 COMPONENTES ADICIONALES

4.3 EJEMPLO 1 - Escribir cabecera, configurar pines de E/S, utilizar la funcin


Delay y el operador Switch
4.4 EJEMPLO 2 - Utilizar instrucciones en ensamblador y el oscilador interno
LFINTOSC...
4.5 EJEMPLO 3 - Timer0 como un contador, declarar variables nuevas,
constantes de enumeracin, utilizar rels...
4.6 EJEMPLO 4 - Utilizar los temporizadores Timer0, Timer1 y Timer2.
4.7 EJEMPLO 5 - Utilizar el temporizador perro - guardin
4.8 EJEMPLO 6 - Mdulo CCP1 como generador de seal PWM
4.9 EJEMPLO 7 - Utilizar el convertidor A/D
4.10 EJEMPLO 8 - Utilizar memoria EEPROM
4.11 EJEMPLO 9 - Contador de dos dgitos LED, multiplexin
4.12 EJEMPLO 10 - Utilizar el visualizador LCD
4.13 EJEMPLO 11 - Comunicacin serial RS-232
4.14 EJEMPLO 12 - Medicin de temperatura por medio del sensor DS1820.
Uso del protocolo '1-wire'...
4.15 EJEMPLO 13 - Generacin de sonido, librera de sonido...
4.16 EJEMPLO 14 - Utilizar el visualizador LCD grfico
4.17 EJEMPLO 15 - Utilizar el panel tctil...
4.1 CONEXIN BSICA

Para que un microcontrolador funcione apropiadamente es necesario proporcionar


lo siguiente:
Alimentacin;
Seal de reinicio; y
Seal de reloj.

Como se muestra en la figura anterior, se trata de circuitos simples, pero no tiene


que ser siempre as. Si el dispositivo destino se utiliza para controlar las mquinas
caras o para mantener funciones vitales, todo se vuelve mucho ms complicado.
ALIMENTACIN
Aunque el PIC16F887 es capaz de funcionar a diferentes voltajes de alimentacin,
no es recomendable probar la ley de Murphy. Lo ms adecuado es proporcionar un
voltaje de alimentacin de 5V DC. Este circuito, mostrado en la pgina anterior,
utiliza un regulador de voltaje positivo de tres terminales LM7805. Es un regulador
integrado y barato que proporciona una estabilidad de voltaje de alta calidad y

suficiente corriente para habilitar el funcionamiento apropiado del controlador y


de los perifricos (aqu suficiente significa una corriente de 1A).
SEAL DE REINICIO
Para que un microcontrolador pueda funcionar apropiadamente, un uno lgico
(VCC) se debe colocar en el pin de reinicio. El botn de presin que conecta el pin
MCLR a GND no es necesario. Sin embargo, este botn casi siempre est
proporcionado ya que habilita al microcontrolador volver al modo normal de
funcionamiento en caso de que algo salga mal. Al pulsar sobre el botn RESET, el
pin MCLR se lleva un voltaje de 0V, el microcontrolador se reinicia y la ejecucin
de programa comienza desde el principio. Una resistencia de 10k se utiliza para
impedir un corto circuito a tierra al presionar este botn.
SEAL DE RELOJ
A pesar de tener un oscilador incorporado, el microcontrolador no puede funcionar
sin componentes externos que estabilizan su funcionamiento y determinan su
frecuencia (velocidad de operacin del microcontrolador). Dependiendo de los
elementos utilizados as como de las frecuencias el oscilador puede funcionar en
cuatro modos diferentes:
LP - Cristal de bajo consumo;
XT - Cristal / Resonador;
HS - Cristal/Resonador de alta velocidad; y
RC - Resistencia / Condensador.

Por qu son estos modos importantes? Como es casi imposible construir un


oscilador

estable

que

funcione

un

amplio

rango

de

frecuencias,

el

microcontrolador tiene que saber a qu cristal est conectado, para poder


ajustar el funcionamiento de sus componentes internos. sta es la razn por la
que todos los programas utilizados para escribir un programa en el chip contienen
una opcin para seleccionar el modo de oscilador. Vea la figura de la izquierda.
Cristal de cuarzo
Al utilizar el cristal de cuarzo para estabilizar la frecuencia, un oscilador
incorporado funciona a una frecuencia determinada, y no es afectada por los
cambios de temperatura y de voltaje de alimentacin. Esta frecuencia se etiqueta
normalmente en el encapsulado del cristal. Aparte del cristal, los condensadores
C1 y C2 deben estar conectados como se muestra en el siguiente esquema. Su
capacitancia no es de gran importancia. Por eso, los valores proporcionados en la
siguiente tabla se deben tomar como recomendacin y no como regla estricta.

Resonador cermico
Un resonador cermico es ms barato y muy similar a un cuarzo por la funcin y
el modo de funcionamiento. Por esto, los esquemas que muestran su conexin al
microcontrolador son idnticos. No obstante, los valores de los condensadores
difieren un poco debido a las diferentes caractersticas elctricas. Refirase a la
tabla que est a continuacin.

Estos resonadores se conectan normalmente a los osciladores en caso de que no


sea necesario proporcionar una frecuencia extremadamente precisa.
Oscilador RC
Si la frecuencia de operacin no es de importancia, entonces no es necesario
utilizar los componentes caros y adicionales para la estabilizacin. En vez de eso,
basta con utilizar una simple red RC, mostrada en la siguiente figura. Como aqu
es utilizada slo la entrada del oscilador local, la seal de reloj con la frecuencia
Fosc/4 aparecer en el pin OSC2. sta es la frecuencia de operacin del
microcontrolador, o sea la velocidad de ejecucin de instrucciones.

Oscilador externo
Si se requiere sincronizar el funcionamiento de varios microcontroladores o si por
alguna razn no es posible utilizar ninguno de los esquemas anteriores, una seal
de reloj se puede generar por un oscilador externo. Refirase a la siguiente figura.

Apesar del hecho de que el microcontrolador es un producto de la tecnologa


moderna, no es tan til sin estar conectado a los componentes adicionales. Dicho
de otra manera, el voltaje llevado a los pines del microcontrolador no sirve para
nada si no se utiliza para llevar a cabo ciertas operaciones como son
encender/apagar, desplazar, visualizar etc.
4.2 COMPONENTES ADICIONALES
Esta parte trata los componentes adicionales utilizados con ms frecuencia en la
prctica, tales como resistencias, transistores, diodos LED, visualizadores LED,
visualizadores LCD y los circuitos de comunicacin RS-232.
INTERRUPTORES Y BOTONES DE PRESIN

Los interruptores y los botones de presin son los dispositivos simples para
proporcionar la forma ms simple de detectar la aparicin de voltaje en un pin de
entrada del microcontrolador. No obstante, no es tan simple como parece... Es por
un rebote de contacto. El rebote de contacto es un problema comn en los
interruptores mecnicos.

Al tocarse los contactos, se produce un rebote por su inercia y elasticidad. Por


consiguiente, la corriente elctrica es rpidamente pulsada en lugar de tener una
clara transicin de cero a la corriente mxima. Por lo general, esto ocurre debido
a las vibraciones, los desniveles suaves y la suciedad entre los contactos. Este
efecto no se percibe normalmente al utilizar estos componentes en la vida
cotidiana porque el rebote ocurre demasiado rpido para afectar a la mayora de
los dispositivos elctricos. Sin embargo, pueden surgir problemas en algunos
circuitos lgicos que responden lo suficientemente rpido de manera que
malinterpreten los pulsos producidos al tocarse los contactos como un flujo de
datos. De todos modos, el proceso entero no dura mucho (unos pocos micro - o
milisegundos), pero dura lo suficiente para que lo detecte el microcontrolador. Al
utilizar slo un botn de presin como una fuente de seal de contador, en casi
100% de los casos ocurren los errores.
El problema se puede resolver con facilidad al conectar un simple circuito RC para
suprimir rpidos cambios de voltaje. Como el perodo del rebote no est definido,
los valores de los componentes no estn precisamente determinados. En la

mayora de los casos es recomendable utilizar los valores que se muestran en la


siguiente figura.

Si se necesita una estabilidad completa, entonces hay que tomar medidas


radicales. La salida del circuito, mostrado en la siguiente figura (biestable RS,
tambin llamado flip flop RS), cambiar de estado lgico despus de detectar el
primer pulso producido por un rebote de contacto. Esta solucin es ms cara
(interruptor SPDT), pero el problema es resuelto.

Aparte de estas soluciones de hardware, hay tambin una simple solucin de


software. Mientras el programa prueba el estado de circuito lgico de un pin de
entrada, si detecta un cambio, hay que probarlo una vez ms despus de un
cierto tiempo de retardo. Si el programa confirma el cambio, esto significa que un
interruptor/botn de presin ha cambiado de posicin. Las ventajas de esta
solucin son obvias: es gratuita, se borran los efectos del rebote de contacto y se
puede aplicar a los contactos de una calidad ms baja tambin.

REL
Un rel es un interruptor elctrico que se abre y se cierra bajo el control de otro
circuito electrnico. Por eso est conectado a los pines de salida del
microcontrolador y utilizado para encender/apagar los dispositivos de alto
consumo tales como: motores, transformadores, calefactores, bombillas etc. Estos
dispositivos se colocan casi siempre lejos de los componentes sensibles de la
placa. Hay varios tipos de rels, pero todos funcionan de la misma manera. Al fluir
la corriente por la bobina, el rel funciona por medio de un electromagneto,
abriendo

cerrando

uno

ms

conjunto

de

contactos.

Similar

los

optoacopladores no hay conexin galvnica (contacto elctrico) entre los circuitos


de entrada y salida. Los rels requieren con frecuencia tanto un voltaje ms alto y
una corriente ms alta para empezar a funcionar. Tambin hay rels miniatura
que se pueden poner en marcha por una corriente baja obtenida directamente de
un pin del microcontrolador.

La figura que sigue muestra la solucin utilizada con ms frecuencia.

Para prevenir la aparicin de un alto voltaje de autoinduccin, causada por una


parada repentina del flujo de corriente por la bobina, un diodo polarizado invertido
se conecta en paralelo con la bobina. El propsito de este diodo es de cortar
este pico de voltaje.
DIODOS LED
Probablemente sepa todo lo que necesita saber sobre los diodos LED, pero
tambin debe pensar en los jvenes... A ver, cmo destruir un LED? Bueno...muy
fcil.

Quemar con rapidez

Como cualquier otro diodo, los LEDs tienen dos puntas - un nodo y un ctodo.
Conecte un diodo apropiadamente a la fuente de alimentacin y va a emitir luz
sin ningn problema. Ponga al diodo al revs y conctelo a la misma fuente de
alimentacin (aunque sea por un momento). No emitir luz - nunca ms!
Quemar lentamente
Hay un lmite de corriente nominal, o sea, lmite de corriente mxima especificada
para cada LED que no se deber exceder. Si eso sucede, el diodo emitir luz ms
intensiva, pero slo por un perodo corto de tiempo.
Algo para recordar
De manera similar, todo lo que tiene que hacer es elegir una resistencia para
limitar la corriente mostrada a continuacin. Dependiendo de voltaje de
alimentacin, los efectos pueden ser espectaculares.

VISUALIZADOR LED

Bsicamente, un visualizador LED no es nada ms que varios diodos LED


moldeados en la misma caja plstica. Hay varios tipos de los visualizadores y
algunos de ellos estn compuestos por varias docenas de diodos incorporados
que pueden visualizar diferentes smbolos. No obstante, el visualizador utilizado
con ms frecuencia es el visualizador de 7 segmentos. Est compuesto por 8
LEDs. Los siete segmentos de un dgito estn organizados en forma de un
rectngulo para visualizar los smbolos, mientras que el segmento adicional se
utiliza para el propsito de visualizar los puntos decimales. Para simplificar la
conexin, los nodos y los ctodos de todos los diodos se conectan al pin comn
as que tenemos visualizadores de nodo comn y visualizadores de ctodo
comn, respectivamente. Los segmentos estn etiquetados con letras de a a g y
dp, como se muestra en la siguiente figura. Al conectarlos, cada diodo LED se
trata por separado, lo que significa que cada uno dispone de su propia resistencia
para limitar la corriente.
Aqu le presentamos unas cosas importantes a las que debe prestar atencin al
comprar un visualizador LED:
Como hemos mencionado, dependiendo de si nodos o ctodos estn
conectados al pin comn, tenemos visualizadores de nodo comn y
visualizadores de ctodo comn. Visto de afuera, parece que no hay
ninguna diferencia entre estos visualizadores, pues se le recomienda
comprobar cul se va a utilizar antes de instalarlo.
Cada pin del microcontrolador tiene un lmite de corriente mxima que
puede recibir o dar. Por eso, si varios visualizadores estn conectados al
microcontrolador, es recomendable utilizar as llamados LEDs de Bajo
consumo que utilizan solamente 2mA para su funcionamiento.
Los segmentos del visualizador estn normalmente etiquetados con letras
de a a g, pero no hay ninguna regla estrictaa cules pines del visualizador
estarn conectados. Por eso es muy importante comprobarlo antes de
empezar a escribir un programa o disear un dispositivo.

Los visualizadores conectados al microcontrolador normalmente ocupan un gran


nmero de los pines de E/S valiosos, lo que puede ser un problema sobre todo
cuando se necesita visualizar los nmeros compuestos por varios dgitos. El
problema se vuelve ms obvio si, por ejemplo, se necesita visualizar dos nmeros
de seis dgitos (un simple clculo muestra que en este caso se necesitan 96 pines
de salida). La solucin de este problema es denominada multiplexin.
Aqu es cmo se ha hecho una ilusin ptica basada en el mismo principio de
funcionamiento como una cmara de pelcula. Un slo dgito est activo a la vez,
pero se tiene la impresin de que todos los dgitos de un nmero estn
simultneamente activos por cambiar tan rpidamente de las condiciones de
encendido/apagado.

Veamos la figura anterior. Primero se aplica un byte que representa unidades al


puerto PORT2 del microcontrolador y se activa el transistor T1 a la vez. Despus
de poco tiempo, el transistor T1 se apaga, un byte que representa decenas se
aplica al puerto PORT2 y el transistor T2 se activa. Este proceso se est repitiendo
cclicamente a alta velocidad en todos los dgitos y transistores correspondientes.
Lo decepcionante es que el microcontrolador es slo un tipo de computadora
miniatura diseada para interpretar el lenguaje de ceros y unos, lo que se pone
de manifiesto al visualizar cualquier dgito. Concretamente, el microcontrolador no
conoce cmo son unidades, decenas, centenas, ni diez dgitos a los que estamos
acostumbrados. Por esta razn, cada nmero a visualizar debe pasar por el
siguiente procedimiento:
Antes que nada, un nmero de varios dgitos debe ser dividido en unidades,
centenas etc. en una subrutina especfica. Luego, cada de estos dgitos se debe
almacenar en los bytes particulares. Los dgitos se hacen reconocibles al realizar
"enmascaramiento". En otras palabras, el formato binario de cada dgito se
sustituye por una combinacin diferente de los bits por medio de una subrutina
simple. Por ejemplo, el dgito 8 (0000 1000) se sustituye por el nmero binario

0111 1111 para activar todos los LEDs que visualizan el nmero 8. El nico diodo
que queda inactivo aqu est reservado para el punto decimal.
Si un puerto del microcontrolador est conectado al visualizador de tal manera
que el bit 0 active el segmento 'a', el bit 1 active el segmento 'b', el bit 2 active el
segmento 'c' etc, entonces la tabla que sigue muestra la "mscara" para cada
dgito.

DGITOS

V I S UA L I Z A

S E G M E N T O S D E L V I S UA L I Z A D O R

R
dp

Adems de los dgitos de 0 a 9, hay algunas letras -A, C, E, J, F, U, H, L, b, c, d, o,


r, t - que se pueden visualizar al enmascarar.
En caso de que se utilicen los visualizadores de nodo comn, todos los unos
contenidos en la tabla anterior se deben sustituir por ceros y viceversa. Adems,
los transistores PNP se deben utilizar como controladores.
OPTOACOPLADORES
Un optoacoplador es un dispositivo frecuentemente utilizado para aislar
galvnicamente el microcontrolador de corriente o voltaje potencialmente
peligroso de su entorno. Los optoacopladores normalmente disponen de una, dos
o cuatro fuentes de luz (diodos LED) en su entrada mientras que en su salida,
frente a los diodos, se encuentra el mismo nmero de los elementos sensibles a la
luz (foto-transistores, foto-tiristores, foto-triacs). El punto es que un optoacoplador
utiliza una corta ruta de transmisin ptica para transmitir una seal entre los
elementos de circuito, que estn aislados elctricamente. Este aislamiento tiene
sentido slo si los diodos y los elementos foto-sensitivos se alimentan por
separado. As, el microcontrolador y los componentes adicionales y caros estn
completamente protegidos de alto voltaje y ruidos que son la causa ms
frecuente de destruccin, dao y funcionamiento inestable de los dispositivos
electrnicos en la prctica. Los optoacopladores utilizados con ms frecuencia son
aqullos con foto-transistores en sus salidas. En los optoacopladores con la base
conectada al pin 6 interno (tambin hay optoacopladores sin ella), la base puede
quedarse desconectada.

La red R/C representada por una lnea quebrada en la figura anterior indica una
conexin opcional de la base de transistores dentro del optoacoplador, que reduce
los efectos de ruidos al eliminar los pulsos muy cortos.
VISUALIZADOR LCD
Este componente est especficamente fabricado para ser utilizado con los
microcontroladores, lo que significa que no se puede activar por los circuitos
integrados estndar. Se utiliza para visualizar los diferentes mensajes en un
visualizador de cristal lquido miniatura. El modelo descrito aqu es el ms
utilizado en la prctica por su bajo precio y grandes capacidades. Est basado en
el microcontrolador HD44780 (Hitachi) integrado y puede visualizar mensajes en
dos lneas con 16 caracteres cada una. Puede visualizar todas las letras de
alfabeto, letras de alfabeto griego, signos de puntuacin, smbolos matemticos
etc. Tambin es posible visualizar smbolos creados por el usuario. Entre otras
caractersticas tiles es el desplazamiento automtico de mensajes (a la izquierda
y a la derecha), aparicin del cursor, retroiluminacin LED etc.

Pines del visualizador LCD


A lo largo de un lado de una placa impresa pequea del visualizador LCD se
encuentran los pines que le permiten estar conectado al microcontrolador. Hay 14
pines en total marcados con nmeros (16 si hay retroiluminacin). Su funcin se
muestra en la tabla que sigue:
NMER

NOMBR

E S TA D O

L G I C O

Tierra

Vss

0V

Alimentacin

Vdd

+5V

Contraste

Vee

0 - Vdd

FUNCIN

Control

de

funcionamiento

DESCRIPCIN

D0 D7 considerados
4

RS

como

comandos

D0 D7 considerados
como datos
Escribir los datos (del

R/W

0
1

microcontrolador

al

LCD)
Leer los datos (del LCD
al microcontrolador)

Acceso al visualizador

LCD

Transicin

Funcionamiento normal

de 1 a 0

Datos/comandos

deshabilitado
se

estn transmitiendo al
LCD

Datos
comandos

D0

0/1

Bit 0 LSB

D1

0/1

Bit 1

D2

0/1

Bit 2

/ 10

D3

0/1

Bit 3

11

D4

0/1

Bit 4

12

D5

0/1

Bit 5

13

D6

0/1

Bit 6

14

D7

0/1

Bit 7 MSB

Pantalla LCD
Una pantalla LCD puede visualizar dos lneas con 16 caracteres cada una. Cada
carcter consiste en 5x8 o 5x11 pxeles. Este libro cubre un visualizador de 5x8
pxeles que es utilizado con ms frecuencia.

El contraste del visualizador depende del voltaje de alimentacin y de si los


mensajes se visualizan en una o dos lneas. Por esta razn, el voltaje variable 0Vdd se aplica al pin marcado como Vee. Un potencimetro trimer se utiliza con
frecuencia para este propsito. Algunos de los visualizadores LCD tienen
retroiluminacin incorporada (diodos LED azules o verdes). Al utilizarlo durante el
funcionamiento, se debe de conectar una resistencia en serie a uno de los pines
para limitar la corriente (similar a diodos LED).

Si no hay caracteres visualizados o si todos los caracteres estn oscurecidos al


encender el visualizador, lo primero que se debe hacer es comprobar el
potencimetro para ajustar el contraste. Est ajustado apropiadamente? Lo
mismo se aplica si el modo de funcionamiento ha sido cambiado (escribir en una o
en dos lneas).
Memoria LCD
El visualizador LCD dispone de tres bloques de memoria:
DDRAM Display Data RAM (RAM de datos de visualizacin);
CGRAM Character Generator RAM (generador de caracteres RAM); y
CGROM Character Generator ROM (generador de caracteres ROM)
Memoria DDRAM
La memoria DDRAM se utiliza para almacenar los caracteres a visualizar. Tiene
una capacidad de almacenar 80 caracteres. Algunas localidades de memoria
estn directamente conectadas a los caracteres en el visualizador.
Todo funciona muy simple: basta con configurar el visualizador para incrementar
direcciones automticamente (desplazamiento a la derecha) y establecer la
direccin inicial para el mensaje que se va a visualizar (por ejemplo 00 hex).
Luego, todos los caracteres enviados por las lneas D0-D7 se van a visualizar en el
formato de mensaje al que nos hemos acostumbrado - de la izquierda a la

derecha. En este caso, la visualizacin empieza por el primer campo de la primera


lnea ya que la direccin inicial es 00hex. Si se enva ms de 16 caracteres, todos
se memorizarn, pero slo los primeros 16 sern visibles. Para visualizar los
dems, se debe utilizar el comando shift. Virtualmente, parece como si el
visualizador LCD fuera una ventana, desplazndose de la izquierda a la derecha
sobre las localidades de memoria con diferentes caracteres. En realidad, as es
cmo se cre el efecto de desplazar los mensajes sobre la pantalla.

Si se habilita ver el cursor, aparecer en la localidad actualmente direccionada. En


otras palabras, si un carcter aparece en la posicin del cursor, se va a mover
automticamente a la siguiente localidad direccionada.
Esto es un tipo de memoria RAM as que los datos se pueden escribir en ella y leer
de ella, pero su contenido se pierde irrecuperablemente al apagar la fuente de
alimentacin.
Memoria CGROM
La memoria CGROM contiene un mapa estndar de todos los caracteres que se
pueden visualizar en la pantalla. A cada carcter se le asigna una localidad de
memoria:

Las direcciones de las localidades de memoria CGROM corresponden a los


caracteres ASCII. Si el programa que se est actualmente ejecutando llega al
comando enviar el carcter P al puerto, el valor binario 0101 0000 aparecer en
el puerto. Este valor es el equivalente ASCII del carcter P. Al escribir este valor en
un LCD, se visualizar el smbolo de la localidad 0101 0000 de la CGROM. En otras

palabras, se visualizar el carcter P. Esto se aplica a todas las letras del alfabeto
(minsculas y maysculas), pero no se aplica a los nmeros.
Como se muestra en el mapa anterior, las direcciones de todos los dgitos se
desplazan por 48 en relacin con sus valores (direccin del dgito 0 es 48,
direccin del dgito 1 es 49, direccin del dgito 2 es 50 etc.). Por consiguiente,
para visualizar los dgitos correctamente es necesario aadir el nmero decimal
48 a cada uno antes de enviarlos a un LCD.

Qu es un cdigo ASCII? Desde su aparicin hasta hoy en da, las computadoras


han sido capaces de reconocer solamente nmeros, y no las letras. Esto significa
que todos los datos que una computadora intercambia con un perifrico,
reconocidos como letras por los humanos, en realidad estn en el formato binario

(el teclado es un buen ejemplo). En otras palabras, a cada carcter le corresponde


la combinacin nica de ceros y unos. El cdigo ASCII representa una codificacin
de

caracteres

basada

en

el

alfabeto

ingls.

El

ASCII

especifica

una

correspondencia entre los smbolos de caracteres estndar y sus equivalentes


numricos.
Memoria CGRAM
Adems de los caracteres estndar, el visualizador LCD puede visualizar smbolos
definidos por el usuario. Esto puede ser cualquier smbolo de 5x8 pxeles. La
memoria RAM denominada CGRAM de 64 bytes lo habilita.
Los registros de memoria son de 8 bits de anchura, pero slo se utilizan 5 bits
ms bajos. Un uno lgico (1) en cada registro representa un punto oscurecido,
mientras que 8 localidades agrupados representan un carcter. Esto se muestra
en la siguiente figura:

Los smbolos estn normalmente definidos al principio del programa por una
simple escritura de ceros y unos de la memoria CGRAM as que crean las formas
deseadas. Para visualizarlos basta con especificar su direccin. Preste atencin a
la primera columna en el mapa de caracteres CGROM. No contiene direcciones de
la memoria RAM, sino los smbolos de los que se est hablando aqu. En este
ejemplo visualizar 0 significa visualizar sonrisa, visualizar 1 significa visualizar ancla etc.
Comandos bsicos del visualizador LCD
Todos los datos transmitidos a un visualizador LCD por las salidas D0-D7 sern
interpretados como un comando o un dato, lo que depende del estado lgico en el
pin RS:

RS = 1 - Los bits D0 - D7 son direcciones de los caracteres a visualizar. El


procesador LCD direcciona un carcter del mapa de caracteres y lo
visualiza. La direccin DDRAM especifica la localidad en la que se va a
visualizar el carcter. Esta direccin se define antes de transmitir el
carcter o la direccin del carcter anteriormente transmitido ser
aumentada automticamente.
RS = 0 - Los bits D0 - D7 son los comandos para ajustar el modo del
visualizador.
En la siguiente tabla se muestra una lista de comandos reconocidos por el LCD:
TIEMPO
COMANDO

DE

EJECUCI
N

Borrar

el

1.64mS

1.64mS

I/D

40uS

el 0

40uS

D/C R/L x

40uS

DL

40uS

la 0

Direccin CGRAM

visualizador
Poner el cursor
al inicio
Modo

de

entrada
Activar/desacti
var
visualizador
Desplazar

el

cursor/visualiz
ador
Modo

de

funcionamient

o
Establecer
direccin

40uS

CGRAM
Establecer

la

direccin

Direccin CGRAM

40uS

BF

Direccin CGRAM

CGRAM o en la 1

D7

D6

D5

D4

D3

D2

D1

D0

40uS

D7

D6

D5

D4

D3

D2

D1

D0

40uS

DDRAM
Leer

la

bandera
"BUSY"(ocupa
do) (BF)
Escribir en la
DDRAM
Leer la CGRAM
o la DDRAM

I/D 1 = Incremento (por 1)

R/L 1 = Desplazamiento a la

derecha
0 = Decremento (por 1)

0 = Desplazamiento a la izquierda

S 1 = Desplazamiento del visualizador activado

DL 1 = Bus de datos de 8

bits
0 = Desplazamiento del visualizador desactivado

0 = Bus de datos de 4

bits

D 1 = Visualizador encendido
0 = Visualizador apagado

N 1 = Visualizador de dos lneas


0 = Visualizador en una lnea

U 1 = Cursor activado

F 1 = Carcter de 5x10 puntos

0 = Cursor desactivado

0 = Carcter de 5x7 puntos

B 1 = Parpadeo del cursor encendido

D/C 1 = Desplazamiento del

visualizador
0 = Parpadeo del cursor apagado

0 = Desplazamiento del cursor

QU ES UNA BANDERA DE OCUPADO (BUSY FLAG)?


En comparacin al microcontrolador, el LCD es un componente extremadamente
lento. Por esta razn, era necesario proporcionar una seal que, al ejecutar un
comando, indicara que el visualizador estaba listo para recibir el siguiente dato.
Esta seal denominada bandera de ocupado (busy flag) se puede leer de la lnea
D7. El visualizador est listo para recibir un nuevo dato cuando el voltaje en esta
lnea es de 0V (BF=0).
Conectar al visualizador LCD
Dependiendo

de

cuntas

lneas

se

utilizan

para

conectar

un

LCD

al

microcontrolador, hay dos modos de LCD, el de 8 bits y el de 4 bits. El modo


apropiado se selecciona en el inicio del funcionamiento en el proceso denominado
inicializacin. El modo de LCD de 8 bits utiliza los pines D0-D7 para transmitir los
datos, como hemos explicado en la pgina anterior. El propsito principal del
modo de LCD de 4 bits es de ahorrar los valiosos pines de E/S del
microcontrolador. Slo los 4 bits ms altos (D4-D7) se utilizan para la
comunicacin, mientras que los dems pueden quedarse desconectados. Cada
dato se enva al LCD en dos pasos - primero se envan 4 bits ms altos

(normalmente por las lneas D4- D7), y luego los 4 bits ms bajos. La inicializacin
habilita que el LCD conecte e interprete los bits recibidos correctamente.

Pocas veces se leen los datos del LCD (por lo general se transmiten del
microcontrolador al LCD) as que, con frecuencia, es posible guardar un pin de E/S
de sobra. Es simple, basta con conectar el pin L/E a Tierra. Este ahorro del pin
tiene su precio. Los mensajes se visualizarn normalmente, pero no ser posible
leer la bandera de ocupado ya que tampoco es posible leer los datos del
visualizador. Afortunadamente, hay una solucin simple. Despus de enviar un
carcter o un comando es importante dar al LCD suficiente tiempo para hacer su
tarea. Debido al hecho de que la ejecucin de un comando puede durar
aproximadamente 1.64mS, el LCD tarda como mximo 2mS en realizar su tarea.
Inicializar al visualizador LCD
Al encender la fuente de alimentacin, el LCD se reinicia automticamente. Esto
dura aproximadamente 15mS. Despus de eso, el LCD est listo para funcionar.
Asimismo, el modo de funcionamiento est configurado por defecto de la
siguiente manera:
1. Visualizador est borrado.

2. Modo
DL
N

Bus

de

datos

LCD

de

de

bits

una

lnea

F = 0 - Carcter de 5 x 8 puntos
3. Visualizador/Cursor
D
U

encendido/apagado
0

Visualizador
-

Cursor

apagado
apagado

B = 0 - Parpadeo del cursor apagado


4. Introduccin

de

caracteres

ID = 1 Direcciones visualizadas se incrementan automticamente en 1


S = Desplazamiento del visualizador desactivado
Por lo general, el reinicio automtico se lleva a cabo sin problemas. En la mayora
de los casos, pero no siempre! Si por cualquier razn, el voltaje de alimentacin
no llega a su mximo valor en 10mS, el visualizador se pone a funcionar de
manera completamente imprevisible. Si la unidad de voltaje no es capaz de
cumplir con las condiciones o si es necesario proporcionar un funcionamiento
completamente seguro, se aplicar el proceso de inicializacin. La inicializacin,
entre otras cosas, reinicia de nuevo al LCD, al habilitarle un funcionamiento
normal.
Hay dos algoritmos de inicializacin. Cul se utilizar depende de si la conexin al
microcontrolador se realiza por el bus de datos de 4 o 8 bits. En ambos casos,
despus de inicializacin slo queda especificar los comandos bsicos y, por
supuesto, visualizar los mensajes.
Refirase a la Figura que sigue para el procedimiento de inicializacin por el bus
de datos de 8 bits:

Esto no es un error! En este algoritmo, el mismo valor se transmite tres veces en


fila.
El procedimiento de inicializacin por el bus de datos de 4 bits:

Vamos a hacerlo en mikroC...

/* En mikroC for PIC, basta con escribir slo una funcin para realizar todo el
proceso
de la inicializacin del LCD. Antes de llamar esta funcin es necesario declarar
los
bits LCD_D4-LCD_D7, LCD_RS y LCD_EN. */

...
Lcd_Init(); // Inicializar el LCD
...

EJEMPLOS PRCTICOS
El proceso de crear un proyecto nuevo es muy simple. Seleccione la opcin New
Project del men Project como se muestra en la Figura de la derecha.

Aparecer una ventana que le guiar a travs del proceso de creacin de un


proyecto nuevo. La ventana de entrada de este programa contiene una lista de
acciones a realizar para crear un proyecto nuevo. Pulse el botn Next.

El proceso de creacin de un proyecto nuevo consiste en cinco pasos:


1. Seleccione el tipo de microcontrolador a programar. En este caso se trata del
PIC16F887.
2. Seleccione la frecuencia de reloj del microcontrolador. En este caso el valor
seleccionado es 8 MHz.
3. Seleccione el nombre y la ruta del proyecto. En este caso, el nombre del proyecto
es First_Project. Est guardado en la carpeta C:\My projects. Al nombre del
proyecto se le asigna automticamente la extensin .mcppi. Se crear en el
proyecto el archivo fuente con el mismo nombre (First_Project .c.h).
4. Si el nuevo proyecto consiste de varios archivos fuente, se necesita especificarlos
y pulse sobre el botn Add para incluirlos. En este ejemplo no hay archivos fuente
adicionales.
5. Por ltimo, se necesita confirmar todas las opciones seleccionadas. Pulse sobre
Finish.
Despus de crear el proyecto, aparecer una ventana blanca en la que debe
escribir el programa. Vea la siguiente figura:

Una vez creado el programa, es necesario compilarlo en un cdigo .hex.


Seleccione una de las opciones para compilar del men Project:
Para crear un archivo .hex, seleccione la opcin Build (Ctrl+F9) del men
Project o pulse sobre el icono Build de la barra de herramientas Project.

Por medio de la opcin Build All Projects (Shift+F9) se compilan todos los
archivos del proyecto, libreras (si el cdigo fuente contiene alguna de
ellas) y los archivos def para el microcontrolador utilizado.
La opcin Build + Program (Ctrl+F11) es importante ya que permite al
compilador mikroC PRO for PIC cargar automticamente el programa en el
microcontrolador despus de la compilacin. El proceso de la programacin
se realiza por medio del programador PICFlash.
Todos los errores encontrados durante la compilacin aparecern en la ventana
Message. Si no hay errores en el programa, el compilador mikroC PRO for PIC
generar los correspondientes archivos de salida.
4.3 EJEMPLO 1
Escribir cabecera, configurar pines de E/S, utilizar la funcin Delay y el
operador Switch
El nico propsito de este programa es de encender varios diodos LED en el
puerto B. Utilice este ejemplo para examinar cmo es un programa real. La
siguiente figura muestra el esquema de conexin, mientras que el programa se
encuentra en la siguiente pgina.

Al encender la fuente de alimentacin, cada segundo, el diodo LED en el puerto B


emite luz, lo que indica que el microcontrolador est conectado correctamente y
que funciona normalmente.
En este ejemplo se muestra cmo escribir una cabecera correctamente. Lo mismo
se aplica a todos los programas descritos en este libro. Para no repetir, en los
siguientes ejemplos no vamos a escribir la cabecera. Se considera estar en el
principio de cada programa, marcada como "Cabecera".

Para hacer este ejemplo ms interesante, vamos a habilitar que los LEDs
conectados al puerto PORTB parpadeen. Hay varios modos de hacerlo:
1. Tan pronto como se encienda el microcontrolador, todos los LEDs emitirn la luz
por un segundo. La funcin Delay se encarga de eso en el programa. Slo se
necesita ajustar la duracin del tiempo de retardo en milisegundos.
2. Despus de un segundo, el programa entra en el bucle for, y se queda all hasta
que la variable k sea menor que 20. La variable se incrementa en 1 despus de
cada iteracin. Dentro del bucle for, el operador switch monitorea el estado lgico
en el puerto PORTB. Si PORTB=0xFF, su estado se invierte en 0x00 y viceversa.
Cualquier cambio de estos estados lgicos hace todos los LEDs parpadear. El ciclo
de trabajo es 5:1 (500mS:100mS).

3. Al salir del bucle for, el estado lgico del puerto POTRB cambia (0xb 01010101) y
el programa entra en el bucle infinito while y se queda all hasta que 1=1. El
estado lgico del puerto PORTB se invierte cada 200mS.

4.4 EJEMPLO 2

Utilizar instrucciones en ensamblador y el oscilador interno LFINTOSC...


En realidad, esto es una continuacin del ejemplo anterior, pero se ocupa de un
problema un poco ms complicado... El propsito era hacer los LEDs en el puerto
PORTB parpadear lentamente. Se puede realizar al introducir un valor suficiente
grande para el parmetro del tiempo de retardo en la funcin Delay. No obstante,
hay otra manera ms eficiente para ejecutar el programa lentamente. Acurdese
de que este microcontrolador tiene un oscilador incorporado LFINTOSC que
funciona a una frecuencia de 31kHz. Ahora lleg la hora de darle una
oportunidad.
El programa se inicia con el bucle do-while y se queda all por 20 ciclos. Despus
da cada iteracin, llega el tiempo de retardo de 100ms, indicado por un parpadeo
relativamente rpido de los LEDs en el puerto PORTB. Cuando el programa salga
de este bucle, el microcontrolador se inicia al utilizar el oscilador LFINTOSC como
una fuente de seal de reloj. Los LEDs parpadean ms lentamente aunque el
programa ejecuta el mismo bucle do-while con un tiempo de retardo 10 veces
ms corto.
Con el propsito de hacer evidentes algunas situaciones potencialmente
peligrosas, se activan los bits de control por medio de las instrucciones en
ensamblador. Dicho de manera sencilla, al entrar o salir una instruccin en
ensamblador en el programa, el compilador no almacena los datos en un banco
actualmente activo de la RAM, lo que significa que en esta seccin de programa,
la seleccin de bancos depende del registro SFR utilizado. Al volver a la seccin
de programa escrito en C, los bits de control RP0 y RP1 deben recuperar el estado
que tenan antes de la aventura en ensamblador. En este programa, el problema
se resuelve al utilizar la variable auxiliar saveBank, lo que guarda el estado de
estos dos bits.

/* Cabecera *********************************************/

int k = 0;
char saveBank;

// Variable k es de tipo int


// Variable saveBank es de tipo char

void main() {
ANSEL = 0;

// Todos los pines de E/S se configuran como digitales

ANSELH = 0;
PORTB = 0;
TRISB = 0;

// Todos los pines del puerto PORTB se ponen a 0


// Pines del puerto PORTB se configuran como salidas

do {
PORTB = ~PORTB;
Delay_ms(100);
k++;

// Invertir el estado lgico del puerto PORTB


// Tiempo de retardo de 100mS
// Incrementar k en 1

}
while(k<20);

k=0;

// Quedarse en bucle hasta que k<20

// Reiniciar variable k

saveBank = STATUS & 0b01100000; // Guardar el estado de los bits RP0 y RP1

// (bits 5 y 6 del registro STATUS)


asm {

// Inicio de una secuencia en ensamblador

bsf STATUS,RP0

// Seleccionar el banco de memoria que contiene el

bcf STATUS,RP1

// registro OSCCON

bcf OSCCON,6

// Seleccionar el oscilador interno LFINTOSC

bcf OSCCON,5

// de frecuencia de 31KHz

bcf OSCCON,4
bsf OSCCON,0
}

// Microcontrolador utiliza oscilador interno


// Final de la secuencia en ensamblador

STATUS &= 0b10011111;

// Bits RP0 y RP1 recuperan el estado original

STATUS |= saveBank;

do {
PORTB = ~PORTB;
Delay_ms(10);
k++;

// Invertir el estado lgico del puerto PORTB


// Tiempo de retardo de 10 mS
// Incrementar k en 1

}
while(k<20);

// Quedarse en el bucle hasta que k<20

4.5 EJEMPLO 3
Timer0 como un contador, declarar variables nuevas, constantes de
enumeracin, utilizar rels...
En cuanto a los ejemplos anteriores, el microcontrolador ha ejecutado el programa
sin haber sido afectado de ninguna forma por su entorno. En la prctica, hay
pocos dispositivos que funcionen de esta manera (por ejemplo, un simple
controlador de luz de nen). Los pines de entrada se utilizan tambin en este
ejemplo. En la siguiente figura se muestra un esquema, mientras que el programa
est en la siguiente pgina. Todo sigue siendo muy simple. El temporizador
Timer0 se utiliza como un contador. La entrada del contador est conectada a un
botn de presin, as que cada vez que se presiona el botn, el temporizador
Timer0 cuenta un pulso.
Cuando el nmero de pulsos coincida con el nmero almacenado en el registro
TEST, un uno lgico (5V) aparecer en el pin PORTD.3. Este voltaje activa un rel
electromecnico, y por eso este bit se le denomina REL en el programa.

/*Cabecera****************************************************/

void main() {
char TEST = 5;

// Constante TEST = 5

enum salidas {REL = 3}; // Constante RELAY = 3

ANSEL = 0;

// Todos los pines de E/S se configuran como digitales

ANSELH = 0;
PORTA = 0;
TRISA = 0xFF;
entradas

// Reiniciar el puerto PORTA


// Todos los pines del puerto PORTA se configuran como

PORTD = 0;

// Reiniciar el puerto PORTD

TRISD = 0b11110111;

// Pin RD3 se configura como salida, mientras que los

dems

// se configuran como entradas


OPTION_REG.F5 = 1;

// Contador TMR0 recibe los pulsos por el pin RA4

OPTION_REG.F3 = 1;

// Valor del pre-escalador 1:1

TMR0 = 0;

// Reiniciar el temporizador/contador TMR0

do {
if (TMR0 == TEST)

// Coincide el nmero en el temporizador con la

// constante TEST?
(PORTD.RELAY = 1);

// Nmeros coinciden. Poner el bit RD3 a uno (salida

REL)
}
while (1);
}

// Quedarse en el bucle infinito

Slo una constante de enumeracin REL se utiliza en este ejemplo. Se le asigna


un valor mediante la declaracin.

enum salidas {REL = 3}; // Constante REL = 3

Si varios pines del puerto PORTD estn conectados a los rels, la expresin
anterior se puede escribir de la siguiente manera tambin:

enum salidas {REL=3, CALENTADOR, MOTOR=6, SURTIDOR};

A todas las constantes, precedidas por las constantes con valores asignados
(REL=3 y MOTOR=6), se les asignan automticamente los valores de las
constantes precedentes, incrementados en 1. En este ejemplo, a las constantes
CALENTADOR y SURTIDOR se les asignan los valores 4 y 7, es decir
(CALENTADOR=4 y SURTIDOR=7), respectivamente.
4.6 EJEMPLO 4
Utilizar

los

temporizadores

Timer0,

Timer1

Timer2.

Utilizar

interrupciones, declarar nuevas funciones...


Al analizar los ejemplos anteriores, es probable que se haya fijado en la
desventaja de proporcionar tiempo de retardo por medio de la funcin Delay. En
estos casos, el microcontrolador se queda esttico y no hace nada. Simplemente
espera que transcurra una cierta cantidad de tiempo. Tal prdida de tiempo es un
lujo inaceptable, por lo que se deber aplicar otro mtodo.
Se acuerda usted del captulo de los temporizadores? Se acuerda de lo de
interrupciones? Este ejemplo los conecta de una manera prctica. El esquema se
queda inalterada, y el desafo sigue siendo presente. Es necesario proporcionar un
tiempo de retardo suficiente largo para darse cuenta de los cambios en el puerto.
Para este propsito se utiliza el temporizador Timer0 con el pre-escalador

asignado. Siempre que se genere una interrupcin con cada desbordamiento en el


registro del temporizador, la variable cnt se aumenta automticamente en 1 al
ejecutarse cada rutina de interrupcin. Cuando la variable llega al valor 400, el
puerto PORTB se incrementa en 1. Todo el procedimiento se lleva a cabo entre
bastidores, lo que habilita al microcontrolador hacer otra tarea.

/*Cabecera******************************************************/

unsigned cnt;

// Definir la variable cnt

void interrupt() {
cnt++;

// Con una interrupcin la cnt se incrementa en 1

TMR0 = 96;

// El valor inicial se devuelve en el temporizador TMR0

INTCON = 0x20;

// Bit T0IE se pone a 1, el bit T0IF se pone a 0

void main(){
OPTION_REG = 0x84; // Pre-escalador se le asigna al temporizador TMR0
ANSEL = 0;

// Todos los pines de E/S se configuran como digitales

ANSELH = 0;
TRISB = 0;

// Todos los pines de puerto PORTB se configuran

// como salidas
PORTB = 0x0;

// Reiniciar el puerto PORTB

TMR0 = 96;

// Temporizador T0 cuenta de 96 a 255

INTCON = 0xA0;
cnt = 0;

do {

// Habilitada interrupcin TMR0

// A la variable cnt se le asigna un 0

// Bucle infinito

if (cnt == 400) { // Incrementar el puerto PORTB despus 400 interrupciones

PORTB = PORTB++; // Incrementar nmero en el puerto PORTB en 1


cnt = 0;

// Reiniciar la variable cnt

}
} while(1);

Siempre que se produzca un desbordamiento en el registro del temporizador


TRM0, ocurre una interrupcin.

/*Cabecera******************************************************/

unsigned short cnt; // Definir la variable cnt

void interrupt() {
cnt++ ;

// Con una interrupcin la cnt se incrementa en 1

PIR1.TMR1IF = 0;

// Reiniciar el bit TMR1IF

TMR1H = 0x80;

// El valor inicial se devuelve en los registros

TMR1L = 0x00;

// del temporizador TMR1H y TMR1L

void main() {
ANSEL = 0;

// Todos los pines de E/S se configuran como digitales

ANSELH = 0;
PORTB = 0xF0;

// Valor inicial de los bits del puerto PORTB

TRISB = 0;

// Pines del puerto PORTB se configuran como salidas

T1CON = 1;

// Configurar el temporizador TMR1

PIR1.TMR1IF = 0;

// Reiniciar el bit TMR1IF

TMR1H = 0x80;

// Ajustar el valor inicial del temporizador TMR1

TMR1L = 0x00;
PIE1.TMR1IE = 1;
cnt = 0;

// Reiniciar la variable cnt

INTCON = 0xC0;

do {

// Habilitar la interrupcin al producirse un desbordamiento

// Interrupcin habilitada (bits GIE y PEIE)

// Bucle infinito

if (cnt == 76) {

// Cambiar el estado del puerto PORTB despus de 76

interrupciones
PORTB = ~PORTB; // Nmero en el puerto PORTB est invertido
cnt = 0;

// Reiniciar la variable cnt

}
} while (1);
}

En este caso, una interrupcin se habilita despus de que se produzca un


desbordamiento en el registro del temporizador TMR1 (TMR1H, TMR1L). Adems,
la combinacin de los bits que vara en el puerto POTRB difiere de la en el ejemplo
anterior.

/*Cabecera******************************************************/

unsigned short cnt; // Definir la variable cnt

void Reemplazar() {

PORTB = ~PORTB;
}

// Definir nueva funcin Reemplazar

// Funcin invierte el estado del puerto

void interrupt() {
if (PIR1.TMR2IF) { // Si el bit TMR2IF = 1,
cnt++ ;

// Incrementar variable la cnt en 1

PIR1.TMR2IF = 0; // Reiniciar el bit y


TMR2 = 0;

// Reiniciar el registro TMR2

}
}

// main
void main() {
cnt = 0;
ANSEL = 0;

// Reiniciar la variable cnt


// Todos los pines de E/S se configuran como digitales

ANSELH = 0;
PORTB = 0b10101010; // Estado lgico en los pines del puerto PORTB

TRISB = 0;

// Todos los pines del puerto PORTB se configuran como

salidas
T2CON = 0xFF;

// Configurar el temporizador T2

TMR2 = 0;

// Valor inicial del registro del temporizador TMR2

PIE1.TMR2IE = 1;

// Interrupcin habilitada

INTCON = 0xC0;

// Bits GIE y PEIE se ponen a 1

while (1) {

// Bucle infinito

if (cnt > 30) { // Cambiar el estado del puerto PORTB despus de


// ms de 30 interrupciones
Reemplazar(); // Funcin Reemplazar invierte el estado del puerto PORTB
cnt = 0;
}
}
}

// Reiniciar la variable cnt

En este ejemplo, una interrupcin ocurre despus de que se produce un


desbordamiento en el registro del temporizador TMR2. Para invertir el estado
lgico de los pines del puerto se utiliza la funcin Reemplazar, que normalmente
no pertenece al lenguaje C estndar.
4.7 EJEMPLO 5
Utilizar el temporizador perro - guardin
Este ejemplo muestra cmo NO se debe utilizar el temporizador perro-guardin.
Un comando utilizado para reiniciar este temporizador se omite a propsito en el
bucle del programa principal, lo que habilita al temporizador perro guardin
ganar la batalla del tiempo y reiniciar al microcontrolador. Por consiguiente, el
microcontrolador se va a reiniciar sin parar, lo que indicar el parpadeo de los
LEDs del puerto PORTB.

/*Cabecera******************************************************/

unsigned int temp_res;

void main() {
ANSEL = 0x0C;
TRISA = 0xFF;

// Pines AN2 y AN3 se configuran como analgicos


// Todos los pines del puerto PORTA se configuran

// como entradas
ANSELH = 0;

// Los dems pines se configuran como digitales

TRISB = 0x3F;

// Pines del puerto PORTB, RB7 y RB6 se configuran

// como salidas
TRISD = 0;
ADCON1.F4 = 1 ;

// Todos los pines del PORTD se configuran como salidas


// Voltaje de referencia es llevado al pin RA3.

do {
temp_res = ADC_Read(2); // Resultado de la conversin A/D es copiado a
temp_res

PORTD = temp_res;

// 8 bits menos significativos se mueven al puerto

PORTD
PORTB = temp_res >> 2; // 2 bits ms significativos se mueven a los bits
RB6 y RB7
} while(1);

// Bucle infinito

Para que este ejemplo funcione apropiadamente, es necesario marcar la librera


ADC en la ventana Library Manager antes de compilar el programa:
ADC
4.10 EJEMPLO 8
Utilizar memoria EEPROM
Este ejemplo muestra cmo escribir y leer la memoria EEPROM incorporada. El
programa funciona de la siguiente manera. El bucle principal lee constantemente
el contenido de localidad de la memoria EEPROM en la direccin 5 (decimal).
Luego el programa entra en el bucle infinito en el que el puerto PORTB se
incrementa y se comprueba el estado de entradas del puerto PORTA.2. En el
momento de presionar el botn denominado MEMO, un nmero almacenado en el
puerto PORTB ser guardado en la memoria EEPROM, directamente ledo y
visualizado en el puerto PORTD en forma binaria.

/*Cabecera******************************************************/

void main() {{
ANSEL = 0;

// Todos los pines de E/S se configuran como digitales

ANSELH = 0;
PORTB = 0;
TRISB = 0;

// Valor inicial del puerto PORTB


// Todos los pines del puerto PORTB se configuran

// como salidas
PORTD = 0;
TRISD = 0;

// Valor inicial del puerto PORTB


// Todos los pines del puerto PORTD se configuran

// como salidas
TRISA = 0xFF;

// Todos los pines del puerto PORTA se configuran

// como entradas
PORTD = EEPROM_Read(5);

// Leer la memoria EEPROM en la direccin 5

do {
PORTB = PORTB++;
Delay_ms(100);

// Incrementar el puerto PORTB en 1


// Tiempo de retardo de 100mS

if (PORTA.F2)
EEPROM_Write(5,PORTB); // Si se pulsa el botn MEMO, guardar el puerto
PORTB

PORTD = EEPROM_Read(5); // Leer el dato escrito

do {
while (PORTA.F2);

// Quedarse en este bucle hasta que el botn est

pulsado
}
}
while(1);

// Bucle infinito

Para comprobar el funcionamiento de este circuito, basta con pulsar el botn


MEMO y apagar el dispositivo. Despus de reiniciar el dispositivo, el programa
visualizar el valor guardado en el puerto PORTD. Acurdese de que en el
momento de escribir, el valor fue visualizado en el puerto PORTB.
Para que este ejemplo funcione apropiadamente, es necesario marcar la librera
EEPROM en la ventana Library Manager antes de compilar el programa:
EEPROM

4.11 EJEMPLO 9
Contador de dos dgitos LED, multiplexin
En este ejemplo el microcontrolador funciona como un contador de dos dgitos. La
variable i se incrementa (suficiente lentamente para ser visible) y su valor se
visualiza en un visualizador de dos dgitos LED (99-0). El punto es habilitar una
conversin de un nmero binario en un decimal y partirlo en dos dgitos (en
decenas y unidades). Como los segmentos del visualizador LED se conectan en
paralelo, es necesario asegurar que alternen rpidamente para tener una
impresin de que emiten la luz simultneamente (multiplexin por divisin en
tiempo).
En este ejemplo, el temporizador TMR0 est encargado de la multiplexin por
divisin en tiempo, mientras que la funcin mask convierte un nmero binario a
formato decimal.

/*Cabecera******************************************************/

unsigned short mask(unsigned short num);


unsigned short digit_no, digit10, digit1, digit, i;

void interrupt() {
if (digit_no == 0) {
PORTA = 0;

// Apagar ambos visualizadores

PORTD = digit1; // Colocar mscara para visualizar unidades en el

// puerto PORTD
PORTA = 1;

// Encender el visualizador para las unidades (LSD)

digit_no = 1;
}else{
PORTA = 0;

// Apagar ambos visualizadores

PORTD = digit10; // Colocar mscara para visualizar decenas en el

// puerto PORTD
PORTA = 2;

// Encender el visualizador para las decenas (MSD)

digit_no = 0;
}

TMR0 = 0;
INTCON = 0x20;

// Reiniciar el contador TMRO


// Bit T0IF=0, T0IE=1

void main() {
OPTION_REG = 0x80; // Ajustar el temporizador TMR0
TMR0 = 0;
INTCON = 0xA0;

// Deshabilitar las interrupciones PEIE,INTE,RBIE,T0IE

PORTA = 0;

// Apagar ambos visualizadores

TRISA = 0;

// Todos los pines del puerto PORTA se configuran

// como salidas
PORTD = 0;
TRISD = 0;

// Apagar todos los segmentos del visualizador


// Todos los pines del puerto PORTD se configuran

// como salidas
do {
for (i = 0; i<=99; i++) { // Contar de 0 a 99
digit = i % 10u;
digit1 = mask(digit); // Preparar la mscara para visualizar unidades
digit = (char)(i / 10u) % 10u;
digit10 = mask(digit); // Preparar la mscara para visualizar decenas
Delay_ms(1000);
}
} while (1);

// Bucle infinito

mask.c

/*Cabecera******************************************************/

unsigned short mask(unsigned short num) {


switch (num) {
case 0 : return 0x3F;

case 1 : return 0x06;


case 2 : return 0x5B;
case 3 : return 0x4F;
case 4 : return 0x66;
case 5 : return 0x6D;
case 6 : return 0x7D;
case 7 : return 0x07;
case 8 : return 0x7F;
case 9 : return 0x6F;
}
}

Para que este ejemplo funcione apropiadamente, es necesario incluir el archivo


mask.c en el proyecto (aparte del archivo example9.c) en la ventana Project
Manager antes de compilar el programa:
Example9.mcppi - Sources - Add File To Project
mask.c
example9.c
4.12 EJEMPLO 10
Utilizar el visualizador LCD

Este ejemplo muestra cmo utilizar un visualizador LCD alfanumrico. Las libreras
de funciones simplifican este programa, lo que significa que al final el esfuerzo
para crear el software vale la pena.
Un mensaje escrito en dos lneas aparece en el visualizador:
mikroElektronika
LCD example
Dos segundos ms tarde, el mensaje en la segunda lnea cambia, y se visualiza el
voltaje presente en la entrada del convertidor A/D (el pin RA2). Por ejemplo:
mikroElektronika
voltage:3.141V
En un dispositivo real se puede visualizar temperatura actual o algn otro valor
medido en vez de voltaje.

Para que este ejemplo funcione apropiadamente, es necesario marcar las


siguientes libreras en la ventana Library Manager antes de compilar el programa:
ADC
LCD

/*Cabecera*****************************************************/

// Conexiones del mdulo LCD


sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;

sbit LCD_D7_Direction at TRISB3_bit;


// Final de las conexiones del mdulo LCD

// Declarar variables
unsigned char ch;
unsigned int adc_rd;
char *text;
long tlong;

void main() {
INTCON = 0;

// Todas las interrupciones deshabilitadas

ANSEL = 0x04;

// Pin RA2 se configura como una entrada analgica

TRISA = 0x04;
ANSELH = 0;

Lcd_Init();

// Los dems pines se configuran como digitales

// Inicializacin del visualizador LCD

Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_Cmd(_LCD_CLEAR);

// Comando LCD (apagar el cursor)


// Comando LCD (borrar el LCD)

text = "mikroElektronika";
Lcd_Out(1,1,text);

text = "LCD example";


Lcd_Out(2,1,text);

ADCON1 = 0x82;

// Definir el primer mensaje


// Escribir el primer mensaje en la primera lnea

// Definir el segundo mensaje


// Definir el primer mensaje

// Voltaje de referencia para la conversin A/D es

VCC
TRISA = 0xFF;

// Todos los pines del puerto PORTA se configuran

como entradas
Delay_ms(2000);

text = "voltage:";

// Definir el tercer mensaje

while (1) {
adc_rd = ADC_Read(2);
Lcd_Out(2,1,text);

// Conversin A/D. Pin RA2 es una entrada.


// Escribir el resultado en la segunda lnea

tlong = (long)adc_rd * 5000; // Convertir el resultado en milivoltios

tlong = tlong / 1023;


ch = tlong / 1000;

// 0..1023 -> 0-5000mV


// Extraer voltios (miles de milivoltios)

// del resultado
Lcd_Chr(2,9,48+ch);

// Escribir resultado en formato ASCII

Lcd_Chr_CP('.');
ch = (tlong / 100) % 10;

// Extraer centenas de milivoltios

Lcd_Chr_CP(48+ch);

// Escribir resultado en formato ASCII

ch = (tlong / 10) % 10;


Lcd_Chr_CP(48+ch);
ch = tlong % 10;
Lcd_Chr_CP(48+ch);

// Extraer decenas de milivoltios


// Escribir resultado en formato ASCII
// Extraer unidades de milivoltios
// Escribir resultado en formato ASCII

Lcd_Chr_CP('V');
Delay_ms(1);
}
}

4.13 EJEMPLO 11
Comunicacin serial RS-232

Este ejemplo muestra cmo utilizar el mdulo EUSART del microcontrolador. La


conexin a una PC se habilita por medio del estndar de comunicacin RS-232. El
programa funciona de la siguiente manera. Cada byte recibido por medio de la
comunicacin serial se visualiza al utilizar los LEDs conectados al puerto PORTB y
despus se devuelve automticamente al transmisor. Si ocurre un error en
recepcin, se lo indicar al encender el diodo LED. La manera ms fcil es
comprobar el funcionamiento del dispositivo en la prctica al utilizar un programa
estndar de Windows denominado Hyper Terminal.

/*Cabecera******************************************************/

unsigned short i;

void main() {
UART1_Init(19200); // Inicializar el mdulo USART
// (8 bits, tasa de baudios 19200, no hay bit
// de paridad...)

while (1) {
if (UART1_Data_Ready()) { // si se ha recibido un dato
i = UART1_Read(); // leerlo
UART1_Write(i); // enviarlo atrs
}
}
}

Para que este ejemplo funcione apropiadamente, es necesario marcar la librera


UART en la ventana Library Manager antes de compilar el programa:
UART
4.14 EJEMPLO 12
Medicin de temperatura por medio del sensor DS1820. Uso del
protocolo 1-wire...

La medicin de temperatura es una de las tareas ms frecuentes realizadas por el


microcontrolador. En este ejemplo, se utiliza un sensor DS1820 para medir. Es
capaz de medir en el rango de 55 C a 125 C con exactitud de 0.5 C. Para
transmitir los datos al microcontrolador se utiliza un tipo especial de la
comunicacin serial denominado 1-wire. Debido al hecho de que estos sensores
son simples de utilizar y de grandes capacidades, los comandos utilizados para
hacerlos funcionar y controlarlos tienen la forma de funciones almacenadas en la
librera One_Wire. En total son las siguientes tres funciones:
Ow_Reset se utiliza para reiniciar el sensor;
Ow_Read se utiliza para recibir los datos del sensor; y
Ow_Write se utiliza para enviar los comandos al sensor

Este ejemplo muestra la ventaja de utilizar libreras con las funciones listas para
ser utilizadas. Concretamente, no tiene que examinar la documentacin
proporcionada por el fabricante para utilizar el sensor. Basta con copiar alguna de

estas funciones en el programa. Si le interesa saber cmo se declaran, basta con


pulsar sobre alguna de ellas y seleccione la opcin Help.

/*Cabecera******************************************************/

// Conexiones del mdulo LCD


sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// Final de conexiones del mdulo LCD

const unsigned short TEMP_RESOLUTION = 9;


char *text = "000.0000";
unsigned temp;

void Display_Temperature(unsigned int temp2write) {


const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
char temp_whole;
unsigned int temp_fraction;

// comprobar si la temperatura es negativa


if (temp2write & 0x8000) {
text[0] = '-';
temp2write = ~temp2write + 1;
}

// extraer temp_whole
temp_whole = temp2write >> RES_SHIFT ;

// convertir temp_whole en caracteres


if (temp_whole/100)
text[0] = temp_whole/100 + 48;
else
text[0] = '0';

text[1] = (temp_whole/10)%10 + 48;


text[2] = temp_whole%10 + 48;

// Extraer dgito de decenas


// Extraer dgito de unidades

// extraer temp_fraction y convertirlo en unsigned int


temp_fraction = temp2write << (4-RES_SHIFT);
temp_fraction &= 0x000F;
temp_fraction *= 625;

// convertir temp_fraction en caracteres


text[4] = temp_fraction/1000 + 48;

// Extraer dgito de miles

text[5] = (temp_fraction/100)%10 + 48; // Extraer dgito de centenas

text[6] = (temp_fraction/10)%10 + 48; // Extraer dgito de decenas


text[7] = temp_fraction%10 + 48;

// Extraer dgito de unidades

// Visualizar temperatura en el LCD


Lcd_Out(2, 5, text);
}

void main() {
ANSEL = 0;

// Configurar los pines AN como digitales

ANSELH = 0;
C1ON_bit = 0;

// Deshabilitar los comparadores

C2ON_bit = 0;

Lcd_Init();

// Inicializar el LCD

Lcd_Cmd(_LCD_CLEAR);

// Borrar el LCD

Lcd_Cmd(_LCD_CURSOR_OFF); // Apagar el cursor


Lcd_Out(1, 1, " Temperatura: ");

// Visualizar el carcter de grado, 'C' para centgrados


Lcd_Chr(2,13,223); // distintos visualizadores LCD tienen diferentes cdigos

// de caracteres para el grado


// si ve la letra griega Alfa, intente introducir 178 en vez de 223
Lcd_Chr(2,14,'C');

//--- bucle principal


do {
//--- realizar lectura de temperatura
Ow_Reset(&PORTE, 2);

// Seal de reinicio de Onewire

Ow_Write(&PORTE, 2, 0xCC); // Ejecutar el comando SKIP_ROM


Ow_Write(&PORTE, 2, 0x44); // Ejecutar el comando CONVERT_T
Delay_us(120);
Ow_Reset(&PORTE, 2);
Ow_Write(&PORTE, 2, 0xCC); // Ejecutar el comando SKIP_ROM
Ow_Write(&PORTE, 2, 0xBE); // Ejecutar el comando READ_SCRATCHPAD
temp = Ow_Read(&PORTE, 2);

temp = (Ow_Read(&PORTE, 2) << 8) + temp;

//--- Formatear y visualizar el resultado en el LCD


Display_Temperature(temp);
Delay_ms(500);
} while (1);
}

Para que este ejemplo funcione apropiadamente, es necesario marcar las


siguientes libreras en la ventana Library Manager antes de compilar el programa:
One_Wire
LCD
4.15 EXAMPLE 13
Generacin de sonido, librera de sonido...
Las seales de audio se utilizan con frecuencia cuando se necesita llamar la
atencin de usuario, confirmar que alguno de los botones se ha pulsado, avisar
que se ha llegado hasta los valores mnimos o mximos etc. Pueden ser una
simple seal de pitido as como melodas de una duracin ms larga o ms corta.
En este ejemplo se muestra la generacin de sonido por medio de funciones que
pertenecen a la librera Sound.

Adems de estas funciones, la funcin Button que pertenece a la misma librera


se utiliza para probar los botones de presin.

/*Cabecera******************************************************/

void Tone1() {
Sound_Play(659, 250); // Frecuencia = 659Hz, duracin = 250ms
}

void Tone2() {
Sound_Play(698, 250); // Frecuencia = 698Hz, duracin = 250ms
}

void Tone3() {
Sound_Play(784, 250); // Frecuencia = 784Hz, duracin = 250ms
}

void Melody1() { // Componer una meloda divertida 1


Tone1(); Tone2(); Tone3(); Tone3();
Tone1(); Tone2(); Tone3(); Tone3();
Tone1(); Tone2(); Tone3();
Tone1(); Tone2(); Tone3(); Tone3();
Tone1(); Tone2(); Tone3();
Tone3(); Tone3(); Tone2(); Tone2(); Tone1();
}

void ToneA() { // Tono A

Sound_Play( 880, 50);


}

void ToneC() { // Tono C


Sound_Play(1046, 50);
}

void ToneE() { // Tono E


Sound_Play(1318, 50);
}

void Melody2() { // Componer una meloda divertida 2


unsigned short i;

for (i = 9; i > 0; i--) {


ToneA(); ToneC(); ToneE();
}
}

void main() {
ANSEL = 0;

// Todos los pines de E/S son digitales

ANSELH = 0;
TRISB = 0xF0;

// Pines RB7-RB4 se configuran como entradas

// RB3 se configura como salida


Sound_Init(&PORTB, 3);
Sound_Play(1000, 500);

while (1) {
if (Button(&PORTB,7,1,1)) // RB7 genera Tono1
Tone1();
while (PORTB & 0x80) ;

// Esperar que se suelte el botn

if (Button(&PORTB,6,1,1)) // RB6 genera Tono2


Tone2();
while (PORTB & 0x40) ;

// Esperar que se suelte el botn

if (Button(&PORTB,5,1,1)) // RB5 genera meloda 2

Melody2();
while (PORTB & 0x20) ;

// Esperar que se suelte el botn

if (Button(&PORTB,4,1,1)) // RB4 genera meloda 1


Melody1();
while (PORTB & 0x10) ;

// Esperar que se suelte el botn

}
}

Para que este ejemplo funcione apropiadamente, es necesario marcar las


siguientes libreras en la ventana Library Manager antes de compilar el programa:
Button
Sound
4.16 EJEMPLO 14
Utilizar el visualizador LCD grfico
Un LCD grfico (GLCD) proporciona un mtodo avanzado para visualizar
mensajes. Mientras que un LCD de caracteres puede visualizar slo caracteres
alfanumricos, el LCD grfico puede visualizar los mensajes en forma de dibujos y
mapas de bits. El LCD grfico utilizado con ms frecuencia tiene una resolucin de
pantalla de 128x64 pxeles. El contraste de un GLCD se puede ajustar por medio
del potencimetro P1.

En este ejemplo el GLCD visualiza una secuencia de imgenes, de las que un


mapa de bits representa un camin almacenado en otro archivo denominado
truck_bmp.c. Para habilitar que este programa funcione apropiadamente, usted
debe aadir este archivo como archivo fuente a su proyecto.
Las directivas del preprocesador incluidas en este ejemplo le permiten elegir si
quiere visualizar toda la secuencia de imgenes o slo una secuencia corta. Por
defecto se visualizar toda la secuencia de imgenes. Sin embargo, al aadir un
comentario delante de la directiva #define COMPLETE_EXAMPLE se deshabilita
visualizar algunas imgenes de la secuencia. Si se comenta (o si se borra) esta
directiva, las sentencias entre las directivas #ifdef COMPLETE_EXAMPLE y #endif
no sern compiladas, as que no se ejecutarn.

/*Cabecera******************************************************/

//Declaraciones----------------------------------------------------------------const code char truck_bmp[1024]; // Declarar la constante definida en


truck_bmp.c
// para utilizarla en este archivo
//--------------------------------------------------------final-de-declaraciones

// Conexiones del mdulo Glcd


char GLCD_DataPort at PORTD;
sbit GLCD_CS1 at RB0_bit;
sbit GLCD_CS2 at RB1_bit;
sbit GLCD_RS at RB2_bit;
sbit GLCD_RW at RB3_bit;
sbit GLCD_EN at RB4_bit;
sbit GLCD_RST at RB5_bit;
sbit GLCD_CS1_Direction at TRISB0_bit;
sbit GLCD_CS2_Direction at TRISB1_bit;
sbit GLCD_RS_Direction at TRISB2_bit;
sbit GLCD_RW_Direction at TRISB3_bit;

sbit GLCD_EN_Direction at TRISB4_bit;


sbit GLCD_RST_Direction at TRISB5_bit;
// Final de conexiones del mdulo Glcd

void delay2S(){

// Funcin de tiempo de retardo de 2 segundos

Delay_ms(2000);
}

void main() {
unsigned short ii;
char *someText;

/* Esta directiva define un macro denominado COMPLETE_EXAMPLE. Ms tarde


en el
programa, la directiva ifdef prueba si este macro est definido. Si se borra esta
lnea o si se transforma en un comentario, las secciones del cdigo entre las
directivas ifdef y endif no sern compiladas. */

#define COMPLETE_EXAMPLE // Poner esta lnea como un comentario si quiere


// visualizar la versin corta de la secuencia

ANSEL = 0;

// Configurar los pines AN como digitales

ANSELH = 0;
C1ON_bit = 0;

// Deshabilitar comparadores

C2ON_bit = 0;
Glcd_Init();

// Inicializar el GLCD

Glcd_Fill(0x00); // Borrar el GLCD

while(1) {

// bucle infinito, la secuencia se repite

/* Dibujar la primera imagen */


#ifdef COMPLETE_EXAMPLE
Glcd_Image(truck_bmp);

// Dibujar la imagen

delay2S(); delay2S();
#endif
Glcd_Fill(0x00);

// Borrar el GLCD

/* Dibujar la segunda imagen */


Glcd_Box(62,40,124,56,1);

// Dibujar la caja

Glcd_Rectangle(5,5,84,35,1); // Dibujar el rectngulo


Glcd_Line(0, 0, 127, 63, 1); // Dibujar la lnea

delay2S();

for(ii = 5; ii < 60; ii+=5 ){ // Dibujar lneas horizontales y verticales


Delay_ms(250);
Glcd_V_Line(2, 54, ii, 1);
Glcd_H_Line(2, 120, ii, 1);
}

delay2S();
Glcd_Fill(0x00); // Borrar el GLCD

/* Dibujar la tercera imagen */

#ifdef COMPLETE_EXAMPLE
Glcd_Set_Font(Character8x7, 8, 7, 32); // Seleccionar la fuente, ver
// __Lib_GLCDFonts.c en la carpeta Uses
#endif

Glcd_Write_Text("mikroE", 1, 7, 2);
for (ii = 1; ii <= 10; ii++)

// Escribir la cadena
// Dibujar los crculos

Glcd_Circle(63,32, 3*ii, 1);


delay2S();

Glcd_Box(12,20, 70,57, 2);

// Dibujar la caja

delay2S();

/* Dibujar la cuarta imagen */


#ifdef COMPLETE_EXAMPLE
Glcd_Fill(0xFF); // Llenar el GLCD
Glcd_Set_Font(Character8x7, 8, 7, 32);

// Cambiar de la fuente

someText = "8x7 Font";


Glcd_Write_Text(someText, 5, 0, 2);

// Escribir la cadena

delay2S();
Glcd_Set_Font(System3x5, 3, 5, 32);

// Cambiar de la fuente

someText = "3X5 CAPITALS ONLY";


Glcd_Write_Text(someText, 60, 2, 2);

// Escribir la cadena

delay2S();
Glcd_Set_Font(font5x7, 5, 7, 32);

// Cambiar de la fuente

someText = "5x7 Font";


Glcd_Write_Text(someText, 5, 4, 2);

// Escribir la cadena

delay2S();
Glcd_Set_Font(FontSystem5x7_v2, 5, 7, 32); // Cambiar de la fuente
someText = "5x7 Font (v2)";
Glcd_Write_Text(someText, 5, 6, 2);
delay2S();
#endif
}
}

// Escribir la cadena

truck_bmp.c:

/*Cabecera*****************************************************/

unsigned char const truck_bmp[1024] = {


0, 0, 0, 0, 0,248, 8, 8, 8, 8, 8, 8, 12, 12, 12, 12,
12, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9,137,137,137,137,137,137,
137,137,137,137,137,137,137, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 13,253, 13,195, 6,252, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
240,240,240,240,240,224,224,240,240,240,240,240,224,192,192,224,
240,240,240,240,240,224,192, 0, 0, 0,255,255,255,255,255,195,
195,195,195,195,195,195, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0,255,240, 79,224,255, 96, 96, 96, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 64, 64, 64, 64,128, 0, 0, 0,

0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
255,255,255,255,255, 0, 0, 0, 0,255,255,255,255,255, 0, 0,
0, 0,255,255,255,255,255, 0, 0, 0,255,255,255,255,255,129,
129,129,129,129,129,129,128, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0,255, 1,248, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 8, 16,224, 24, 36,196, 70,130,130,133,217,102,112,
160,192, 96, 96, 32, 32,160,160,224,224,192, 64, 64,128,128,192,
64,128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 63, 96, 96, 96,224, 96, 96, 96, 96, 96, 96,
99, 99, 99, 99, 99, 96, 96, 96, 96, 99, 99, 99, 99, 99, 96, 96,
96, 96, 99, 99, 99, 99, 99, 96, 96, 96, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 96, 96, 96, 96, 96, 96, 96, 64, 64,
64,224,224,255,246, 1, 14, 6, 6, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2,130, 67,114, 62, 35, 16, 16, 0, 7, 3, 3, 2,
4, 4, 4, 4, 4, 4, 4, 28, 16, 16, 16, 17, 17, 9, 9, 41,
112, 32, 67, 5,240,126,174,128, 56, 0, 0, 0, 0, 0, 0, 0,

0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
1, 1,127,127,127,127,255,255,247,251,123,191, 95, 93,125,189,
189, 63, 93, 89,177,115,243,229,207, 27, 63,119,255,207,191,255,
255,255,255,255,255,255,255,127,127,127,127,127,127,127,127,255,
255,255,127,127,125,120,120,120,120,120,248,120,120,120,120,120,
120,248,248,232,143, 0, 0, 0, 0, 0, 0, 0, 0,128,240,248,
120,188,220, 92,252, 28, 28, 60, 92, 92, 60,120,248,248, 96,192,
143,168,216,136, 49, 68, 72, 50,160, 96, 0, 0, 0, 0, 0, 0,
0, 0, 0,128,192,248,248,248,248,252,254,254,254,254,254,254,
254,254,254,254,254,255,255,255,255,255,246,239,208,246,174,173,
169,128,209,208,224,247,249,255,255,252,220,240,127,255,223,255,
255,255,255,255,255,254,254,255,255,255,255,255,255,255,254,255,
255,255,255,255,255,255,254,254,254,254,254,254,254,254,254,254,
254,254,254,254,255,255,255,255,255,255,254,255,190,255,255,253,
240,239,221,223,254,168,136,170,196,208,228,230,248,127,126,156,
223,226,242,242,242,242,242,177, 32, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 1, 1, 3, 3, 3, 7, 7, 7, 7, 7, 15,
15, 15, 7, 15, 15, 15, 7, 7, 15, 14, 15, 13, 15, 47, 43, 43,

43, 43, 43, 47,111,239,255,253,253,255,254,255,255,255,255,255,


191,191,239,239,239,191,255,191,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,127,127,127,127,255,255,191,191,191,191,255,254,
255,253,255,255,255,251,255,255,255,127,125, 63, 31, 31, 31, 31,
31, 31, 63, 15, 15, 7, 7, 3, 3, 3, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
1, 1, 1, 1, 3, 3, 3, 11, 11, 11, 11, 7, 3, 14, 6, 6,
6, 2, 18, 19, 19, 3, 23, 21, 21, 17, 1, 19, 19, 3, 6, 6,
14, 15, 15, 7, 15, 15, 15, 11, 2, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

Para que este ejemplo funcione apropiadamente, es necesario marcar la librera


GLCD en la ventana Library Manager antes de compilar el programa. Asimismo, es
necesario incluir el documento truck_bmp.c en el proyecto.

4.17 EJEMPLO 15
Utilizar el panel tctil...
Un panel tctil es un panel fino, autoadhesivo y transparente, colocado sobre la
pantalla de un LCD grfico. Es muy sensible a la presin as que un suave toque
provoca algunos cambios en la seal de salida. Hay diferentes tipos de paneles
tctiles. El ms sencillo es el panel tctil resistivo del que se hablar aqu.

Un panel tctil est compuesto por dos lminas rgidas, formando una estructura
de sndwich que tiene capas resistivas en sus caras internas. La resistencia de
estas capas no excede normalmente de 1Kohm. Los lados opuestos de las lminas
disponen de los contactos para acceder a un cable plano.

El procedimiento para determinar las coordenadas de la posicin del panel que ha


sido presionado se puede dividir en dos pasos. El primero es determinacin de la
coordenada X, y el segundo es de determinar la coordenada Y de la posicin.
Para determinar la coordenada X, es necesario conectar el contacto izquierdo en
la superficie A a la masa (tierra) y el contacto derecho a la fuente de
alimentacin. Esto permite obtener un divisor de voltaje al presionar el panel
tctil. El valor de voltaje obtenido en el divisor se puede leer en el contacto
inferior de la superficie B. El voltaje variar en el rango de 0V al voltaje
suministrado por la fuente de alimentacin y depende de la coordenada X. Si el
punto est prximo al contacto izquierdo de la superficie A, el voltaje estar
prximo a 0V.

Para la determinacin de la coordenada Y, es necesario conectar el contacto


inferior de la superficie B a masa (tierra), mientras que el contacto superior se
conectar a la fuente de alimentacin. En este caso, el voltaje se puede leer en el
contacto izquierdo de la superficie A .
Para conectar un panel tctil al microcontrolador es necesario crear un circuito
para el control del panel tctil. Por medio de este circuito, el microcontrolador
conecta los contactos adecuados del panel tctil a masa y a la voltaje de
alimentacin (como describimos anteriormente) para determinar las coordenadas
X y Y. El contacto inferior de la superficie B y el contacto izquierdo de la superficie
A estn conectados al convertidor A/D del microcontrolador. Las coordenadas X e
Y se determinan midiendo el voltaje en los respectivos contactos. El software
consiste en mostrar un men en una pantalla LCD grfica, conmutar de encendido

a apagado del panel tctil (control del panel tctil) y leer los valores del
convertidor A/D que representan realmente las coordenadas X e Y de la posicin.
Una vez determinadas las coordenadas, es posible decidir qu es lo que
deseamos que haga el microcontrolador. En este ejemplo se explica cmo
conmutar entre encendido y apagado dos pines digitales del microcontrolador,
conectados a los LEDs A y B.
En este ejemplo se utilizan las funciones que pertenecen a las libreras Glcd y
ADC.
Teniendo en cuenta que la superficie del panel tctil es ligeramente mayor que la
del LCD grfico, en caso de requerir una mayor precisin en la determinacin de
las coordenadas, es necesario incluir el software de calibracin del panel tctil.

/* Cabecera ***************************************************/

// Conexiones del mdulo Glcd


char GLCD_DataPort at PORTD;
sbit GLCD_CS1 at RB0_bit;
sbit GLCD_CS2 at RB1_bit;
sbit GLCD_RS at RB2_bit;
sbit GLCD_RW at RB3_bit;
sbit GLCD_EN at RB4_bit;
sbit GLCD_RST at RB5_bit;

sbit GLCD_CS1_Direction at TRISB0_bit;


sbit GLCD_CS2_Direction at TRISB1_bit;
sbit GLCD_RS_Direction at TRISB2_bit;
sbit GLCD_RW_Direction at TRISB3_bit;
sbit GLCD_EN_Direction at TRISB4_bit;
sbit GLCD_RST_Direction at TRISB5_bit;
// Final de conexiones del mdulo Glcd

// Declaracin de la cadena a visualizar en el GLCD


char msg1[] = "TOUCHPANEL EXAMPLE";
char msg2[] = "MIKROELEKTRONIKA";
char msg3[] = "BUTTON1";
char msg4[] = "BUTTON2";
char msg5[] = "RC6 OFF";
char msg6[] = "RC7 OFF";
char msg7[] = "RC6 ON ";
char msg8[] = "RC7 ON ";

// Declaracin de variables globales


long x_coord, y_coord, x_coord128, y_coord64; // almacenar la posicin de las
// coordenadas x e y

// Leer la coordenada X
unsigned int GetX() {
//reading X
PORTC.F0 = 1;

// DRIVEA = 1 (electrodo izquierdo (LEFT) conectado,

electrodo
// derecho (RIGHT) conectado, electrodo superior
(TOP)desconectado)
PORTC.F1 = 0;

// DRIVEB = 0 (electrodo inferior (BOTTOM) desconectado)

Delay_ms(5);
return ADC_Read(0); // leer el valor de X de RA0(BOTTOM)
}

// Leer la coordenada Y
unsigned int GetY() {

//Leer la Y
PORTC.F0 = 0;

// DRIVEA = 0 (electrodo izquierdo (LEFT) desconectado,

electrodo
// derecho (RIGHT) desconectado, electrodo superior (TOP)
conectado)
PORTC.F1 = 1;

// DRIVEB = 1 (electrodo inferior (BOTTOM) conectado)

Delay_ms(5);
return ADC_Read(1); // leer el valor de Y de RA1 (del elctrodo izquierdo LEFT)
}

void main() {
PORTA = 0x00;
TRISA = 0x03; // RA0 y RA1 son entradas analgicas
ANSEL = 0x03;
ANSELH = 0; // Configurar otros pines AN como digitales de E/S
PORTC = 0 ; // Todos los pines del puerto PORTC estn a 0 (incluyendo los
// pines RC6 y RC7)

TRISC = 0 ; // PORTC es una salida

// Inicializacin del GLCD


Glcd_Init();

// Glcd_Init_EP5

Glcd_Set_Font(FontSystem5x7_v2, 5, 7, 32); // Seleccionar el tamao de fuente


5x7
Glcd_Fill(0);

// Borrar GLCD

Glcd_Write_Text(msg1,10,0,1);
Glcd_Write_Text(msg2,17,7,1);

// Visualizar botones en el GLCD:


Glcd_Rectangle(8,16,60,48,1);
Glcd_Rectangle(68,16,120,48,1);
Glcd_Box(10,18,58,46,1);
Glcd_Box(70,18,118,46,1);

// Visualizar los mensajes en los botones


Glcd_Write_Text(msg3,14,3,0);

Glcd_Write_Text(msg5,14,4,0);
Glcd_Write_Text(msg4,74,3,0);
Glcd_Write_Text(msg6,74,4,0);

while (1) {
// leer X-Y y convertirlo en la resolucin de 128x64 pxeles
x_coord = GetX();
y_coord = GetY();
x_coord128 = (x_coord * 128) / 1024;
y_coord64 = 64 -((y_coord *64) / 1024);

//Si BUTTON1 ha sido presionado


if ((x_coord128 >= 10) && (x_coord128 <= 58) && (y_coord64 >= 18) &&
(y_coord64 <= 46)) {
if(PORTC.F6 == 0) {
PORTC.F6 = 1;

// Si RC6 = 0
// Invertir el estado lgico del pin RC6

Glcd_Write_Text(msg7,14,4,0); // Visualizar un nuevo mensaje: RC6 ON


}

else { // Si RC6 = 1
PORTC.F6 = 0;

// Invertir el estado lgico del pin RC6

Glcd_Write_Text(msg5,14,4,0); // Visualizar un nuevo mensaje: RC6 OFF


}
}

// Si BUTTON2 ha sido presionado


if ((x_coord128 >= 70) && (x_coord128 <= 118) && (y_coord64 >= 18) &&
(y_coord64 <= 46)) {
if(PORTC.F7 == 0) { // Si RC7 = 0
PORTC.F7 = 1;

// Invertir el estado lgico del pin RC7

Glcd_Write_Text(msg8,74,4,0); // Visualizar un nuevo mensaje: RC7 ON


}
else { // Si RC7 = 1
PORTC.F7 = 0;

// Invertir el estado lgico del pin RC7

Glcd_Write_Text(msg6,74,4,0); // Visualizar un nuevo mensaje: RC7 OFF


}
}

Delay_ms(100);
}
}

Para que este ejemplo funcione apropiadamente, es necesario marcar las


siguientes libreras en la ventana Library Manager antes de compilar el programa.
GLCD
ADC
C_Stdlib
Apndice A: Es hora de divertirse
Un microcontrolador se parece a un genio en la botella, y no se necesita saber
mucho

para

utilizarlo.

Para

crear

un

dispositivo

controlado

por

un

microcontrolador, se necesita una PC, programa para compilar y un dispositivo


para transmitir el cdigo de la PC al chip mismo. Aunque este proceso parece
muy lgico, con frecuencia surgen las dudas, no por que es complicado, sino por
un gran nmero de variaciones. A ver...
A.1 VAMOS A EMPEZAR...
A.2 COMPILACIN DE PROGRAMA
A.3 PROGRAMAR EL MICROCONTROLADOR
A.4 SISTEMAS DE DESARROLLO
VAMOS A EMPEZAR...

Los programas especiales en el entorno de Windows se utilizan para escribir un


programa para el microcontrolador. Este libro describe el programa denominado
mikroC PRO for PIC. La ventaja principal de este programa son las herramientas
adicionales instaladas para facilitar el proceso de desarrollo.
Si tiene experiencia en escribir programas, entonces sabe que se trata de escribir
todas las instrucciones en el orden en el que se deben ejecutar por el
microcontrolador y observar las reglas del lenguaje C. En otras palabras, slo
tiene que seguir su idea al escribir el programa. Esto es todo!

A.2 COMPILACIN DE PROGRAMA

El microcontrolador no entiende los lenguajes de alto nivel de programacin, de


ah que sea necesario compilar el programa en lenguaje mquina. Basta con
pulsar slo una vez sobre el icono apropiado dentro del compilador para crear un
documento nuevo con extensin .hex. En realidad, es el mismo programa, pero
compilado en lenguaje mquina que el microcontrolador entiende perfectamente.
Este programa se le denomina con frecuencia un cdigo hex y forma una
secuencia de nmeros hexadecimales aparentemente sin significado.

Una vez compilado, el programa se debe cargar en el chip. Usted necesita un


hardware apropiado para hacerlo posible - un programador.
PROGRAMAR EL MICROCONTROLADOR
Como

hemos

mencionado,

para

habilitar

cargar

un

cdigo

hex

en

el

microcontrolador es necesario proporcionar un dispositivo especial, denominado


el programador, con software apropiado. Un gran nmero de programas y
circuitos electrnicos utilizados con este propsito se pueden encontrar en

Internet. El procedimiento es bsicamente el mismo para todos ellos y se parece a


lo siguiente:
1. Coloque el microcontrolador en el zcalo apropiado del programador;
2. Utilice un cable adecuado para conectar el programador a una PC;
3. Abra el programa en cdigo hex dentro de software del programador, ajuste
varios parmetros, y pulse sobre el icono para transmitir el cdigo. Pocos
segundos despus, una secuencia de ceros y unos se va a programar en el
microcontrolador.
Slo ha quedado instalar el chip programado en el dispositivo destino. Si es
necesario hacer algunos cambios en el programa, el procedimiento anterior se
puede repetir un nmero ilimitado de veces.
A.3 SER UN FINAL FELIZ?
Esta seccin describe en breve el uso del programa (compilador) mikroC PRO for
PIC y del software de programacin (programador) PICflash. Todo es muy simple...
Usted ya tiene instalado el mikroC PRO for PIC, verdad? Al iniciarlo, abra un
proyecto nuevo y un documento nuevo con extensin .c dentro del mismo. Escriba
su programa...

OK. The program has been written and tested with the simulator. It did not report
any errors during the process of compiling into the hex code? It seems that
everything is under control...
De acuerdo. El programa ha sido escrito y probado con el simulador. No ha
informado de ningn error durante el proceso de compilacin en el cdigo hex?
Parece que todo funciona perfecto...
El

programa

ha

sido

compilado

con

xito.

Slo

queda

cargarlo

en

el

microcontrolador. Ahora necesita un programador que est compuesto por


software y hardware. Inicie el programa PICFlash.

La configuracin es simple y no hacen falta explicaciones adicionales (tipo de


microcontrolador, frecuencia y reloj del oscilador etc.).
Conecte la PC con el hardware del programador por un cable USB;
Cargue el cdigo hex utilizando el comando: File a Load HEX; y
Pulse sobre el botn Write y espere...

Esto es todo! El microcontrolador est programado y todo est listo para su


funcionamiento. Si no est satisfecho, haga algunos cambios en el programa y
repita el procedimiento. Hasta cundo? Hasta quedar satisfecho...
A.4 SISTEMAS DE DESARROLLO

Un dispositivo que puede simular cualquier dispositivo en la fase de prueba, es


denominado un sistema de desarrollo. Aparte del programador, unidad de
alimentacin, zcalo del microcontrolador, el sistema de desarrollo dispone de los
componentes para activar los pines de entrada y monitorear los pines de salida.
La versin ms simple tiene cada pin conectado a su respectivo botn de presin
y un LED.

Una versin de calidad alta tiene los pines conectados a los visualizadores LED,
visualizadores LCD, sensores de temperatura u otros componentes por los que
puede estar compuesto un dispositivo destino. Si es necesario, todos estos
perifricos pueden estar conectados al microcontrolador por medio de los
puentes. Esto permite probar el programa entero en la prctica an durante el
proceso de desarrollo, porque el microcontrolador no sabe o no le interesa si su
entrada est activada por un botn de presin o un sensor incorporado en un
dispositivo real.
Si dispone de un sistema de desarrollo, el proceso de programar y probar un
programa es an ms sencillo. Teniendo en cuenta que el compilador mikroC PRO
for PIC (en su PC) y el hardware del programador PICflash (en su sistema de
desarrollo) colaboran perfectamente, el proceso de compilar un programa y

programar el microcontrolador se lleva a cabo en un simple paso - al pulsar sobre


el icono Build and Program dentro del compilador. Desde este momento, cualquier
cambio en el programa afectar inmediatamente al funcionamiento de alguno de
los componentes del sistema de desarrollo.
Est de acuerdo con nosotros que es hora de divertirse?
Caractersticas principales del sistema de desarrollo EasyPIC6

1. Regulador de voltaje de alimentacin


2. Conector USB para el programador en la placa

3. Programador USB 2.0 con soporte de mikroICD


4. Zcalo para el sensor de temperatura DS1820
5. Conector para el depurador externo (ICD2 o ICD3) de Microchip
6. Conector para la comunicacin USB
7. Entradas de prueba del convertidor A/D
8. Conector PS/2
9. LCD 2x16 en la placa
10.

Interruptores DIP permiten el funcionamiento de las resistencias pull-up/pull-

down
11.

Puente para seleccionar las resistencias pull-up/pull-down

12.

Conectores de los puertos E/S

13.

Zcalo para colocar el microcontrolador PIC

14.

Controlador del panel tcti

15.

Extensor de puertos

16.

Conector del LCD grfico128x64

17.

Potencimetro de contraste del LCD grfico

18.

Conector de panel tctil

19.

Teclado Menu

20.

Teclado 4x4

21.

Botones de presin para simular las entradas digitales

22.

Puente para seleccionar el estado lgico de los botones de presin

23.

Puente para poner en cortocircuito la resistencia de proteccin

24.

Botn para reiniciar el microcontrolador

25.

36 diodos LED indican el estado lgico de los pines

26.

Ajuste de contraste del LCD alfanumrico

27.

Conector del LCD alfanumrico

28.

Conector para la comunicacin RS-232