SlideShare una empresa de Scribd logo
1
2
Programación de microcontroladores PIC con Lenguaje C, Tomo I
Gestión de puertos e interrupciones externas
Sixto Reinoso; Luis Mena; Marco Pilatasig y Jorge Sánchez
Primera edición electrónica. Octubre de 2018
ISBN: 978-9942-765-36-9
Revisión científica: Juan Pablo Pallo Noroña y Julio Enrique Cuji Rodriguez
	
Universidad de las Fuerzas Armadas ESPE
Crnl. Ing. Ramiro Pazmiño O.
Rector
Publicación autorizada por:
Comisión Editorial de la Universidad de las Fuerzas Armadas ESPE
Cpnv. Hugo Pérez
Presidente
	
Edición y producción
David Andrade Aguirre
daa06@yahoo.es
Diseño
Pablo Zavala A.
Derechos reservados. Se prohibe la reproducción de esta obra por cualquier
medio impreso, reprográfico o electrónico.
El contenido, uso de fotografías, gráficos, cuadros, tablas y referencias es de
exclusiva responsabilidad del autor.
Los derechos de esta edición electrónica son de la Universidad de las Fuerzas
Armadas ESPE, para consulta de profesores y estudiantes de la universidad
e investigadores en: htpp//www.repositorio.espe.edu.ec.
Universidad de las Fuerzas Armadas ESPE
Av. General Rumiñahui s/n, Sangolquí, Ecuador.
htpp//www.espe.edu.ec
3
PROGRAMACIÓN DE
MICROCONTROLADORES PIC
CON LENGUAJE C
Tomo I
GESTIÓN DE PUERTOS E INTERRUPCIONES EXTERNAS
Sixto Reinoso V.
Luis Mena
Marco Pilatasig
Jorge Sánchez
4
Dedicatoria
Una vez más gracias a DIOS por todo lo que nos da y que es mucho. “Y
cantarán de los caminos del SEÑOR, porque grande es la gloria del SEÑOR”
(salmo 138:5).
A la memoria de Adriana Alexandra Reinoso V.
5
6
En este capítulo se describen brevemente el software y el hardware a
utilizarse en el desarrollo de las aplicaciones propuestas. Es importante
hacer un recordatorio de las sentencias y elementos generales que soporta
el compilador CCS, y que son utilizados en los programas propuestos en el
texto. Detalles, mayor información y características adicionales se pueden
obtener del sitio web oficial de CCS en www.ccsinfo.com o en manuales y
textos que sobre CCS existen ampliamente en el mercado. Luego del análisis
del software a utilizarse se describen las características más relevantes de los
microcontroladores PIC, dando énfasis a los PICs que se van a utilizar en el
desarrollo de las aplicaciones.
ESTRUCTURA DE UN PROGRAMA EN CCS
Para escribir un programa en C que acepte el Compilador CCS, se deben
tener en cuenta los elementos que forman el programa los mismos que se
indican en la figura 1.1.
Directivas: Controlan como debe generar el compilador el código de
máquina.
Programas o Funciones: Bloques de código escrito en instrucciones
de lenguajes de alto nivel. Como en C común siempre existirá la función
principal main.
Instrucciones: Sentencias que indican que va a realizar el programa y
determinan la ejecución del mismo. Las instrucciones se separan o finalizan
con punto y como (;). Ejemplo: x= x*10;
Comentarios: Describen el significado de las líneas del código. Útil para
leer las instrucciones de un programa.
Las directivas, funciones y otros elementos que usa el compilador se irán
describiendo según las necesidades de programación. Se dará un vistazo
general a los comentarios, datos, variables, instrucciones y funciones que se
necesitan para empezar a programar utilizando compilador CCS.
7
Figura 1.1. Estructura de un programa en C para el compilador PCWHD – CCS.
Elaborado por los autores.
Comentarios
Los comentarios son útiles para interpretar el código de un programa. Se
puede colocar en cualquier parte del programa y cumplir con los estándares
del ANSI C original. Se pueden escribir en dos formas:
Colocando //. A continuación se escribe el comentario o leyenda
correspondiente.
Ejemplos: // Esta es la forma de colocar un comentario en una línea.
delay_ms (200); //retardo de 200 milisegundos
#include <18F4550.h> //Incluye la librería para utilizar el PIC18F4550
Colocando /* */. Dentro de los símbolos se inserta el texto del comentario.
Cuando se quiere realizar un comentario de varias líneas se utiliza esta
opción.
Ejemplos: /* Otra forma de comentario */.
delay_ms (200); /*retardo de 200 milisegundos */
#include <18F4550.h> /*Incluye la librería para utilizar el PIC18F4550.
Con esta directiva se define la serie del microcontrolador a utilizarse en el
programa */
8
Tipos de datos
El compilador CCS acepta los siguientes tipos de datos:
Tipo Tamaño Rango Descripción
Int1
Short
1 bit 0 a 1 Entero de 1 bit
Int
Int8
8 bit 0 a 255 Entero
Int16
Long
16 bit 0 a 65,535 Entero de 16 bit
Int32 32 bit 0 a 4,294,967,295 Entero de 32 bit
Float 32 bit 1.5x10-45
a 3.402x1038
Coma flotante
Char 8 bit 0 a 255 Carácter
Void - - Sin valor
Signed Int8 8 bit -128 a +127 Entero con signo
Signed Int16 16 bit -32,768 a +32,767 Entero largo con signo
Signed Int32 32 bit -2147483648 a +2147483647 Entero 32 bits con signo
Tabla 1.1. Tipos de datos aceptados por el compilador CCS.
Fuente: García Breijo. Compilador C CSS y Simulador PROTEUS para Microcontroladores PIC.
Constantes
Las constantes pueden ser decimal, octal, hexadecimal y binario.
453 Decimal
0705 Octal (0)
0x1C5 Hexadecimal(0x)
0b111000101 Binario (0b)
‘x’ Carácter
‘010’ Carácter octal
‘xA5’ Carácter hexadecimal
“abcdef” Cadena
Tabla 1.2. Ejemplos de constantes aceptados por el compilador CCS.
Fuente: García Breijo. Compilador C CSS y Simulador PROTEUS para Microcontroladores PIC.
9
También se definen las constantes con sufijo.
Int8 83U
Long 70UL
Signed INT16 93L
Float 3.14f
Char Comillas simples ‘C’
Tabla 1.3. Otra forma de definir constantes en el compilador CCS.
Fuente: García Breijo. Compilador C CSS y Simulador PROTEUS para Microcontroladores PIC.
Se utilizan caracteres especiales como:
n Cambio de línea
r Retorno de carro
t Tabulación
b Backspace (retroceso)
Tabla 1.4. Uso de caracteres especiales en el compilador CCS.
Fuente: García Breijo. Compilador C CSS y Simulador PROTEUS para Microcontroladores PIC.
Hay que aclarar que el retorno de carro (r), pone el cursor al principio de
la línea actual, y el cambio de línea (n) avanza una. Tabulación y backspace,
trabajan de forma similar al teclado.
Variables
Las variables sirven para nombrar posiciones de memoria RAM. Se debe
declarar obligatoriamente, de acuerdo a las reglas ANSI del lenguaje C. El
formato es:
TIPO NOMBRE [=VALOR INICIAL];
TIPO: Se refiere al tipo de datos indicados en la tabla 1.1.
NOMBRE: Un nombre válido de acuerdo a las normas ANSI del lenguaje
C común. Algunas reglas mencionamos aquí:
•	
Deben empezar con una letra o guión bajo. Ejemplo: amperios,
_7segmentos;
•	No debe empezar con números o caracteres especiales. Ejemplos:3voltios,
7segmentos, -voltaje, %contador, &luz; contienen números y caracteres
especiales que no admite las variables.
10
•	Nodebetenerelmismonombrequeuna“palabrareservada”dellenguaje.
Ejemplo: for, if, int, while, do, entre otras son palabras reservadas del
lenguaje que no pueden ser usadas.
•	No pueden llevar tildes. Ejemplo: Número, ecuación, lección, dígito; son
palabras que tienen tilde y no deben usarse.
•	No debe existir espacios en blanco. Ejemplo: la ciudad. Hay un espacio
en blanco entre las palabras la y ciudad. En esta forma no se puede
utilizar.
[=VALOR INICIAL]. Este argumento es opcional (se puede omitir). A
una variable se puede asignar un valor de inicio o en su defecto no poner
ningún valor. Ejemplo:
int voltaje = 20;
int1 LED;
Las variables pueden ser de tipo LOCALo GLOBAL. Las variables locales
se utilizan sólo en la función donde se encuentran declaradas y las globales
en todas las funciones del programa. Ambas variables deben declararse
antes de cualquier función y fuera de ella. Las variables globales son puestas
a cero cuando se inicia la función principal main (). Ejemplo:
PROGRAMA:
#include <18F4550.h>
#fuses HS,NOWDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles.
#use delay (clock=12000000) // FOSC =12MHz
#byte tris_b = 0xF93
#bit b0= 0xF81.0
int puertos; //variable global
void main()
{
int8 voltaje; //variable local
}
void función (void)
{
float res ; //variable local
}
11
Operadores
El compilador CCS acepta la mayor parte de los operadores: aritméticos,
de asignación, relacionales, lógicos y punteros del lenguaje C ANSI original.
1.6.1 Aritméticos
Los operadores aritméticos que soporta el compilador CCS, se resume en
la tabla 1.5.
Símbolo Significado
+ Suma
- Resta
* Multiplicación
/ División
% Módulo, resto de una división entera
++ Incremento
- - Decremento
Sizeof Determina el tamaño, en bytes de un operando
Tabla 1.5. Operadores de aritméticos.
Fuente: CCS C Compiler Manual PCD.
De Asignación
Las operaciones de asignación se indican en la tabla 1.6.
Símbolo Significado
+= Asignación de suma: m +=n, es lo mismo m= m+n
-= Asignación de resta: m -=n, es lo mismo m= m-n
*= Asignación de multiplicación: m *=n, es lo mismo m= m*n
/= Asignación de división: m /=n, es lo mismo m= m/n
%= Asignación del resto de la división: m %=n, es lo mismo m= m%n
<<= Asignación de desplazamiento a la izquierda: m <<=n, es lo mismo m= m<<n
>>= Asignación de desplazamiento a la derecha: m >>=n, es lo mismo m= m>>n
&= Asignación AND de bits: m &=n, es lo mismo m= m&n
|= Asignación OR de bits: m |=n, es lo mismo m= m|n
^^= Asignación de OR exclusivo de bits
^= Asignación de suma: m ^=n, es lo mismo m= m^n
~= ~= Asignación de negación de bits
Tabla 1.6. Operadores de asignación.
Fuente: CCS C Compiler Manual PCD.
12
Relacionales
Compara dos operandos y da un resultado entero: 1 (verdadero); 0 (falso).
La siguiente tabla ilustra estos operadores: Los operadores relacionales se
muestran en la tabla 1.7.
Símbolo Significado
< Menor que
> Mayor que
>= Mayor o igual que
<= Menor o igual que
== Igual
!= Diferente
?: Expresión condicional
Tabla 1.7. Operadores relacionales.
Fuente: CCS C Compiler Manual PCD.
Lógicos
Al igual que los operadores relacionales, éstos devuelven 1 (verdadero),
0 (falso) tras la evaluación de sus operandos. La tabla siguiente ilustra estos
operadores. Los operadores lógicos que utiliza el compilador, se indica en la
tabla 1.8.
Símbolo Significado
! NOT
&& AND
|| OR
Tabla 1.8. Operadores lógicos.
Fuente: Manual del usuario del Compilador CCS.
De bits
Estos operadores permiten actuar sobre los operandos a nivel de bits y
sólo pueden ser de tipo entero (incluyendo el tipo char). Las operaciones de
bits están representadas en la tabla 1.9.
Símbolo Significado
~ Complemento a 1 (Inversión)
& AND
^^ XOR
| OR
Tabla 1.9. Operadores de bits.
Fuente: Manual del usuario del Compilador CCS.
13
Operadores de desplazamiento
Estos operadores utilizan dos operandos enteros (tipo int): el primero es
el elemento a desplazar y el segundo, el número de posiciones de bits que se
desplaza.
>> Desplazamiento a la derecha.
<< Desplazamiento a la izquierda
Tabla 1.10. Operadores de desplazamiento.
Fuente: Manual del usuario del Compilador CCS.
El formato es: m Operando n.
Donde:
m, es el elemento a desplazar.
Operando, desplazamiento a la izquierda <<, o desplazamiento a la
derecha >>, y
n, indica el número de posiciones que se desplazarán los bits.
Ejemplo: En una variable x se almacena el número binario 111000101. Si
se realizan las operaciónes indicadas, cuáles son los nuevos valores de x para
cada caso.
a.	x= 11000101 << 1
b.	x= 11000101 << 2
c.	x= 11000101 << 3
d.	x= 11000101 >> 1
e.	x= 11000101 >> 2
f.	x= 11000101 >> 3
En todos los casos los “unos” son reemplazados por “ceros”, desde el bit
menos significado y los bits que superan la capacidad del entero del bit más
significativo se desbordan y desaparecen.
El 1 después del signo << indica que los bits se desplazarán una posición
a la izquierda. Por tanto, el nuevo valor de x es 10001010. En este caso es lo
mismo que realizar una multiplicación al número binario por 2.
El 2 después del signo << indica que los bits se desplazarán dos posiciones
a la izquierda. Por tanto, el nuevo valor de x es 00010100. En este caso es lo
mismo que realizar una multiplicación al número binario por 4.
14
El 3 después del signo << indica que los bits se desplazarán tres posiciones
a la izquierda. Por tanto, el nuevo valor de x es 00101000. En este caso es lo
mismo que realizar una multiplicación al número binario por 8.
Para el desplazamiento a la derecha, los “unos” son reemplazados por
“ceros” desde el bit más significativo y al superar la capacidad del número
el bit menos significativo desparece.
El 1 después del signo >> indica que los bits se desplazarán una posición
a la derecha. Por tanto, el nuevo valor de x es 01100010. En este caso es lo
mismo que realizar una multiplicación al número binario por 2.
El 2 después del signo >> indica que los bits se desplazarán dos posiciones
a la derecha. Por tanto, el nuevo valor de x es 00110001. En este caso es lo
mismo que realizar una multiplicación al número binario por 4.
El 3 después del signo >> indica que los bits se desplazarán tres posiciones
a la derecha. Por tanto, el nuevo valor de x es 00011000. En este caso es lo
mismo que realizar una multiplicación al número binario por 4.
Punteros
El compilador CCS, soporta también el trabajo con punteros. Los
operadores de punteros más comunes se presentan en la tabla 1.10.
Símbolo Significado
& Dirección
* Indirección
-> Puntero estructura
Tabla 1.11. Operadores punteros.
Fuente: Manual del usuario del Compilador CCS.
Instrucciones de control
Las instrucciones de control para los programas con condiciones o que
necesiten bucles o lazos repetitivos que admite CCS, son los mismos del
ANSI C original:
•	IF - ELSE
•	SWITCH – CASE
•	WHILE
•	DO – WHILE
•	FOR
15
•	CONTINUE
•	RETURN
•	BREAK
•	GOTO
IF – ELSE
Sirve para tomar decisiones en un programa. El formato es:
if (condición)
	Instrucción1;
[else
Instrucción2];
Si la condición es verdadera (True o 1) se ejecuta la Instrucción1, si es
falsa (False o 0) se ejecuta la instrucción2. Las sentencias que están entre
corchetes [], son opcionales. Ejemplo:
if (x==1)
	 bit_set(port_b,0);
else
	bit_set(port_b,1);
Cuando existen varias instrucciones se deben utilizar las llaves {}.
if (prender == 0 && k==0)
{
k= 1;
bit_set(port_b,0);
}
Se pueden formar instrucciones anidadas para formar lazos de decisión
ELSE – IF.
if (condición1)
	Instrucción1;
[else if (condición2)
Instrucción2;]
[else
Instrucción3;]
16
La mejor forma de representar la instrucción IF – ELSE es mediante la
figura 1.2. Si la condición es TRUE se ejecutan las instrucciones que están por
el lado del THEN o si la condición es FALSE se ejecutan las instrucciones del
lado del ELSE.
Figura 1.2. Representación de la instrucción IF – ELSE.
Elaborado por los autores.
SWITCH CASE
Se utiliza para tomar una decisión múltiple. Evalúa la expresión y de
acuerdo a la constante ejecuta la o las instrucciones. La instrucción break evita
que continúe ejecutando el siguiente case. Si no existe ningún case se ejecuta
las instrucciones de default (que es opcional).
switch (expresión)
{
case constante_1:
			instrucción_11;
			instrucción_12;
			...
			break;
case constante_2:
			instrucción_21;
			instrucción_22;
			...
break;
case constante_n:
17
			instrucción_n
			...
			break;
[default:
Instrucciones;]
}
WHILE
WHILE repite una serie de instrucciones, mientras la expresión sea cierta
(TRUE o 1).
while (expresión)
{
			instrucciones;
}
Se puede ejecutar un bucle sin fin.
while (1)
{
			instrucciones;
}
O también utilizando el formato:
while (TRUE)
{
			instrucciones;
}	
DO WHILE
Con DO WHILE la expresión se evalúa al final de las instrucciones.
do
{
instrucciones;
}
while(expresión);
Las instrucciones primero se ejecutan y se evalúa la expresión al final, si
ésta resulta cierta (TRUE), se repite el bucle hasta que la condición sea falsa
(FALSE).
18
También con DO WHILE, se puede ejecutar un bucle sin fin. Por ejemplo:
do
{
		 instrucciones;
}
while(1);
FOR
El bucle de control FOR sin dudas es el más usado en la mayoría de
lenguajes de programación. En CCS es similar al formato delANSI C original,
o sea:
for (valor_inicial, valor_final, incremento)
{
		 instrucciones;
}
Ejemplo:
for (j=0; j<=9;++j)
Las instrucciones se repiten mientras la variable j sea menor o igual a 9. La
variable j se incrementa su valor en 1 cada vez que se ejecute una instrucción.
Nota: Recuerde que en C una variable se puede incrementar usando ++j, o bien,
j++.
Un bucle sin fin usando FOR se genera mediante el siguiente formato:
for ( ; ; )
{
		 instrucciones;
}
Continue
La instrucción de salto CONTINUE se usa para interrumpir la ejecución
normal de un bucle. El control del programa no se transfiere a la primera
instrucción después del bucle (como sí hace la instrucción break), es decir,
el bucle no finaliza, sino que, finaliza la iteración en curso, transfiriéndose
19
el control del programa a la condición de salida del bucle, para decidir si se
debe realizar una nueva iteración o no.
CONTINUE se puede emplear con cualquiera de los tres bucles, pero
no con SWITCH. Al igual que antes el programa no ejecuta las sentencias
restantes del bucle donde se encuentra. En bucles FOR o WHILE se comienza
a ejecutar el siguiente ciclo del bucle. En DO WHILE se comprueba la
condición de salida; si se cumple, se comienza el nuevo ciclo.
RETURN
El formato de la instrucción es:
return (expresión);
return expresión;
Se usa para devolver datos en las funciones. El valor de expresión debe
ser el mismo definido en la función.
BREAK
La instrucción BREAK sale de la ejecución de un bucle for, while, do y
switch.
GOTO
Es un salto incondicional. En C casi no se utiliza porque se pierde la
conceptualización de programa estructural y modular.
Funciones de retardo
Cuando se trabaja con microcontroladores es muy frecuente que se
necesitan generar retardos; el compilador CCS, proporciona algunas
funciones para estas situaciones.
delay_ms(tiempo)
Esta función realiza retardos del valor especificado en la variable tiempo.
El valor es un int16 (0-65535) en milisegundos. Ejemplo:
delay_ms(500);		 //genera un retardo de 500 ms.
20
delay_us(tiempo)
Los retardos conseguidos con esta función son especificados en la variable
tiempo en microsegundos y es un int16 (0-65535). Ejemplo:
delay_us(500);		 //genera un retardo de 500 us.
delay_cycles(contador)
Con esta función, se realizan retardos de acuerdo al número de ciclos de
máquina especificado en la variable contador. Los valores van desde 1 a 255.
Un ciclo de máquina o instrucción es igual a cuatro ciclos de reloj.
Ejemplo:
delay_cycles( 5 ); 		 // retardo de 5 ciclos instrucción.
Es decir, si el microcontrolador trabaja con un oscilador de 4 MHz, el
ciclo de instrucción o de máquina (CM) será igual:
CM= 4*1/4000000Hz = 1us
Por tanto, en el ejemplo anterior se ha obtenido un retardo de 5 us.
Directiva #use delay (clock=frecuencia)
Las tres funciones de retardo descritas trabajan en conjunto con la
directiva #use
delay. Esta directiva indica al compilador que frecuencia de reloj va
utilizar el microcontrolador. Ejemplos:
#use delay (clock=4000000) //Indica que MC va utilizar un oscilador de 4MHz.
#use delay (clock=20000000) //Indica que MC va utilizar un oscilador de
20MHz.
También se puede escribir:
#use delay (clock=4M) //Indica que MC va utilizar un oscilador de 4MHz.
#use delay (clock=20M) //Indica que MC va utilizar un oscilador de 20MHz.
Los microcontroladores PIC
Los microcontroladores PIC de Microchip Technology INC., son los
número 1 en ventas a nivel mundial, por las diferentes ventajas que ofrecen,
entre las que se puede mencionar:
21
•	Diversidad de gamas de microcontroladores para todas las necesidades
y aplicaciones que el diseñador pueda imaginarse.
•	
Soporte técnico documental amplio: libros, manuales, tutoriales,
aplicaciones específicas, abundante información en internet.
•	Gran cantidad de herramientas de desarrollo software y hardware.
•	
Compatibilidad en la arquitectura entre las diferentes familias de
microcontroladores PIC.
•	
Unidades funcionales y módulos embebidos: temporizadores,
conversores analógicos-digitales, USB, UART, PWM, CCP, etc.
•	Precios muy competitivos.
Familias de microcontroladores PIC
Microchip produce diferentes dispositivos que según el número de
terminales lo clasifica en:
Gama baja
•	Microcontroladoresde8bits,debajocoste,de6 pinesybajasprestaciones.
Algunos PIC’s de las serie PIC10 se conocen como gama enana.
•	PIC12: microcontroladores de 8 bits, de bajo coste, de 8 pines y bajas
prestaciones.
Gama media
•	PIC16: microcontroladores de 8 bits, con gran variedad de número de
pines y prestaciones medias.
Gama alta
•	
PIC17 y PIC18: microcontroladores de 8 bits, con gran variedad de
número de pines y prestaciones medias/altas.
•	PIC24: microcontroladores de 16 bits.
•	PIC32: microcontroladores de 32 bits.
•	
dsPIC’s. Microcontroladores especializados para el procesamiento de
señales digitales.
PIC18: Características fundamentales
Las principales características de los microcontroladores de gama alta
PIC18, se puede resumir en los siguientes:
22
•	Arquitectura Harvard, RISC avanzada de 16 bits (instrucciones) con 8 bit
de datos.
•	77 instrucciones a nivel de assembler.
•	Desde 18 a 80 pines.
•	Tecnología CMOS.
•	Puertos de I/O con múltiples funciones.
•	Módulos CCP. ECCP, PWM y comparadores incorporados.
•	Conversores con múltiples canales multiplexados.
•	Hasta 64K bytes de memoria de programa (hasta 2 Mbytes en ROMless).
•	Multiplicador Hardware 8x8.
•	Hasta 3968 bytes de RAM y 1KBytes de EEPROM.
•	Frecuencia máxima de reloj 40Mhz. Hasta 10 MIPS.
•	Pila de 32 niveles.
•	Múltiples fuentes de interrupción.
•	Resistencias pull-up programables en el puerto B.
•	Temporizadores 8 y 16 bits.
•	Comunicación serial sincrónica y asincrónica.
•	Periféricos de comunicación avanzados (CAN y USB).
La tabla 1.12, muestra las características generales de los PIC18F2455,
PIC18F2550, PICF4455 y PIC18F4550 que son los más populares.
Tabla 1.12. Características PIC18Fxxx.
Fuente: PIC18F2455/2550/4455/4550 Data Sheet. Microchip Technology INC.
Del listado de microcontroladores indicados en la tabla 1.12, el
PIC18F4550, es uno de los más difundidos por sus altas prestaciones y
recursos que dispone. Tiene 40 pines con 5 puertos numerados A, B, C, D
y E. Cada puerto puede estar formado hasta con 8 líneas que se pueden
configurar como entradas o salidas digitales. Además cada línea tiene más
de una función como se ve en la figura 1.3.
23
Registros de los puertos
Cada puerto tiene tres registros para su funcionamiento. Estos registros son:
• Registro TRISx. Registro de la dirección de datos. El compilador CCS
utiliza la instrucción TRISx para definir al puerto como salida (TRISx =
0) o como entrada (TRISx= 1).
• Registro PORTx. Lee los niveles en los pines del dispositivo. Los
datos existentes en los pines son leídos a través del registro PORT. El
compilador CCS a través de la instrucción PORTx escribe datos al puerto
respectivo.
• Registro LATx. Latch de salida. Registro latch o cerrojo, almacena los
estados lógicos que van a sacar las líneas de salida. No existe ninguna
instrucción del compilador CCS asociada con el registro LAT.
Cada pin de los puertos que sea de entrada/salida tiene incorporado
una línea al registro PORT, LAT y TRIS. La letra x en TRISx, PORTx y LATx
corresponde al nombre del puerto usado (A, B, C, D, E).
Figura 1.3. Distribución de pines del PIC18F4550, versión DIP.
Fuente: PIC18F2455/2550/4455/4550 Data Sheet. Microchip Technology INC.
24
La figura 1.4, muestra el diagrama de conexiones de un puerto de
entrada/salida para su operación.
Figura 1.4. Diagrama de un puerto entrada/salida.
Fuente: PIC18F2455/2550/4455/4550 Data Sheet. Microchip Technology INC.
PIC16: Principales características
Indudablemente la familia más numerosa Microcontroladores PIC de
gama media de la familia son los PIC16, en sus diferentes series y tecnologías
son las más utilizadas y exitosas.
Una de las series más famosas han sido los PIC de 18 pines como son
el PIC16F84, PIC16F627A, PIC16F628A y actualmente el PIC16F88. Los
micros de 40 pines el más destacado ha sido el PIC16F877 que está siendo
reemplazado por la versión mejorada del PIC16F887.
De acuerdo a las hojas de datos proporcionados por Microchip, las
características generales que presenta esta gama son:
•	Arquitectura Harvard, RISC avanzada de 14 bits (instrucciones) con 8 bit
de datos.
•	35 instrucciones a nivel de assembler.
•	Desde 18 a 68 pines.
25
•	Hasta 8K bytes de memoria de programa.
•	Frecuencia máxima de reloj 20MHz.
•	Múltiples fuentes de interrupción.
•	Módulos de comunicación sincrónica y asincrónica.
•	Módulos PWM/CCP/ECCP y comparadores.
•	Circuitos temporizadores de 8 y 16 bits.
•	Memoria RAM de hasta 368 bytes.
•	Memoria EEPROM de hasta 256 bytes.
•	Conversor con canales multiplexados.
•	Resistencias pull-up programables en el puerto B.
•	Dos puertos I/0 en los micros de 18 pines y 5 puertos en los PIC de 40
pines.
El PIC16F84, fue el que revolucionó el diseño de circuitos con
microcontroladores y se utilizó en la mayoría de centros de enseñanza la
programación en base a este PIC.
Los PIC 16F627A, 16F628A y 16F648A, ingresan al mercado con
características mejoradas y reemplazan al PIC16F84A, siendo el PIC16F628A
el de mayor acogida. Tienen una configuración para 8 osciladores. Un
único pin para un circuito RC es la solución de más bajo coste. En modo LP,
para mínimo consumo, XT para oscilador estándar y dos fuentes internas
de precisión INTOSC. El modo HS para cristales de alta velocidad (hasta
20MHz) y el modo EC para una fuente externa de reloj. En estas series el pin
RA4 es de drenador abierto y el pin RA5 que corresponde al MCLR (Master
Clear), solo puede actuar como puerto de entrada.
El microcontrolador PIC16F88, es 100% compatible con sus antecesores
microcontroladores 16F628A/84A, pero incluye un módulo conversor
análogo digital y el doble de la capacidad de la memoria FLASH. Además
el PIC en mención, incluye un bloque de oscilador interno con 8 frecuencias
seleccionables que van desde 31KHz hasta 8MHz, tres modos de osciladores
decristalexternoLP,XTyHShasta20MHz,dosmodosexternosRCyunmodo
de reloj externo ECIO de hasta 20MHz. También, es un microcontrolador
multifunciones, con capacidad de autoprogramación mediante firmware
bootloader residente.
26
La tabla 1.13, presenta un resumen de las características más importantes
de los microcontroladores mencionados en este punto.
CARACTERÍSTICAS PICF16F84A PIC16F627A PIC16F628A PIC16F648A PIC16F88
Memoria FLASH
(Words)
1024 1024 2048 4096 4096
Memoria EEPROM
(bytes)
64 128 128 256 256
Memoria SRAM
(bytes)
68 224 224 256 368
Puertos I/O 2 2 2 2 2
Pines de I/O 13 16 16 16 16
Oscilador Externo Interno/Externo
Interno/
Externo
Interno/Externo Interno/Externo
Fuentes de interrupción 10 10 10 10 12
Comunicación serial USART USART USART USART
AUSART, SSP
(SPI e I2C)
Comparadores - 2 2 2 2
Conversores AD - - - -
7 canales
mulltiplexados
Tabla 1.13. Características principales de los microcontroladores PIC16F84/627A/628A/88.
Elaborado por: Los Autores.
La figura 1.5 a, muestra el diagrama del microcontrolador
16F627A/628A/648A y la figura 1.5 b, el diagrama del microcontrolador
16F88, en versiones DIP.
a.	Diagrama de distribución de pines de los PIC16F627A/628A/648A.
27
b. Diagrama de distribución de pines de los PIC16F88.
Figura 1.5. Microcontroladores PIC gama media de 18 pines, series 16FXXX versión DIP.
Fuente: PIC16F87/88 Data Sheet, PIC16F627A/628A/648A Data Sheet.Microchip Technology INC.
En versiones de 28, 40 y 44 pines el microcontrolador de gama media
16F877A ha sido uno de los más exitosos. Entre las características más
destacadas de este micro está que tiene 5 puertos (A, B, C, D, E). Posee un
módulo de Comunicación Serial Universal Asincrónico USART, que soporta
RS-485, RS-232 y LIN2.0 y un Puerto Serie Síncrono Maestro (MSSP), para
modos SPI (Serial Peripheral Interface) e I2C (Inter-Integrated Circuit).
ElPIC16F877Anoincluyeunsistemaderelojinterno,porloqueMicrochip
para suplir esta necesidad introduce el PIC16F887, con varias mejoras. Este
micro posee un sistema de selección de reloj interno de precisión desde
8MHz a 31KHz. Posee un registro postescaler de 8 bits, para dividir la fuente
de 8MHz y obtener 8 frecuencias distintas (8, 4, 2, 1 MHz, 500, 250, 125 y 31.25
kHz). Los modos de oscilador externo son LP, XT, HS, RC, RCIO, EC, y en
oscilador interno INTOSC y INTOSCIO.
El módulo CCP mejorado (ECCP) útil para el control PWM de puentes
y semipuentes para circuitos inversores, es otra de las características
relevantes de este PIC. El módulo EUSART (Enhanced USART), permite la
autodetección de baudios.
El módulo ADC, es de 10 bits y tiene hasta 14 canales multiplexados
para ser utilizados simultáneamente. Los microcontroladores de esta gama
poseen un amplio rango de voltaje de operación que va de entre 2 y 5.5V.
28
La tabla 1.14, muestra un resumen comparativo de las principales
características que distinguen a estos dos microcontroladores.
CARACTERÍSTICAS PIC16F877A PIC16F887
Frecuencia Máxima 20MHZ 20MHZ
Memoria FLASH (Words) 8192 8192
Memoria EEPROM (bytes) 256 256
Memoria SRAM (bytes) 368 368
Puertos I/O 33 35
Timer (8/16 bits) ½ ½
Oscilador Externo Interno/Externo
Comparadores 2 2
Conversores AD 8 canales (10 bits) 14 canales (10 bits)
Frecuencias INTOSC - 31 KHZ-8 MHZ
Fuentes de interrupción 15 15
ECCP/CCP 0/2 ½
Comunicación serial USART/MSSP EUSART/MSSP
Modos de oscilador 4 8
Tabla 1.14. Características de los PIC 16F877A/887.
Elaborado por los autores.
Los diagramas de distribución de pines para los PIC16F877A/887,
versión DIP, se observa en la figura 1.6.
a. Diagrama del PIC16F877.
29
b.	Diagrama de distribución de pines del PIC16F887.
Figura 1.6. Microcontroladores PIC16F877/887 versión DIP.
Fuente: PIC18F2455/2550/4455/4550 Data Sheet. Microchip Technology INC.
EJERCICIOS Y PREGUNTAS PROPUESTAS
1.	¿Cuál carácter se utiliza para hacer comentarios en una sola línea?
2.	¿Con qué carácter se separan instrucciones?
3.	¿Cuál es la diferencia entre retorno de línea y cambio de línea?
4.	¿Qué palabra se debe utilizar para declarar un variable entero de 1 bit?
5.	Realice la declaración de la variable I = 2.536
6.	¿Cuáles son las restricciones que se deben tomar en cuenta al declarar
una variable?
30
7.	Encuentre el error en la declaración de la variable y corríjala: float 2
contadores = 5;
8.	Una variable int16 ¿qué rango de valores contiene?
9.	¿En qué parte del programa puede ser utilizada una variable global?
10. Se realiza la operación: c= 10%4, ¿cuál es el valor de c?
11. En la operación x+=2; ¿cuánto es el resultado de x?
12. ¿Cuál es el resultado de la operación x= x>>2, si x= 25? Realice las
operaciones en binario.
13. ¿Cuál es el resultado de la operación x= x<<4, si x= 63? Realice las
operaciones en binario.
14. Explique la diferencia entre realizar la operación:
a. a&b y a&&b.
b. a|b y a||b.
15. En el siguiente código
if (x < 18)
		 printf(“Eres menor de edad.n”);
else
		 printf(“Eres un joven.n”);
Sea x= 25, ¿qué mensaje se imprime?
16. En el siguiente ejemplo:
a. ¿Para qué sirve break?
b. Si lista=0, ¿qué mensaje se imprime?
Switch( lista)
{
case 0: printf(“No hay elementos.”);
31
break;
case 1: printf(“Hay solo un elemento.”);
break;
default: printf(“Hay varios elementos”);
}
17. Usando while escriba la forma para crear un bucle infinito.
18. Usando for escriba la forma para crear un bucle infinito.
19. Escriba la instrucción usando for para que una variable entrada cuente
del 0 al 99.
20. ¿Qué tiempo de retardo genera delay_ms(1500)?
21. De los microcontroladores citados en este capítulo, ¿cuáles no tienen
reloj interno?
22. Cuál microcontrolador de 18 pines tiene memoria FLASH de 4096
words y posee un módulo conversor de AD de 7 canales.
23. ¿Cuáles series de microcontroladores PIC tienen un módulo de
conexión USB?
32
33
Los fuses del microcontrolador PIC18
TodoslosmicrocontroladoresPICtienenincorporadoscircuitosespeciales
que se pueden activar o desactivar según los requerimientos de la aplicación
o algún caso en particular. Estos circuitos o características especiales se deben
configurar mediante software o por el equipo programador al momento de
grabar el programa en el microcontrolador. La configuración adecuada de
estos circuitos determina en gran parte la funcionabilidad y eficiencia del
programa desarrollado.
Los fuses permiten entre otras cosas seleccionar el oscilador: interno o
externoquesevautilizar,lafrecuenciadetrabajodelsistema,elusodelMaster
Clear (reset del sistema), etc. Los fuses internamente en el microcontrolador
son controlados por registros internos y que se pueden habilitar o deshabilitar
mediante software o por medio del equipo programador. CCS provee de
instrucciones de alto nivel que permiten de forma transparente configurar los
FUSES (fusibles). En el PIC18F4550, los fuses que CCS configura se muestra
en la tabla 2.1. Para no distorsionar la descripción del fuse, se ha dejado en el
idioma original, que CCS proporciona en el IDE del programa.
FUSE DESCRIPCIÓN
LP Low power osc < 200 kHz
XT Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
HS High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
RC Resistor/Capacitor Osc with CLKOUT
EC External clock with CLKOUT
EC_IO External clock
H4 High speed osc with HW enabled 4X PLL
RC_IO Resistor/capacitor osc
RC Resistor/Capacitor Osc with CLKOUT
INTRC_IO Internal RC Osc, no CLKOUT
INTRC Internal RC Osc
NOFCMEN Fail-safe clock monitor disabled
FCMEN Fail-safe clock monitor enabled
IESO Internal External Switch Over mode enabled
NOIESO Internal External Switch Over mode disabled
PUT Power up timer
NOPUT No power up timer
BROWNOUT Reset when brownout detected
34
NOBROWNOUT No brownout reset
BROWNOUT_SW Brownout controlled by configuration bit in special file register
B R O W N O U T _
NOSL Brownout enabled during operation, disabled during SLEEP
BORV45 Brownout reset at 4.5V
BORV42 Brownout reset at 4.2V
BORV27 Brownout reset at 2.7V
BORV20 Brownout reset at 2.0V
NOWDT No watch dog timer
WDT Watch dog timer
WDT128 Watch Dog Timer uses 1:128 Postscale
WDT64 Watch Dog Timer uses 1:64 Postscale
WDT32 Watch Dog Timer uses 1:32 Postscale
WDT8192 Watch Dog Timer uses 1:8192 Postscale
WDT16384 Watch Dog Timer uses 1:16384 Postscale
WDT16 Watch Dog Timer uses 1:16 Postscale
WDT8 Watch Dog Timer uses 1:8 Postscale
WDT256 Watch Dog Timer uses 1:256 Postscale
WDT512 Watch Dog Timer uses 1:512 Postscale
WDT1024 Watch Dog Timer uses 1:1024 Postscale
WDT2048 Watch Dog Timer uses 1:2048 Postscale
WDT4 Watch Dog Timer uses 1:4 Postscale
WDT32768 Watch Dog Timer uses 1:32768 Postscale
WDT4096 Watch Dog Timer uses 1:4096 Postscale
WDT1 Watch Dog Timer uses 1:1 Postscale
WDT2 Watch Dog Timer uses 1:2 Postscale
CCP2B3 CCP2 input/output multiplexed with RB3
CCP2C1 CCP2 input/output multiplexed with RC1
NOPBADEN PORTB pins are configured as digital I/O on RESET
PBADEN PORTB pins are configured as analog input channels on RESET
LPT1OSC Timer1 configured for low-power operation
NOLPT1OSC Timer1 configured for higher power operation
NOMCLR Master Clear pin used for I/O
MCLR Master Clear pin enabled
STVREN Stack full/underflow will cause reset
NOSTVREN Stack full/underflow will not cause reset
NOLVP No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
LVP Low Voltage Programming on B3(PIC16) or B5(PIC18)
35
NOXINST
Extended set extension and Indexed Addressing mode disabled
(Legacy mode)
XINST Extended set extension and Indexed Addressing mode enabled
NODEBUG No Debug mode for ICD
DEBUG Debug mode for use with ICD
PROTECT Code protected from reads
NOPROTECT Code not protected from Reading
NOCPB No Boot Block code protection
CPB Boot block code protected
CPD Data eeprom code protected
NOCPD No EE protection
WRT Program memory write protected
NOWRT Program memory not write protected
WRTC Configuration registers write protected
NOWRTC Configuration not registers write protected
NOWRTB Boot block not write protected
WRTB Boot block write protected
WRTD Data EEPROM write protected
NOWRTD Data EEPROM not write protected
NOEBTR Memory not protected from table reads
EBTR Memory protected from table reads
EBTRB Boot block protected from table reads
NOEBTRB Boot block not protected from table reads
Tabla 2.1. FUSES para el PIC184550 del compilador CCS.
Fuente: CCS Compiler V4.084.
Algunos fuses de interés significan:
LVP: Low Voltage programming. Programación por voltaje bajo.
• 1 = LVP habilitado, la terminal RB4/PGM tiene tal función.
• 0 = LVP deshabilitado, RB4/PGM es una terminal de I/O
BODEN: Brown Out Detect Reset Enable bit (Bit de reset por voltaje de
alimentación bajo). En CCS el fusible es BROWNOUT NOBROWNOUT.
• 1 = Reset por BOD habilitado.
• 0 = Reset por BOD deshabilitado.
BOR: Brown-out Reset. Este circuito hace que el PIC se reinicie cuando
se detecta una inestabilidad en la alimentación. El compilador proporciona
36
varios FUSES para configurar el BOR para diferentes niveles de tensiones (ver
tabla 2.1). Por ejemplo: BORV45 reinicia el microcontrolador en nivel de 4.5V.
PBADEN y NOPBADEN: Cuando se produce un RESET en el Micro,
con PBADEN los pines del puerto B se configuran como canales de entrada
analógicos y con NOPBADEN los pines del puerto B se configuran como
entradas o salidas digitales.
MCLR: Master Clear. Habilitación/deshabilitación del terminal de reset.
• 1 = Terminal de reset (MCLR) en RA5.
• 0 = MCLR conectado internamente a Vdd, RA5 es un pin de I/O.
PUT: Power up Timer enable bit. En el datasheet del microcontrolador
es el bit que se conoce como PWRT. Es el bit de habilitación de temporizador
al energizar. Al activar el POWER UP TIMER lo que hace es retardar el
arranque del PIC. Este empieza a funcionar unos 65.5 ms., después de recibir
la tensión de alimentación.
• 1 = PWRT habilitado.
• 0 = PWRT deshabilitado.
WDT: Watch Dog Timer Enable Bit. Bit de habilitación del Watch-Dog.
• 1 = WDT habilitado.
• 0 = WDT deshabilitado.
Para configurar los fusibles se debe incluir en el programa la directiva
#fuses, seguido de los nombres y separados entre comas (,) de los fuses
que se necesiten fijar en el programa. Si no se considera algunos de ellos el
programa asume el valor por default que suministra el fabricante, mismo
que podemos ver en el datasheet del microcontrolador. Ejemplo:
Suponer que se va a utilizar un cristal de 4 MHz, desactivar el Master
Clear, No proteger el código para lectura, desactivar la programación a bajo
voltaje; el código del compilador CCS para los FUSES mencionados es:
#fuses XT, NOWDT, NOPROTECT, NOLVP //Configuración de Fuses.
Nota: Se debe indicar que el compilador acepta mayúsculas o minúsculas
al escribir las instrucciones, funciones u otras sentencias para el desarrollo
de los programas.
37
Configuración del reloj
La mayoría de los microcontroladores PIC de la familia 16F y 18F tienen
incorporado un sistema de reloj para ser utilizado según las necesidades
del diseño. El hardware de control del oscilador es el registro OSCCON
(Oscillator Control Register) y el registro oscilador de ajuste OSCTUNE
(Oscillator Tuning Register), se utiliza para ajustar frecuencia interna vía
software.
Tipos de osciladores
Según el datasheet del fabricante, los dispositivos PIC18F2455 /
2550/4455/4550 y PIC16F88, PIC16F887, pueden ser operados en distintos
modos de oscilador, siendo estos los más usados:
• XT Crystal / Resonador (se usa para cristales <= 4 MHZ).
• HS alta velocidad Crystal / Resonador (>4MHZ).
• HSPLL alta velocidad Crystal / Resonador con PLL activado.
• EC reloj externo con FOSC
/ 4 de salida.
• ECIO reloj externo con I / O en RA6.
• ECPLL Reloj externo con PLL Activado y FOSC
/ 4 Salida en RA6.
• ECPIO Reloj externo con PLL habilitado, I/O en RA6.
• INTHS oscilador interno utilizado como
		 • Microcontroladores fuente de reloj, HS
		 • Oscilador utilizado como USB Fuente de reloj
• INTIO oscilador interno utilizado como:
		 • Microcontrolador fuente de reloj, EC
		 • Oscilador utilizado como fuente de reloj USB,
		 • I/O digital en RA6
• INTCKO oscilador interno utilizado como
		 • Microcontrolador fuente de reloj, EC
		 • Oscilador utilizado como fuente de reloj USB,
		 • FOSC
/ 4 Salida en RA6
El PIC16F628A tiene los modos LP, XT, HS, ECIO, INTIO, INTCKO.
La tabla 2.2, indica los valores típicos del cristal y los capacitores que el
fabricante sugiere utilizar con los diferentes cristales para modo XT y HS.
Mayor información sobre los valores del oscilador de cristal y los capacitores
38
para los resonadores cerámicos se pueden encontrar en las hojas del datasheet
del fabricante.
Tabla 2.2. Selección de capacitores para el oscilador de cristal.
Fuente: PIC18F2455/2550/4455/4550 Data Sheet. Microchip Technology INC.
El oscilador se conecta en los pines RA6/OSC2/CLKO y OSC1/CLK1.
La figura 2.1, muestra el diagrama de conexiones del oscilador de cristal de
8MHz y los capacitores cerámicos de 22 pF, como recomienda el fabricante.
Figura 2.1. Conexión del oscilador de cristal externo.
Elaborado por los autores.
39
Todas las frecuencias se derivan de 8MHZ y con el registro POSTSCALER
de 8 bits se obtienen el resto de frecuencias (8MHz/256= 31.25kHz) y son
seleccionables por software. La figura 2.2, indica los valores de las frecuencias
internas que pueden ser usadas.
Figura 2.2. Diagrama de bloques del oscilador interno y la gama de frecuencias derivadas. Fuente:
PIC18F2455/2550/4455/4550 Data Sheet. Microchip Tecnhology INC.
Mediante la configuración de los FUSES se puede utilizar el oscilador
externo o la fuente de frecuencia interna. El compilador provee una serie
FUSES para configurar el reloj interno.
Configuración del oscilador
La instrucción para utilizar el tipo de oscilador es:
#fuses TIPO DE OSCILADOR
Donde el TIPO DE OSCILADOR hace referencia a los descritos en este
punto. Ejemplo:
#fuses HS
#use delay (clock=12000000)
Se indica al microcontrolador que utilizará un oscilador externo de alta
velocidad (HS) con un cristal de 12000000 Hz. Para indicar directamente la
frecuencia en MHz, se puede utilizar la notación:
#use delay (clock=12M)
40
Para el caso que utilicemos la fuente de reloj interno del microcontrolador,
se utilizaría así:
#fuses INTRC_IO
#use delay (clock=8M)
Se indica al compilador que se va a utilizar el oscilador interno RC y el
pin RA6, se configura para que sea utilizado como entrada o salida digital.
Es válido también en algunos Micros que tienen el puerto RA7, o sea RA6 y
RA7, se configuran como I/O digitales.
La instrucción #use delay (clock=8M), indica al compilador usar frecuencia
de reloj para el sistema de 8MHz. En la figura 2.2, se pueden observar los
valores de reloj internos que se pueden utilizar.
Si se utiliza la configuración del fusible:
#fuses INTRC.
Se indica al compilador use el reloj interno y por el terminal RA6 se
obtendrá una salida de reloj del sistema interno (FOSC
/4).
Otra forma de fijar el oscilador interno es mediante la función
setup_oscillator(). Esta función hace referencia al registro OSCCON del
microcontrolador. La función controla y devuelve el estado del oscilador RC
interno en los micros que disponen del registro OSCCON. Se debe tener
en cuenta que si INTRC o INTRC_IO se especifica en #fuses y un retraso
#use se utiliza para una opción de velocidad válido, el compilador hará esta
configuración automáticamente al inicio del main ().
La sintaxis y argumentos de la función son:
setup_oscillator(mode, finetune)
Dónde:
mode, es dependiente en el chip. Por ejemplo, algunos chips permiten
ajuste de velocidad tales como OSC_8MHZ u OSC_32KHZ. Otros micros
permite el cambio del origen como OSC_TIMER1.
finetune, es el ajuste preciso, es un variable entera que va desde -31 a
+31. Solo se permiten en microcontroladores que disponen del registro
OSCTUNE.
41
Algunos chips devuelven un estado tal como OSC_STATE_STABLE para
indicar el oscilador es estable. La función descrita debe siempre colocarla
dentro del main () del programa. Ejemplo:
void main()
{
setup_oscillator(OSC_8MHz|OSC_INTRC|OSC_PLL_OFF);
}
Conexión de LEDS en los puertos
La figura 2.3, muestra la conexión de diodos LEDS al puerto A, B,
C, D y E del microcontrolador. Hay que tomar en cuenta que la máxima
corriente que puede entregar o recibir los puertos del microcontrolador es
de 25 mA, según las características eléctricas que Microchip establece para
el PIC18F4550. Por tanto, tomando en consideración el valor indicado, se
ha colocado resistencias de 330 Ω, en las líneas del puerto para limitar la
corriente y evitar dañar el puerto. Esta conexión es común para todos los
puertos excepto para el pin RA4, que en algunos de los microcontroladores
son de drenador abierto.
Dado que la caída de tensión en el LED cuando está conduciendo es de
aproximadamente 1.3 V, la corriente de cada pin del puerto es:
El valor obtenido es inferior a los 25 mA y está en el rango (5 a 15 mA)
que necesita un LED para iluminar adecuadamente.
42
Figura 2.3. Conexión de LEDS en los puertos del microcontrolador.
Elaborado por los autores.
Gestión de puertos
En el compilador CCS se pueden gestionar los puertos de dos formas:
• Definiendo la posición de la memoria RAM como una variable C para los
registros TRISX y PORTX.
• Usando la directivas específicas del compilador (#USE FAST_IO, #USE
FIXED_IO, #USE STANDARD_IO)
Usando la memoria RAM
Las posiciones de memoria que utilizan los registros TRISX y PORTX del
PIC18 se identifican así:
#BYTE tris_n = Dir
#BYTE port_n = Dir
Donde, n es el nombre del puerto (A, B, C, D, E) y la variable Dir la
dirección en la memoria RAM.
Ejemplo:
#BYTE tris_b = 0xF93
#BYTE port_b = 0xF81
43
La tabla 2.3, muestra las direcciones de memoria ocupadas por los
registros TRIS en la familia de PIC18FXXX. En todo caso, siempre es necesario
consultar el datasheet del fabricante para verificar la dirección exacta que
ocupa los registros TRIS en la memoria RAM.
REGISTRO TRIS DIRECCIÓN DE MEMORIA
A 0xF92
B 0xF93
C 0xF94
D 0xF95
E 0xF96
Tabla 2.3. Localidades de memoria ocupados por los registros TRIS, para los PIC18FXXX.
Fuente: PIC18F2455/2550/4455/4550 Data Sheet. Microchip Tecnhology INC.
La tabla 2.4, indica las direcciones de la memoria RAM que son asignadas
para el registro PORT de los PIC de la serie PIC 18F4550. Esta información
se encuentra en las hojas de datos técnicos que proporciona el fabricante de
microcontroladores PIC, Microchip Technology INC.
REGISTRO PORT DIRECCIÓN DE MEMORIA
A 0xF80
B 0xF81
C 0xF82
D 0xF83
E 0xF84
Tabla 2.4. Localidades de memoria ocupados por los registros PORT, para los PIC18FXXX.
Fuente: PIC18F2455/2550/4455/4550 Data Sheet. Microchip Tecnhology INC.
Para las series de microcontroladores PIC 16F8XX y 16F6XX, las
direcciones del registro TRIS y PORT son:
REGISTRO TRIS DIRECCIÓN DE MEMORIA
A 0x85
B 0x86
C 0x87
D 0x88
E 0x89
Tabla 2.5. Localidades de memoria ocupados por los registros TRIS, para los PIC16F.
Fuente: PIC18F2455/2550/4455/4550 Data Sheet. Microchip Tecnhology INC.
44
REGISTRO PORT DIRECCIÓN DE MEMORIA
A 0x05
B 0x06
C 0x07
D 0x08
E 0x09
Tabla 2.6. Localidades de memoria ocupados por los registros PORT, para los PIC16F.
Fuente: PIC18F2455/2550/4455/4550 Data Sheet. Microchip Tecnhology INC.
Definidas las variables se pueden controlar los puertos por comandos de
asignación. Ejemplos:
• tris_a = 0xFF ; Define todo el puerto a como entrada
• tris_b = 0x00; Define todo el puerto b como salida
• tris_d = 0x0F; Define los 4 primeros bits del puerto d como entrada y los
4 bits (MSB) como salida.
Luego se escribe o lee los datos en el puerto.
Escritura del puerto:
port_b = 0x0B; El dato 1011, se coloca en el puerto b.
Lectura del puerto:
Contador = port_a; El dato del puerto a se asigna a la variable Contador.
Ejercicio 2.1. Prender y apagar un LED conectado en el puerto B0.
El primer programa de computadora que enseñan en programación y en
la mayoría de lenguajes es imprimir en la pantalla “Hola Mundo”. El primer
programa semejante que se realiza con un microcontrolador es prender y
apagar un LED indefinidamente.
En el programa primero debemos definir el microcontrolador a utilizarse,
para lo cual se utiliza la directiva:
#include <18F4550.h> //Librería para usar el PIC18F4550.
Ahoraseprocedeaconfigurarlosfusibles.Lahabilitaciónodeshabilitación
de los fusibles dependerá de la aplicación que se esté desarrollando, pero el
fusible que siempre se debe incluir es el reloj que se utilice. En este caso
definimos un cristal de alta velocidad HS.
#fuses HS,NOWDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles.
45
Es importante también definir la frecuencia del oscilador:
#use delay (clock=12000000) // FOSC
=12MHz.
En este programa el LED se conecta en el puerto RB0. Se define el bit a
utilizar mediante la instrucción #bit b0= 0xF81.0. La variable bit b0 se puede
asignar valores de 0 y 1 para obtener valores lógicos de tensión de 0 y 5V
respectivamente en el puerto RB0. Por tanto, en el programa las asignaciones
de b0= 0; establecen que el puerto RB0 sea igual a 0V y b0= 1; en el puerto
RB1 tendrá el nivel lógico de 5V.
Cuando no se utiliza las interrupciones, es conveniente deshabilitar todas
las interrupciones, sin que sea una exigencia de alta prioridad. La instrucción
disable_interrupts (GLOBAL); realiza esta función.
El registro TRISB está definido en la localidad 0xF93 como indica en las
hojas técnicas del microcontrolador PIC18F4550.
Otro aspecto importante que se debe tomar en cuenta dentro de la
programación es la definición del puerto como salida. La instrucción tris_b =
0x00; configura el puerto como salida, para que permita establecer los niveles
lógicos de 0 y 1.
PROGRAMA:
#include <18F4550.h> //Librería para usar el PIC18F4550.
#fuses HS,NOWDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles.
#use delay (clock=12000000) // FOSC =12MHz.
#byte tris_b = 0xF93 //Define el registro tris b en la localidad 0xF93.
#bit b0= 0xF81.0 //Define el bit b0 en la localidad 0xF81.0.
void main() //Función principal main.
{
disable_interrupts (GLOBAL); //Deshabilita las interrupciones globales.
tris_b = 0x00; //Configura el puerto B como salida.
do{ //Inicio del bucle infinito.
b0= 0; //El puerto RB0 = 0.
delay_ms( 500 ); //Retardo de 500 ms.
b0 =1; //El Puerto RB0 = 1.
delay_ms(500); //Retardo de 500 ms.
} while ( TRUE ); //Bucle infinito.
} //Fin del bucle main.
46
El circuito para comprobar el funcionamiento se indica en la figura 2.4.
Como en la configuración de los FUSES no está definido el uso del MCLR, es
necesario conectar este terminal a través de una resistencia a VCC
, el pulsador
permitirá tener un botón de RESET.
Figura 2.4. Conexión de un LED en el puerto RB0.
Elaborado por los autores.
Ejercicio 2.2. Prender y apagar los LEDS del puerto B.
En el ejercicio 2.2, los LEDS conectados al puerto B se prenden y apagan
indefinidamente, como indica la figura 2.5. En este caso en el programa
todos los ocho bits de la localidad de memoria 0xF81 se asignan a la variable
port_b, de igual manera ocurre con el registro tris_b, con la localidad de
memoria 0xF93.
47
PROGRAMA:
#include <18F4550.h> //Librería para usar el PIC18F4550.
#fuses HS,NOWDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles.
#use delay (clock=12000000) / / FOSC = 12MHz.
#byte port_b = 0xF81 //Identificador para el puerto b en la localidad 0xF81.
#byte tris_b = 0xF93 //Identificador para el registro tris b en la localidad 0xF93.
void main() //Función principal main.
{
disable_interrupts(GLOBAL); //Deshabilita todas las interrupciones globales.
tris_b = 0x00; //Configura todo el puerto B como salida.
port_b = 0x00; // Asigna a todo el Puerto B cero (0).
do{ // Hace o empieza el bucle infinito.
port_b = 0xFF; //Coloca todo el puerto B en 1.
delay_ms( 500 ); //Retardo de 500 ms.
port_b = 0x00; //Coloca todo el puerto B en 0.
delay_ms(500); //Retardo de 500 ms.
} while ( TRUE ); //Bucle infinito.
} //Fin del bucle main.
Figura 2.5. LEDS conectados en el puerto B.
Elaborado por los autores.
48
Con el programa propuesto y el circuito indicado los LEDS se prenden
por 500 ms y se apagan por un tiempo igual. La ejecución de la secuencia
de prendido y apagado es indefinido, el bucle DO – WHILE en la función
principal main() se encarga de ejecutar las instrucciones en bucle infinito.
Otra forma de generar un bucle infinito es utilizando la sentencia while
(TRUE) o while(1) como se indica en el ejercicio 2.3.
Ejercicio 2.3. Prender y apagar los LEDS que están conectados al puerto
B indefinidamente.
La mayoría de programas que se desarrollan en C, para generar los bucles
infinitos se utiliza la sentencia while(TRUE), por lo que en este programa se
utilizará esta forma.
PROGRAMA:
#include <18F4550.h> //Librería para usar el PIC18F4550.
#fuses HS,NOWDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles.
#use delay (clock=12000000) // FOSC = 12MHz.
#byte port_b = 0xF81 //Identificador para el puerto b en la localidad 0xF81.
#byte tris_b = 0xF93 //Identificador del registro tris b en la localidad 0xF93.
void main() //Función principal main.
{
disable_interrupts(GLOBAL); //Deshabilita todas las interrupciones globales.
tris_b = 0x00; // Configura el puerto B como salida.
port_b = 0x00; // Asigna a todo el Puerto B cero (0).
while (TRUE){ //Bucle infinito.
port_b = 0xFF; //Coloca todo el puerto B en 1.
delay_ms( 500 ); //Retardo de 500 ms.
port_b = 0x00; //Coloca todo el puerto B en 0.
delay_ms(500); //Retardo de 500 ms.
} //Fin del bucle infinito.
} //Fin del bucle main.
A través de directivas
El compilador ofrece funciones predefinidas para trabajar con los puertos.
Estas directivas son:
• output_x (value); por el puerto indicado saca el valor correspondiente a
0 a 255.
49
• input_x(); se obtiene el valor del puerto.
•set_tris_x(value);configuraelpuertoxcomoentradaosalidadependiendo
de la variable value. Ejemplo:
			 set_tris_b(0x00); el puerto b es de salida.
			 set_tris_b(0xFF); el puerto b es de entrada.
• get_tris_x(); devuelve el valor del registro tris_x.
x, es el símbolo correspondiente a los puertos A, B, C, D, E.
Las funciones asociadas al terminal o pin son:
• output_low (PIN_n);	 pin a 0.
• output_high (PIN_n); pin a 1.
• output_bit (PIN_n,value); pin al valor especificado.
• output_toggle (PIN_n); complemento el valor del pin.
• output_float (PIN_n); pin de entrada, quedando a tensión flotante.
Simula salida de drenador abierto.	
• output_state (PIN_n); lee el valor del pin.
• input_state(PIN_n);	 lee el valor del PIN sin cambiar el sentido del
terminal.
• input(PIN_n); lee el valor del PIN.
n, se refiere al nombre del puerto y/o del PIN.
Directiva #use standard_io (puerto)
Es la directiva por defecto. Las funciones output_x e input_x, modifican el
registro TRIS asegurando que los terminales usados sean de salida o entrada
respectivamente.
Si no se incluye ninguna directiva, el programa tomará por defecto #use
standard_io(puerto), que reprogramará cada vez al pin como entrada o salida
aumentando el código generado por el compilador.
Al usar las directivas no es necesario identificar las direcciones que
ocupan los registros PORT y TRIS, porque estos ya están definidos en las
directivas.
Ejercicio 2.4. Prender y apagar un LED por el puerto RB0.
Este programa trabaja de la misma forma del ejercicio 2.1. En este caso
se utiliza las funciones de la directiva #USE STANDARD_IO(PUERTO) para
50
definir el puerto a usarse. Nótese que ya no se Define port_x de entrada o
salida con TRIS. El circuito de figura 2.4, se puede utilizar para demostrar el
funcionamiento.
PROGRAMA:
#include <18f4550.h> / /Librería para usar el PIC18F4550.
#fuses HS,NOWDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles.
#use delay (clock=12000000) //FOSC=12MHz.
#use standard_io(b) //Directiva usado por el compilador por defecto.
//Es opcional llamarla en el programa.
void main(void) //Función principal main.
{
disable_interrupts(GLOBAL); //Todas las interrupciones desactivadas.
while(TRUE); //Bucle infinito.
{ //Inicio del bucle.
output_low(PIN_B0); //LED off.
delay_ms(500); //Retardo de 500 ms.
output_high(PIN_B0); //LED on.
delay_ms(500); //Retardo de 500 ms.
} //Fin del bucle infinito.
} //Fin del bucle main.
b. Directiva #use fast_io(port)
Esta directiva define a los puertos como entradas o salidas digitales.
La variable port puede tomar los valores de a, b, c, d, e, o all para señalar
que todos los puertos se utilizarán como entradas y salidas digitales. Las
funciones output_x e input_x, no modifican el registro TRIS, por lo cual se
debe colocar necesariamente la instrucción para definir que los terminales
usados sean de salida o entrada respectivamente.
Al utilizar esta directiva, el compilador optimiza el código generado
y ahorra memoria de programa. El uso de las funciones output e input no
reprograman los puertos ya que quedan definidos en la instrucción TRIS.
Por tanto, la respuesta de los puertos para conmutaciones rápidas se ve
mejorado con el uso el uso de la directiva #use fast_io(port).
51
Ejercicio 2.5. Prende y apaga LED por el puerto RB0.
En el programa para definir el estado en alto del puerto se utiliza la
función output_high(PIN_B0) y el estado en bajo la función output_low(PIN_
B0). El registro TRIS no identifica con la dirección de memoria respectiva
y se hace referencia directamente para fijar al puerto B como salida con la
instrucción set_tris_b (00x00).
PROGRAMA:
#include <18f4550.h> / /Librería para usar el PIC18F4550.
#fuses HS,NOWDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles.
#use delay (clock=12000000) //FOSC=12MHz.
#use fast_io(b) //Define el puerto b como i/o digital.
void main(void) //Función principal main.
{
set_tris_b(0x00) //Define port_b como salida.
disable_interrupts(GLOBAL); //Todas las interrupciones desactivadas.
while(TRUE); //Bucle infinito.
{ //Inicio del bucle.
output_low(PIN_B0); //LED off.
delay_ms(500); //Retardo de 500 ms.
output_high(PIN_B0); //LED on.
delay_ms(500); //Retardo de 500 ms.
} //Fin del bucle infinito.
} //Fin del main.
c. Directiva #use fixed_io(puerto_outputs=pinx)
Con la directiva #use fixed_io(puerto_outputs=pinx), cuando se utilizan las
funciones input y output los puertos son reprogramados como entradas y
salidas por lo que el código generado es mayor. Sin embargo, se ahorra una
posición de memoria RAM por cada puerto utilizado.
Ejemplo: #use fixed_io(b_outputs=pin_b0, pin_b1)
52
Ejercicio 2.6. Prender y apagar un LED.
PROGRAMA:
/* MANEJO DEL PUERTO USANDO DIRECTIVA #USE FIXED */
#include <18F4550.h> / /Librería para usar el PIC18F4550.
#fuses HS,NOWDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles.
#use delay (clock=12000000) //FOSC=12MHz.
#use fixed_io(b_outputs=pin_b0) //Define el puerto b0 como salida.
void main() //Función principal main.
{
disable_interrupts(GLOBAL); //Desactiva todas las interrupciones.
while (TRUE) //Bucle infinito.
{ //Inicio del bucle.
output_high(pin_b0); //Puerto RB0 en alto.
delay_ms( 500 ); //Retardo de 500 ms.
output_low(pin_b0); //Puerto RB0 en bajo.
delay_ms(500); //Retardo de 500 ms.
} //Fin del bucle infinito.
} //Fin del bucle main.
Secuencias con LEDS
En muchas aplicaciones como en luces de discotecas, decoraciones de
locales, etc., se necesita controlar luces que deben un efecto visual atrayente.
Utilizando el microcontrolador se puede realizar una serie de proyectos de
este tipo.
Ejercicio 2.7. Secuencia de encendido y apagado de LEDS.
El ejercicio siguiente, consiste en activar y desactivar los LEDS que están
conectados al puerto uno a uno empezando desde el puerto RB0 hasta llegar
al RB7 en forma indefinida.
Para clarificar el funcionamiento y la secuencia de los bits que se desea
implementar, la tabla 2.7, muestra el estado del puerto b, en cada uno de los
bits que forman el puerto. 
53
RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0
0 0 0 0 0 0 0 1
0 0 0 0 0 0 1 0
0 0 0 0 0 1 0 0
0 0 0 0 1 0 0 0
0 0 0 1 0 0 0 0
0 0 1 0 0 0 0 0
0 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0
Tabla 2.7. Secuencia de encendido y apagado del puerto B.
Elaborado por los autores.
Para realizar el programa, se utiliza la siguiente lógica de programación:
• Inicializar el puerto B con (00000001), para activar el LED que está
conectado en RB0.
• Mostrar este valor durante un tiempo (100 ms).
• Desplazar el valor del puerto una posición a la izquierda (port_b = port_
b<<1).
• Repetir este proceso hasta que llegue el 1 al puerto RB7. Mediante el
bucle for se controla que el bit 1 que está en puerto RB0, se desplace
hasta llegar al puerto RB7. Como el puerto tiene ocho bits, entonces el
desplazamiento se debe repetir 7 veces. La instrucción que realiza esta
función es:  for (i=1;i<=8;++i).
• Al llegar el bit a la posición 7 el valor del puerto será 128 (27
=128). Apartir
de este valor, en este punto, el desplazamiento se realiza a la derecha
(port_b=port_b>>1) hasta que el bit llegue a RB0.
• Repetir el proceso.
54
PROGRAMA:
#include <18f4550.h> //Librería para usar el PIC18F4550
#fuses HS,NOWDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles.
#use delay (clock=12000000) //FOSC=12MHz
#BYTE port_b= 0xF81 //Identificador para el puerto b en la localidad 0xF81.
int i; //Variable i tipo int para el bucle FOR.
void main(void) { //Función principal main
set_tris_b(0x00); //Puerto B como salida
disable_interrupts(GLOBAL); //Todas las interrupciones desactivadas
while(TRUE) //Bucle infinito
{ //Inicio del bucle.
port_b=0x01; //Puerto RB0 = 1
for (i=1;i<=8;++i) //Realiza el bucle para i = 0 hasta que sea menor o igual 8 en
//incrementos de 1.
{
delay_ms(100); //Retardo de 100 ms
port_b= port_b<<1; //Desplaza el valor del puerto a la izquierda en 1
}
port_b= 128; //port_b = 128.
for (i=1;i<=8;++i) //Realiza el bucle para i = 0 hasta que sea menor o igual
//8 en incrementos de 1.
{
delay_ms(100); //Retardo de 100 ms
port_b= port_b>>1; //Desplaza el valor del puerto a la derecha en 1
}
} //Fin del bucle infinito.
} //Fin del bucle main.
Conexión en el Puerto A
En algunas familias de los PIC16F y 18F el puerto RA4, es de drenador
abierto, lo cual significa que en la salida se debe conectar una resistencia en
serie con el LED y luego a VDD
. Para los demás pines del puerto Ala conexión
es normal, como indica en la figura 2.6.
55
Figura 2.6. Conexión de LED en puerto RA4.
Elaborado por los autores.
Debido a la conexión, cuando el puerto RA4 tenga un nivel alto el LED2
se apaga y en un nivel bajo se prende.
Ejercicio 2.8. Manejo de LEDS con el puerto A.
PROGRAMA:
#include <18f4550.h> //Librería para usar el PIC18F4550
#fuses HS,NOWDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles.
#use delay (clock=12000000) // FOSC =12MHz
#BYTE port_a= 0xF80 //Identificador para el puerto a en la localidad 0xF80.
void main() //Función main.
{
set_tris_a(0x00); //Puerto A como salida.
disable_interrupts(GLOBAL); //Todas las interrupciones desactivadas.
port_a=0x00; //Puerto A = 0.
while(TRUE); //Bucle infinito
{
output_low(PIN_A0); //LED conectado en el Puerto RA0 off.
output_low(PIN_A4); //LED conectado en el Puerto RA4 on.
delay_ms(500); //Retardo 500 ms.
output_high(PIN_A0);//LED conectado en el Puerto RA0 on.
output_high(PIN_A4);//LED conectado en el Puerto RA4 off.
delay_ms(500); //Retardo 500 ms.
} //Fin del bucle infinito.
} //Fin del main
56
Conexión de pulsadores
Todos los ejercicios realizados, hasta aquí, los puertos del PIC se han
utilizado como salidas. A continuación se utilizaran como entradas. Se
conectan pulsadores para cambiar los niveles de tensión en los pines del
puerto.
La figura 2.7, muestra las conexiones para manejar pulsadores. Con esta
conexión los pines del puerto (RD0 y RD1), están directamente en estado
lógico de 1. Por consiguiente, el accionamiento del pulsador determina que
pasen los puertos indicados a bajo.
Figura 2.7. Conexión de pulsadores.
Elaborado por los autores.
Ejercicio 2.9. Manejo de pulsadores.
El ejercicio 2.9, consiste en prender un LED al accionar un pulsador 1
(P1) y apagar el LED al accionar el pulsador 2 (P2).
Los pulsadores P1 y P2 se han conectado al puerto D en los pines RD0
y RD1 respectivamente. En el programa se definen las variables prender y
apagar mediante las directivas #define prender bit_test(port_d,0), #define
apagarbit_test(port_d,1),lascualespermitentestearelestadodelasentradas.
57
PROGRAMA:
#include <18f4550.h> / /Librería para usar el PIC18F4550.
#fuses HS,WDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles.
#use delay (clock=12000000) // FOSC =12MHz.
#BYTE port_b= 0xF81 //Identificador para el puerto b en la localidad 0xF81
#BYTE port_d= 0xF83 //Identificador para el puerto d en la localidad 0xF83.
#define prender bit_test(port_d,0) //Define el pin RD0 para prender.
#define apagar bit_test(port_d,1) //Define el pin RD1 para apagar.
void main(void) //Función principal main.
{
set_tris_b(0x00); //Define puerto b como salida.
set_tris_d(0xff); //Define puerto d como entrada.
disable_interrupts(GLOBAL); //Todas las interrupciones desactivadas.
while(TRUE){ //Inicio del bucle.
if (prender == 0) //Censa si P1= 0 .
{
bit_set(port_b,0); //LED on.
}
if (apagar==0) //Censa si P2 = 0.
{
bit_clear(port_b,0); //LED off.
}
} / /Fin de bucle infinito.
} //Fin del main.
Uso de la función input
Otra forma de censar el estado de los pines es utilizando la función
input(PIN_D0) == 0. Para este caso si el pin del puerto D0 (o cualquier
otro) que está en alto, si cambia de estado será detectado por la instrucción
indicada. 
58
Ejercicio 2.10. Manejo de pulsadores mediante la función input.
PROGRAMA:
#include <18f4550.h> //Librería para usar el PIC18F4550.
#fuses HS,WDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles.
#use delay (clock=12000000) / /FOSC =12MHz
#use standard_io(B) //Usa librería estándar para el puerto B.
#use standard_io(D) //Usa librería estándar para el puerto D.
void main(void) //Función principal main.
{
disable_interrupts(GLOBAL); //Todas las interrupciones desactivadas.
output_low(PIN_B0); //LED off.
while(TRUE){ //Inicio del bucle.
if (input(PIN_D0) == 0) //Detecta si se accionado el pulsador P1.
output_high(PIN_B0); //LED on.
if (input(PIN_D1) == 0) //Detecta si se accionado el pulsador P2.
output_low(PIN_B0); //LED off.
} / Fin de bucle infinito.
} //Fin del main.
Uno de los problemas que presentan los pulsadores mecánicos al
momento de su accionamiento es el rebote de los contactos, lo que genera
que se produzcan varios transitorios de voltaje (pulsos) que afectan el
funcionamiento normal del circuito.
Una forma práctica de averiguar el anti rebote, es mediante el siguiente
ejercicio, que consiste, en prender y apagar un LED con un mismo pulsador.
En este caso al accionar el pulsador se prende el LED (si está apagado), y al
volver a accionar el mismo pulsador se apaga el LED.
59
Ejercicio 2.11. Efecto del rebote mecánico de un pulsador.
PROGRAMA:
#include <18f4550.h> //Librería para usar el PIC18F4550.
#fuses HS,WDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles.
#use delay (clock=12000000) / / FOSC =12MHz.
#use fast_io(b) //Directivas de i/o para puerto b.
#use fast_io(d) //Directivas de i/o para puerto d.
#BYTE port_b= 0xF81 //Identificador para el puerto b en la localidad 0xF81.
#BYTE port_d= 0xF83 //Identificador para el puerto d en la localidad 0xF83.
#define pulsador bit_test(port_d,0); //Define el pin RD0 para prender.
int k; //Variable k para determinar el estado del LED.
void main() //Función principal main.
{
set_tris_b(0x00); //Fija el puerto B como salida.
set_tris_d(0xff); //Fija el puerto D como entrada.
disable_interrupts(GLOBAL); //Todas las interrupciones desactivadas.
port_b = 0; //Port =0.
k= 0; //k=0.
while(TRUE){ //Inicio del bucle.
if (pulsador== 0 && k==0) //Si pulsador = 0 y k = 0, realiza.
{
k= 1; //k=1.
bit_set(port_b,0); //LED on.
}
if (pulsador==0 && k==1) //Si pulsador = 0 y k = 1, realiza…..
{
k=0; //k=0.
bit_clear(port_b,0); //LED off.
}
} //Bucle infinito.
} //Fin del main.
La variable k, permite en conjunto con el estado del pulsador prender
el LED (k=0) y apagar el LED (k=1). Observe también que se efectúa una
operación lógica AND con el estado de la entrada (pulsador == 0 && k==0). 
Al simular el programa o implementar en protoboard, el circuito de la
figura 2.8, se observa como el LED titila varias veces hasta que se estabiliza:
60
quedando prendido o apagado. Claramente existe una situación de
ambigüedad porque el LED no se sabe, qué estado tomará por la condición
del pulsador.
Figura 2.8. Circuito para demostrar el rebote mecánico del pulsador.
Elaborado por los autores.
Una forma de eliminar este inconveniente es mediante la inclusión de
compuertas Smitch Trigger, o por software, como se presenta a continuación.
Ejercicio 2.12. Eliminación del rebote del pulsador.
PROGRAMA:
#include <18f4550.h> //Librería para usar el PIC18F4550.
#fuses HS,WDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles.
#use delay (clock=12000000) // FOSC =12MHz.
#use fast_io(b) //Directivas de i/o para puerto b.
#use fast_io(d) //Directivas de i/o para puerto d.
#BYTE port_b= 0xF81 //Identificador para el puerto b en la localidad 0xF81.
#BYTE port_d= 0xF83 //Identificador para el puerto b en la localidad 0xF83.
#define pulsador bit_test(port_d,0); //Define el pin RD0 para prender.
int k; //Variable k para determinar el estado del LED.
void antirebote(); //Función anti rebote.
61
void main() //Función principal main.
{
set_tris_b(0x00); //Fija el puerto B como salida.
set_tris_d(0xff); //Fija el puerto D como entrada.
disable_interrupts(GLOBAL); //Todas las interrupciones desactivadas.
port_b = 0; //Port =0.
k= 0; //k=0.
while(TRUE){ //Inicio del bucle.
if (pulsador== 0 && k==0) //Si pulsador = 0 y k = 0, realiza.
{
antirebote(); //Si el pulsador = 0 llama a subrutina anti rebote.
k= 1; //k=1.
bit_set(port_b,0); //LED on.
}
if (pulsador==0 && k==1) //Si pulsador = 0 y k = 1, realiza…..
{
antirebote(); //Si el pulsador = 0 llama a subrutina anti rebote.
k=0; //k=0.
bit_clear(port_b,0); //LED off.
}
} //Bucle infinito.
} //Fin del main.
void antirebote(void) //Función anti rebote.
{
while(pulsador == 0) { } //No realiza nada hasta que el pulsador esté inactivo.
delay_ms(30); //Retardo de 30 ms.
return; //Retorna al programa principal.
} //Bucle infinito.
Cada vez que se accione un pulsador se averigua si el estado del puerto
sigue siendo 0, de ser afirmativo se llama a una función “antirebote”, para
que de mantenerse en este estado no realice ninguna acción hasta que el
pulsador este inactivo. La instrucción usada para el efecto es while(pulsador
== 0) { }. Una vez que el pulsador este inactivo, de la función retornará (por
return) al programa a siguiente instrucción desde donde fue llamado a seguir
ejecutando el programa.
AlsimularoimplementarelcircuitoseobservaqueelLEDinmediatamente
se prende o se apaga, según el caso, eliminando el efecto del rebote del
pulsador mecánico.
62
Generación de sonido
Otro de los elementos de Multimedia es el sonido, que vienen
incorporados en la mayoría de equipos de comunicación y de procesamiento
de información, razón por la cual, en este punto nos centraremos a la
generación de sonido usando el microcontrolador, ya que los instrumentos y
otros equipos electrónicos como pianos, guitarras eléctricas, ecualizadores,
sintetizadores, alarmas, reloj digital, celulares, etc., basan el tratamiento y la
generación de sonido en forma electrónica.
Las canciones, voz y sonido audible se componen de notas musicales:
DO, RE, MI, FA, SOL, LA, SI. En términos de electrónica, cada nota
musical equivale a una frecuencia. La tabla 2.8 muestra la nota musical y la
correspondiente frecuencia.
NOTA FRECUENCIA (Hz)
DO – C 262
RE – D 294
MI – E 330
FA – F 349
SOL- G 392
LA – A 440
SI – B 494
Tabla 2.8. Notas musicales y su correspondiente frecuencia.
Fuente: Electrónica, Microcontroladores y Psicología: Internet.
Las letras al lado de cada nota pertenecen a la nomenclatura inglesa. La
librería TONES.C que maneja el sonido utiliza la nomenclatura inglesa.
Las notas tienen una duración, que está determinada por las figuras
musicales, indicadas en la tabla 2.9.
FIGURA MUSICAL TIEMPO DE DURACIÓN
Fusa 62 ms
Semicorchea 125 ms
Corchea 250 ms
Negra 500 ms
Blanca 1 segundo
Redonda 2 segundos
Tabla 2.9. Duración de una figura musical.
Fuente: Electrónica, Microcontroladores y Psicología: Internet.
63
El intervalo de frecuencias sonoras audibles se suele dividir en 10
intervalos de frecuencia (10 octavas), como muestra la tabla 2.10.
OCTAVA FRECUENCIA
(Hz)
Primera 15 – 30
Segunda 30 – 60
Tercera 60 – 125
Cuarta 125 – 250
Quinta 250 – 500
Sexta 500 – 1000
Séptima 1000 – 2000
Octava 2000 – 4000
Novena 4000 – 8000
Décima 8000 – 16000
Tabla 2.10. Octavas y sus equivalencias en frecuencia.
Fuente: Electrónica, Microcontroladores y Psicología: Internet.
El compilador CCS trae incorporado la librería llamada TONES.C para
generar las notas musicales. Esta librería incluye la función:
generate_tone(frequency,duration);quepermitecrearlasnotasmusicales.
Los argumentos de la función son:
Frecuency, es una variable que toma el valor de la nota que se requiere
generar, es decir la frecuencia de la nota.
Duration, es el tiempo que dura la nota y está dada en milisegundos.
Cada nota trae en la librería predefinida las frecuencias, lo cual permite elegir
en que octava tocarla; hasta una tercera octava.
Una parte del código de la librería TONES.C, se indica en la figura 2.9.
64
Figura 2.9. Parte del código de la librería TONES.C, compilador CCS, versión 4.084.
Elaborado por los autores.
Tomando en cuenta esto (octavas y sus frecuencias), lo único que se
necesita son las partituras de las canciones que deseamos generar o combinar
las notas para crear diversos sonidos.
En la librería TONES.C, está definido el pin del puerto B.0 por donde
genera las señales del sonido, como se ve en la figura 2.10. Basta modificar
esta línea para utilizar cualquier otro pin del PIC.
Figura 2.10. Definición del pin por donde se genera la señal del sonido. Compilador CCS versión 4.084
Elaborado por los autores.
65
Ejercicio 2.13. Generación de sonido.
En el siguiente ejercicio se van a generar las notas musicales DO, RE,
MI, FA, SOL y con octavas alternadas de 0 a la 3 que proporciona la librería
TONES.C
PROGRAMA:
#include <18f4550.h> / /Librería para usar el PIC18F4550.
#fuses HS,NOWDT,NOPROTECT,NOPUT, NOLVP //Configuración de fusibles.
#use delay (clock=12000000) //FOSC =12MHz.
#include <TONES.c> //Librería para gestión de sonido.
void main(void) { //Función principal main.
int fusa=62; //Tiempo de duración fusa.
int semicorchea=125; //Tiempo de duración semicorchea.
int corchea=250; //Tiempo de duración corchea.
while(TRUE) { //Bucle infinito.
generate_tone(C_NOTE[0],fusa);
generate_tone(C_NOTE[1],fusa);
generate_tone(Eb_NOTE[2],corchea);
generate_tone(C_NOTE[3],fusa);
generate_tone(C_NOTE[0],fusa);
generate_tone(Eb_NOTE[1],corchea);
generate_tone(C_NOTE[3],fusa);
generate_tone(Eb_NOTE[3],fusa);
generate_tone(Ab_NOTE[3],semicorchea);
generate_tone(G_NOTE[3],semicorchea);
generate_tone(F_NOTE[3],semicorchea);
generate_tone(F_NOTE[3],semicorchea);
generate_tone(Eb_NOTE[3],semicorchea);
delay_ms(100);
} //Fin del bucle infinito.
} //Fin del main.
66
Figura 2.11. Circuito para generar sonido.
Elaborado por los autores.
En la figura 2.12, se muestra el circuito para la generación del sonido.
Se debe acotar que el microcontrolador genera pulsos de voltaje cuadrados,
es necesario filtrar esta señal. La inclusión de un capacitor como filtro a la
salida ayuda a mejorar la señal audible. En todo caso, esto no garantiza la
calidad del sonido. No es del alcance del texto realizar un análisis de filtros o
del filtrado de la señal, por lo que el lector interesado puede consultar textos
especializados para el manejo de filtros digitales o analógicos.
EJERCICIOS ADICIONALES
Ejercicios resueltos
Encender y apagar un LED con un interruptor.
En este ejercicio, cuando el interruptor está abierto el LED se apaga y
cuando el interruptor está cerrado el LED se prende. Además se activan las
resistencias PULL_UP para conectar internamente al puerto B a 5V.
67
PROGRAMA:
#include <18f4550.h> //Librería para usar el PIC18F4550.
#fuses HS,WDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles.
#use delay (clock=12000000) //FOSC =12MHz
#byte tris_b = 0xF93 //Identificador para el registro TRIS B en la localidad 0xF93.
void main() { //Función principal main.
set_tris_b(0xFF); //Fija el Puerto B como salida.
port_b_pullups(TRUE); //Habilitación del Pull-up.
while(TRUE){ //Bucle Infinito.
if (input(PIN_B3) == 0) //Detecta si se accionado el pulsador P1….
output_high(PIN_D0); //….y activa al LED.
else //caso contrario…..
output_low(PIN_D0); //….el LED permanece apagado.
} //Fin del bucle infinito.
} / /Fin del main.
Figura 2.12. Conexión de un interruptor con resistencia PULL-UP interna.
Elaborado por los autores.
68
Secuencia de LEDS.
En este programa para que los LEDS conectados al puerto B se activen
empezando desde RB0 hasta RB7. Luego empiezan a desactivarse uno por
uno desde el último que se activó. La tabla 2.11, ilustra el funcionamiento.
RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 0 1 1
0 0 0 0 0 1 1 1
0 0 0 0 1 1 1 1
0 0 0 1 1 1 1 1
0 0 1 1 1 1 1 1
0 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
0 1 1 1 1 1 1 1
0 0 1 1 1 1 1 1
0 0 0 1 1 1 1 1
0 0 0 0 1 1 1 1
0 0 0 0 0 1 1 1
0 0 0 0 0 0 1 1
0 0 0 0 0 0 0 1
Tabla 2.11. Secuencia de encendido de LEDS.
Elaborado por los autores.
Figura 2.13. Encendido y apagado secuencial de LEDS.
Elaborado por los autores.
69
Uso de la resistencias internas Pull Up.
En el siguiente ejercicio un pulsador se conecta al puerto RB0 y un LED
al puerto RA0. Al accionar el pulsador el LED se prende, caso contrario el
LED permanece apagado. Se activa las resistencias internas Pull Up del
puerto B mediante la instrucción port_b_pullups (TRUE); con el propósito
de conectar el pulsador a VCC
y al accionar el mismo se conecte a GND.
PROGRAMA:
#include <16f88.h> //Librería para usar el PIC16F88.
#fuses INTRC,NOWDT,NOMCLR,NOPROTECT,NOPUT //Configuración de fusibles.
#use delay (clock=4000000) //Fosc=4MHz
void main(void){ //Función principal main.
port_b_pullups (TRUE); //Activa las resistencias Pull Up del puerto B.
disable_interrupts(GLOBAL); //Todas las interrupciones desactivadas.
output_low(PIN_A0); //Pin A0= 0.
while(TRUE){ //Bucle infinito.
if (input(PIN_B0) == 0) //Si pin RB0= 0….
output_high (PIN_A0); //Pin RA0= 1.
else //Caso contrario…
output_low(PIN_A0); / /Pin RA0=0.
} //Fin del bucle infinito
} //Fin del main.
70
Figura 2.14. Demostración del funcionamiento de las resistencias PULL UP del puerto RB.
Elaborado por: Los Autores.
Ejercicios propuestos
Realice un programa para controlar dos semáforos.
Desarrolle el programa para que los LEDS conectados al puerto B se
activen y desactiven según indica la secuencia en la tabla 2.12.
Nota: Optimizar la programación sin utilizar instrucciones repetitivas, en
base a las instrucciones de desplazamiento elaborar una ecuación matemática
para mover los bits.
RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 0 1 1
0 0 0 0 0 1 1 1
0 0 0 0 1 1 1 1
0 0 0 1 1 1 1 1
0 0 1 1 1 1 1 1
0 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
71
1 1 1 1 1 1 1 0
1 1 1 1 1 1 0 0
1 1 1 1 1 0 0 0
1 1 1 1 0 0 0 0
1 1 1 0 0 0 0 0
1 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
Tabla 2.12. Secuencia de encendido para el ejercicio 2.5.
Elaborado por los autores.
Codifique la tabla de datos para manejar directamente a través del puerto
B un display de 7 segmentos tipo cátodo común y realice el programa para
un contador descendente.
Realice un programa para manejar los LEDS conectados a los puertos B y
D. La secuencia de la tabla 2.13, se realiza en el puerto D y la secuencia de la
tabla 2.14, en el puerto B. Optimizar la programación sin utilizar instrucciones
repetitivas, utilizar instrucciones de desplazamiento.
RD7 RD6 RD5 RD4 RD3 RD2 RD1 RD0
0 0 0 0 0 0 0 1
0 0 0 0 0 0 1 0
0 0 0 0 0 1 0 0
0 0 0 0 1 0 0 0
0 0 0 1 0 0 0 0
0 0 1 0 0 0 0 0
0 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 1 0 0 0 0 0 0
0 0 1 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0
Tabla 2.13. Secuencia de encendidos de LEDs, para el ejercicio 2.7.
Elaborado por los autores.
72
RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 0 1 1
0 0 0 0 0 1 1 1
0 0 0 0 1 1 1 1
0 0 0 1 1 1 1 1
0 0 1 1 1 1 1 1
0 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 0
1 1 1 1 1 1 0 0
1 1 1 1 1 0 0 0
1 1 1 1 0 0 0 0
1 1 1 0 0 0 0 0
1 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
Tabla 2.14. Secuencia de encendidos de LEDs, para el ejercicio 2.7.
Elaborado por los autores.
Figura 2.15. Circuito para el ejercicio 2.7.
Elaborado por los autores.
73
En el circuito de la figura 2.16, el LED D1 se activa al pulsar P1, D2 con
P2 y D3 con P3. Cualquier LED puede activarse si los tres están apagados. El
pulsador P4, sirve para apagar el LED que esté prendido.
Figura 2.16. Ejercicio 2.8.
Elaborado por los autores.
Realizarelprogramaparasimularelfuncionamientodedosconmutadores
de tres vías. Al pulsar cualquiera de los pulsadores el estado del LED cambia.
Figura 2.17. Ejercicio 2.9.
Elaborado por los autores.
74
Realizar el programa para prender 3 LEDS en secuencia al ir pulsando P1
y apagarlos con P2, si los tres LEDS están prendidos.
Figura 2.18. Encendido secuencial de LEDS.
Elaborado por los autores.
75
76
Para la visualización de datos es muy común el uso de displays de 7
segmentos, módulos LCD y GLCD, por lo que en este capítulo revisaremos
las diferentes formas de manejo y control de estos dispositivos, con el
propósito de que los estudiantes tengan las herramientas suficientes para
programar y controlar los puertos del Microcontrolador. El manejo de los
teclados hexadecimales es otra que las aplicaciones que abordamos en este
capítulo.
Manejo de Display de 7 segmentos
Para visualizar los datos en un display de 7 segmentos, existen dos
posibilidades.
•	Conectar un decodificador de BCD a 7 segmentos,
•	Conectar el display directamente al puerto.
Figura 3.1. Conexión de display de 7 segmentos tipo ánodo común
Elaborado por los autores.
77
Conexión de un decodificador de BCD a 7 segmentos
Un decodificador de BCD a 7 segmentos tiene cuatro líneas de entrada
y siete salidas, el código binario generado por el microcontrolador es
transformado a 7 segmentos para ser visualizado en el display. Si el display es
de ánodo común se utiliza el decodificador TTL 7447, para un display cátodo
común el decodificador TTL 7448. La figura 3.1, muestra las conexiones de
un decodificador 7447 y un display ánodo común. Se debe tener en cuenta
de limitar la corriente de los segmentos mediante resistencias. El uso de
resistencias de valores entre 220Ω y 330Ω garantiza el funcionamiento normal
del display.
Ejercicio 3.1. Contador de 0 a 9 utilizando un decodificador y display.
EnestecasolosdatosdeuncontadorrealizadoenunbucleFOR,sepueden
sacar directamente al puerto y el decodificador se encarga de convertirlos en
7 segmentos. La variable i se incrementa en 1 cada 500 ms y este valor es
asignado al puerto b (port_b= i;)
PROGRAMA:
#include <18f4550.h> //Librería para usar el PIC18F4550.
#fuses HS,WDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles.
#use delay (clock=12000000) // FOSC = 12MHz.
#BYTE port_b= 0xF81 //Identificador para el puerto b en la localidad 0xF81.
int i; //Variable i para el bucle FOR.
void main(void) //Función principal main.
{
set_tris_b(0x00); //Define port_b como salida
disable_interrupts(GLOBAL); //Todas las interrupciones desactivadas.
port_b = 0; //Puerto b = 0.
while(TRUE) //Bucle infinito.
{ //Inicio del bucle.
for (i=0; i<=9;++i){ //Repite mientras i sea menor o igual a 9.
delay_ms(500); //Retardo de 500 ms.
port_b= i; //El valor de i se saca al Puerto B. i varia de 0 a 9.
}
} //Fin del bucle de inicio.
} //Fin del bucle main.
78
Manejo directo de display de 7 segmentos
En ciertas aplicaciones donde se disponen de suficientes líneas del puerto
del microcontrolador y reducir el espacio físico es la prioridad, el display se
puede conectar directamente a cualquier puerto.
En la figura 3.2, se muestra el circuito del display conectado al puerto B
del microcontrolador. Se utiliza un display de ánodo común por lo que el
terminal común del display se conecta a VCC
. También se podría utilizar un
display cátodo común.
Así mismo, como cuando se utiliza un driver decodificador de 7
segmentos, se debe tener cuidado de utilizar las resistencias limitadores
de corriente para conectar los segmentos del display al puerto y evitar
que se produzcan posibles sobrecorrientes que puedan afectar al puerto o
al segmento del display. Resistencias con valores entre 220Ω y 330Ω, son
comunes utilizar para activar los segmentos del display.
Figura 3.2. Conexión directa del display de 7 segmentos al microcontrolador.
Elaborado por los autores.
Ahora considerando que los datos que salen al puerto deben estar
decodificadosen7segmentos,sedebeelaborarlatabladedatosdecodificados
para manejar por software y obtener los números respectivos.
La tabla 3.1, muestra los valores para activar los segmentos de un display
ánodo común, recuerde que el display de ánodo común con un nivel alto (1)
el segmento se desactiva y con un nivel bajo (0) el segmento se activa.
79
g f e d C B a Equivalencia decimal Número en el display
1 0 0 0 0 0 0 64 0
1 1 1 1 0 0 1 121 1
0 1 0 0 1 0 0 36 2
0 1 1 0 0 0 0 48 3
0 0 1 1 0 0 1 25 4
0 0 1 0 0 1 0 18 5
0 0 0 0 0 1 1 3 6
1 1 1 1 0 0 0 120 7
0 0 0 0 0 0 0 0 8
0 0 1 0 0 0 0 16 9
Tabla 3.1. Datos decodificados para activar al display de 7 segmentos.
Elaborado por los autores.
Ejercicio 3.2. Contador MOD 10, manejando directamente el display
de 7 segmentos con el microcontrolador.
Los datos mostrados en la tabla 3.1 deben ser enviados directamente al
puerto para activar los segmentos según el número indicado. Para esto en el
programa en una constante tipo array se almacenan los valores codificados:
const int x[]= {64,121,36,48,25,18,2,120,0,16};
Mediante el lazo for se van sacando los valores desde el 0 hasta el 9.
La variable i del bucle for va asignando al puerto el valor que ocupa en el
vector const. Así, por ejemplo si i vale 3, el puerto tendrá el valor de 48 que
corresponde al número 3. Observe la instrucción port_d= x[i].
80
PROGRAMA:
#include <18f4550.h> //Librería para usar el PIC18F4550
#fuses HS,WDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles
#use delay (clock=12000000) //FOSC =12MHz
#BYTE port_d= 0xF83 //Identificador para el puerto d en la localidad 0xF83.
int i; //Variable i, contador para el bucle FOR.
const int x[]= {64,121,36,48,25,18,2,120,0,16};//Tabla de datos decodificados a 7 segmentos.
void main(void) //Función principal main.
{
set_tris_d(0x00); //Identificador para el puerto d como salida.
disable_interrupts(GLOBAL); //Todas las interrupciones desactivadas.
port_d = 64; //Asigna el valor de 64 al Puerto para ver el número 0.
while(TRUE) //Bucle infinito.
{ //Inicio del bucle.
for (i=0; i<=9;++i) //Repite mientras i sea menor o igual a 9.
{
delay_ms(500); //Retardo de 500 ms. Necesario para mantener el dato en el
// puerto.
port_d= x[i]; //Asigna al puerto el valor apuntado por la variable i en el
//array x.
}
} //Fin del bucle infinito.
} //Fin del main.
MULTIPLEXACIÓN DE DISPLAYS DE 7 SEGMENTOS
En ciertos proyectos es necesario el ahorro de las líneas de los puertos
para utilizarlos en otras aplicaciones, en estos casos, se recurre a manejar
los displays por el mismo puerto. Esto se consigue usando el principio de la
multiplexación.
Para el ejemplo se va a diseñar un contador módulo 100 (00-99). Los
datos de las unidades se visualizan en el display 1 y las decenas en el display
2. Para controlar los dos displays simultáneamente, el proceso consiste en
prender el display 1 y apagar el display 2 durante un corto tiempo y mostrar
los datos de las unidades, luego prender el display 2 y apagar el display 1
para indicar los datos de las decenas. El encendido y apagado de los displays
se realiza controlando la corriente de la base de dos transistores que trabajan
en corte y saturación los mismos que manejan a los displays como se indica
en la figura 3.3.
81
LosdatosenbinarioparalosdisplayssonenviadosporelpuertoRB0:RB3,
el decodificador 7447 convierte de BCD a 7 segmentos. Las dos líneas de
control para los transistores PNP, son del puerto RD0 y RD1 (líneas S1 y S2).
Los transistores permanecen en corte y saturación durante 20 ms, con lo cual
para ojo humano “casi” es imperceptible el apagado del display y apenas
existirá un leve parpadeo. Esta acción se repite por 50 veces en la función
display() obteniendo un tiempo de retardo de 1s.
En la figura 3.3, RD0 controla al display de las decenas y RD1 al display
de las unidades, por tanto, cuando se ejecuta la instrucción port_d= 1; RD0=1
y RD1= 0, con lo cual el transistor Q1 se apaga y el transistor Q2 se prende,
los datos del puerto corresponden a las unidades port_b= unidad. En el caso
de port_d= 2; RD0=0 y RD1= 1, en este caso el transistor Q1 se prende y
el transistor Q2 se apaga, los datos del puerto corresponden a las decenas
port_b= decenas. Recuerde que en los transistores PNP con un 0 lógico en la
base conduce y con un 1 lógico en la base el transistor está abierto.
La figura 3.3, muestra las conexiones para manejar por el mismo puerto
y un solo decodificador dos display de 7 segmentos simultáneamente.
Ejercicio 3.3. Manejo de dos display por principio de multiplexación
PROGRAMA:
#include <18f4550.h> //Librería para usar el PIC18F4550.
#fuses HS,WDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles.
#use delay (clock=12000000) //FOSC =12MHz.
#BYTE port_b= 0xF81 //Identificador para el puerto b en la localidad 0xF81.
#BYTE port_d= 0xF83 //Identificador para el puerto d en la localidad 0xF83.
int unidad, decena, x; //Variables.
//Función display. Muestra los datos en los display y genera un retardo de 1segundo.
void display()
{
for (x= 1; x<= 25; ++x){ //Repite 25 veces.
port_d = 1; //Habilita display unidad y apaga display decena.
port_b= unidad; //Asigna al Puerto b el dato de unidad.
delay_ms(20); //El dato de unidad permanece el Puerto b 20 ms.
port_d = 2; //Habilita el display decena y apaga display unidad.
port_b= decena; //Asigna al Puerto b el dato de decena.
delay_ms(20); //El dato de decena permanece el Puerto b 20 ms.
82
}
return; //Retorna al programa principal.
}
void main(void) //Función principal main.
{
set_tris_b(0x00); //Define port_b como salida.
set_tris_d(0x00); //Identificador para el puerto d como salida.
disable_interrupts(GLOBAL); //Todas las interrupciones desactivadas.
port_b = 0; //Puerto b =0.
while(TRUE){
for (decena=0; decena<=9;++decena){ //Datos para el display decena 0 a 9.
for (unidad=0; unidad<=9;++unidad){ //Datos para el display unidad 0 a 9.
display(); //Función display.
}
}
} //Fin del bucle infinito.
} //Fin del bucle main.
Figura 3.3. Conexión de dos display con el mismo decodificador.
Elaborado por los autores.
83
Módulo LCD
Los módulos LCD son muy útiles para ver cualquier tipo de información.
La pantalla de cristal líquido está conformada por  una, dos o cuatro líneas
de 8, 16, 20, 24 o 40 caracteres de 5x7 pixels c/u. Los más comunes son los
módulos LCD de 16x2, 16x4, con y sin backlight). La figura 3.4 a, muestra
una vista de módulo LCD 16 x2 de 16 pines (los pines 15 y 16 corresponden
al backlight, control de luz de fondo). Las conexiones para controlar el
contraste y el backlight del LCD se indican en la figura 3.4 b. Dependiendo el
puerto que se utilice los demás pines se conectan al microcontrolador como
veremos más adelante.
Imagen de un módulo LCD típico.
Conexiones de las señales de contraste y backlight para LCD que disponen de esos terminales.
Figura 3.4. Módulo LCD.
Elaborado por los autores.
84
La descripción de pines del módulo LDC, se indica en la tabla 3.2.
Pin
número
Símbolo Función
1 Vss Tierra o Masa
2 Vdd Alimentación   + 5 VDC
3 Vo
Voltaje de ajuste de contraste (5V no visible,
0v más visible)
4 R/S Selección de Dato / Comando
5 R/W Lectura / Escritura
6 E Habilitador
7 D0 1a línea de datos (LSB)
8 D1 2a línea de datos
9 D2 3a línea de datos
10 D3 4a línea de datos
11 D4 5a línea de datos
12 D5 6a línea de datos
13 D6 7a línea de datos
14 D7 8a línea de datos (MSB)
15 A Alimentación Backlight +3.5 V a +5V
16 K GND del Backlight
Tabla 3.2. Funciones de los pines del módulo LCD.
Elaborado por los autores
El compilador CCS incluye un archivo (driver) lcd.c. El driver lcd.c está
configurado para trabajar con el puerto d. Modificando este fichero es posible
usarlo para cualquier puerto.  El fichero se llama con #include <lcd.c> y
algunas funciones que presenta son: 
Las instrucciones básicas para manejar el LCD son las siguientes:
lcd_init();
Es la primera función que debe ser llamada. Borra el LCD y lo configura
en formato de 4 bits con dos líneas y con caracteres de 5x8 puntos, en
modo encendido, cursor apagado y sin parpadeo. Configura el LCD con
un autoincremento del puntero de direcciones y sin desplazamiento del
display real.
lcd_gotoxy(byte x, byte y);
85
Indica la posición de acceso al LCD. Por ejemplo (1,2) indica la primera
posición de la segunda línea; (2,1)  segunda posición de la primera línea  (El
LCD tratado tiene 16 posiciones en cada línea).
lcd_getc (byte x, byte y);
Lee el carácter de la posición (x,y).
lcd_putc (char s);
Escribe la variable en la posición correspondiente, s es una variable tipo
char. Además se puede incluir:
f se limpia el LCD.
n el cursor cambia de línea.
b el cursor retrocede una posición.
Existe la función printf  que es más versátil para trabajar en el LCD.
	 printf (string)
	 printf (cstring, valores,,)
	 printf(fname, cstring, valores,,)
string es una cadena o array de caracteres, valores es una lista de variables
separadas por comas, y fname es una función. 
	 El formato es %nt,
	Dónde:
		 n es opcional y puede ser:
		 1-9 especifica el número de caracteres.
		 01-09 indica la cantidad de ceros a la izquierda.
		 1.1-9.9 para punto flotante.
t puede indicar un: carácter c, cadena o caracteres, entero sin signo u,
entero con signo d, entero largo sin signo Lu, Entero largo con signo Ld,
entero hexadecimal (minúsculas) x, entero hexadecimal (mayúsculas)
X, entero largo hexadecimal (minúsculas) Lx, entero largo hexadecimal
(mayúsculas) LX, flotante con truncado f, flotante con redondeo g, flotante
el forma exponencial e, entero sin signo con decimales insertados w.
86
Manejo del módulo LCD usando Puerto D
El siguiente programa envía el conocido mensaje “HOLA MUNDO” al
LCD. Abran el archivo C:Archivos de programaPICCDriverslcd.c, y
ahí les muestra la forma de conectar el LDC a los pines del puerto D, como se
indica en la figura 3.5. Se debe aclarar que el archivo utilizado corresponde
al CCS versión v4.084.
Figura 3.5. Conexión de pines del PIC con el LCD.
Elaborado por los autores.
Ejercicio 3.4. Manejo del módulo LCD por el Puerto D.
Algunos aspectos importantes para manejar el LCD son:
• Incluir la librería que maneja el LCD: #include <lcd.c>
• Inicializar el LCD: lcd_init(); esta instrucción “arranca” el LCD.
• Situar el cursor en la posición columna y fila desde donde se visualice los
caracteres: lcd_gotoxy(4,1); en este caso está indicando que empiece en la
columna 4 fila 1.
• Escribir el mensaje: lcd_putc(“HOLA MUNDO!!n LCD en CCS”). En
la instrucción el argumento n. Por tanto, en la primera fila a partir de
la columna 4 en el LCD se indicará la palabra HOLA MUNDO!!, y en
la segunda fila a partir de la columna 4 se mostrará LCD en CCS. Cada
espacio en blanco que separa los caracteres o leras (n LCD) ocupan una
posición en las columnas del LCD.
87
PROGRAMA:
#include <18f4550.h> //Librería para usar el PIC18F4550.
#fuses HS, NOPROTECT, NOWRT, NOPUT, NOWDT //Configuración de fusibles.
#use delay (clock=12000000) //FOSC =12MHz.
#include <lcd.c> //Librería lcd.c
set_tris_d(0x00); //Identificador para el puerto d como salida
void main(void) //Función principal main.
{
lcd_init(); // Inicializa el LCD.
lcd_gotoxy(4,1); //Sitúa el cursor en columna 4, fila 1.
lcd_putc("HOLA MUNDO!!n LCD en CCS"); //Escribe en el LCD.
}
Para cambiar el cursor de una línea a otra o posicionar en una columna
distinta la instrucción lcd_gotoxy(x,y); es de mucha utilidad. En el presente
ejercicio se tiene el mismo resultado si se escribe el código así:
lcd_gotoxy(4,1); 				 //Sitúa el cursor en columna 4, fila 1.
lcd_putc(“HOLA MUNDO!! “); 	 //Escribe en el LCD.
lcd_gotoxy(4,2); 				 //Sitúa el cursor en columna 4, fila 2.
lcd_putc(LCD en CCS”); 		 //Escribe en el LCD.
Todo dependerá de las necesidades de diseño y habilidades del
programador. El diagrama de conexiones para realizar las pruebas de
funcionamiento de los programas del módulo LCD conectado al puerto D,
se muestra en la figura 3.6. No están consideradas las conexiones del control
de contraste y el Bach light. Al implementar el circuito físico las conexiones
mencionadas se indican en la figura 3.4 b.
88
Figura 3.6. Conexión del LCD en el puerto D.
Elaborado por los autores.
Para indicar el valor de una variable se debe utilizar la función printf(lcd_
putc,” %d constante  “,variable);
Ejercicio 3.5. Contador con visualización en LCD.
El ejercicio 3.5, muestra un contador ascendente de 0 a 9 con visualización
de datos en el LCD. Para mostrar el valor numérico se utiliza la instrucción
printf(lcd_putc,” %d “,i). El argumento %d de la función printf indica que el
valor de la variable i es entero decimal.
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1
Microcontroladores: Programación de microcontroladores tomo 1

Más contenido relacionado

La actualidad más candente

Respuesta en frecuencia
Respuesta en frecuenciaRespuesta en frecuencia
Respuesta en frecuencia
hebermartelo
 
Modelos equivalentes de pequeña señal de los transistores fet
Modelos equivalentes de pequeña señal de los transistores fetModelos equivalentes de pequeña señal de los transistores fet
Modelos equivalentes de pequeña señal de los transistores fetArmando Bautista
 
Electronica analisis a pequeña señal fet
Electronica  analisis a pequeña señal fetElectronica  analisis a pequeña señal fet
Electronica analisis a pequeña señal fetVelmuz Buzz
 
3 2 circuitos-disparo
3 2 circuitos-disparo3 2 circuitos-disparo
3 2 circuitos-disparo
Axtridf Gs
 
Electrónica de potencia. Convertidores aplicaciones y diseño (Ned Mohán Tore,...
Electrónica de potencia. Convertidores aplicaciones y diseño (Ned Mohán Tore,...Electrónica de potencia. Convertidores aplicaciones y diseño (Ned Mohán Tore,...
Electrónica de potencia. Convertidores aplicaciones y diseño (Ned Mohán Tore,...
SANTIAGO PABLO ALBERTO
 
Ac ac monofasicos
Ac ac monofasicosAc ac monofasicos
Practica 7 Flip Flop
Practica 7 Flip FlopPractica 7 Flip Flop
Practica 7 Flip Flop
Orlando Rodriguez
 
Circuitos secuenciales: Contadores, Registros de Desplazamiento y Circuito de...
Circuitos secuenciales: Contadores, Registros de Desplazamiento y Circuito de...Circuitos secuenciales: Contadores, Registros de Desplazamiento y Circuito de...
Circuitos secuenciales: Contadores, Registros de Desplazamiento y Circuito de...
Jomicast
 
Informe arduino y proteus
Informe arduino y proteusInforme arduino y proteus
Informe arduino y proteus
99belen
 
5a clase el amplificador diferencial
5a clase el amplificador diferencial 5a clase el amplificador diferencial
5a clase el amplificador diferencial ManuelGmoJaramillo
 
informe-control de potencia por angulo de disparro
informe-control de potencia por angulo de disparroinforme-control de potencia por angulo de disparro
informe-control de potencia por angulo de disparro
Henry Paredes
 
Controles mediante el lugar de las raices
Controles mediante el lugar de las raicesControles mediante el lugar de las raices
Controles mediante el lugar de las raicesUNEFA
 
Valores eficaces
Valores eficacesValores eficaces
Valores eficaces
Ferr CzBf Carrasco
 
Electronica de potencia
Electronica de potenciaElectronica de potencia
Electronica de potencia
Gerson Chavarria Vera
 
Microcontroladores
MicrocontroladoresMicrocontroladores
Microcontroladores
Mario César Ramírez Venegas
 
Transformadores
TransformadoresTransformadores
Transformadores
Hola Carlos
 
Simatic s7 300 caracteristicas
Simatic s7 300 caracteristicasSimatic s7 300 caracteristicas
Simatic s7 300 caracteristicas
techonmyweb
 

La actualidad más candente (20)

Respuesta en frecuencia
Respuesta en frecuenciaRespuesta en frecuencia
Respuesta en frecuencia
 
Modelos equivalentes de pequeña señal de los transistores fet
Modelos equivalentes de pequeña señal de los transistores fetModelos equivalentes de pequeña señal de los transistores fet
Modelos equivalentes de pequeña señal de los transistores fet
 
Electronica analisis a pequeña señal fet
Electronica  analisis a pequeña señal fetElectronica  analisis a pequeña señal fet
Electronica analisis a pequeña señal fet
 
3 2 circuitos-disparo
3 2 circuitos-disparo3 2 circuitos-disparo
3 2 circuitos-disparo
 
Sensores analogicos
Sensores analogicosSensores analogicos
Sensores analogicos
 
Electrónica de potencia. Convertidores aplicaciones y diseño (Ned Mohán Tore,...
Electrónica de potencia. Convertidores aplicaciones y diseño (Ned Mohán Tore,...Electrónica de potencia. Convertidores aplicaciones y diseño (Ned Mohán Tore,...
Electrónica de potencia. Convertidores aplicaciones y diseño (Ned Mohán Tore,...
 
Conexion de motores recomendado
Conexion de motores recomendadoConexion de motores recomendado
Conexion de motores recomendado
 
Ac ac monofasicos
Ac ac monofasicosAc ac monofasicos
Ac ac monofasicos
 
Practica 7 Flip Flop
Practica 7 Flip FlopPractica 7 Flip Flop
Practica 7 Flip Flop
 
Circuitos secuenciales: Contadores, Registros de Desplazamiento y Circuito de...
Circuitos secuenciales: Contadores, Registros de Desplazamiento y Circuito de...Circuitos secuenciales: Contadores, Registros de Desplazamiento y Circuito de...
Circuitos secuenciales: Contadores, Registros de Desplazamiento y Circuito de...
 
Informe arduino y proteus
Informe arduino y proteusInforme arduino y proteus
Informe arduino y proteus
 
8 2 convertidor-analogico_-digital
8 2 convertidor-analogico_-digital8 2 convertidor-analogico_-digital
8 2 convertidor-analogico_-digital
 
5a clase el amplificador diferencial
5a clase el amplificador diferencial 5a clase el amplificador diferencial
5a clase el amplificador diferencial
 
informe-control de potencia por angulo de disparro
informe-control de potencia por angulo de disparroinforme-control de potencia por angulo de disparro
informe-control de potencia por angulo de disparro
 
Controles mediante el lugar de las raices
Controles mediante el lugar de las raicesControles mediante el lugar de las raices
Controles mediante el lugar de las raices
 
Valores eficaces
Valores eficacesValores eficaces
Valores eficaces
 
Electronica de potencia
Electronica de potenciaElectronica de potencia
Electronica de potencia
 
Microcontroladores
MicrocontroladoresMicrocontroladores
Microcontroladores
 
Transformadores
TransformadoresTransformadores
Transformadores
 
Simatic s7 300 caracteristicas
Simatic s7 300 caracteristicasSimatic s7 300 caracteristicas
Simatic s7 300 caracteristicas
 

Similar a Microcontroladores: Programación de microcontroladores tomo 1

Introduccion a C++.pdf
Introduccion a C++.pdfIntroduccion a C++.pdf
Introduccion a C++.pdf
Daniel Carpio Contreras
 
Programación en C++
Programación en C++Programación en C++
Programación en C++
Monica Barrera
 
Lenguaje c
Lenguaje c Lenguaje c
Lenguaje c
camilofigueroa14
 
FUNDAMENTOS_DE_PROGRAMACION.pptx
FUNDAMENTOS_DE_PROGRAMACION.pptxFUNDAMENTOS_DE_PROGRAMACION.pptx
FUNDAMENTOS_DE_PROGRAMACION.pptx
jonathanzhanay
 
Tema 2 - Programación básica en C (II)
Tema 2  - Programación básica en C (II)Tema 2  - Programación básica en C (II)
Tema 2 - Programación básica en C (II)
Pablo Haya
 
Elementos basicos de programacion
Elementos basicos de programacionElementos basicos de programacion
Elementos basicos de programacion
rotflol
 
Programacion-en-C.pdf
Programacion-en-C.pdfProgramacion-en-C.pdf
Programacion-en-C.pdf
FreddyFcc
 
Lenguaje De Programacion
Lenguaje De ProgramacionLenguaje De Programacion
Lenguaje De Programacioncharnisch
 
Curso basico de programacion en c
Curso basico de programacion en cCurso basico de programacion en c
Curso basico de programacion en c
Ashley Stronghold Witwicky
 
Lenguaje cx1
Lenguaje cx1Lenguaje cx1
Lenguaje cx1
andreadelacruz002
 
Lenguaje en C
Lenguaje en CLenguaje en C
Tutorial Lenguaje C
Tutorial Lenguaje CTutorial Lenguaje C
Tutorial Lenguaje C
Michelle Rosales Salvador
 
Curso basico de programacion en c
Curso basico de programacion en cCurso basico de programacion en c
Curso basico de programacion en cvictdiazm
 
Lenguaje C
Lenguaje CLenguaje C
Lenguaje C
PROAM
 

Similar a Microcontroladores: Programación de microcontroladores tomo 1 (20)

Introduccion a C++.pdf
Introduccion a C++.pdfIntroduccion a C++.pdf
Introduccion a C++.pdf
 
Programación en C++
Programación en C++Programación en C++
Programación en C++
 
Lenguaje c
Lenguaje c Lenguaje c
Lenguaje c
 
Evaluacion
EvaluacionEvaluacion
Evaluacion
 
FUNDAMENTOS_DE_PROGRAMACION.pptx
FUNDAMENTOS_DE_PROGRAMACION.pptxFUNDAMENTOS_DE_PROGRAMACION.pptx
FUNDAMENTOS_DE_PROGRAMACION.pptx
 
Sesion 4
Sesion 4Sesion 4
Sesion 4
 
Tema 2 - Programación básica en C (II)
Tema 2  - Programación básica en C (II)Tema 2  - Programación básica en C (II)
Tema 2 - Programación básica en C (II)
 
Lenguaje c
Lenguaje cLenguaje c
Lenguaje c
 
Elementos basicos de programacion
Elementos basicos de programacionElementos basicos de programacion
Elementos basicos de programacion
 
Programacion-en-C.pdf
Programacion-en-C.pdfProgramacion-en-C.pdf
Programacion-en-C.pdf
 
Lenguaje De Programacion
Lenguaje De ProgramacionLenguaje De Programacion
Lenguaje De Programacion
 
Curso basico de programacion en c
Curso basico de programacion en cCurso basico de programacion en c
Curso basico de programacion en c
 
Lenguaje cx1
Lenguaje cx1Lenguaje cx1
Lenguaje cx1
 
Lenguaje en C
Lenguaje en CLenguaje en C
Lenguaje en C
 
Tutorial Lenguaje C
Tutorial Lenguaje CTutorial Lenguaje C
Tutorial Lenguaje C
 
Curso basico de programacion en c
Curso basico de programacion en cCurso basico de programacion en c
Curso basico de programacion en c
 
Lenguaje C
Lenguaje CLenguaje C
Lenguaje C
 
Tercera unidad
Tercera unidadTercera unidad
Tercera unidad
 
Tercera unidad
Tercera unidadTercera unidad
Tercera unidad
 
Tercera unidad
Tercera unidadTercera unidad
Tercera unidad
 

Más de SANTIAGO PABLO ALBERTO

secuencia electroneumática parte 1
secuencia electroneumática parte 1secuencia electroneumática parte 1
secuencia electroneumática parte 1
SANTIAGO PABLO ALBERTO
 
secuencia electroneumática parte 2
secuencia electroneumática parte 2secuencia electroneumática parte 2
secuencia electroneumática parte 2
SANTIAGO PABLO ALBERTO
 
Manual de teoría y practica electroneumática avanzada
Manual de teoría y practica electroneumática avanzadaManual de teoría y practica electroneumática avanzada
Manual de teoría y practica electroneumática avanzada
SANTIAGO PABLO ALBERTO
 
Programacion de PLC basado en Rslogix 500 por Roni Domínguez
Programacion de PLC basado en Rslogix 500 por Roni Domínguez Programacion de PLC basado en Rslogix 500 por Roni Domínguez
Programacion de PLC basado en Rslogix 500 por Roni Domínguez
SANTIAGO PABLO ALBERTO
 
Programación de microcontroladores PIC en C con Fabio Pereira
Programación de microcontroladores PIC en  C con Fabio PereiraProgramación de microcontroladores PIC en  C con Fabio Pereira
Programación de microcontroladores PIC en C con Fabio Pereira
SANTIAGO PABLO ALBERTO
 
Análisis y Diseño de Sistemas de Control Digital por Ricardo Fernandez del Bu...
Análisis y Diseño de Sistemas de Control Digital por Ricardo Fernandez del Bu...Análisis y Diseño de Sistemas de Control Digital por Ricardo Fernandez del Bu...
Análisis y Diseño de Sistemas de Control Digital por Ricardo Fernandez del Bu...
SANTIAGO PABLO ALBERTO
 
Arduino: Arduino de cero a experto
Arduino: Arduino de cero a expertoArduino: Arduino de cero a experto
Arduino: Arduino de cero a experto
SANTIAGO PABLO ALBERTO
 
Programación de autómatas PLC OMRON CJ/CP1
Programación de  autómatas PLC OMRON CJ/CP1Programación de  autómatas PLC OMRON CJ/CP1
Programación de autómatas PLC OMRON CJ/CP1
SANTIAGO PABLO ALBERTO
 
Manual del sistema del controlador programable S7-200 SMART
Manual del sistema del controlador programable S7-200 SMARTManual del sistema del controlador programable S7-200 SMART
Manual del sistema del controlador programable S7-200 SMART
SANTIAGO PABLO ALBERTO
 
Catálogo de PLC S7-200 SMART
Catálogo de PLC S7-200 SMART Catálogo de PLC S7-200 SMART
Catálogo de PLC S7-200 SMART
SANTIAGO PABLO ALBERTO
 
PLC: Automatismos industriales
PLC: Automatismos industrialesPLC: Automatismos industriales
PLC: Automatismos industriales
SANTIAGO PABLO ALBERTO
 
PLC: Buses industriales y de campo practicas de laboratorio por Jose Miguel R...
PLC: Buses industriales y de campo practicas de laboratorio por Jose Miguel R...PLC: Buses industriales y de campo practicas de laboratorio por Jose Miguel R...
PLC: Buses industriales y de campo practicas de laboratorio por Jose Miguel R...
SANTIAGO PABLO ALBERTO
 
PLC y Electroneumática: Electricidad y Automatismo eléctrico por Luis Miguel...
PLC y Electroneumática: Electricidad y Automatismo eléctrico por  Luis Miguel...PLC y Electroneumática: Electricidad y Automatismo eléctrico por  Luis Miguel...
PLC y Electroneumática: Electricidad y Automatismo eléctrico por Luis Miguel...
SANTIAGO PABLO ALBERTO
 
Electrónica: Diseño y desarrollo de circuitos impresos con Kicad por Miguel P...
Electrónica: Diseño y desarrollo de circuitos impresos con Kicad por Miguel P...Electrónica: Diseño y desarrollo de circuitos impresos con Kicad por Miguel P...
Electrónica: Diseño y desarrollo de circuitos impresos con Kicad por Miguel P...
SANTIAGO PABLO ALBERTO
 
PLC: Diseño, construcción y control de un motor doble Dahlander(cuatro veloci...
PLC: Diseño, construcción y control de un motor doble Dahlander(cuatro veloci...PLC: Diseño, construcción y control de un motor doble Dahlander(cuatro veloci...
PLC: Diseño, construcción y control de un motor doble Dahlander(cuatro veloci...
SANTIAGO PABLO ALBERTO
 
Electrónica digital: Introducción a la Lógica Digital - Teoría, Problemas y ...
Electrónica digital:  Introducción a la Lógica Digital - Teoría, Problemas y ...Electrónica digital:  Introducción a la Lógica Digital - Teoría, Problemas y ...
Electrónica digital: Introducción a la Lógica Digital - Teoría, Problemas y ...
SANTIAGO PABLO ALBERTO
 

Más de SANTIAGO PABLO ALBERTO (20)

secuencia electroneumática parte 1
secuencia electroneumática parte 1secuencia electroneumática parte 1
secuencia electroneumática parte 1
 
secuencia electroneumática parte 2
secuencia electroneumática parte 2secuencia electroneumática parte 2
secuencia electroneumática parte 2
 
Manual de teoría y practica electroneumática avanzada
Manual de teoría y practica electroneumática avanzadaManual de teoría y practica electroneumática avanzada
Manual de teoría y practica electroneumática avanzada
 
Programacion de PLC basado en Rslogix 500 por Roni Domínguez
Programacion de PLC basado en Rslogix 500 por Roni Domínguez Programacion de PLC basado en Rslogix 500 por Roni Domínguez
Programacion de PLC basado en Rslogix 500 por Roni Domínguez
 
Programación de microcontroladores PIC en C con Fabio Pereira
Programación de microcontroladores PIC en  C con Fabio PereiraProgramación de microcontroladores PIC en  C con Fabio Pereira
Programación de microcontroladores PIC en C con Fabio Pereira
 
Análisis y Diseño de Sistemas de Control Digital por Ricardo Fernandez del Bu...
Análisis y Diseño de Sistemas de Control Digital por Ricardo Fernandez del Bu...Análisis y Diseño de Sistemas de Control Digital por Ricardo Fernandez del Bu...
Análisis y Diseño de Sistemas de Control Digital por Ricardo Fernandez del Bu...
 
Arduino: Arduino de cero a experto
Arduino: Arduino de cero a expertoArduino: Arduino de cero a experto
Arduino: Arduino de cero a experto
 
Fisica I
Fisica IFisica I
Fisica I
 
Quimica.pdf
Quimica.pdfQuimica.pdf
Quimica.pdf
 
Manual básico PLC OMRON
Manual básico PLC OMRON Manual básico PLC OMRON
Manual básico PLC OMRON
 
Programación de autómatas PLC OMRON CJ/CP1
Programación de  autómatas PLC OMRON CJ/CP1Programación de  autómatas PLC OMRON CJ/CP1
Programación de autómatas PLC OMRON CJ/CP1
 
Manual del sistema del controlador programable S7-200 SMART
Manual del sistema del controlador programable S7-200 SMARTManual del sistema del controlador programable S7-200 SMART
Manual del sistema del controlador programable S7-200 SMART
 
Catálogo de PLC S7-200 SMART
Catálogo de PLC S7-200 SMART Catálogo de PLC S7-200 SMART
Catálogo de PLC S7-200 SMART
 
PLC: Automatismos industriales
PLC: Automatismos industrialesPLC: Automatismos industriales
PLC: Automatismos industriales
 
PLC: Buses industriales y de campo practicas de laboratorio por Jose Miguel R...
PLC: Buses industriales y de campo practicas de laboratorio por Jose Miguel R...PLC: Buses industriales y de campo practicas de laboratorio por Jose Miguel R...
PLC: Buses industriales y de campo practicas de laboratorio por Jose Miguel R...
 
PLC y Electroneumática: Electricidad y Automatismo eléctrico por Luis Miguel...
PLC y Electroneumática: Electricidad y Automatismo eléctrico por  Luis Miguel...PLC y Electroneumática: Electricidad y Automatismo eléctrico por  Luis Miguel...
PLC y Electroneumática: Electricidad y Automatismo eléctrico por Luis Miguel...
 
Electrónica: Diseño y desarrollo de circuitos impresos con Kicad por Miguel P...
Electrónica: Diseño y desarrollo de circuitos impresos con Kicad por Miguel P...Electrónica: Diseño y desarrollo de circuitos impresos con Kicad por Miguel P...
Electrónica: Diseño y desarrollo de circuitos impresos con Kicad por Miguel P...
 
PLC: Diseño, construcción y control de un motor doble Dahlander(cuatro veloci...
PLC: Diseño, construcción y control de un motor doble Dahlander(cuatro veloci...PLC: Diseño, construcción y control de un motor doble Dahlander(cuatro veloci...
PLC: Diseño, construcción y control de un motor doble Dahlander(cuatro veloci...
 
PLC: Motor Dahlander
PLC: Motor DahlanderPLC: Motor Dahlander
PLC: Motor Dahlander
 
Electrónica digital: Introducción a la Lógica Digital - Teoría, Problemas y ...
Electrónica digital:  Introducción a la Lógica Digital - Teoría, Problemas y ...Electrónica digital:  Introducción a la Lógica Digital - Teoría, Problemas y ...
Electrónica digital: Introducción a la Lógica Digital - Teoría, Problemas y ...
 

Último

UNIVERSIDAD NACIONAL ALTIPLANO PUNO - FACULTAD DE INGENIERIA MECANICA ELECTRICA.
UNIVERSIDAD NACIONAL ALTIPLANO PUNO - FACULTAD DE INGENIERIA MECANICA ELECTRICA.UNIVERSIDAD NACIONAL ALTIPLANO PUNO - FACULTAD DE INGENIERIA MECANICA ELECTRICA.
UNIVERSIDAD NACIONAL ALTIPLANO PUNO - FACULTAD DE INGENIERIA MECANICA ELECTRICA.
HaroldKewinCanaza1
 
Una solucion saturada contiene la cantidad máxima de un soluto que se disuel...
Una solucion saturada contiene la cantidad máxima de un  soluto que se disuel...Una solucion saturada contiene la cantidad máxima de un  soluto que se disuel...
Una solucion saturada contiene la cantidad máxima de un soluto que se disuel...
leonpool521
 
Distribución Muestral de Diferencia de Medias
Distribución Muestral de Diferencia de MediasDistribución Muestral de Diferencia de Medias
Distribución Muestral de Diferencia de Medias
arielemelec005
 
PLAN DE TRABAJO DE REFUERZO ESCOLAR 2024.pdf
PLAN DE TRABAJO DE REFUERZO ESCOLAR 2024.pdfPLAN DE TRABAJO DE REFUERZO ESCOLAR 2024.pdf
PLAN DE TRABAJO DE REFUERZO ESCOLAR 2024.pdf
MariaCortezRuiz
 
PLAN DE EMERGENCIAS Y EVACUACION 2024.pdf
PLAN DE EMERGENCIAS Y EVACUACION 2024.pdfPLAN DE EMERGENCIAS Y EVACUACION 2024.pdf
PLAN DE EMERGENCIAS Y EVACUACION 2024.pdf
Daniel Jose Sierra Garcia
 
Ejercicios-de-Divisibilidad-para-Primero-de-Primaria (3).doc
Ejercicios-de-Divisibilidad-para-Primero-de-Primaria (3).docEjercicios-de-Divisibilidad-para-Primero-de-Primaria (3).doc
Ejercicios-de-Divisibilidad-para-Primero-de-Primaria (3).doc
LuisEnriqueCarboneDe
 
Las Fuentes de Alimentacion Conmutadas (Switching).pdf
Las Fuentes de Alimentacion Conmutadas (Switching).pdfLas Fuentes de Alimentacion Conmutadas (Switching).pdf
Las Fuentes de Alimentacion Conmutadas (Switching).pdf
NicolasGramajo1
 
FISICA_Hidrostatica_uyhHidrodinamica.pdf
FISICA_Hidrostatica_uyhHidrodinamica.pdfFISICA_Hidrostatica_uyhHidrodinamica.pdf
FISICA_Hidrostatica_uyhHidrodinamica.pdf
JavierAlejosM
 
PLANIFICACION INDUSTRIAL ( Gantt-Pert-CPM ).docx
PLANIFICACION INDUSTRIAL ( Gantt-Pert-CPM ).docxPLANIFICACION INDUSTRIAL ( Gantt-Pert-CPM ).docx
PLANIFICACION INDUSTRIAL ( Gantt-Pert-CPM ).docx
Victor Manuel Rivera Guevara
 
Criterios de la primera y segunda derivada
Criterios de la primera y segunda derivadaCriterios de la primera y segunda derivada
Criterios de la primera y segunda derivada
YoverOlivares
 
choro ciclo de vida anatomía y fisiología
choro ciclo de vida anatomía y fisiologíachoro ciclo de vida anatomía y fisiología
choro ciclo de vida anatomía y fisiología
elvis2000x
 
Sesiones 3 y 4 Estructuras Ingenieria.pdf
Sesiones 3 y 4 Estructuras Ingenieria.pdfSesiones 3 y 4 Estructuras Ingenieria.pdf
Sesiones 3 y 4 Estructuras Ingenieria.pdf
DeyvisPalomino2
 
Becas de UOC _ Caja Ingenieros 2024-25.pdf
Becas de UOC _ Caja Ingenieros 2024-25.pdfBecas de UOC _ Caja Ingenieros 2024-25.pdf
Becas de UOC _ Caja Ingenieros 2024-25.pdf
UOC Estudios de Informática, Multimedia y Telecomunicación
 
Sistema de disposición sanitarias – UBS composteras 2 PARTE.pptx
Sistema de disposición sanitarias – UBS composteras 2 PARTE.pptxSistema de disposición sanitarias – UBS composteras 2 PARTE.pptx
Sistema de disposición sanitarias – UBS composteras 2 PARTE.pptx
RobertRamos84
 
Clasificacion geomecanica de Q de Barton
Clasificacion geomecanica de Q de BartonClasificacion geomecanica de Q de Barton
Clasificacion geomecanica de Q de Barton
edujunes132
 
libro conabilidad financiera, 5ta edicion.pdf
libro conabilidad financiera, 5ta edicion.pdflibro conabilidad financiera, 5ta edicion.pdf
libro conabilidad financiera, 5ta edicion.pdf
MiriamAquino27
 
Plan de Desarrollo Urbano de la Municipalidad Provincial de Ilo
Plan de Desarrollo Urbano de la Municipalidad Provincial de IloPlan de Desarrollo Urbano de la Municipalidad Provincial de Ilo
Plan de Desarrollo Urbano de la Municipalidad Provincial de Ilo
AlbertoRiveraPrado
 
Ciclo de Otto. Máquinas térmicas para el estudio de la termodinámica química
Ciclo de Otto. Máquinas térmicas para el estudio de la termodinámica químicaCiclo de Otto. Máquinas térmicas para el estudio de la termodinámica química
Ciclo de Otto. Máquinas térmicas para el estudio de la termodinámica química
ycalful01
 
Diagrama de flujo "Resolución de problemas".pdf
Diagrama de flujo "Resolución de problemas".pdfDiagrama de flujo "Resolución de problemas".pdf
Diagrama de flujo "Resolución de problemas".pdf
joseabachesoto
 
NORMATIVA AMERICANA ASME B30.5-2021 ESPAÑOL
NORMATIVA AMERICANA ASME B30.5-2021 ESPAÑOLNORMATIVA AMERICANA ASME B30.5-2021 ESPAÑOL
NORMATIVA AMERICANA ASME B30.5-2021 ESPAÑOL
Pol Peña Quispe
 

Último (20)

UNIVERSIDAD NACIONAL ALTIPLANO PUNO - FACULTAD DE INGENIERIA MECANICA ELECTRICA.
UNIVERSIDAD NACIONAL ALTIPLANO PUNO - FACULTAD DE INGENIERIA MECANICA ELECTRICA.UNIVERSIDAD NACIONAL ALTIPLANO PUNO - FACULTAD DE INGENIERIA MECANICA ELECTRICA.
UNIVERSIDAD NACIONAL ALTIPLANO PUNO - FACULTAD DE INGENIERIA MECANICA ELECTRICA.
 
Una solucion saturada contiene la cantidad máxima de un soluto que se disuel...
Una solucion saturada contiene la cantidad máxima de un  soluto que se disuel...Una solucion saturada contiene la cantidad máxima de un  soluto que se disuel...
Una solucion saturada contiene la cantidad máxima de un soluto que se disuel...
 
Distribución Muestral de Diferencia de Medias
Distribución Muestral de Diferencia de MediasDistribución Muestral de Diferencia de Medias
Distribución Muestral de Diferencia de Medias
 
PLAN DE TRABAJO DE REFUERZO ESCOLAR 2024.pdf
PLAN DE TRABAJO DE REFUERZO ESCOLAR 2024.pdfPLAN DE TRABAJO DE REFUERZO ESCOLAR 2024.pdf
PLAN DE TRABAJO DE REFUERZO ESCOLAR 2024.pdf
 
PLAN DE EMERGENCIAS Y EVACUACION 2024.pdf
PLAN DE EMERGENCIAS Y EVACUACION 2024.pdfPLAN DE EMERGENCIAS Y EVACUACION 2024.pdf
PLAN DE EMERGENCIAS Y EVACUACION 2024.pdf
 
Ejercicios-de-Divisibilidad-para-Primero-de-Primaria (3).doc
Ejercicios-de-Divisibilidad-para-Primero-de-Primaria (3).docEjercicios-de-Divisibilidad-para-Primero-de-Primaria (3).doc
Ejercicios-de-Divisibilidad-para-Primero-de-Primaria (3).doc
 
Las Fuentes de Alimentacion Conmutadas (Switching).pdf
Las Fuentes de Alimentacion Conmutadas (Switching).pdfLas Fuentes de Alimentacion Conmutadas (Switching).pdf
Las Fuentes de Alimentacion Conmutadas (Switching).pdf
 
FISICA_Hidrostatica_uyhHidrodinamica.pdf
FISICA_Hidrostatica_uyhHidrodinamica.pdfFISICA_Hidrostatica_uyhHidrodinamica.pdf
FISICA_Hidrostatica_uyhHidrodinamica.pdf
 
PLANIFICACION INDUSTRIAL ( Gantt-Pert-CPM ).docx
PLANIFICACION INDUSTRIAL ( Gantt-Pert-CPM ).docxPLANIFICACION INDUSTRIAL ( Gantt-Pert-CPM ).docx
PLANIFICACION INDUSTRIAL ( Gantt-Pert-CPM ).docx
 
Criterios de la primera y segunda derivada
Criterios de la primera y segunda derivadaCriterios de la primera y segunda derivada
Criterios de la primera y segunda derivada
 
choro ciclo de vida anatomía y fisiología
choro ciclo de vida anatomía y fisiologíachoro ciclo de vida anatomía y fisiología
choro ciclo de vida anatomía y fisiología
 
Sesiones 3 y 4 Estructuras Ingenieria.pdf
Sesiones 3 y 4 Estructuras Ingenieria.pdfSesiones 3 y 4 Estructuras Ingenieria.pdf
Sesiones 3 y 4 Estructuras Ingenieria.pdf
 
Becas de UOC _ Caja Ingenieros 2024-25.pdf
Becas de UOC _ Caja Ingenieros 2024-25.pdfBecas de UOC _ Caja Ingenieros 2024-25.pdf
Becas de UOC _ Caja Ingenieros 2024-25.pdf
 
Sistema de disposición sanitarias – UBS composteras 2 PARTE.pptx
Sistema de disposición sanitarias – UBS composteras 2 PARTE.pptxSistema de disposición sanitarias – UBS composteras 2 PARTE.pptx
Sistema de disposición sanitarias – UBS composteras 2 PARTE.pptx
 
Clasificacion geomecanica de Q de Barton
Clasificacion geomecanica de Q de BartonClasificacion geomecanica de Q de Barton
Clasificacion geomecanica de Q de Barton
 
libro conabilidad financiera, 5ta edicion.pdf
libro conabilidad financiera, 5ta edicion.pdflibro conabilidad financiera, 5ta edicion.pdf
libro conabilidad financiera, 5ta edicion.pdf
 
Plan de Desarrollo Urbano de la Municipalidad Provincial de Ilo
Plan de Desarrollo Urbano de la Municipalidad Provincial de IloPlan de Desarrollo Urbano de la Municipalidad Provincial de Ilo
Plan de Desarrollo Urbano de la Municipalidad Provincial de Ilo
 
Ciclo de Otto. Máquinas térmicas para el estudio de la termodinámica química
Ciclo de Otto. Máquinas térmicas para el estudio de la termodinámica químicaCiclo de Otto. Máquinas térmicas para el estudio de la termodinámica química
Ciclo de Otto. Máquinas térmicas para el estudio de la termodinámica química
 
Diagrama de flujo "Resolución de problemas".pdf
Diagrama de flujo "Resolución de problemas".pdfDiagrama de flujo "Resolución de problemas".pdf
Diagrama de flujo "Resolución de problemas".pdf
 
NORMATIVA AMERICANA ASME B30.5-2021 ESPAÑOL
NORMATIVA AMERICANA ASME B30.5-2021 ESPAÑOLNORMATIVA AMERICANA ASME B30.5-2021 ESPAÑOL
NORMATIVA AMERICANA ASME B30.5-2021 ESPAÑOL
 

Microcontroladores: Programación de microcontroladores tomo 1

  • 1. 1
  • 2. 2 Programación de microcontroladores PIC con Lenguaje C, Tomo I Gestión de puertos e interrupciones externas Sixto Reinoso; Luis Mena; Marco Pilatasig y Jorge Sánchez Primera edición electrónica. Octubre de 2018 ISBN: 978-9942-765-36-9 Revisión científica: Juan Pablo Pallo Noroña y Julio Enrique Cuji Rodriguez Universidad de las Fuerzas Armadas ESPE Crnl. Ing. Ramiro Pazmiño O. Rector Publicación autorizada por: Comisión Editorial de la Universidad de las Fuerzas Armadas ESPE Cpnv. Hugo Pérez Presidente Edición y producción David Andrade Aguirre daa06@yahoo.es Diseño Pablo Zavala A. Derechos reservados. Se prohibe la reproducción de esta obra por cualquier medio impreso, reprográfico o electrónico. El contenido, uso de fotografías, gráficos, cuadros, tablas y referencias es de exclusiva responsabilidad del autor. Los derechos de esta edición electrónica son de la Universidad de las Fuerzas Armadas ESPE, para consulta de profesores y estudiantes de la universidad e investigadores en: htpp//www.repositorio.espe.edu.ec. Universidad de las Fuerzas Armadas ESPE Av. General Rumiñahui s/n, Sangolquí, Ecuador. htpp//www.espe.edu.ec
  • 3. 3 PROGRAMACIÓN DE MICROCONTROLADORES PIC CON LENGUAJE C Tomo I GESTIÓN DE PUERTOS E INTERRUPCIONES EXTERNAS Sixto Reinoso V. Luis Mena Marco Pilatasig Jorge Sánchez
  • 4. 4 Dedicatoria Una vez más gracias a DIOS por todo lo que nos da y que es mucho. “Y cantarán de los caminos del SEÑOR, porque grande es la gloria del SEÑOR” (salmo 138:5). A la memoria de Adriana Alexandra Reinoso V.
  • 5. 5
  • 6. 6 En este capítulo se describen brevemente el software y el hardware a utilizarse en el desarrollo de las aplicaciones propuestas. Es importante hacer un recordatorio de las sentencias y elementos generales que soporta el compilador CCS, y que son utilizados en los programas propuestos en el texto. Detalles, mayor información y características adicionales se pueden obtener del sitio web oficial de CCS en www.ccsinfo.com o en manuales y textos que sobre CCS existen ampliamente en el mercado. Luego del análisis del software a utilizarse se describen las características más relevantes de los microcontroladores PIC, dando énfasis a los PICs que se van a utilizar en el desarrollo de las aplicaciones. ESTRUCTURA DE UN PROGRAMA EN CCS Para escribir un programa en C que acepte el Compilador CCS, se deben tener en cuenta los elementos que forman el programa los mismos que se indican en la figura 1.1. Directivas: Controlan como debe generar el compilador el código de máquina. Programas o Funciones: Bloques de código escrito en instrucciones de lenguajes de alto nivel. Como en C común siempre existirá la función principal main. Instrucciones: Sentencias que indican que va a realizar el programa y determinan la ejecución del mismo. Las instrucciones se separan o finalizan con punto y como (;). Ejemplo: x= x*10; Comentarios: Describen el significado de las líneas del código. Útil para leer las instrucciones de un programa. Las directivas, funciones y otros elementos que usa el compilador se irán describiendo según las necesidades de programación. Se dará un vistazo general a los comentarios, datos, variables, instrucciones y funciones que se necesitan para empezar a programar utilizando compilador CCS.
  • 7. 7 Figura 1.1. Estructura de un programa en C para el compilador PCWHD – CCS. Elaborado por los autores. Comentarios Los comentarios son útiles para interpretar el código de un programa. Se puede colocar en cualquier parte del programa y cumplir con los estándares del ANSI C original. Se pueden escribir en dos formas: Colocando //. A continuación se escribe el comentario o leyenda correspondiente. Ejemplos: // Esta es la forma de colocar un comentario en una línea. delay_ms (200); //retardo de 200 milisegundos #include <18F4550.h> //Incluye la librería para utilizar el PIC18F4550 Colocando /* */. Dentro de los símbolos se inserta el texto del comentario. Cuando se quiere realizar un comentario de varias líneas se utiliza esta opción. Ejemplos: /* Otra forma de comentario */. delay_ms (200); /*retardo de 200 milisegundos */ #include <18F4550.h> /*Incluye la librería para utilizar el PIC18F4550. Con esta directiva se define la serie del microcontrolador a utilizarse en el programa */
  • 8. 8 Tipos de datos El compilador CCS acepta los siguientes tipos de datos: Tipo Tamaño Rango Descripción Int1 Short 1 bit 0 a 1 Entero de 1 bit Int Int8 8 bit 0 a 255 Entero Int16 Long 16 bit 0 a 65,535 Entero de 16 bit Int32 32 bit 0 a 4,294,967,295 Entero de 32 bit Float 32 bit 1.5x10-45 a 3.402x1038 Coma flotante Char 8 bit 0 a 255 Carácter Void - - Sin valor Signed Int8 8 bit -128 a +127 Entero con signo Signed Int16 16 bit -32,768 a +32,767 Entero largo con signo Signed Int32 32 bit -2147483648 a +2147483647 Entero 32 bits con signo Tabla 1.1. Tipos de datos aceptados por el compilador CCS. Fuente: García Breijo. Compilador C CSS y Simulador PROTEUS para Microcontroladores PIC. Constantes Las constantes pueden ser decimal, octal, hexadecimal y binario. 453 Decimal 0705 Octal (0) 0x1C5 Hexadecimal(0x) 0b111000101 Binario (0b) ‘x’ Carácter ‘010’ Carácter octal ‘xA5’ Carácter hexadecimal “abcdef” Cadena Tabla 1.2. Ejemplos de constantes aceptados por el compilador CCS. Fuente: García Breijo. Compilador C CSS y Simulador PROTEUS para Microcontroladores PIC.
  • 9. 9 También se definen las constantes con sufijo. Int8 83U Long 70UL Signed INT16 93L Float 3.14f Char Comillas simples ‘C’ Tabla 1.3. Otra forma de definir constantes en el compilador CCS. Fuente: García Breijo. Compilador C CSS y Simulador PROTEUS para Microcontroladores PIC. Se utilizan caracteres especiales como: n Cambio de línea r Retorno de carro t Tabulación b Backspace (retroceso) Tabla 1.4. Uso de caracteres especiales en el compilador CCS. Fuente: García Breijo. Compilador C CSS y Simulador PROTEUS para Microcontroladores PIC. Hay que aclarar que el retorno de carro (r), pone el cursor al principio de la línea actual, y el cambio de línea (n) avanza una. Tabulación y backspace, trabajan de forma similar al teclado. Variables Las variables sirven para nombrar posiciones de memoria RAM. Se debe declarar obligatoriamente, de acuerdo a las reglas ANSI del lenguaje C. El formato es: TIPO NOMBRE [=VALOR INICIAL]; TIPO: Se refiere al tipo de datos indicados en la tabla 1.1. NOMBRE: Un nombre válido de acuerdo a las normas ANSI del lenguaje C común. Algunas reglas mencionamos aquí: • Deben empezar con una letra o guión bajo. Ejemplo: amperios, _7segmentos; • No debe empezar con números o caracteres especiales. Ejemplos:3voltios, 7segmentos, -voltaje, %contador, &luz; contienen números y caracteres especiales que no admite las variables.
  • 10. 10 • Nodebetenerelmismonombrequeuna“palabrareservada”dellenguaje. Ejemplo: for, if, int, while, do, entre otras son palabras reservadas del lenguaje que no pueden ser usadas. • No pueden llevar tildes. Ejemplo: Número, ecuación, lección, dígito; son palabras que tienen tilde y no deben usarse. • No debe existir espacios en blanco. Ejemplo: la ciudad. Hay un espacio en blanco entre las palabras la y ciudad. En esta forma no se puede utilizar. [=VALOR INICIAL]. Este argumento es opcional (se puede omitir). A una variable se puede asignar un valor de inicio o en su defecto no poner ningún valor. Ejemplo: int voltaje = 20; int1 LED; Las variables pueden ser de tipo LOCALo GLOBAL. Las variables locales se utilizan sólo en la función donde se encuentran declaradas y las globales en todas las funciones del programa. Ambas variables deben declararse antes de cualquier función y fuera de ella. Las variables globales son puestas a cero cuando se inicia la función principal main (). Ejemplo: PROGRAMA: #include <18F4550.h> #fuses HS,NOWDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles. #use delay (clock=12000000) // FOSC =12MHz #byte tris_b = 0xF93 #bit b0= 0xF81.0 int puertos; //variable global void main() { int8 voltaje; //variable local } void función (void) { float res ; //variable local }
  • 11. 11 Operadores El compilador CCS acepta la mayor parte de los operadores: aritméticos, de asignación, relacionales, lógicos y punteros del lenguaje C ANSI original. 1.6.1 Aritméticos Los operadores aritméticos que soporta el compilador CCS, se resume en la tabla 1.5. Símbolo Significado + Suma - Resta * Multiplicación / División % Módulo, resto de una división entera ++ Incremento - - Decremento Sizeof Determina el tamaño, en bytes de un operando Tabla 1.5. Operadores de aritméticos. Fuente: CCS C Compiler Manual PCD. De Asignación Las operaciones de asignación se indican en la tabla 1.6. Símbolo Significado += Asignación de suma: m +=n, es lo mismo m= m+n -= Asignación de resta: m -=n, es lo mismo m= m-n *= Asignación de multiplicación: m *=n, es lo mismo m= m*n /= Asignación de división: m /=n, es lo mismo m= m/n %= Asignación del resto de la división: m %=n, es lo mismo m= m%n <<= Asignación de desplazamiento a la izquierda: m <<=n, es lo mismo m= m<<n >>= Asignación de desplazamiento a la derecha: m >>=n, es lo mismo m= m>>n &= Asignación AND de bits: m &=n, es lo mismo m= m&n |= Asignación OR de bits: m |=n, es lo mismo m= m|n ^^= Asignación de OR exclusivo de bits ^= Asignación de suma: m ^=n, es lo mismo m= m^n ~= ~= Asignación de negación de bits Tabla 1.6. Operadores de asignación. Fuente: CCS C Compiler Manual PCD.
  • 12. 12 Relacionales Compara dos operandos y da un resultado entero: 1 (verdadero); 0 (falso). La siguiente tabla ilustra estos operadores: Los operadores relacionales se muestran en la tabla 1.7. Símbolo Significado < Menor que > Mayor que >= Mayor o igual que <= Menor o igual que == Igual != Diferente ?: Expresión condicional Tabla 1.7. Operadores relacionales. Fuente: CCS C Compiler Manual PCD. Lógicos Al igual que los operadores relacionales, éstos devuelven 1 (verdadero), 0 (falso) tras la evaluación de sus operandos. La tabla siguiente ilustra estos operadores. Los operadores lógicos que utiliza el compilador, se indica en la tabla 1.8. Símbolo Significado ! NOT && AND || OR Tabla 1.8. Operadores lógicos. Fuente: Manual del usuario del Compilador CCS. De bits Estos operadores permiten actuar sobre los operandos a nivel de bits y sólo pueden ser de tipo entero (incluyendo el tipo char). Las operaciones de bits están representadas en la tabla 1.9. Símbolo Significado ~ Complemento a 1 (Inversión) & AND ^^ XOR | OR Tabla 1.9. Operadores de bits. Fuente: Manual del usuario del Compilador CCS.
  • 13. 13 Operadores de desplazamiento Estos operadores utilizan dos operandos enteros (tipo int): el primero es el elemento a desplazar y el segundo, el número de posiciones de bits que se desplaza. >> Desplazamiento a la derecha. << Desplazamiento a la izquierda Tabla 1.10. Operadores de desplazamiento. Fuente: Manual del usuario del Compilador CCS. El formato es: m Operando n. Donde: m, es el elemento a desplazar. Operando, desplazamiento a la izquierda <<, o desplazamiento a la derecha >>, y n, indica el número de posiciones que se desplazarán los bits. Ejemplo: En una variable x se almacena el número binario 111000101. Si se realizan las operaciónes indicadas, cuáles son los nuevos valores de x para cada caso. a. x= 11000101 << 1 b. x= 11000101 << 2 c. x= 11000101 << 3 d. x= 11000101 >> 1 e. x= 11000101 >> 2 f. x= 11000101 >> 3 En todos los casos los “unos” son reemplazados por “ceros”, desde el bit menos significado y los bits que superan la capacidad del entero del bit más significativo se desbordan y desaparecen. El 1 después del signo << indica que los bits se desplazarán una posición a la izquierda. Por tanto, el nuevo valor de x es 10001010. En este caso es lo mismo que realizar una multiplicación al número binario por 2. El 2 después del signo << indica que los bits se desplazarán dos posiciones a la izquierda. Por tanto, el nuevo valor de x es 00010100. En este caso es lo mismo que realizar una multiplicación al número binario por 4.
  • 14. 14 El 3 después del signo << indica que los bits se desplazarán tres posiciones a la izquierda. Por tanto, el nuevo valor de x es 00101000. En este caso es lo mismo que realizar una multiplicación al número binario por 8. Para el desplazamiento a la derecha, los “unos” son reemplazados por “ceros” desde el bit más significativo y al superar la capacidad del número el bit menos significativo desparece. El 1 después del signo >> indica que los bits se desplazarán una posición a la derecha. Por tanto, el nuevo valor de x es 01100010. En este caso es lo mismo que realizar una multiplicación al número binario por 2. El 2 después del signo >> indica que los bits se desplazarán dos posiciones a la derecha. Por tanto, el nuevo valor de x es 00110001. En este caso es lo mismo que realizar una multiplicación al número binario por 4. El 3 después del signo >> indica que los bits se desplazarán tres posiciones a la derecha. Por tanto, el nuevo valor de x es 00011000. En este caso es lo mismo que realizar una multiplicación al número binario por 4. Punteros El compilador CCS, soporta también el trabajo con punteros. Los operadores de punteros más comunes se presentan en la tabla 1.10. Símbolo Significado & Dirección * Indirección -> Puntero estructura Tabla 1.11. Operadores punteros. Fuente: Manual del usuario del Compilador CCS. Instrucciones de control Las instrucciones de control para los programas con condiciones o que necesiten bucles o lazos repetitivos que admite CCS, son los mismos del ANSI C original: • IF - ELSE • SWITCH – CASE • WHILE • DO – WHILE • FOR
  • 15. 15 • CONTINUE • RETURN • BREAK • GOTO IF – ELSE Sirve para tomar decisiones en un programa. El formato es: if (condición) Instrucción1; [else Instrucción2]; Si la condición es verdadera (True o 1) se ejecuta la Instrucción1, si es falsa (False o 0) se ejecuta la instrucción2. Las sentencias que están entre corchetes [], son opcionales. Ejemplo: if (x==1) bit_set(port_b,0); else bit_set(port_b,1); Cuando existen varias instrucciones se deben utilizar las llaves {}. if (prender == 0 && k==0) { k= 1; bit_set(port_b,0); } Se pueden formar instrucciones anidadas para formar lazos de decisión ELSE – IF. if (condición1) Instrucción1; [else if (condición2) Instrucción2;] [else Instrucción3;]
  • 16. 16 La mejor forma de representar la instrucción IF – ELSE es mediante la figura 1.2. Si la condición es TRUE se ejecutan las instrucciones que están por el lado del THEN o si la condición es FALSE se ejecutan las instrucciones del lado del ELSE. Figura 1.2. Representación de la instrucción IF – ELSE. Elaborado por los autores. SWITCH CASE Se utiliza para tomar una decisión múltiple. Evalúa la expresión y de acuerdo a la constante ejecuta la o las instrucciones. La instrucción break evita que continúe ejecutando el siguiente case. Si no existe ningún case se ejecuta las instrucciones de default (que es opcional). switch (expresión) { case constante_1: instrucción_11; instrucción_12; ... break; case constante_2: instrucción_21; instrucción_22; ... break; case constante_n:
  • 17. 17 instrucción_n ... break; [default: Instrucciones;] } WHILE WHILE repite una serie de instrucciones, mientras la expresión sea cierta (TRUE o 1). while (expresión) { instrucciones; } Se puede ejecutar un bucle sin fin. while (1) { instrucciones; } O también utilizando el formato: while (TRUE) { instrucciones; } DO WHILE Con DO WHILE la expresión se evalúa al final de las instrucciones. do { instrucciones; } while(expresión); Las instrucciones primero se ejecutan y se evalúa la expresión al final, si ésta resulta cierta (TRUE), se repite el bucle hasta que la condición sea falsa (FALSE).
  • 18. 18 También con DO WHILE, se puede ejecutar un bucle sin fin. Por ejemplo: do { instrucciones; } while(1); FOR El bucle de control FOR sin dudas es el más usado en la mayoría de lenguajes de programación. En CCS es similar al formato delANSI C original, o sea: for (valor_inicial, valor_final, incremento) { instrucciones; } Ejemplo: for (j=0; j<=9;++j) Las instrucciones se repiten mientras la variable j sea menor o igual a 9. La variable j se incrementa su valor en 1 cada vez que se ejecute una instrucción. Nota: Recuerde que en C una variable se puede incrementar usando ++j, o bien, j++. Un bucle sin fin usando FOR se genera mediante el siguiente formato: for ( ; ; ) { instrucciones; } Continue La instrucción de salto CONTINUE se usa para interrumpir la ejecución normal de un bucle. El control del programa no se transfiere a la primera instrucción después del bucle (como sí hace la instrucción break), es decir, el bucle no finaliza, sino que, finaliza la iteración en curso, transfiriéndose
  • 19. 19 el control del programa a la condición de salida del bucle, para decidir si se debe realizar una nueva iteración o no. CONTINUE se puede emplear con cualquiera de los tres bucles, pero no con SWITCH. Al igual que antes el programa no ejecuta las sentencias restantes del bucle donde se encuentra. En bucles FOR o WHILE se comienza a ejecutar el siguiente ciclo del bucle. En DO WHILE se comprueba la condición de salida; si se cumple, se comienza el nuevo ciclo. RETURN El formato de la instrucción es: return (expresión); return expresión; Se usa para devolver datos en las funciones. El valor de expresión debe ser el mismo definido en la función. BREAK La instrucción BREAK sale de la ejecución de un bucle for, while, do y switch. GOTO Es un salto incondicional. En C casi no se utiliza porque se pierde la conceptualización de programa estructural y modular. Funciones de retardo Cuando se trabaja con microcontroladores es muy frecuente que se necesitan generar retardos; el compilador CCS, proporciona algunas funciones para estas situaciones. delay_ms(tiempo) Esta función realiza retardos del valor especificado en la variable tiempo. El valor es un int16 (0-65535) en milisegundos. Ejemplo: delay_ms(500); //genera un retardo de 500 ms.
  • 20. 20 delay_us(tiempo) Los retardos conseguidos con esta función son especificados en la variable tiempo en microsegundos y es un int16 (0-65535). Ejemplo: delay_us(500); //genera un retardo de 500 us. delay_cycles(contador) Con esta función, se realizan retardos de acuerdo al número de ciclos de máquina especificado en la variable contador. Los valores van desde 1 a 255. Un ciclo de máquina o instrucción es igual a cuatro ciclos de reloj. Ejemplo: delay_cycles( 5 ); // retardo de 5 ciclos instrucción. Es decir, si el microcontrolador trabaja con un oscilador de 4 MHz, el ciclo de instrucción o de máquina (CM) será igual: CM= 4*1/4000000Hz = 1us Por tanto, en el ejemplo anterior se ha obtenido un retardo de 5 us. Directiva #use delay (clock=frecuencia) Las tres funciones de retardo descritas trabajan en conjunto con la directiva #use delay. Esta directiva indica al compilador que frecuencia de reloj va utilizar el microcontrolador. Ejemplos: #use delay (clock=4000000) //Indica que MC va utilizar un oscilador de 4MHz. #use delay (clock=20000000) //Indica que MC va utilizar un oscilador de 20MHz. También se puede escribir: #use delay (clock=4M) //Indica que MC va utilizar un oscilador de 4MHz. #use delay (clock=20M) //Indica que MC va utilizar un oscilador de 20MHz. Los microcontroladores PIC Los microcontroladores PIC de Microchip Technology INC., son los número 1 en ventas a nivel mundial, por las diferentes ventajas que ofrecen, entre las que se puede mencionar:
  • 21. 21 • Diversidad de gamas de microcontroladores para todas las necesidades y aplicaciones que el diseñador pueda imaginarse. • Soporte técnico documental amplio: libros, manuales, tutoriales, aplicaciones específicas, abundante información en internet. • Gran cantidad de herramientas de desarrollo software y hardware. • Compatibilidad en la arquitectura entre las diferentes familias de microcontroladores PIC. • Unidades funcionales y módulos embebidos: temporizadores, conversores analógicos-digitales, USB, UART, PWM, CCP, etc. • Precios muy competitivos. Familias de microcontroladores PIC Microchip produce diferentes dispositivos que según el número de terminales lo clasifica en: Gama baja • Microcontroladoresde8bits,debajocoste,de6 pinesybajasprestaciones. Algunos PIC’s de las serie PIC10 se conocen como gama enana. • PIC12: microcontroladores de 8 bits, de bajo coste, de 8 pines y bajas prestaciones. Gama media • PIC16: microcontroladores de 8 bits, con gran variedad de número de pines y prestaciones medias. Gama alta • PIC17 y PIC18: microcontroladores de 8 bits, con gran variedad de número de pines y prestaciones medias/altas. • PIC24: microcontroladores de 16 bits. • PIC32: microcontroladores de 32 bits. • dsPIC’s. Microcontroladores especializados para el procesamiento de señales digitales. PIC18: Características fundamentales Las principales características de los microcontroladores de gama alta PIC18, se puede resumir en los siguientes:
  • 22. 22 • Arquitectura Harvard, RISC avanzada de 16 bits (instrucciones) con 8 bit de datos. • 77 instrucciones a nivel de assembler. • Desde 18 a 80 pines. • Tecnología CMOS. • Puertos de I/O con múltiples funciones. • Módulos CCP. ECCP, PWM y comparadores incorporados. • Conversores con múltiples canales multiplexados. • Hasta 64K bytes de memoria de programa (hasta 2 Mbytes en ROMless). • Multiplicador Hardware 8x8. • Hasta 3968 bytes de RAM y 1KBytes de EEPROM. • Frecuencia máxima de reloj 40Mhz. Hasta 10 MIPS. • Pila de 32 niveles. • Múltiples fuentes de interrupción. • Resistencias pull-up programables en el puerto B. • Temporizadores 8 y 16 bits. • Comunicación serial sincrónica y asincrónica. • Periféricos de comunicación avanzados (CAN y USB). La tabla 1.12, muestra las características generales de los PIC18F2455, PIC18F2550, PICF4455 y PIC18F4550 que son los más populares. Tabla 1.12. Características PIC18Fxxx. Fuente: PIC18F2455/2550/4455/4550 Data Sheet. Microchip Technology INC. Del listado de microcontroladores indicados en la tabla 1.12, el PIC18F4550, es uno de los más difundidos por sus altas prestaciones y recursos que dispone. Tiene 40 pines con 5 puertos numerados A, B, C, D y E. Cada puerto puede estar formado hasta con 8 líneas que se pueden configurar como entradas o salidas digitales. Además cada línea tiene más de una función como se ve en la figura 1.3.
  • 23. 23 Registros de los puertos Cada puerto tiene tres registros para su funcionamiento. Estos registros son: • Registro TRISx. Registro de la dirección de datos. El compilador CCS utiliza la instrucción TRISx para definir al puerto como salida (TRISx = 0) o como entrada (TRISx= 1). • Registro PORTx. Lee los niveles en los pines del dispositivo. Los datos existentes en los pines son leídos a través del registro PORT. El compilador CCS a través de la instrucción PORTx escribe datos al puerto respectivo. • Registro LATx. Latch de salida. Registro latch o cerrojo, almacena los estados lógicos que van a sacar las líneas de salida. No existe ninguna instrucción del compilador CCS asociada con el registro LAT. Cada pin de los puertos que sea de entrada/salida tiene incorporado una línea al registro PORT, LAT y TRIS. La letra x en TRISx, PORTx y LATx corresponde al nombre del puerto usado (A, B, C, D, E). Figura 1.3. Distribución de pines del PIC18F4550, versión DIP. Fuente: PIC18F2455/2550/4455/4550 Data Sheet. Microchip Technology INC.
  • 24. 24 La figura 1.4, muestra el diagrama de conexiones de un puerto de entrada/salida para su operación. Figura 1.4. Diagrama de un puerto entrada/salida. Fuente: PIC18F2455/2550/4455/4550 Data Sheet. Microchip Technology INC. PIC16: Principales características Indudablemente la familia más numerosa Microcontroladores PIC de gama media de la familia son los PIC16, en sus diferentes series y tecnologías son las más utilizadas y exitosas. Una de las series más famosas han sido los PIC de 18 pines como son el PIC16F84, PIC16F627A, PIC16F628A y actualmente el PIC16F88. Los micros de 40 pines el más destacado ha sido el PIC16F877 que está siendo reemplazado por la versión mejorada del PIC16F887. De acuerdo a las hojas de datos proporcionados por Microchip, las características generales que presenta esta gama son: • Arquitectura Harvard, RISC avanzada de 14 bits (instrucciones) con 8 bit de datos. • 35 instrucciones a nivel de assembler. • Desde 18 a 68 pines.
  • 25. 25 • Hasta 8K bytes de memoria de programa. • Frecuencia máxima de reloj 20MHz. • Múltiples fuentes de interrupción. • Módulos de comunicación sincrónica y asincrónica. • Módulos PWM/CCP/ECCP y comparadores. • Circuitos temporizadores de 8 y 16 bits. • Memoria RAM de hasta 368 bytes. • Memoria EEPROM de hasta 256 bytes. • Conversor con canales multiplexados. • Resistencias pull-up programables en el puerto B. • Dos puertos I/0 en los micros de 18 pines y 5 puertos en los PIC de 40 pines. El PIC16F84, fue el que revolucionó el diseño de circuitos con microcontroladores y se utilizó en la mayoría de centros de enseñanza la programación en base a este PIC. Los PIC 16F627A, 16F628A y 16F648A, ingresan al mercado con características mejoradas y reemplazan al PIC16F84A, siendo el PIC16F628A el de mayor acogida. Tienen una configuración para 8 osciladores. Un único pin para un circuito RC es la solución de más bajo coste. En modo LP, para mínimo consumo, XT para oscilador estándar y dos fuentes internas de precisión INTOSC. El modo HS para cristales de alta velocidad (hasta 20MHz) y el modo EC para una fuente externa de reloj. En estas series el pin RA4 es de drenador abierto y el pin RA5 que corresponde al MCLR (Master Clear), solo puede actuar como puerto de entrada. El microcontrolador PIC16F88, es 100% compatible con sus antecesores microcontroladores 16F628A/84A, pero incluye un módulo conversor análogo digital y el doble de la capacidad de la memoria FLASH. Además el PIC en mención, incluye un bloque de oscilador interno con 8 frecuencias seleccionables que van desde 31KHz hasta 8MHz, tres modos de osciladores decristalexternoLP,XTyHShasta20MHz,dosmodosexternosRCyunmodo de reloj externo ECIO de hasta 20MHz. También, es un microcontrolador multifunciones, con capacidad de autoprogramación mediante firmware bootloader residente.
  • 26. 26 La tabla 1.13, presenta un resumen de las características más importantes de los microcontroladores mencionados en este punto. CARACTERÍSTICAS PICF16F84A PIC16F627A PIC16F628A PIC16F648A PIC16F88 Memoria FLASH (Words) 1024 1024 2048 4096 4096 Memoria EEPROM (bytes) 64 128 128 256 256 Memoria SRAM (bytes) 68 224 224 256 368 Puertos I/O 2 2 2 2 2 Pines de I/O 13 16 16 16 16 Oscilador Externo Interno/Externo Interno/ Externo Interno/Externo Interno/Externo Fuentes de interrupción 10 10 10 10 12 Comunicación serial USART USART USART USART AUSART, SSP (SPI e I2C) Comparadores - 2 2 2 2 Conversores AD - - - - 7 canales mulltiplexados Tabla 1.13. Características principales de los microcontroladores PIC16F84/627A/628A/88. Elaborado por: Los Autores. La figura 1.5 a, muestra el diagrama del microcontrolador 16F627A/628A/648A y la figura 1.5 b, el diagrama del microcontrolador 16F88, en versiones DIP. a. Diagrama de distribución de pines de los PIC16F627A/628A/648A.
  • 27. 27 b. Diagrama de distribución de pines de los PIC16F88. Figura 1.5. Microcontroladores PIC gama media de 18 pines, series 16FXXX versión DIP. Fuente: PIC16F87/88 Data Sheet, PIC16F627A/628A/648A Data Sheet.Microchip Technology INC. En versiones de 28, 40 y 44 pines el microcontrolador de gama media 16F877A ha sido uno de los más exitosos. Entre las características más destacadas de este micro está que tiene 5 puertos (A, B, C, D, E). Posee un módulo de Comunicación Serial Universal Asincrónico USART, que soporta RS-485, RS-232 y LIN2.0 y un Puerto Serie Síncrono Maestro (MSSP), para modos SPI (Serial Peripheral Interface) e I2C (Inter-Integrated Circuit). ElPIC16F877Anoincluyeunsistemaderelojinterno,porloqueMicrochip para suplir esta necesidad introduce el PIC16F887, con varias mejoras. Este micro posee un sistema de selección de reloj interno de precisión desde 8MHz a 31KHz. Posee un registro postescaler de 8 bits, para dividir la fuente de 8MHz y obtener 8 frecuencias distintas (8, 4, 2, 1 MHz, 500, 250, 125 y 31.25 kHz). Los modos de oscilador externo son LP, XT, HS, RC, RCIO, EC, y en oscilador interno INTOSC y INTOSCIO. El módulo CCP mejorado (ECCP) útil para el control PWM de puentes y semipuentes para circuitos inversores, es otra de las características relevantes de este PIC. El módulo EUSART (Enhanced USART), permite la autodetección de baudios. El módulo ADC, es de 10 bits y tiene hasta 14 canales multiplexados para ser utilizados simultáneamente. Los microcontroladores de esta gama poseen un amplio rango de voltaje de operación que va de entre 2 y 5.5V.
  • 28. 28 La tabla 1.14, muestra un resumen comparativo de las principales características que distinguen a estos dos microcontroladores. CARACTERÍSTICAS PIC16F877A PIC16F887 Frecuencia Máxima 20MHZ 20MHZ Memoria FLASH (Words) 8192 8192 Memoria EEPROM (bytes) 256 256 Memoria SRAM (bytes) 368 368 Puertos I/O 33 35 Timer (8/16 bits) ½ ½ Oscilador Externo Interno/Externo Comparadores 2 2 Conversores AD 8 canales (10 bits) 14 canales (10 bits) Frecuencias INTOSC - 31 KHZ-8 MHZ Fuentes de interrupción 15 15 ECCP/CCP 0/2 ½ Comunicación serial USART/MSSP EUSART/MSSP Modos de oscilador 4 8 Tabla 1.14. Características de los PIC 16F877A/887. Elaborado por los autores. Los diagramas de distribución de pines para los PIC16F877A/887, versión DIP, se observa en la figura 1.6. a. Diagrama del PIC16F877.
  • 29. 29 b. Diagrama de distribución de pines del PIC16F887. Figura 1.6. Microcontroladores PIC16F877/887 versión DIP. Fuente: PIC18F2455/2550/4455/4550 Data Sheet. Microchip Technology INC. EJERCICIOS Y PREGUNTAS PROPUESTAS 1. ¿Cuál carácter se utiliza para hacer comentarios en una sola línea? 2. ¿Con qué carácter se separan instrucciones? 3. ¿Cuál es la diferencia entre retorno de línea y cambio de línea? 4. ¿Qué palabra se debe utilizar para declarar un variable entero de 1 bit? 5. Realice la declaración de la variable I = 2.536 6. ¿Cuáles son las restricciones que se deben tomar en cuenta al declarar una variable?
  • 30. 30 7. Encuentre el error en la declaración de la variable y corríjala: float 2 contadores = 5; 8. Una variable int16 ¿qué rango de valores contiene? 9. ¿En qué parte del programa puede ser utilizada una variable global? 10. Se realiza la operación: c= 10%4, ¿cuál es el valor de c? 11. En la operación x+=2; ¿cuánto es el resultado de x? 12. ¿Cuál es el resultado de la operación x= x>>2, si x= 25? Realice las operaciones en binario. 13. ¿Cuál es el resultado de la operación x= x<<4, si x= 63? Realice las operaciones en binario. 14. Explique la diferencia entre realizar la operación: a. a&b y a&&b. b. a|b y a||b. 15. En el siguiente código if (x < 18) printf(“Eres menor de edad.n”); else printf(“Eres un joven.n”); Sea x= 25, ¿qué mensaje se imprime? 16. En el siguiente ejemplo: a. ¿Para qué sirve break? b. Si lista=0, ¿qué mensaje se imprime? Switch( lista) { case 0: printf(“No hay elementos.”);
  • 31. 31 break; case 1: printf(“Hay solo un elemento.”); break; default: printf(“Hay varios elementos”); } 17. Usando while escriba la forma para crear un bucle infinito. 18. Usando for escriba la forma para crear un bucle infinito. 19. Escriba la instrucción usando for para que una variable entrada cuente del 0 al 99. 20. ¿Qué tiempo de retardo genera delay_ms(1500)? 21. De los microcontroladores citados en este capítulo, ¿cuáles no tienen reloj interno? 22. Cuál microcontrolador de 18 pines tiene memoria FLASH de 4096 words y posee un módulo conversor de AD de 7 canales. 23. ¿Cuáles series de microcontroladores PIC tienen un módulo de conexión USB?
  • 32. 32
  • 33. 33 Los fuses del microcontrolador PIC18 TodoslosmicrocontroladoresPICtienenincorporadoscircuitosespeciales que se pueden activar o desactivar según los requerimientos de la aplicación o algún caso en particular. Estos circuitos o características especiales se deben configurar mediante software o por el equipo programador al momento de grabar el programa en el microcontrolador. La configuración adecuada de estos circuitos determina en gran parte la funcionabilidad y eficiencia del programa desarrollado. Los fuses permiten entre otras cosas seleccionar el oscilador: interno o externoquesevautilizar,lafrecuenciadetrabajodelsistema,elusodelMaster Clear (reset del sistema), etc. Los fuses internamente en el microcontrolador son controlados por registros internos y que se pueden habilitar o deshabilitar mediante software o por medio del equipo programador. CCS provee de instrucciones de alto nivel que permiten de forma transparente configurar los FUSES (fusibles). En el PIC18F4550, los fuses que CCS configura se muestra en la tabla 2.1. Para no distorsionar la descripción del fuse, se ha dejado en el idioma original, que CCS proporciona en el IDE del programa. FUSE DESCRIPCIÓN LP Low power osc < 200 kHz XT Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD HS High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD) RC Resistor/Capacitor Osc with CLKOUT EC External clock with CLKOUT EC_IO External clock H4 High speed osc with HW enabled 4X PLL RC_IO Resistor/capacitor osc RC Resistor/Capacitor Osc with CLKOUT INTRC_IO Internal RC Osc, no CLKOUT INTRC Internal RC Osc NOFCMEN Fail-safe clock monitor disabled FCMEN Fail-safe clock monitor enabled IESO Internal External Switch Over mode enabled NOIESO Internal External Switch Over mode disabled PUT Power up timer NOPUT No power up timer BROWNOUT Reset when brownout detected
  • 34. 34 NOBROWNOUT No brownout reset BROWNOUT_SW Brownout controlled by configuration bit in special file register B R O W N O U T _ NOSL Brownout enabled during operation, disabled during SLEEP BORV45 Brownout reset at 4.5V BORV42 Brownout reset at 4.2V BORV27 Brownout reset at 2.7V BORV20 Brownout reset at 2.0V NOWDT No watch dog timer WDT Watch dog timer WDT128 Watch Dog Timer uses 1:128 Postscale WDT64 Watch Dog Timer uses 1:64 Postscale WDT32 Watch Dog Timer uses 1:32 Postscale WDT8192 Watch Dog Timer uses 1:8192 Postscale WDT16384 Watch Dog Timer uses 1:16384 Postscale WDT16 Watch Dog Timer uses 1:16 Postscale WDT8 Watch Dog Timer uses 1:8 Postscale WDT256 Watch Dog Timer uses 1:256 Postscale WDT512 Watch Dog Timer uses 1:512 Postscale WDT1024 Watch Dog Timer uses 1:1024 Postscale WDT2048 Watch Dog Timer uses 1:2048 Postscale WDT4 Watch Dog Timer uses 1:4 Postscale WDT32768 Watch Dog Timer uses 1:32768 Postscale WDT4096 Watch Dog Timer uses 1:4096 Postscale WDT1 Watch Dog Timer uses 1:1 Postscale WDT2 Watch Dog Timer uses 1:2 Postscale CCP2B3 CCP2 input/output multiplexed with RB3 CCP2C1 CCP2 input/output multiplexed with RC1 NOPBADEN PORTB pins are configured as digital I/O on RESET PBADEN PORTB pins are configured as analog input channels on RESET LPT1OSC Timer1 configured for low-power operation NOLPT1OSC Timer1 configured for higher power operation NOMCLR Master Clear pin used for I/O MCLR Master Clear pin enabled STVREN Stack full/underflow will cause reset NOSTVREN Stack full/underflow will not cause reset NOLVP No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O LVP Low Voltage Programming on B3(PIC16) or B5(PIC18)
  • 35. 35 NOXINST Extended set extension and Indexed Addressing mode disabled (Legacy mode) XINST Extended set extension and Indexed Addressing mode enabled NODEBUG No Debug mode for ICD DEBUG Debug mode for use with ICD PROTECT Code protected from reads NOPROTECT Code not protected from Reading NOCPB No Boot Block code protection CPB Boot block code protected CPD Data eeprom code protected NOCPD No EE protection WRT Program memory write protected NOWRT Program memory not write protected WRTC Configuration registers write protected NOWRTC Configuration not registers write protected NOWRTB Boot block not write protected WRTB Boot block write protected WRTD Data EEPROM write protected NOWRTD Data EEPROM not write protected NOEBTR Memory not protected from table reads EBTR Memory protected from table reads EBTRB Boot block protected from table reads NOEBTRB Boot block not protected from table reads Tabla 2.1. FUSES para el PIC184550 del compilador CCS. Fuente: CCS Compiler V4.084. Algunos fuses de interés significan: LVP: Low Voltage programming. Programación por voltaje bajo. • 1 = LVP habilitado, la terminal RB4/PGM tiene tal función. • 0 = LVP deshabilitado, RB4/PGM es una terminal de I/O BODEN: Brown Out Detect Reset Enable bit (Bit de reset por voltaje de alimentación bajo). En CCS el fusible es BROWNOUT NOBROWNOUT. • 1 = Reset por BOD habilitado. • 0 = Reset por BOD deshabilitado. BOR: Brown-out Reset. Este circuito hace que el PIC se reinicie cuando se detecta una inestabilidad en la alimentación. El compilador proporciona
  • 36. 36 varios FUSES para configurar el BOR para diferentes niveles de tensiones (ver tabla 2.1). Por ejemplo: BORV45 reinicia el microcontrolador en nivel de 4.5V. PBADEN y NOPBADEN: Cuando se produce un RESET en el Micro, con PBADEN los pines del puerto B se configuran como canales de entrada analógicos y con NOPBADEN los pines del puerto B se configuran como entradas o salidas digitales. MCLR: Master Clear. Habilitación/deshabilitación del terminal de reset. • 1 = Terminal de reset (MCLR) en RA5. • 0 = MCLR conectado internamente a Vdd, RA5 es un pin de I/O. PUT: Power up Timer enable bit. En el datasheet del microcontrolador es el bit que se conoce como PWRT. Es el bit de habilitación de temporizador al energizar. Al activar el POWER UP TIMER lo que hace es retardar el arranque del PIC. Este empieza a funcionar unos 65.5 ms., después de recibir la tensión de alimentación. • 1 = PWRT habilitado. • 0 = PWRT deshabilitado. WDT: Watch Dog Timer Enable Bit. Bit de habilitación del Watch-Dog. • 1 = WDT habilitado. • 0 = WDT deshabilitado. Para configurar los fusibles se debe incluir en el programa la directiva #fuses, seguido de los nombres y separados entre comas (,) de los fuses que se necesiten fijar en el programa. Si no se considera algunos de ellos el programa asume el valor por default que suministra el fabricante, mismo que podemos ver en el datasheet del microcontrolador. Ejemplo: Suponer que se va a utilizar un cristal de 4 MHz, desactivar el Master Clear, No proteger el código para lectura, desactivar la programación a bajo voltaje; el código del compilador CCS para los FUSES mencionados es: #fuses XT, NOWDT, NOPROTECT, NOLVP //Configuración de Fuses. Nota: Se debe indicar que el compilador acepta mayúsculas o minúsculas al escribir las instrucciones, funciones u otras sentencias para el desarrollo de los programas.
  • 37. 37 Configuración del reloj La mayoría de los microcontroladores PIC de la familia 16F y 18F tienen incorporado un sistema de reloj para ser utilizado según las necesidades del diseño. El hardware de control del oscilador es el registro OSCCON (Oscillator Control Register) y el registro oscilador de ajuste OSCTUNE (Oscillator Tuning Register), se utiliza para ajustar frecuencia interna vía software. Tipos de osciladores Según el datasheet del fabricante, los dispositivos PIC18F2455 / 2550/4455/4550 y PIC16F88, PIC16F887, pueden ser operados en distintos modos de oscilador, siendo estos los más usados: • XT Crystal / Resonador (se usa para cristales <= 4 MHZ). • HS alta velocidad Crystal / Resonador (>4MHZ). • HSPLL alta velocidad Crystal / Resonador con PLL activado. • EC reloj externo con FOSC / 4 de salida. • ECIO reloj externo con I / O en RA6. • ECPLL Reloj externo con PLL Activado y FOSC / 4 Salida en RA6. • ECPIO Reloj externo con PLL habilitado, I/O en RA6. • INTHS oscilador interno utilizado como • Microcontroladores fuente de reloj, HS • Oscilador utilizado como USB Fuente de reloj • INTIO oscilador interno utilizado como: • Microcontrolador fuente de reloj, EC • Oscilador utilizado como fuente de reloj USB, • I/O digital en RA6 • INTCKO oscilador interno utilizado como • Microcontrolador fuente de reloj, EC • Oscilador utilizado como fuente de reloj USB, • FOSC / 4 Salida en RA6 El PIC16F628A tiene los modos LP, XT, HS, ECIO, INTIO, INTCKO. La tabla 2.2, indica los valores típicos del cristal y los capacitores que el fabricante sugiere utilizar con los diferentes cristales para modo XT y HS. Mayor información sobre los valores del oscilador de cristal y los capacitores
  • 38. 38 para los resonadores cerámicos se pueden encontrar en las hojas del datasheet del fabricante. Tabla 2.2. Selección de capacitores para el oscilador de cristal. Fuente: PIC18F2455/2550/4455/4550 Data Sheet. Microchip Technology INC. El oscilador se conecta en los pines RA6/OSC2/CLKO y OSC1/CLK1. La figura 2.1, muestra el diagrama de conexiones del oscilador de cristal de 8MHz y los capacitores cerámicos de 22 pF, como recomienda el fabricante. Figura 2.1. Conexión del oscilador de cristal externo. Elaborado por los autores.
  • 39. 39 Todas las frecuencias se derivan de 8MHZ y con el registro POSTSCALER de 8 bits se obtienen el resto de frecuencias (8MHz/256= 31.25kHz) y son seleccionables por software. La figura 2.2, indica los valores de las frecuencias internas que pueden ser usadas. Figura 2.2. Diagrama de bloques del oscilador interno y la gama de frecuencias derivadas. Fuente: PIC18F2455/2550/4455/4550 Data Sheet. Microchip Tecnhology INC. Mediante la configuración de los FUSES se puede utilizar el oscilador externo o la fuente de frecuencia interna. El compilador provee una serie FUSES para configurar el reloj interno. Configuración del oscilador La instrucción para utilizar el tipo de oscilador es: #fuses TIPO DE OSCILADOR Donde el TIPO DE OSCILADOR hace referencia a los descritos en este punto. Ejemplo: #fuses HS #use delay (clock=12000000) Se indica al microcontrolador que utilizará un oscilador externo de alta velocidad (HS) con un cristal de 12000000 Hz. Para indicar directamente la frecuencia en MHz, se puede utilizar la notación: #use delay (clock=12M)
  • 40. 40 Para el caso que utilicemos la fuente de reloj interno del microcontrolador, se utilizaría así: #fuses INTRC_IO #use delay (clock=8M) Se indica al compilador que se va a utilizar el oscilador interno RC y el pin RA6, se configura para que sea utilizado como entrada o salida digital. Es válido también en algunos Micros que tienen el puerto RA7, o sea RA6 y RA7, se configuran como I/O digitales. La instrucción #use delay (clock=8M), indica al compilador usar frecuencia de reloj para el sistema de 8MHz. En la figura 2.2, se pueden observar los valores de reloj internos que se pueden utilizar. Si se utiliza la configuración del fusible: #fuses INTRC. Se indica al compilador use el reloj interno y por el terminal RA6 se obtendrá una salida de reloj del sistema interno (FOSC /4). Otra forma de fijar el oscilador interno es mediante la función setup_oscillator(). Esta función hace referencia al registro OSCCON del microcontrolador. La función controla y devuelve el estado del oscilador RC interno en los micros que disponen del registro OSCCON. Se debe tener en cuenta que si INTRC o INTRC_IO se especifica en #fuses y un retraso #use se utiliza para una opción de velocidad válido, el compilador hará esta configuración automáticamente al inicio del main (). La sintaxis y argumentos de la función son: setup_oscillator(mode, finetune) Dónde: mode, es dependiente en el chip. Por ejemplo, algunos chips permiten ajuste de velocidad tales como OSC_8MHZ u OSC_32KHZ. Otros micros permite el cambio del origen como OSC_TIMER1. finetune, es el ajuste preciso, es un variable entera que va desde -31 a +31. Solo se permiten en microcontroladores que disponen del registro OSCTUNE.
  • 41. 41 Algunos chips devuelven un estado tal como OSC_STATE_STABLE para indicar el oscilador es estable. La función descrita debe siempre colocarla dentro del main () del programa. Ejemplo: void main() { setup_oscillator(OSC_8MHz|OSC_INTRC|OSC_PLL_OFF); } Conexión de LEDS en los puertos La figura 2.3, muestra la conexión de diodos LEDS al puerto A, B, C, D y E del microcontrolador. Hay que tomar en cuenta que la máxima corriente que puede entregar o recibir los puertos del microcontrolador es de 25 mA, según las características eléctricas que Microchip establece para el PIC18F4550. Por tanto, tomando en consideración el valor indicado, se ha colocado resistencias de 330 Ω, en las líneas del puerto para limitar la corriente y evitar dañar el puerto. Esta conexión es común para todos los puertos excepto para el pin RA4, que en algunos de los microcontroladores son de drenador abierto. Dado que la caída de tensión en el LED cuando está conduciendo es de aproximadamente 1.3 V, la corriente de cada pin del puerto es: El valor obtenido es inferior a los 25 mA y está en el rango (5 a 15 mA) que necesita un LED para iluminar adecuadamente.
  • 42. 42 Figura 2.3. Conexión de LEDS en los puertos del microcontrolador. Elaborado por los autores. Gestión de puertos En el compilador CCS se pueden gestionar los puertos de dos formas: • Definiendo la posición de la memoria RAM como una variable C para los registros TRISX y PORTX. • Usando la directivas específicas del compilador (#USE FAST_IO, #USE FIXED_IO, #USE STANDARD_IO) Usando la memoria RAM Las posiciones de memoria que utilizan los registros TRISX y PORTX del PIC18 se identifican así: #BYTE tris_n = Dir #BYTE port_n = Dir Donde, n es el nombre del puerto (A, B, C, D, E) y la variable Dir la dirección en la memoria RAM. Ejemplo: #BYTE tris_b = 0xF93 #BYTE port_b = 0xF81
  • 43. 43 La tabla 2.3, muestra las direcciones de memoria ocupadas por los registros TRIS en la familia de PIC18FXXX. En todo caso, siempre es necesario consultar el datasheet del fabricante para verificar la dirección exacta que ocupa los registros TRIS en la memoria RAM. REGISTRO TRIS DIRECCIÓN DE MEMORIA A 0xF92 B 0xF93 C 0xF94 D 0xF95 E 0xF96 Tabla 2.3. Localidades de memoria ocupados por los registros TRIS, para los PIC18FXXX. Fuente: PIC18F2455/2550/4455/4550 Data Sheet. Microchip Tecnhology INC. La tabla 2.4, indica las direcciones de la memoria RAM que son asignadas para el registro PORT de los PIC de la serie PIC 18F4550. Esta información se encuentra en las hojas de datos técnicos que proporciona el fabricante de microcontroladores PIC, Microchip Technology INC. REGISTRO PORT DIRECCIÓN DE MEMORIA A 0xF80 B 0xF81 C 0xF82 D 0xF83 E 0xF84 Tabla 2.4. Localidades de memoria ocupados por los registros PORT, para los PIC18FXXX. Fuente: PIC18F2455/2550/4455/4550 Data Sheet. Microchip Tecnhology INC. Para las series de microcontroladores PIC 16F8XX y 16F6XX, las direcciones del registro TRIS y PORT son: REGISTRO TRIS DIRECCIÓN DE MEMORIA A 0x85 B 0x86 C 0x87 D 0x88 E 0x89 Tabla 2.5. Localidades de memoria ocupados por los registros TRIS, para los PIC16F. Fuente: PIC18F2455/2550/4455/4550 Data Sheet. Microchip Tecnhology INC.
  • 44. 44 REGISTRO PORT DIRECCIÓN DE MEMORIA A 0x05 B 0x06 C 0x07 D 0x08 E 0x09 Tabla 2.6. Localidades de memoria ocupados por los registros PORT, para los PIC16F. Fuente: PIC18F2455/2550/4455/4550 Data Sheet. Microchip Tecnhology INC. Definidas las variables se pueden controlar los puertos por comandos de asignación. Ejemplos: • tris_a = 0xFF ; Define todo el puerto a como entrada • tris_b = 0x00; Define todo el puerto b como salida • tris_d = 0x0F; Define los 4 primeros bits del puerto d como entrada y los 4 bits (MSB) como salida. Luego se escribe o lee los datos en el puerto. Escritura del puerto: port_b = 0x0B; El dato 1011, se coloca en el puerto b. Lectura del puerto: Contador = port_a; El dato del puerto a se asigna a la variable Contador. Ejercicio 2.1. Prender y apagar un LED conectado en el puerto B0. El primer programa de computadora que enseñan en programación y en la mayoría de lenguajes es imprimir en la pantalla “Hola Mundo”. El primer programa semejante que se realiza con un microcontrolador es prender y apagar un LED indefinidamente. En el programa primero debemos definir el microcontrolador a utilizarse, para lo cual se utiliza la directiva: #include <18F4550.h> //Librería para usar el PIC18F4550. Ahoraseprocedeaconfigurarlosfusibles.Lahabilitaciónodeshabilitación de los fusibles dependerá de la aplicación que se esté desarrollando, pero el fusible que siempre se debe incluir es el reloj que se utilice. En este caso definimos un cristal de alta velocidad HS. #fuses HS,NOWDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles.
  • 45. 45 Es importante también definir la frecuencia del oscilador: #use delay (clock=12000000) // FOSC =12MHz. En este programa el LED se conecta en el puerto RB0. Se define el bit a utilizar mediante la instrucción #bit b0= 0xF81.0. La variable bit b0 se puede asignar valores de 0 y 1 para obtener valores lógicos de tensión de 0 y 5V respectivamente en el puerto RB0. Por tanto, en el programa las asignaciones de b0= 0; establecen que el puerto RB0 sea igual a 0V y b0= 1; en el puerto RB1 tendrá el nivel lógico de 5V. Cuando no se utiliza las interrupciones, es conveniente deshabilitar todas las interrupciones, sin que sea una exigencia de alta prioridad. La instrucción disable_interrupts (GLOBAL); realiza esta función. El registro TRISB está definido en la localidad 0xF93 como indica en las hojas técnicas del microcontrolador PIC18F4550. Otro aspecto importante que se debe tomar en cuenta dentro de la programación es la definición del puerto como salida. La instrucción tris_b = 0x00; configura el puerto como salida, para que permita establecer los niveles lógicos de 0 y 1. PROGRAMA: #include <18F4550.h> //Librería para usar el PIC18F4550. #fuses HS,NOWDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles. #use delay (clock=12000000) // FOSC =12MHz. #byte tris_b = 0xF93 //Define el registro tris b en la localidad 0xF93. #bit b0= 0xF81.0 //Define el bit b0 en la localidad 0xF81.0. void main() //Función principal main. { disable_interrupts (GLOBAL); //Deshabilita las interrupciones globales. tris_b = 0x00; //Configura el puerto B como salida. do{ //Inicio del bucle infinito. b0= 0; //El puerto RB0 = 0. delay_ms( 500 ); //Retardo de 500 ms. b0 =1; //El Puerto RB0 = 1. delay_ms(500); //Retardo de 500 ms. } while ( TRUE ); //Bucle infinito. } //Fin del bucle main.
  • 46. 46 El circuito para comprobar el funcionamiento se indica en la figura 2.4. Como en la configuración de los FUSES no está definido el uso del MCLR, es necesario conectar este terminal a través de una resistencia a VCC , el pulsador permitirá tener un botón de RESET. Figura 2.4. Conexión de un LED en el puerto RB0. Elaborado por los autores. Ejercicio 2.2. Prender y apagar los LEDS del puerto B. En el ejercicio 2.2, los LEDS conectados al puerto B se prenden y apagan indefinidamente, como indica la figura 2.5. En este caso en el programa todos los ocho bits de la localidad de memoria 0xF81 se asignan a la variable port_b, de igual manera ocurre con el registro tris_b, con la localidad de memoria 0xF93.
  • 47. 47 PROGRAMA: #include <18F4550.h> //Librería para usar el PIC18F4550. #fuses HS,NOWDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles. #use delay (clock=12000000) / / FOSC = 12MHz. #byte port_b = 0xF81 //Identificador para el puerto b en la localidad 0xF81. #byte tris_b = 0xF93 //Identificador para el registro tris b en la localidad 0xF93. void main() //Función principal main. { disable_interrupts(GLOBAL); //Deshabilita todas las interrupciones globales. tris_b = 0x00; //Configura todo el puerto B como salida. port_b = 0x00; // Asigna a todo el Puerto B cero (0). do{ // Hace o empieza el bucle infinito. port_b = 0xFF; //Coloca todo el puerto B en 1. delay_ms( 500 ); //Retardo de 500 ms. port_b = 0x00; //Coloca todo el puerto B en 0. delay_ms(500); //Retardo de 500 ms. } while ( TRUE ); //Bucle infinito. } //Fin del bucle main. Figura 2.5. LEDS conectados en el puerto B. Elaborado por los autores.
  • 48. 48 Con el programa propuesto y el circuito indicado los LEDS se prenden por 500 ms y se apagan por un tiempo igual. La ejecución de la secuencia de prendido y apagado es indefinido, el bucle DO – WHILE en la función principal main() se encarga de ejecutar las instrucciones en bucle infinito. Otra forma de generar un bucle infinito es utilizando la sentencia while (TRUE) o while(1) como se indica en el ejercicio 2.3. Ejercicio 2.3. Prender y apagar los LEDS que están conectados al puerto B indefinidamente. La mayoría de programas que se desarrollan en C, para generar los bucles infinitos se utiliza la sentencia while(TRUE), por lo que en este programa se utilizará esta forma. PROGRAMA: #include <18F4550.h> //Librería para usar el PIC18F4550. #fuses HS,NOWDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles. #use delay (clock=12000000) // FOSC = 12MHz. #byte port_b = 0xF81 //Identificador para el puerto b en la localidad 0xF81. #byte tris_b = 0xF93 //Identificador del registro tris b en la localidad 0xF93. void main() //Función principal main. { disable_interrupts(GLOBAL); //Deshabilita todas las interrupciones globales. tris_b = 0x00; // Configura el puerto B como salida. port_b = 0x00; // Asigna a todo el Puerto B cero (0). while (TRUE){ //Bucle infinito. port_b = 0xFF; //Coloca todo el puerto B en 1. delay_ms( 500 ); //Retardo de 500 ms. port_b = 0x00; //Coloca todo el puerto B en 0. delay_ms(500); //Retardo de 500 ms. } //Fin del bucle infinito. } //Fin del bucle main. A través de directivas El compilador ofrece funciones predefinidas para trabajar con los puertos. Estas directivas son: • output_x (value); por el puerto indicado saca el valor correspondiente a 0 a 255.
  • 49. 49 • input_x(); se obtiene el valor del puerto. •set_tris_x(value);configuraelpuertoxcomoentradaosalidadependiendo de la variable value. Ejemplo: set_tris_b(0x00); el puerto b es de salida. set_tris_b(0xFF); el puerto b es de entrada. • get_tris_x(); devuelve el valor del registro tris_x. x, es el símbolo correspondiente a los puertos A, B, C, D, E. Las funciones asociadas al terminal o pin son: • output_low (PIN_n); pin a 0. • output_high (PIN_n); pin a 1. • output_bit (PIN_n,value); pin al valor especificado. • output_toggle (PIN_n); complemento el valor del pin. • output_float (PIN_n); pin de entrada, quedando a tensión flotante. Simula salida de drenador abierto. • output_state (PIN_n); lee el valor del pin. • input_state(PIN_n); lee el valor del PIN sin cambiar el sentido del terminal. • input(PIN_n); lee el valor del PIN. n, se refiere al nombre del puerto y/o del PIN. Directiva #use standard_io (puerto) Es la directiva por defecto. Las funciones output_x e input_x, modifican el registro TRIS asegurando que los terminales usados sean de salida o entrada respectivamente. Si no se incluye ninguna directiva, el programa tomará por defecto #use standard_io(puerto), que reprogramará cada vez al pin como entrada o salida aumentando el código generado por el compilador. Al usar las directivas no es necesario identificar las direcciones que ocupan los registros PORT y TRIS, porque estos ya están definidos en las directivas. Ejercicio 2.4. Prender y apagar un LED por el puerto RB0. Este programa trabaja de la misma forma del ejercicio 2.1. En este caso se utiliza las funciones de la directiva #USE STANDARD_IO(PUERTO) para
  • 50. 50 definir el puerto a usarse. Nótese que ya no se Define port_x de entrada o salida con TRIS. El circuito de figura 2.4, se puede utilizar para demostrar el funcionamiento. PROGRAMA: #include <18f4550.h> / /Librería para usar el PIC18F4550. #fuses HS,NOWDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles. #use delay (clock=12000000) //FOSC=12MHz. #use standard_io(b) //Directiva usado por el compilador por defecto. //Es opcional llamarla en el programa. void main(void) //Función principal main. { disable_interrupts(GLOBAL); //Todas las interrupciones desactivadas. while(TRUE); //Bucle infinito. { //Inicio del bucle. output_low(PIN_B0); //LED off. delay_ms(500); //Retardo de 500 ms. output_high(PIN_B0); //LED on. delay_ms(500); //Retardo de 500 ms. } //Fin del bucle infinito. } //Fin del bucle main. b. Directiva #use fast_io(port) Esta directiva define a los puertos como entradas o salidas digitales. La variable port puede tomar los valores de a, b, c, d, e, o all para señalar que todos los puertos se utilizarán como entradas y salidas digitales. Las funciones output_x e input_x, no modifican el registro TRIS, por lo cual se debe colocar necesariamente la instrucción para definir que los terminales usados sean de salida o entrada respectivamente. Al utilizar esta directiva, el compilador optimiza el código generado y ahorra memoria de programa. El uso de las funciones output e input no reprograman los puertos ya que quedan definidos en la instrucción TRIS. Por tanto, la respuesta de los puertos para conmutaciones rápidas se ve mejorado con el uso el uso de la directiva #use fast_io(port).
  • 51. 51 Ejercicio 2.5. Prende y apaga LED por el puerto RB0. En el programa para definir el estado en alto del puerto se utiliza la función output_high(PIN_B0) y el estado en bajo la función output_low(PIN_ B0). El registro TRIS no identifica con la dirección de memoria respectiva y se hace referencia directamente para fijar al puerto B como salida con la instrucción set_tris_b (00x00). PROGRAMA: #include <18f4550.h> / /Librería para usar el PIC18F4550. #fuses HS,NOWDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles. #use delay (clock=12000000) //FOSC=12MHz. #use fast_io(b) //Define el puerto b como i/o digital. void main(void) //Función principal main. { set_tris_b(0x00) //Define port_b como salida. disable_interrupts(GLOBAL); //Todas las interrupciones desactivadas. while(TRUE); //Bucle infinito. { //Inicio del bucle. output_low(PIN_B0); //LED off. delay_ms(500); //Retardo de 500 ms. output_high(PIN_B0); //LED on. delay_ms(500); //Retardo de 500 ms. } //Fin del bucle infinito. } //Fin del main. c. Directiva #use fixed_io(puerto_outputs=pinx) Con la directiva #use fixed_io(puerto_outputs=pinx), cuando se utilizan las funciones input y output los puertos son reprogramados como entradas y salidas por lo que el código generado es mayor. Sin embargo, se ahorra una posición de memoria RAM por cada puerto utilizado. Ejemplo: #use fixed_io(b_outputs=pin_b0, pin_b1)
  • 52. 52 Ejercicio 2.6. Prender y apagar un LED. PROGRAMA: /* MANEJO DEL PUERTO USANDO DIRECTIVA #USE FIXED */ #include <18F4550.h> / /Librería para usar el PIC18F4550. #fuses HS,NOWDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles. #use delay (clock=12000000) //FOSC=12MHz. #use fixed_io(b_outputs=pin_b0) //Define el puerto b0 como salida. void main() //Función principal main. { disable_interrupts(GLOBAL); //Desactiva todas las interrupciones. while (TRUE) //Bucle infinito. { //Inicio del bucle. output_high(pin_b0); //Puerto RB0 en alto. delay_ms( 500 ); //Retardo de 500 ms. output_low(pin_b0); //Puerto RB0 en bajo. delay_ms(500); //Retardo de 500 ms. } //Fin del bucle infinito. } //Fin del bucle main. Secuencias con LEDS En muchas aplicaciones como en luces de discotecas, decoraciones de locales, etc., se necesita controlar luces que deben un efecto visual atrayente. Utilizando el microcontrolador se puede realizar una serie de proyectos de este tipo. Ejercicio 2.7. Secuencia de encendido y apagado de LEDS. El ejercicio siguiente, consiste en activar y desactivar los LEDS que están conectados al puerto uno a uno empezando desde el puerto RB0 hasta llegar al RB7 en forma indefinida. Para clarificar el funcionamiento y la secuencia de los bits que se desea implementar, la tabla 2.7, muestra el estado del puerto b, en cada uno de los bits que forman el puerto. 
  • 53. 53 RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 Tabla 2.7. Secuencia de encendido y apagado del puerto B. Elaborado por los autores. Para realizar el programa, se utiliza la siguiente lógica de programación: • Inicializar el puerto B con (00000001), para activar el LED que está conectado en RB0. • Mostrar este valor durante un tiempo (100 ms). • Desplazar el valor del puerto una posición a la izquierda (port_b = port_ b<<1). • Repetir este proceso hasta que llegue el 1 al puerto RB7. Mediante el bucle for se controla que el bit 1 que está en puerto RB0, se desplace hasta llegar al puerto RB7. Como el puerto tiene ocho bits, entonces el desplazamiento se debe repetir 7 veces. La instrucción que realiza esta función es:  for (i=1;i<=8;++i). • Al llegar el bit a la posición 7 el valor del puerto será 128 (27 =128). Apartir de este valor, en este punto, el desplazamiento se realiza a la derecha (port_b=port_b>>1) hasta que el bit llegue a RB0. • Repetir el proceso.
  • 54. 54 PROGRAMA: #include <18f4550.h> //Librería para usar el PIC18F4550 #fuses HS,NOWDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles. #use delay (clock=12000000) //FOSC=12MHz #BYTE port_b= 0xF81 //Identificador para el puerto b en la localidad 0xF81. int i; //Variable i tipo int para el bucle FOR. void main(void) { //Función principal main set_tris_b(0x00); //Puerto B como salida disable_interrupts(GLOBAL); //Todas las interrupciones desactivadas while(TRUE) //Bucle infinito { //Inicio del bucle. port_b=0x01; //Puerto RB0 = 1 for (i=1;i<=8;++i) //Realiza el bucle para i = 0 hasta que sea menor o igual 8 en //incrementos de 1. { delay_ms(100); //Retardo de 100 ms port_b= port_b<<1; //Desplaza el valor del puerto a la izquierda en 1 } port_b= 128; //port_b = 128. for (i=1;i<=8;++i) //Realiza el bucle para i = 0 hasta que sea menor o igual //8 en incrementos de 1. { delay_ms(100); //Retardo de 100 ms port_b= port_b>>1; //Desplaza el valor del puerto a la derecha en 1 } } //Fin del bucle infinito. } //Fin del bucle main. Conexión en el Puerto A En algunas familias de los PIC16F y 18F el puerto RA4, es de drenador abierto, lo cual significa que en la salida se debe conectar una resistencia en serie con el LED y luego a VDD . Para los demás pines del puerto Ala conexión es normal, como indica en la figura 2.6.
  • 55. 55 Figura 2.6. Conexión de LED en puerto RA4. Elaborado por los autores. Debido a la conexión, cuando el puerto RA4 tenga un nivel alto el LED2 se apaga y en un nivel bajo se prende. Ejercicio 2.8. Manejo de LEDS con el puerto A. PROGRAMA: #include <18f4550.h> //Librería para usar el PIC18F4550 #fuses HS,NOWDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles. #use delay (clock=12000000) // FOSC =12MHz #BYTE port_a= 0xF80 //Identificador para el puerto a en la localidad 0xF80. void main() //Función main. { set_tris_a(0x00); //Puerto A como salida. disable_interrupts(GLOBAL); //Todas las interrupciones desactivadas. port_a=0x00; //Puerto A = 0. while(TRUE); //Bucle infinito { output_low(PIN_A0); //LED conectado en el Puerto RA0 off. output_low(PIN_A4); //LED conectado en el Puerto RA4 on. delay_ms(500); //Retardo 500 ms. output_high(PIN_A0);//LED conectado en el Puerto RA0 on. output_high(PIN_A4);//LED conectado en el Puerto RA4 off. delay_ms(500); //Retardo 500 ms. } //Fin del bucle infinito. } //Fin del main
  • 56. 56 Conexión de pulsadores Todos los ejercicios realizados, hasta aquí, los puertos del PIC se han utilizado como salidas. A continuación se utilizaran como entradas. Se conectan pulsadores para cambiar los niveles de tensión en los pines del puerto. La figura 2.7, muestra las conexiones para manejar pulsadores. Con esta conexión los pines del puerto (RD0 y RD1), están directamente en estado lógico de 1. Por consiguiente, el accionamiento del pulsador determina que pasen los puertos indicados a bajo. Figura 2.7. Conexión de pulsadores. Elaborado por los autores. Ejercicio 2.9. Manejo de pulsadores. El ejercicio 2.9, consiste en prender un LED al accionar un pulsador 1 (P1) y apagar el LED al accionar el pulsador 2 (P2). Los pulsadores P1 y P2 se han conectado al puerto D en los pines RD0 y RD1 respectivamente. En el programa se definen las variables prender y apagar mediante las directivas #define prender bit_test(port_d,0), #define apagarbit_test(port_d,1),lascualespermitentestearelestadodelasentradas.
  • 57. 57 PROGRAMA: #include <18f4550.h> / /Librería para usar el PIC18F4550. #fuses HS,WDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles. #use delay (clock=12000000) // FOSC =12MHz. #BYTE port_b= 0xF81 //Identificador para el puerto b en la localidad 0xF81 #BYTE port_d= 0xF83 //Identificador para el puerto d en la localidad 0xF83. #define prender bit_test(port_d,0) //Define el pin RD0 para prender. #define apagar bit_test(port_d,1) //Define el pin RD1 para apagar. void main(void) //Función principal main. { set_tris_b(0x00); //Define puerto b como salida. set_tris_d(0xff); //Define puerto d como entrada. disable_interrupts(GLOBAL); //Todas las interrupciones desactivadas. while(TRUE){ //Inicio del bucle. if (prender == 0) //Censa si P1= 0 . { bit_set(port_b,0); //LED on. } if (apagar==0) //Censa si P2 = 0. { bit_clear(port_b,0); //LED off. } } / /Fin de bucle infinito. } //Fin del main. Uso de la función input Otra forma de censar el estado de los pines es utilizando la función input(PIN_D0) == 0. Para este caso si el pin del puerto D0 (o cualquier otro) que está en alto, si cambia de estado será detectado por la instrucción indicada. 
  • 58. 58 Ejercicio 2.10. Manejo de pulsadores mediante la función input. PROGRAMA: #include <18f4550.h> //Librería para usar el PIC18F4550. #fuses HS,WDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles. #use delay (clock=12000000) / /FOSC =12MHz #use standard_io(B) //Usa librería estándar para el puerto B. #use standard_io(D) //Usa librería estándar para el puerto D. void main(void) //Función principal main. { disable_interrupts(GLOBAL); //Todas las interrupciones desactivadas. output_low(PIN_B0); //LED off. while(TRUE){ //Inicio del bucle. if (input(PIN_D0) == 0) //Detecta si se accionado el pulsador P1. output_high(PIN_B0); //LED on. if (input(PIN_D1) == 0) //Detecta si se accionado el pulsador P2. output_low(PIN_B0); //LED off. } / Fin de bucle infinito. } //Fin del main. Uno de los problemas que presentan los pulsadores mecánicos al momento de su accionamiento es el rebote de los contactos, lo que genera que se produzcan varios transitorios de voltaje (pulsos) que afectan el funcionamiento normal del circuito. Una forma práctica de averiguar el anti rebote, es mediante el siguiente ejercicio, que consiste, en prender y apagar un LED con un mismo pulsador. En este caso al accionar el pulsador se prende el LED (si está apagado), y al volver a accionar el mismo pulsador se apaga el LED.
  • 59. 59 Ejercicio 2.11. Efecto del rebote mecánico de un pulsador. PROGRAMA: #include <18f4550.h> //Librería para usar el PIC18F4550. #fuses HS,WDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles. #use delay (clock=12000000) / / FOSC =12MHz. #use fast_io(b) //Directivas de i/o para puerto b. #use fast_io(d) //Directivas de i/o para puerto d. #BYTE port_b= 0xF81 //Identificador para el puerto b en la localidad 0xF81. #BYTE port_d= 0xF83 //Identificador para el puerto d en la localidad 0xF83. #define pulsador bit_test(port_d,0); //Define el pin RD0 para prender. int k; //Variable k para determinar el estado del LED. void main() //Función principal main. { set_tris_b(0x00); //Fija el puerto B como salida. set_tris_d(0xff); //Fija el puerto D como entrada. disable_interrupts(GLOBAL); //Todas las interrupciones desactivadas. port_b = 0; //Port =0. k= 0; //k=0. while(TRUE){ //Inicio del bucle. if (pulsador== 0 && k==0) //Si pulsador = 0 y k = 0, realiza. { k= 1; //k=1. bit_set(port_b,0); //LED on. } if (pulsador==0 && k==1) //Si pulsador = 0 y k = 1, realiza….. { k=0; //k=0. bit_clear(port_b,0); //LED off. } } //Bucle infinito. } //Fin del main. La variable k, permite en conjunto con el estado del pulsador prender el LED (k=0) y apagar el LED (k=1). Observe también que se efectúa una operación lógica AND con el estado de la entrada (pulsador == 0 && k==0).  Al simular el programa o implementar en protoboard, el circuito de la figura 2.8, se observa como el LED titila varias veces hasta que se estabiliza:
  • 60. 60 quedando prendido o apagado. Claramente existe una situación de ambigüedad porque el LED no se sabe, qué estado tomará por la condición del pulsador. Figura 2.8. Circuito para demostrar el rebote mecánico del pulsador. Elaborado por los autores. Una forma de eliminar este inconveniente es mediante la inclusión de compuertas Smitch Trigger, o por software, como se presenta a continuación. Ejercicio 2.12. Eliminación del rebote del pulsador. PROGRAMA: #include <18f4550.h> //Librería para usar el PIC18F4550. #fuses HS,WDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles. #use delay (clock=12000000) // FOSC =12MHz. #use fast_io(b) //Directivas de i/o para puerto b. #use fast_io(d) //Directivas de i/o para puerto d. #BYTE port_b= 0xF81 //Identificador para el puerto b en la localidad 0xF81. #BYTE port_d= 0xF83 //Identificador para el puerto b en la localidad 0xF83. #define pulsador bit_test(port_d,0); //Define el pin RD0 para prender. int k; //Variable k para determinar el estado del LED. void antirebote(); //Función anti rebote.
  • 61. 61 void main() //Función principal main. { set_tris_b(0x00); //Fija el puerto B como salida. set_tris_d(0xff); //Fija el puerto D como entrada. disable_interrupts(GLOBAL); //Todas las interrupciones desactivadas. port_b = 0; //Port =0. k= 0; //k=0. while(TRUE){ //Inicio del bucle. if (pulsador== 0 && k==0) //Si pulsador = 0 y k = 0, realiza. { antirebote(); //Si el pulsador = 0 llama a subrutina anti rebote. k= 1; //k=1. bit_set(port_b,0); //LED on. } if (pulsador==0 && k==1) //Si pulsador = 0 y k = 1, realiza….. { antirebote(); //Si el pulsador = 0 llama a subrutina anti rebote. k=0; //k=0. bit_clear(port_b,0); //LED off. } } //Bucle infinito. } //Fin del main. void antirebote(void) //Función anti rebote. { while(pulsador == 0) { } //No realiza nada hasta que el pulsador esté inactivo. delay_ms(30); //Retardo de 30 ms. return; //Retorna al programa principal. } //Bucle infinito. Cada vez que se accione un pulsador se averigua si el estado del puerto sigue siendo 0, de ser afirmativo se llama a una función “antirebote”, para que de mantenerse en este estado no realice ninguna acción hasta que el pulsador este inactivo. La instrucción usada para el efecto es while(pulsador == 0) { }. Una vez que el pulsador este inactivo, de la función retornará (por return) al programa a siguiente instrucción desde donde fue llamado a seguir ejecutando el programa. AlsimularoimplementarelcircuitoseobservaqueelLEDinmediatamente se prende o se apaga, según el caso, eliminando el efecto del rebote del pulsador mecánico.
  • 62. 62 Generación de sonido Otro de los elementos de Multimedia es el sonido, que vienen incorporados en la mayoría de equipos de comunicación y de procesamiento de información, razón por la cual, en este punto nos centraremos a la generación de sonido usando el microcontrolador, ya que los instrumentos y otros equipos electrónicos como pianos, guitarras eléctricas, ecualizadores, sintetizadores, alarmas, reloj digital, celulares, etc., basan el tratamiento y la generación de sonido en forma electrónica. Las canciones, voz y sonido audible se componen de notas musicales: DO, RE, MI, FA, SOL, LA, SI. En términos de electrónica, cada nota musical equivale a una frecuencia. La tabla 2.8 muestra la nota musical y la correspondiente frecuencia. NOTA FRECUENCIA (Hz) DO – C 262 RE – D 294 MI – E 330 FA – F 349 SOL- G 392 LA – A 440 SI – B 494 Tabla 2.8. Notas musicales y su correspondiente frecuencia. Fuente: Electrónica, Microcontroladores y Psicología: Internet. Las letras al lado de cada nota pertenecen a la nomenclatura inglesa. La librería TONES.C que maneja el sonido utiliza la nomenclatura inglesa. Las notas tienen una duración, que está determinada por las figuras musicales, indicadas en la tabla 2.9. FIGURA MUSICAL TIEMPO DE DURACIÓN Fusa 62 ms Semicorchea 125 ms Corchea 250 ms Negra 500 ms Blanca 1 segundo Redonda 2 segundos Tabla 2.9. Duración de una figura musical. Fuente: Electrónica, Microcontroladores y Psicología: Internet.
  • 63. 63 El intervalo de frecuencias sonoras audibles se suele dividir en 10 intervalos de frecuencia (10 octavas), como muestra la tabla 2.10. OCTAVA FRECUENCIA (Hz) Primera 15 – 30 Segunda 30 – 60 Tercera 60 – 125 Cuarta 125 – 250 Quinta 250 – 500 Sexta 500 – 1000 Séptima 1000 – 2000 Octava 2000 – 4000 Novena 4000 – 8000 Décima 8000 – 16000 Tabla 2.10. Octavas y sus equivalencias en frecuencia. Fuente: Electrónica, Microcontroladores y Psicología: Internet. El compilador CCS trae incorporado la librería llamada TONES.C para generar las notas musicales. Esta librería incluye la función: generate_tone(frequency,duration);quepermitecrearlasnotasmusicales. Los argumentos de la función son: Frecuency, es una variable que toma el valor de la nota que se requiere generar, es decir la frecuencia de la nota. Duration, es el tiempo que dura la nota y está dada en milisegundos. Cada nota trae en la librería predefinida las frecuencias, lo cual permite elegir en que octava tocarla; hasta una tercera octava. Una parte del código de la librería TONES.C, se indica en la figura 2.9.
  • 64. 64 Figura 2.9. Parte del código de la librería TONES.C, compilador CCS, versión 4.084. Elaborado por los autores. Tomando en cuenta esto (octavas y sus frecuencias), lo único que se necesita son las partituras de las canciones que deseamos generar o combinar las notas para crear diversos sonidos. En la librería TONES.C, está definido el pin del puerto B.0 por donde genera las señales del sonido, como se ve en la figura 2.10. Basta modificar esta línea para utilizar cualquier otro pin del PIC. Figura 2.10. Definición del pin por donde se genera la señal del sonido. Compilador CCS versión 4.084 Elaborado por los autores.
  • 65. 65 Ejercicio 2.13. Generación de sonido. En el siguiente ejercicio se van a generar las notas musicales DO, RE, MI, FA, SOL y con octavas alternadas de 0 a la 3 que proporciona la librería TONES.C PROGRAMA: #include <18f4550.h> / /Librería para usar el PIC18F4550. #fuses HS,NOWDT,NOPROTECT,NOPUT, NOLVP //Configuración de fusibles. #use delay (clock=12000000) //FOSC =12MHz. #include <TONES.c> //Librería para gestión de sonido. void main(void) { //Función principal main. int fusa=62; //Tiempo de duración fusa. int semicorchea=125; //Tiempo de duración semicorchea. int corchea=250; //Tiempo de duración corchea. while(TRUE) { //Bucle infinito. generate_tone(C_NOTE[0],fusa); generate_tone(C_NOTE[1],fusa); generate_tone(Eb_NOTE[2],corchea); generate_tone(C_NOTE[3],fusa); generate_tone(C_NOTE[0],fusa); generate_tone(Eb_NOTE[1],corchea); generate_tone(C_NOTE[3],fusa); generate_tone(Eb_NOTE[3],fusa); generate_tone(Ab_NOTE[3],semicorchea); generate_tone(G_NOTE[3],semicorchea); generate_tone(F_NOTE[3],semicorchea); generate_tone(F_NOTE[3],semicorchea); generate_tone(Eb_NOTE[3],semicorchea); delay_ms(100); } //Fin del bucle infinito. } //Fin del main.
  • 66. 66 Figura 2.11. Circuito para generar sonido. Elaborado por los autores. En la figura 2.12, se muestra el circuito para la generación del sonido. Se debe acotar que el microcontrolador genera pulsos de voltaje cuadrados, es necesario filtrar esta señal. La inclusión de un capacitor como filtro a la salida ayuda a mejorar la señal audible. En todo caso, esto no garantiza la calidad del sonido. No es del alcance del texto realizar un análisis de filtros o del filtrado de la señal, por lo que el lector interesado puede consultar textos especializados para el manejo de filtros digitales o analógicos. EJERCICIOS ADICIONALES Ejercicios resueltos Encender y apagar un LED con un interruptor. En este ejercicio, cuando el interruptor está abierto el LED se apaga y cuando el interruptor está cerrado el LED se prende. Además se activan las resistencias PULL_UP para conectar internamente al puerto B a 5V.
  • 67. 67 PROGRAMA: #include <18f4550.h> //Librería para usar el PIC18F4550. #fuses HS,WDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles. #use delay (clock=12000000) //FOSC =12MHz #byte tris_b = 0xF93 //Identificador para el registro TRIS B en la localidad 0xF93. void main() { //Función principal main. set_tris_b(0xFF); //Fija el Puerto B como salida. port_b_pullups(TRUE); //Habilitación del Pull-up. while(TRUE){ //Bucle Infinito. if (input(PIN_B3) == 0) //Detecta si se accionado el pulsador P1…. output_high(PIN_D0); //….y activa al LED. else //caso contrario….. output_low(PIN_D0); //….el LED permanece apagado. } //Fin del bucle infinito. } / /Fin del main. Figura 2.12. Conexión de un interruptor con resistencia PULL-UP interna. Elaborado por los autores.
  • 68. 68 Secuencia de LEDS. En este programa para que los LEDS conectados al puerto B se activen empezando desde RB0 hasta RB7. Luego empiezan a desactivarse uno por uno desde el último que se activó. La tabla 2.11, ilustra el funcionamiento. RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 1 1 1 0 0 0 0 1 1 1 1 0 0 0 1 1 1 1 1 0 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 0 1 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 Tabla 2.11. Secuencia de encendido de LEDS. Elaborado por los autores. Figura 2.13. Encendido y apagado secuencial de LEDS. Elaborado por los autores.
  • 69. 69 Uso de la resistencias internas Pull Up. En el siguiente ejercicio un pulsador se conecta al puerto RB0 y un LED al puerto RA0. Al accionar el pulsador el LED se prende, caso contrario el LED permanece apagado. Se activa las resistencias internas Pull Up del puerto B mediante la instrucción port_b_pullups (TRUE); con el propósito de conectar el pulsador a VCC y al accionar el mismo se conecte a GND. PROGRAMA: #include <16f88.h> //Librería para usar el PIC16F88. #fuses INTRC,NOWDT,NOMCLR,NOPROTECT,NOPUT //Configuración de fusibles. #use delay (clock=4000000) //Fosc=4MHz void main(void){ //Función principal main. port_b_pullups (TRUE); //Activa las resistencias Pull Up del puerto B. disable_interrupts(GLOBAL); //Todas las interrupciones desactivadas. output_low(PIN_A0); //Pin A0= 0. while(TRUE){ //Bucle infinito. if (input(PIN_B0) == 0) //Si pin RB0= 0…. output_high (PIN_A0); //Pin RA0= 1. else //Caso contrario… output_low(PIN_A0); / /Pin RA0=0. } //Fin del bucle infinito } //Fin del main.
  • 70. 70 Figura 2.14. Demostración del funcionamiento de las resistencias PULL UP del puerto RB. Elaborado por: Los Autores. Ejercicios propuestos Realice un programa para controlar dos semáforos. Desarrolle el programa para que los LEDS conectados al puerto B se activen y desactiven según indica la secuencia en la tabla 2.12. Nota: Optimizar la programación sin utilizar instrucciones repetitivas, en base a las instrucciones de desplazamiento elaborar una ecuación matemática para mover los bits. RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 1 1 1 0 0 0 0 1 1 1 1 0 0 0 1 1 1 1 1 0 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
  • 71. 71 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 1 1 1 1 1 0 0 0 1 1 1 1 0 0 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 Tabla 2.12. Secuencia de encendido para el ejercicio 2.5. Elaborado por los autores. Codifique la tabla de datos para manejar directamente a través del puerto B un display de 7 segmentos tipo cátodo común y realice el programa para un contador descendente. Realice un programa para manejar los LEDS conectados a los puertos B y D. La secuencia de la tabla 2.13, se realiza en el puerto D y la secuencia de la tabla 2.14, en el puerto B. Optimizar la programación sin utilizar instrucciones repetitivas, utilizar instrucciones de desplazamiento. RD7 RD6 RD5 RD4 RD3 RD2 RD1 RD0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 Tabla 2.13. Secuencia de encendidos de LEDs, para el ejercicio 2.7. Elaborado por los autores.
  • 72. 72 RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 1 0 0 0 0 0 1 1 1 0 0 0 0 1 1 1 1 0 0 0 1 1 1 1 1 0 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 1 1 1 1 1 0 0 0 1 1 1 1 0 0 0 0 1 1 1 0 0 0 0 0 1 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 Tabla 2.14. Secuencia de encendidos de LEDs, para el ejercicio 2.7. Elaborado por los autores. Figura 2.15. Circuito para el ejercicio 2.7. Elaborado por los autores.
  • 73. 73 En el circuito de la figura 2.16, el LED D1 se activa al pulsar P1, D2 con P2 y D3 con P3. Cualquier LED puede activarse si los tres están apagados. El pulsador P4, sirve para apagar el LED que esté prendido. Figura 2.16. Ejercicio 2.8. Elaborado por los autores. Realizarelprogramaparasimularelfuncionamientodedosconmutadores de tres vías. Al pulsar cualquiera de los pulsadores el estado del LED cambia. Figura 2.17. Ejercicio 2.9. Elaborado por los autores.
  • 74. 74 Realizar el programa para prender 3 LEDS en secuencia al ir pulsando P1 y apagarlos con P2, si los tres LEDS están prendidos. Figura 2.18. Encendido secuencial de LEDS. Elaborado por los autores.
  • 75. 75
  • 76. 76 Para la visualización de datos es muy común el uso de displays de 7 segmentos, módulos LCD y GLCD, por lo que en este capítulo revisaremos las diferentes formas de manejo y control de estos dispositivos, con el propósito de que los estudiantes tengan las herramientas suficientes para programar y controlar los puertos del Microcontrolador. El manejo de los teclados hexadecimales es otra que las aplicaciones que abordamos en este capítulo. Manejo de Display de 7 segmentos Para visualizar los datos en un display de 7 segmentos, existen dos posibilidades. • Conectar un decodificador de BCD a 7 segmentos, • Conectar el display directamente al puerto. Figura 3.1. Conexión de display de 7 segmentos tipo ánodo común Elaborado por los autores.
  • 77. 77 Conexión de un decodificador de BCD a 7 segmentos Un decodificador de BCD a 7 segmentos tiene cuatro líneas de entrada y siete salidas, el código binario generado por el microcontrolador es transformado a 7 segmentos para ser visualizado en el display. Si el display es de ánodo común se utiliza el decodificador TTL 7447, para un display cátodo común el decodificador TTL 7448. La figura 3.1, muestra las conexiones de un decodificador 7447 y un display ánodo común. Se debe tener en cuenta de limitar la corriente de los segmentos mediante resistencias. El uso de resistencias de valores entre 220Ω y 330Ω garantiza el funcionamiento normal del display. Ejercicio 3.1. Contador de 0 a 9 utilizando un decodificador y display. EnestecasolosdatosdeuncontadorrealizadoenunbucleFOR,sepueden sacar directamente al puerto y el decodificador se encarga de convertirlos en 7 segmentos. La variable i se incrementa en 1 cada 500 ms y este valor es asignado al puerto b (port_b= i;) PROGRAMA: #include <18f4550.h> //Librería para usar el PIC18F4550. #fuses HS,WDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles. #use delay (clock=12000000) // FOSC = 12MHz. #BYTE port_b= 0xF81 //Identificador para el puerto b en la localidad 0xF81. int i; //Variable i para el bucle FOR. void main(void) //Función principal main. { set_tris_b(0x00); //Define port_b como salida disable_interrupts(GLOBAL); //Todas las interrupciones desactivadas. port_b = 0; //Puerto b = 0. while(TRUE) //Bucle infinito. { //Inicio del bucle. for (i=0; i<=9;++i){ //Repite mientras i sea menor o igual a 9. delay_ms(500); //Retardo de 500 ms. port_b= i; //El valor de i se saca al Puerto B. i varia de 0 a 9. } } //Fin del bucle de inicio. } //Fin del bucle main.
  • 78. 78 Manejo directo de display de 7 segmentos En ciertas aplicaciones donde se disponen de suficientes líneas del puerto del microcontrolador y reducir el espacio físico es la prioridad, el display se puede conectar directamente a cualquier puerto. En la figura 3.2, se muestra el circuito del display conectado al puerto B del microcontrolador. Se utiliza un display de ánodo común por lo que el terminal común del display se conecta a VCC . También se podría utilizar un display cátodo común. Así mismo, como cuando se utiliza un driver decodificador de 7 segmentos, se debe tener cuidado de utilizar las resistencias limitadores de corriente para conectar los segmentos del display al puerto y evitar que se produzcan posibles sobrecorrientes que puedan afectar al puerto o al segmento del display. Resistencias con valores entre 220Ω y 330Ω, son comunes utilizar para activar los segmentos del display. Figura 3.2. Conexión directa del display de 7 segmentos al microcontrolador. Elaborado por los autores. Ahora considerando que los datos que salen al puerto deben estar decodificadosen7segmentos,sedebeelaborarlatabladedatosdecodificados para manejar por software y obtener los números respectivos. La tabla 3.1, muestra los valores para activar los segmentos de un display ánodo común, recuerde que el display de ánodo común con un nivel alto (1) el segmento se desactiva y con un nivel bajo (0) el segmento se activa.
  • 79. 79 g f e d C B a Equivalencia decimal Número en el display 1 0 0 0 0 0 0 64 0 1 1 1 1 0 0 1 121 1 0 1 0 0 1 0 0 36 2 0 1 1 0 0 0 0 48 3 0 0 1 1 0 0 1 25 4 0 0 1 0 0 1 0 18 5 0 0 0 0 0 1 1 3 6 1 1 1 1 0 0 0 120 7 0 0 0 0 0 0 0 0 8 0 0 1 0 0 0 0 16 9 Tabla 3.1. Datos decodificados para activar al display de 7 segmentos. Elaborado por los autores. Ejercicio 3.2. Contador MOD 10, manejando directamente el display de 7 segmentos con el microcontrolador. Los datos mostrados en la tabla 3.1 deben ser enviados directamente al puerto para activar los segmentos según el número indicado. Para esto en el programa en una constante tipo array se almacenan los valores codificados: const int x[]= {64,121,36,48,25,18,2,120,0,16}; Mediante el lazo for se van sacando los valores desde el 0 hasta el 9. La variable i del bucle for va asignando al puerto el valor que ocupa en el vector const. Así, por ejemplo si i vale 3, el puerto tendrá el valor de 48 que corresponde al número 3. Observe la instrucción port_d= x[i].
  • 80. 80 PROGRAMA: #include <18f4550.h> //Librería para usar el PIC18F4550 #fuses HS,WDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles #use delay (clock=12000000) //FOSC =12MHz #BYTE port_d= 0xF83 //Identificador para el puerto d en la localidad 0xF83. int i; //Variable i, contador para el bucle FOR. const int x[]= {64,121,36,48,25,18,2,120,0,16};//Tabla de datos decodificados a 7 segmentos. void main(void) //Función principal main. { set_tris_d(0x00); //Identificador para el puerto d como salida. disable_interrupts(GLOBAL); //Todas las interrupciones desactivadas. port_d = 64; //Asigna el valor de 64 al Puerto para ver el número 0. while(TRUE) //Bucle infinito. { //Inicio del bucle. for (i=0; i<=9;++i) //Repite mientras i sea menor o igual a 9. { delay_ms(500); //Retardo de 500 ms. Necesario para mantener el dato en el // puerto. port_d= x[i]; //Asigna al puerto el valor apuntado por la variable i en el //array x. } } //Fin del bucle infinito. } //Fin del main. MULTIPLEXACIÓN DE DISPLAYS DE 7 SEGMENTOS En ciertos proyectos es necesario el ahorro de las líneas de los puertos para utilizarlos en otras aplicaciones, en estos casos, se recurre a manejar los displays por el mismo puerto. Esto se consigue usando el principio de la multiplexación. Para el ejemplo se va a diseñar un contador módulo 100 (00-99). Los datos de las unidades se visualizan en el display 1 y las decenas en el display 2. Para controlar los dos displays simultáneamente, el proceso consiste en prender el display 1 y apagar el display 2 durante un corto tiempo y mostrar los datos de las unidades, luego prender el display 2 y apagar el display 1 para indicar los datos de las decenas. El encendido y apagado de los displays se realiza controlando la corriente de la base de dos transistores que trabajan en corte y saturación los mismos que manejan a los displays como se indica en la figura 3.3.
  • 81. 81 LosdatosenbinarioparalosdisplayssonenviadosporelpuertoRB0:RB3, el decodificador 7447 convierte de BCD a 7 segmentos. Las dos líneas de control para los transistores PNP, son del puerto RD0 y RD1 (líneas S1 y S2). Los transistores permanecen en corte y saturación durante 20 ms, con lo cual para ojo humano “casi” es imperceptible el apagado del display y apenas existirá un leve parpadeo. Esta acción se repite por 50 veces en la función display() obteniendo un tiempo de retardo de 1s. En la figura 3.3, RD0 controla al display de las decenas y RD1 al display de las unidades, por tanto, cuando se ejecuta la instrucción port_d= 1; RD0=1 y RD1= 0, con lo cual el transistor Q1 se apaga y el transistor Q2 se prende, los datos del puerto corresponden a las unidades port_b= unidad. En el caso de port_d= 2; RD0=0 y RD1= 1, en este caso el transistor Q1 se prende y el transistor Q2 se apaga, los datos del puerto corresponden a las decenas port_b= decenas. Recuerde que en los transistores PNP con un 0 lógico en la base conduce y con un 1 lógico en la base el transistor está abierto. La figura 3.3, muestra las conexiones para manejar por el mismo puerto y un solo decodificador dos display de 7 segmentos simultáneamente. Ejercicio 3.3. Manejo de dos display por principio de multiplexación PROGRAMA: #include <18f4550.h> //Librería para usar el PIC18F4550. #fuses HS,WDT,NOPROTECT,PUT, NOPBADEN //Configuración de fusibles. #use delay (clock=12000000) //FOSC =12MHz. #BYTE port_b= 0xF81 //Identificador para el puerto b en la localidad 0xF81. #BYTE port_d= 0xF83 //Identificador para el puerto d en la localidad 0xF83. int unidad, decena, x; //Variables. //Función display. Muestra los datos en los display y genera un retardo de 1segundo. void display() { for (x= 1; x<= 25; ++x){ //Repite 25 veces. port_d = 1; //Habilita display unidad y apaga display decena. port_b= unidad; //Asigna al Puerto b el dato de unidad. delay_ms(20); //El dato de unidad permanece el Puerto b 20 ms. port_d = 2; //Habilita el display decena y apaga display unidad. port_b= decena; //Asigna al Puerto b el dato de decena. delay_ms(20); //El dato de decena permanece el Puerto b 20 ms.
  • 82. 82 } return; //Retorna al programa principal. } void main(void) //Función principal main. { set_tris_b(0x00); //Define port_b como salida. set_tris_d(0x00); //Identificador para el puerto d como salida. disable_interrupts(GLOBAL); //Todas las interrupciones desactivadas. port_b = 0; //Puerto b =0. while(TRUE){ for (decena=0; decena<=9;++decena){ //Datos para el display decena 0 a 9. for (unidad=0; unidad<=9;++unidad){ //Datos para el display unidad 0 a 9. display(); //Función display. } } } //Fin del bucle infinito. } //Fin del bucle main. Figura 3.3. Conexión de dos display con el mismo decodificador. Elaborado por los autores.
  • 83. 83 Módulo LCD Los módulos LCD son muy útiles para ver cualquier tipo de información. La pantalla de cristal líquido está conformada por  una, dos o cuatro líneas de 8, 16, 20, 24 o 40 caracteres de 5x7 pixels c/u. Los más comunes son los módulos LCD de 16x2, 16x4, con y sin backlight). La figura 3.4 a, muestra una vista de módulo LCD 16 x2 de 16 pines (los pines 15 y 16 corresponden al backlight, control de luz de fondo). Las conexiones para controlar el contraste y el backlight del LCD se indican en la figura 3.4 b. Dependiendo el puerto que se utilice los demás pines se conectan al microcontrolador como veremos más adelante. Imagen de un módulo LCD típico. Conexiones de las señales de contraste y backlight para LCD que disponen de esos terminales. Figura 3.4. Módulo LCD. Elaborado por los autores.
  • 84. 84 La descripción de pines del módulo LDC, se indica en la tabla 3.2. Pin número Símbolo Función 1 Vss Tierra o Masa 2 Vdd Alimentación   + 5 VDC 3 Vo Voltaje de ajuste de contraste (5V no visible, 0v más visible) 4 R/S Selección de Dato / Comando 5 R/W Lectura / Escritura 6 E Habilitador 7 D0 1a línea de datos (LSB) 8 D1 2a línea de datos 9 D2 3a línea de datos 10 D3 4a línea de datos 11 D4 5a línea de datos 12 D5 6a línea de datos 13 D6 7a línea de datos 14 D7 8a línea de datos (MSB) 15 A Alimentación Backlight +3.5 V a +5V 16 K GND del Backlight Tabla 3.2. Funciones de los pines del módulo LCD. Elaborado por los autores El compilador CCS incluye un archivo (driver) lcd.c. El driver lcd.c está configurado para trabajar con el puerto d. Modificando este fichero es posible usarlo para cualquier puerto.  El fichero se llama con #include <lcd.c> y algunas funciones que presenta son:  Las instrucciones básicas para manejar el LCD son las siguientes: lcd_init(); Es la primera función que debe ser llamada. Borra el LCD y lo configura en formato de 4 bits con dos líneas y con caracteres de 5x8 puntos, en modo encendido, cursor apagado y sin parpadeo. Configura el LCD con un autoincremento del puntero de direcciones y sin desplazamiento del display real. lcd_gotoxy(byte x, byte y);
  • 85. 85 Indica la posición de acceso al LCD. Por ejemplo (1,2) indica la primera posición de la segunda línea; (2,1)  segunda posición de la primera línea  (El LCD tratado tiene 16 posiciones en cada línea). lcd_getc (byte x, byte y); Lee el carácter de la posición (x,y). lcd_putc (char s); Escribe la variable en la posición correspondiente, s es una variable tipo char. Además se puede incluir: f se limpia el LCD. n el cursor cambia de línea. b el cursor retrocede una posición. Existe la función printf  que es más versátil para trabajar en el LCD. printf (string) printf (cstring, valores,,) printf(fname, cstring, valores,,) string es una cadena o array de caracteres, valores es una lista de variables separadas por comas, y fname es una función.  El formato es %nt, Dónde: n es opcional y puede ser: 1-9 especifica el número de caracteres. 01-09 indica la cantidad de ceros a la izquierda. 1.1-9.9 para punto flotante. t puede indicar un: carácter c, cadena o caracteres, entero sin signo u, entero con signo d, entero largo sin signo Lu, Entero largo con signo Ld, entero hexadecimal (minúsculas) x, entero hexadecimal (mayúsculas) X, entero largo hexadecimal (minúsculas) Lx, entero largo hexadecimal (mayúsculas) LX, flotante con truncado f, flotante con redondeo g, flotante el forma exponencial e, entero sin signo con decimales insertados w.
  • 86. 86 Manejo del módulo LCD usando Puerto D El siguiente programa envía el conocido mensaje “HOLA MUNDO” al LCD. Abran el archivo C:Archivos de programaPICCDriverslcd.c, y ahí les muestra la forma de conectar el LDC a los pines del puerto D, como se indica en la figura 3.5. Se debe aclarar que el archivo utilizado corresponde al CCS versión v4.084. Figura 3.5. Conexión de pines del PIC con el LCD. Elaborado por los autores. Ejercicio 3.4. Manejo del módulo LCD por el Puerto D. Algunos aspectos importantes para manejar el LCD son: • Incluir la librería que maneja el LCD: #include <lcd.c> • Inicializar el LCD: lcd_init(); esta instrucción “arranca” el LCD. • Situar el cursor en la posición columna y fila desde donde se visualice los caracteres: lcd_gotoxy(4,1); en este caso está indicando que empiece en la columna 4 fila 1. • Escribir el mensaje: lcd_putc(“HOLA MUNDO!!n LCD en CCS”). En la instrucción el argumento n. Por tanto, en la primera fila a partir de la columna 4 en el LCD se indicará la palabra HOLA MUNDO!!, y en la segunda fila a partir de la columna 4 se mostrará LCD en CCS. Cada espacio en blanco que separa los caracteres o leras (n LCD) ocupan una posición en las columnas del LCD.
  • 87. 87 PROGRAMA: #include <18f4550.h> //Librería para usar el PIC18F4550. #fuses HS, NOPROTECT, NOWRT, NOPUT, NOWDT //Configuración de fusibles. #use delay (clock=12000000) //FOSC =12MHz. #include <lcd.c> //Librería lcd.c set_tris_d(0x00); //Identificador para el puerto d como salida void main(void) //Función principal main. { lcd_init(); // Inicializa el LCD. lcd_gotoxy(4,1); //Sitúa el cursor en columna 4, fila 1. lcd_putc("HOLA MUNDO!!n LCD en CCS"); //Escribe en el LCD. } Para cambiar el cursor de una línea a otra o posicionar en una columna distinta la instrucción lcd_gotoxy(x,y); es de mucha utilidad. En el presente ejercicio se tiene el mismo resultado si se escribe el código así: lcd_gotoxy(4,1); //Sitúa el cursor en columna 4, fila 1. lcd_putc(“HOLA MUNDO!! “); //Escribe en el LCD. lcd_gotoxy(4,2); //Sitúa el cursor en columna 4, fila 2. lcd_putc(LCD en CCS”); //Escribe en el LCD. Todo dependerá de las necesidades de diseño y habilidades del programador. El diagrama de conexiones para realizar las pruebas de funcionamiento de los programas del módulo LCD conectado al puerto D, se muestra en la figura 3.6. No están consideradas las conexiones del control de contraste y el Bach light. Al implementar el circuito físico las conexiones mencionadas se indican en la figura 3.4 b.
  • 88. 88 Figura 3.6. Conexión del LCD en el puerto D. Elaborado por los autores. Para indicar el valor de una variable se debe utilizar la función printf(lcd_ putc,” %d constante  “,variable); Ejercicio 3.5. Contador con visualización en LCD. El ejercicio 3.5, muestra un contador ascendente de 0 a 9 con visualización de datos en el LCD. Para mostrar el valor numérico se utiliza la instrucción printf(lcd_putc,” %d “,i). El argumento %d de la función printf indica que el valor de la variable i es entero decimal.