Guia de Microcontroladores
Guia de Microcontroladores
Guia de Microcontroladores
INTRODUCCIN
La gua de microcontroladores fue hecha pensando bsicamente en un material escrito para los
estudiantes, el cual pueda servirles como medio de consulta en las diferentes prcticas y
proyectos que enfrentaran durante el curso de microcontroladores.
Inicialmente explica los conceptos bsicos, como sistemas de numeracin, contina con una
breve explicacin sobre el lenguaje C, ms adelante explica las caractersticas bsicas del
microcontrolador recomendado en el curso (PIC16F883 o PIC16F886) y por ltimo plantea
diferentes ejemplos con el microcontrolador, cada uno refirindose a un tema especfico.
Los ejemplos que se desarrollan en esta gua son relativamente sencillos, y con seguridad no
siempre ser la mejor manera de desarrollarlos, solo es una de muchas formas de hacerlo.
Ingeniera de
de Sistemas
Sistemas Universidad
Universidad EAFIT
EAFIT
Ingeniera
CONCEPTOS BSICOS
27 2 6 2 5 2 4 2 3 2 2 2 1 2 0
DECIMAL
HEXADECIMAL
1.1
SISTEMAS
DE
DECIMAL (BASE 10)
NUMERACIN
1.4 CONVERSIN
DECIMAL
DE
BINARIO
1
24
0
23
16 +
1
0
1
22
21
20
0 + 4 + 0 + 1 = 21
1.5
CONVERSIN
BINARIO
1.3 SISTEMA HEXADECIMAL (BASE 16)
Este sistema es en base 16, lo que significa
que para cada columna es posible escoger
uno entre 16 dgitos.
Estos son: 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E y F.
Donde
A = 10
D = 13
B = 11
E = 14
C = 12 F = 15
DE
DECIMAL
Residuo
Residuo
Residuo
Residuo
Residuo
Residuo
Residuo
1 LSB
0
1
0
0
1
1 MSB
RESPUESTA 1 1 0 0 1 0 12
1.6 CONVERSIN DE HEXADECIMAL A
DECIMAL
0F
10
.
.
.
1F
20
21
.
.
1.6.1
2B616
162 161
2
B
Conversin
hexadecimal
decimal?
160
6
2* 256 + 11 * 16 + 6 * 1 = 694
1.7
CONVERSIN DE BINARIO A
HEXADECIMAL
Cuatro bits binarios corresponden a un dgito
hexadecimal, significa que se requieren
cuatro bits para contar de 0 hasta F. Para
representar nmeros binarios como nmeros
hexadecimales, se forman grupos de cuatro
bits, de izquierda a derecha. A continuacin
se
convierte
cada
grupo
en
el
correspondiente dgito hexadecimal.
Ejemplo
1.7.1
hexadecimal
Conversin
Convertir
10111100
hexadecimal
en
binario
un
nmero
10111100 = BC16
FF16
Binario
F
1111
F
1111
FF16 = 11111111
1.9 DECIMAL CODIFICADO EN BINARIO:
(BCD)
En BCD cada dgito decimal
representado por cuatro bits.
esta
0.0000
1.0001
.
.
.
9.1001
Para representar el 25 decimal en BCD
1.10
REPRESENTACIN
NMEROS DE 0 A 15
DE
LOS
DECIMAL
BINARIO
HEXADECIMAL
BCD
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
0001 0000
0001 0001
0001 0010
0001 0011
0001 0100
0001 0101
MEMORIAS
Son
memorias
que
se
programan
elctricamente y que se borran con la
exposicin de la memoria a una luz
ultravioleta que pasa a travs de la ventana
de cuarzo que tiene en la parte superior del
encapsulado.
INTRODUCCIN AL MICROCONTROLADOR
LENGUAJE DE PROGRAMACIN
C es un lenguaje de alto nivel, aunque permite trabajar en bajo nivel, es decir manipular bits, es
quizs uno de los lenguajes ms utilizados y existen diferentes versiones del lenguaje C. En el
curso se concentra en C bsico, se analiza los diferentes tipos de datos, las estructuras de
control, los tipos de variables y las funciones. Todo programa en C esta compuesto por un
encabezado, unas funciones si se necesitan y el programa principal, llamado main. Los
diferentes tipos de datos que maneja el compilador PICC, son los siguientes:
unsigned define un nmero de 8 bits sin
signo
unsigned int define un nmero de 8 bits sin
signo
int define un nmero de 8 bits sin signo
int16 define un nmero de 16 bits sin signo
char define un nmero de 8 bits sin signo
long define un nmero de 16 bits sin signo
long int define un nmero de 16 bits sin
signo
LA
ESTRUCTURA
CONDICIONAL IF
DE
CONTROL
Sintaxis
if (condicin)
sentencia;
o un bloque de instrucciones:
if (condicin)
{
bloque
}
if (condicin)
{
// Aqu se incluye el cdigo
// que ha de ejecutarse slo
// si se cumple la condicin del if
// (sangrado para que se vea dnde
// empieza y dnde acaba el if)
}
Error comn:
if (condicin);
10
sentencia;
Lo anterior es interpretado como
if (condicin)
; // Sentencia vaca
sentencia;
SELECCIN
MLTIPLE
SENTENCIA SWITCH
CON
LA
Sintaxis
switch (expresin) {
if(Condicin)
{
}
case expr_cte1:
sentencia1;
case expr_cte2:
sentencia2;
CLUSULA ELSE
Una sentencia if, cuando incluye la clusula
else, permite ejecutar un bloque de cdigo si
se cumple la condicin y otro bloque de
cdigo diferente si la condicin no se
cumple.
...
case expr_cteN:
sentenciaN;
default:
sentencia;
}
Se selecciona a partir de la evaluacin de
una nica expresin.
La expresin del switch ha de ser de tipo
entero.
Sintaxis
if (condicin)
sentencia1;
else
sentencia2;
o un bloque de instrucciones:
if (condicin)
{
bloque1
}
else
{
bloque2
}
11
O un bloque de instrucciones:
switch (expresin)
While (Condicin)
{
Sentencia 1;
Sentencia 2;
..
Sentencia n;
}
{
case 0:
sentencia1;
break ;
case 1:
sentencia 2;
break ;
case n:
sentencia n;
break ;
default:
sentencia;
}
BUCLE FOR
4.2
ESTRUCTURAS
REPETITIVAS
DE
CONTROL
BUCLE WHILE
Los ejecuta una instruccin o un bloque de
instrucciones mientras la condicin sea
verdadera
Sintaxis:
While (Condicion)
Sentencia;
En un bucle for
12
expr1;
while(expr2)
{
bloque;
expr3;
}
BUCLES INFINITOS
AUn bucle infinito es un bucle que se repite
infinitas veces:
for (;;) /*bucle infinito*/
while (1) while (true) /*bucle infinito*/
Si nunca deja de cumplirse la condicin del
bucle, nuestro programa se quedar
indefinidamente ejecutando el cuerpo del
bucle, sin llegar a salir de l.
En las estructuras de control If, Else, while,
la condicin puede estar compuesta por una
o ms condiciones, finalmente el programa
evala si la condicin es cierta o falsa.
Para lograr este objetivo existen operadores
de asignacin y operadores de comparacin,
que se presentan en las siguientes del
siguiente capitulo.
13
OPERADORES
14
ENCABEZADO DE UN PROGRAMA
#INCLUDE <16f886.h>
#USE DELAY(CLOCK=4000000)
#FUSES XT,NOPROTECT,NOWDT,NOBROWNOUT,PUT,NOLVP
#DEFINE SW1 PORTB,2
#DEFINE SW2 PORTB,1
#DEFINE LED PORTB,0
#BYTE PORTB= 6
INT CONT;
Con la primera lnea se le indica al compilador con que tipo de microcontrolador se va a
trabajar.
La segunda lnea indica que se esta trabajando con un cristal de 4Mhz.
La tercera lnea consiste en la configuracin de los fusibles:
XT
Tipo de oscilador cristal
NOPROTECT
Cdigo no protegido para lectura
NOWDT
No activa el perro guardin
NOBROWNOUT
No resetea por bajo voltaje
NOPUT
No active el temporizador que retarda el funcionamiento ante la
presencia de tensin de alimentacin
NOLVP
No bajo voltaje de programacin
La cuarta, quinta y sexta lnea consiste en definir un nombre a los diferentes bits que se van a
utilizar en el programa.
La sptima lnea indica la direccin de memoria RAM del puerto B.
La octava lnea indica que se declara la variable CONT tipo entero, esta variable es global, ya
que fue declarada en el encabezado del programa y se podr utilizar tanto en el programa
principal como en las diferentes funciones.
Antes de hacer un programa en C completo, es importante saber la forma de preguntar si
alguna entrada esta activada o desactivada y la forma de activar o desactivar una salida.
15
INSTRUCCIONES BSICAS
PORTB = 0X0F;
o
(Hexadecimal)
PORTB = 0B00001111:
(Binario)
Las tres instrucciones equivalen exactamente a lo mismo, llevar el valor 15 al puerto B, solo
que en diferente formato.
Ejemplo 7.1 Instrucciones bsicas
16
// Configura el puerto B
// Haga por siempre
// Si SW esta activado
// Active el led
// Sino, es decir si SW esta desactivado
// Apagar led
17
// Configura el puerto B
// Haga por siempre
// Active el led
// Retardo de 1 segundo
// Apagar el led
// Retardo de 1 segundo
Encender los 8 leds conectados al puerto B si los suiches conectados a RC0 y RC1 estn
activados y apagarlos si estn desactivados.
#INCLUDE <16F886.h>
#USE DELAY(CLOCK=4000000)
#FUSES XT,NOPROTECT,NOWDT,NOBROWNOUT,PUT,NOLVP
#DEFINE SW1 PORTC,0
#DEFINE SW2 PORTC,1
#BYTE PORTB= 6
#BYTE PORTC= 7
VOID MAIN()
{
SET_TRIS_C(OB11111111);
// Configura el puerto C
18
SET_TRIS_B(OB00000000);
// Configura el puerto B
WHILE(TRUE)
// Haga por siempre
{
IF(BIT_TEST(SW1)&&(BIT_TEST(SW2)))
// Si SW1 Y SW2 estn en 1
{
PORTB=OB11111111;
// Active los 8 leds
}
IF(!BIT_TEST(SW1)&&( ! BIT_TEST(SW2))) // Si SW1 en 1 Y SW2 en 0
{
PORTB = 0;
// Apague los 8 leds
}
}
//Cierra while
//Cierra Main
Hacer un programa en microcontrolador que controle un secador de manos de tal manera que
cuando se oprima el pulsador encienda el motor y la resistencia durante 10 segundos.
#INCLUDE <16f886.h>
#USE DELAY(CLOCK=4000000)
#FUSES XT,NOPROTECT,NOWDT,NOBROWNOUT,PUT,NOLVP
#BYTE PORTB= 6
#BYTE PORTC= 7
#DEFINE MOTOR
PORTB,0
#DEFINE RESISTENCIA
PORTB,1
#DEFINE PULSADOR
PORTC,0
VOID MAIN()
{
SET_TRIS_B(0B0000000);
SET_TRIS_C(0B1111111);
PORTB=0;
// Configura el puerto B
19
WHILE(TRUE)
{
IF(BIT_TEST(PULSADOR))
{
BIT_SET(MOTOR);
BIT_SET(RESISTENCIA);
DELAY_MS(10000);
BIT_CLEAR(MOTOR);
BIT_CLEAR(RESISTENCIA);
}
}
}
// Active el Motor
// Active la Resistencia
// Retardo de 10 segundos
// Apagar el Motor
// Apague la Resistencia
// Cierra el If
// Cierra el While
// Cierra el Main
// Configura el puerto B
// Configura el puerto C
WHILE(TRUE)
// Haga por siempre
{
IF(!BIT_TEST(ENCENDIDO)&&(BIT_TEST(LUCES)))
{
BIT_SET(SONIDO);
DELAY_MS(500);
BIT_CLEAR(SONIDO);
DELAY_MS(500);
}
IF(!BIT_TEST(ENCENDIDO)&&(!BIT_TEST(LUCES)))
{
BIT_CLEAR(SONIDO);
}
}
}
20
INSTRUCCIONES DE ROTACIN
Encender uno a uno los bits del puerto B, cada medio segundo, comenzando por RB0. En
ningn momento se pueden encender dos leds al mismo tiempo.
#INCLUDE <16f886.h>
#USE DELAY(CLOCK=4000000)
#FUSES XT,NOPROTECT,NOWDT,NOBROWNOUT,PUT,NOLVP
#BYTE PORTB= 6
VOID MAIN()
{
SET_TRIS_B(OB00000000);
// Configura el puerto B
WHILE(TRUE)
// Haga por siempre
21
{
PORTB=OB00000001;
DELAY_MS(500);
WHILE(!BIT_TEST(PORTB,7))
{
PORTB= PORTB<<1;
.
DELAY_MS(500);
}
}
}
Encender uno a uno los bits del puerto B (0.5seg) desde RB0 hasta RB7 y luego apagarlos en
sentido contrario desde RB7 hasta RB0.
#INCLUDE <16F886.h>
#USE DELAY(CLOCK=4000000)
#FUSES XT,NOPROTECT,NOWDT,NOBROWNOUT,PUT,NOLVP
#DEFINE SW0 PORTC,0
#BYTE PORTB=6
VOID MAIN()
{
SET_TRIS_B(0B00000000);
PORTB=0;
WHILE(TRUE)
{
PORTB=0B00000001;
DELAY_MS(500);
WHILE (!BIT_TEST(PORTB,7))
{
PORTB=PORTB<<1;
DELAY_MS(500);
}
DELAY_US(500);
WHILE (!BIT_TEST(PORTB,0))
{
PORTB=PORTB>>1;
DELAY_MS(500);
}
}
}
22
6 terminales
5 terminales
Motores Bipolares: este tipo de motor tiene
dos bobinas y no poseen puntos comunes,
es decir tiene cuatro terminales.
23
Controlar un motor paso a paso conectado a los cuatro bits menos significativos del puerto B,
de tal manera que si el suiche conectado a RC0 esta en uno gire a la derecha y si el suiche
esta en cero, el motor gira a la izquierda.
24
Controlar un motor paso a paso conectado a los cuatro bits menos significativos del puerto B,
de tal manera que si el suiche conectado a RC0 esta en uno gire a la derecha y si el suiche
esta en cero, el motor gira a la izquierda.
#INCLUDE <16f886.h>
#fuses
XT,NOPROTECT,NOWDT,NOBROWNOUT,PUT,NOLVP,WRT
#use
delay(clock=4000000)
#byte
PORTB=6
#byte
PORTC=7
#define SW PORTC,0
INT CONT;
byte const HORARIO[4] = {0b1100,
0b0110,
0b0011,
0b1001};
byte const ANTIH[4]
={0b1001,
0b0011,
0b0110,
0b1100};
VOID MAIN()
{
SET_TRIS_C(OB11111111);
SET_TRIS_B(OB00000000);
WHILE(TRUE)
{
IF(BIT_TEST(SW))
{
CONT=0;
WHILE((CONT<4)&&(BIT_TEST(SW)))
{
PORTB=(HORARIO[CONT]);
DELAY_MS(100);
CONT++;
}
// Configura el puerto C
// Configura el puerto B
}
ELSE
// de lo contrario
{
CONT=0;
WHILE((CONT<4)&&(!BIT_TEST(SW)))
// la variable cont =0
// Mientras que cont sea menor a 4
// y SW=0(apagado)
{
PORTB=(ANTIH[CONT]);
DELAY_MS(100);
CONT++;
}
}
}
}
25
Controlar un motor paso a paso conectado a los cuatro bits menos significativos del puerto B,
de tal manera que si el suiche conectado a RC0 esta en uno gire a la derecha y si el suiche
conectado a RC1 esta en uno, el motor gire a la izquierda.
#INCLUDE <16f886.h>
#fuses
XT,NOPROTECT,NOWDT,NOBROWNOUT,PUT,NOLVP,WRT
#use
delay(clock=4000000)
#byte
PORTB=6
#byte
PORTC=7
#define SW PORTC,0
#define SW1 PORTC,1
INT CONT;
byte const HORARIO[4] = {0b1100,
0b0110,
0b0011,
0b1001};
byte const ANTIH[4] = {0b1001,
0b0011,
0b0110,
0b1100};
VOID MAIN()
{
SET_TRIS_C(0B11111111);
SET_TRIS_B(0B00000000);
WHILE(TRUE)
{
WHILE(BIT_TEST(SW))
{
CONT=0;
WHILE((CONT<4))
{
PORTB=(HORARIO[CONT]);
DELAY_MS(500);
CONT++;
}
// Configura el puerto C
// Configura el puerto B
}
PORTB=0;
WHILE(BIT_TEST(SW1))
{
CONT=0;
WHILE((CONT<4))
{
PORTB=(ANTIH[CONT]);
DELAY_MS(500);
CONT++;
// de lo contrario
// los bits del puerto b se apagan
//la variable contador se carga con cero.
}
}
PORTB=0;
}
}
26
10
27
RB7
NUMERO
0
1
2
3
4
5
6
7
8
9
0
0
0
0
0
0
0
0
0
0
CODIGO 7 SEGMENTOS
RB6
RB5 RB4 RB3
g
f
e
d
0
0
1
1
1
1
1
0
1
1
1
0
0
0
1
1
1
0
1
1
1
0
1
0
0
0
1
0
1
0
1
0
1
1
0
1
1
0
1
0
RB2
c
RB1
b
RB0
a
1
1
0
1
1
1
1
1
1
1
1
1
1
1
1
0
0
1
1
1
1
0
1
1
0
1
0
1
1
1
Numero en
hexadecimal
3F
06
5B
4F
66
6D
7D
07
7F
67
Para manejar una estructura en C, lo nico que se debe hacer es aadir la estructura al
encabezado.
Byte CONST display[10]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67};
El nmero 10 indica la cantidad de posiciones de la estructura, los cdigos 7 segmentos estn
en hexadecimal.
28
11
(ANTIRREBOTE)
Cuando se trabaja con pulsadores o suiches, en el momento en que estos cambian de estado
se genera una seal como la que se muestra en la figura:
// Configura el puerto B
// Haga por siempre
29
{
CONTADOR = 0;
WHILE(CONTADOR<10)
// Mientras contador < 10
{
PORTB= DISPLAY[CONTADOR];
// Muestre el valor en el display
CONTADOR++;
// Incrementa contador
DELAY_MS(1000);
// Retardo de 1 segundo
}
}
}
Ejemplo 11.2 Display 7 segmentos.
// Configura el puerto B
// Configura el puerto B
// Inicializa contador en cero
30
WHILE(TRUE)
{
PORTB= DISPLAY[CONTADOR];
BIT_CLEAR(LED);
IF (BIT_TEST(SW1))
{
DELAY_MS(200);
CONTADOR++;
PORTB= DISPLAY[CONTADOR];
IF(CONTADOR==10)
{
CONTADOR=0;
}
}
IF (BIT_TEST(SW2))
{
DELAY_MS(200);
BIT_SET(LED);
WHILE (CONTADOR>0)
{
PORTB= DISPLAY[CONTADOR];
DELAY_MS(1000);
CONTADOR--;
}
BIT_CLEAR(LED);
}
// Antirrebote
}
}
31
12
MULTIPLEXAJE DE DISPLAY
32
LONG CONTRET;
VOID MOSTRAR()
{
INT UNI,DEC;
// Rutina mostrar
// Declarar las variables UNI, DEC
// como un entero, es decir de 8bits
DEC=CONT/10;
UNI=CONT%10;
BIT_CLEAR(TDEC);
BIT_SET (TUNI);
PORTB=(DISPLAY[DEC]);
DELAY_MS(1);
BIT_CLEAR(TUNI);
BIT_SET (TDEC);
PORTB=(DISPLAY[DEC]);
DELAY_MS(1);
}
33
VOID RET1SEG()
{
CONTRET=500;
// Rutina RET1SEG
// Cargue con 500 la variable
// CONTRET
// Mientras que la variable
// CONTRET sea mayor que cero
WHILE (CONTRET>0)
{
MOSTRAR();
CONTRET--;
}
}
VOID MAIN()
SET_TRIS_B(0);
SET_TRIS_C(0B11001111);
CONT=0;
WHILE(TRUE)
{
CONT=0;
WHILE(CONT<100)
{
RET1SEG( );
CONT++;
}
}
}
En el ejemplo anterior se utilizan funciones, son pequeos subprogramas que se pueden llamar
desde el programa principal. Se debe digitar antes del programa principal que es quien las
llama.
Si la funcin no retorna ningn valor se pone la directiva VOID antes del nombre de la funcin
indicando que no retorna ningn valor.
Ejemplo 12.2 Multiplexaje de display.
34
// Rutina mostrar
// Declarar las variables UNI
// DEC como un entero
DEC=CONT/10;
UNI=CONT%10;
BIT_CLEAR(TDEC);
BIT_SET (TUNI);
PORTB=(DISPLAY[DEC]);
DELAY_MS(1)
// Retardo de 1 milisegundos
// en el display
// Apaga el display de unidades
// Prende el display de decenas
// Muestra lo que hay en unidades
// en el display
// Retardo de 1 milisegundos
BIT_CLEAR(TUNI);
BIT_SET (TDEC);
PORTB=(DISPLAY[DEC]);
DELAY_MS(1);
}
VOID MAIN()
{
SET_TRIS_B(0);
SET_TRIS_C(0B11001111);
CONT=0;
WHILE(TRUE)
{
CONT=76;
WHILE(TRUE)
{
MOSTRAR();
}
}
35
INTERRUPCIONES
13
Si Las llamadas funciones desde el programa principal hacen que el programa ejecute un
subprograma y luego regrese al programa principal, sin embargo el programador esta
definiendo en que momento debe saltar a ejecutar la funcin mediante las instrucciones, por
esta razn se considera sincronas.
Las interrupciones son desviaciones de flujo de control del programa originadas
asincrnicamente por diversos sucesos que no dependen del programador, es decir, ocurren
en cualquier momento.
Las interrupciones ocurren por sucesos externos como la generacin de un flanco o nivel en
una patica del microcontrolador o eventos internos tales como el desbordamiento de un
contador, terminacin del conversor anlogo a digital, entre otras.
El comportamiento del microcontrolador ante la interrupcin es similar al procedimiento que se
sigue al llamar una funcin desde el programa principal. En ambos casos se detiene la
ejecucin del programa en curso, se guarda la direccin a donde debe retornar cuando termine
de ejecutar la interrupcin, atiende o ejecuta el programa correspondiente a la interrupcin y
luego continua ejecutando el programa principal, desde donde lo dejo cuando fue interrumpido.
Existen 13 diferentes causas que producen una interrupcin, por lo tanto el primer paso de la
rutina de interrupcin ser identificar la causa de la interrupcin.
Slo se trata en esta gua la interrupcin externa por cambio de estado en la patica RB0.
Los pasos que se deben seguir para atender una interrupcin, son los siguientes:
Digitar la funcin correspondiente a la interrupcin. La funcin debe comenzar con # y la
interrupcin correspondiente, por ejemplo para la funcin de interrupcin por RB0 se digita
#int_EXT
En el programa principal, habilitar las interrupciones en forma global, con la instruccin:
enable_interrupts(GLOBAL);
En el programa principal, habilitar la interrupcin correspondiente, como ejemplo se muestra
como habilitar la interrupcin externa por RB0:
enable_interrupts(INT_EXT);
Ejemplo 13.1 Interrupciones.
36
// Configurar el puerto B
// Configurar el puerto C
// Habilita todas las interrupciones
// Habilita la interrupcin externa
}
}
Existen diferentes tipos de interrupcin en el microcontrolador, algunas de ellas se mencionan
a continuacin:
#INT_EXT INTERRUPCIN EXTERNA
#INT_RTCC DESBORDAMIENTO DEL TIMER0(RTCC)
#INT_RB CAMBIO EN UNO DE LOS PINES B4,B5,B6,B7
#INT_AD CONVERSOR A/D
#INT_EEPROM ESCRITURA EN LA EEPROM COMPLETADA
#INT_TIMER1 DESBORDAMIENTO DEL TIMER1
#INT_TIMER2 DESBORDAMIENTO DEL TIMER2
37
TIMER
14
Control del Timer con interrupciones
38
El valor anterior es decir 3906 debe ser igual a la multiplicacin entre el valor inicial del timer 0
y el valor del contador a decrementar.
3906= valor inicial del timer * valor del contador a decrementar
Observacin: estos dos valores son aleatorios y deben ser menores a 256.
3906 = 18 * 217
Cualquiera de estos dos valores pueden ser el valor inicial del timer 0. En este caso, se elige
18 como valor inicial del timer 0. Al obtener el valor inicial del timer 0 se debe restar el RTCC
utilizado, en este caso 256 para obtener el nmero donde el temporizador debe iniciar para que
en el momento que incremente las 18 veces llegue al valor del RTCC utilizado (256) y produzca
la interrupcin salto. Es decir:
RTCC Valor inicial del timer
256 18 = 238
xisten diferentes tipos de interrupcin en el microcontrolador, algunas de ellas se mencionan a
continuacin:
18
238
Salto
255
Se genera la
interrupcin
Ejemplo 14.2 Timer.
WHILE(I>=10)
{
I=I -10;
DEC++;
}
UNI=I;
BIT_SET(U);
BIT_CLEAR(D);
39
PORTB=display[UNI];
DELAY_MS(1);
BIT_SET(D);
BIT_CLEAR(U);
PORTB=display[DEC];
DELAY_MS(1);
}
#INT_RTCC
VOID RELOJ()
{
VECES--;
SET_RTCC(238);
IF(VECES==0)
{
SEG++;
VECES=217;
}
}
VOID MAIN()
{
SET_TRIS_B(0);
SET_TRIS_C(0);
UNI=0;
DEC=0;
VECES=217;
SEG=0;
SET_RTCC(238);
SETUP_COUNTERS(RTCC_INTERNAL, RTCC_DIV_256);
ENABLE_INTERRUPTS(INT_RTCC);
ENABLE_INTERRUPTS(GLOBAL);
WHILE(TRUE)
{
IF(SEG==60)
SEG=0;
ELSE
MOSTRAR();
}
}
Ejemplo 14.3 Timer.
Hacer un contador de 0 a 9, de tal manera que incremente cada segundo por interrupcin a
travs del timer, al llegar a 9 comienza de nuevo.
#INCLUDE <16F886.H>
#USE
DELAY(CLOCK=4000000)
#FUSES XT,NOLVP,NOWDT
BYTE CONST DISPLAY[10]={0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X67};
#BYTE
PORTB=6
#DEFINE INTS_PER_SECOND 15
// (4000000/(4*256*256)) 4=4mhz, 256=
// Divisin 256, 256=Timer 256 se carga
40
// con cero.
BYTE SEGUNDOS;
BYTE INT_CONTADOR;
#INT_RTCC
VOID CLOCK_ISR() {
--INT_CONTADOR;
IF(INT_CONTADOR==0)
{
++SEGUNDOS;
INT_CONTADOR=INTS_PER_SECOND;
}
}
VOID MAIN()
{
SET_TRIS_B(0);
INT_CONTADOR=INTS_PER_SECOND;
SET_RTCC(0);
SETUP_COUNTERS( RTCC_INTERNAL, RTCC_DIV_256);
ENABLE_INTERRUPTS(INT_RTCC);
//Habilita la interrupcin por RTCC
ENABLE_INTERRUPTS(GLOBAL);
// Habilita todas las interrupciones
DO
{
IF(SEGUNDOS==10)
{
SEGUNDOS=0;
}
PORTB=(DISPLAY[SEGUNDOS]);
}
WHILE (TRUE);
}
41
15
En el compilador hay un driver para manejar un teclado telefnico, que es de gran utilidad en
algunas aplicaciones donde el usuario necesita digitar un nmero.
La conexin entre el teclado y el microcontrolador es la siguiente:
42
#INCLUDE <16F886.H>
#FUSES XT,NOPROTECT,NOWDT,NOBROWNOUT,PUT,NOLVP
#USE DELAY(CLOCK=4000000)
Byte CONST display[10]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67};
#DEFINE USE_PORTB_KBD
#INCLUDE <KBD.C>
#BYTE PORTC= 7
#BYTE PORTB= 6
#BYTE WPUB=0x95
CHAR K;
VOID MAIN()
{
PORT_B_PULLUPS(TRUE);
WPUB=255;
KBD_INIT();
SET_TRIS_C(0);
PORTC=(display[0]);
WHILE (TRUE)
{
K=KBD_GETC();
IF(K=='0')
PORTC=(display[0]);
IF(K=='1')
PORTC=( display [1]);
IF(K=='2')
PORTC=( display [2]);
IF(K=='3')
PORTC=( display [3]);
IF(K=='4')
43
}
}
Mostrar el numero digitado por el teclado en el display y cuando se oprima la tecla #, el display
comienza a decrementar cada segundo hasta llegar a cero.
#INCLUDE <16F886.H>
#FUSES XT,NOPROTECT,NOWDT,NOBROWNOUT,PUT,NOLVP
#USE
DELAY(CLOCK=4000000)
Byte CONST display[10]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67};
#DEFINE USE_PORTB_KBD
#INCLUDE <KBD.C>
#BYTE
PORTC= 7
#BYTE
PORTB= 6
#BYTE
WPUB=0x95
CHAR K;
44
INT CONT;
VOID MAIN()
{
PORT_B_PULLUPS(TRUE);
WPUB=255;
KBD_INIT();
SET_TRIS_C(0B00000000);
CONT=0;
PORTC=( display [CONT]);
WHILE (TRUE)
{
K=KBD_GETC();
IF(K=='0')
{
CONT=0;
PORTC=( display [CONT]);
}
IF(K=='1')
{
CONT=1;
PORTC=( display [CONT]);
}
IF(K=='2')
{
CONT=2;
PORTC=( display [CONT]);
}
IF(K=='3')
{
CONT=3;
PORTC=( display [CONT]);
}
IF(K=='4')
{
CONT=4;
PORTC=( display [CONT]);
}
IF(K=='5')
{
CONT=5;
PORTC=( display [CONT]);
}
IF(K=='6')
{
CONT=6;
PORTC=( display [CONT]);
}
IF(K=='7')
45
CONT=7;
PORTC=( display [CONT]);
}
IF(K=='8')
{
CONT=8;
PORTC=( display [CONT]);
}
IF(K=='9')
{
CONT=9;
PORTC=( display [CONT]);
}
IF(K=='#')
{
WHILE(CONT>0)
{
DELAY_MS(1000);
CONT--;
PORTC=( display [CONT]);
}
}
}
}
46
16
Existe en el compilador un driver para manejar un display de cristal lquido de 2 lneas por 16
caracteres cada una.
El procedimiento para trabajar con el LCD es parecido al procedimiento del teclado telefnico.
La conexin entre el LCD y el microcontrolador es la siguiente:
47
(16,
(1,
Mostrar un mensaje fijo en el LCD que en la primera fila GUIA EN PIC C y en la segunda
EAFIT.
#INCLUDE <16F886.H>
#USE DELAY(CLOCK=4000000)
#DEFINE USE_PORTB_LCD TRUE
#INCLUDE <LCD.C>
#FUSES XT,NOPROTECT,NOWDT,NOBROWNOUT,PUT,NOLVP,WRT
#BYTE PORTB= 6
VOID MAIN()
{
SET_TRIS_B(0);
PORTB=0;
LCD_INIT();
LCD_PUTC("\f");
WHILE(TRUE)
{
LCD_GOTOXY(1,1);
LCD_PUTC(" GUIA EN PIC C
LCD_GOTOXY(1,2);
");
// En la fila 1
// Muestre el mensaje GUIA EN
// PIC C
// Ubicarse en la columna 1 fila 2
48
LCD_PUTC("
EAFIT
");
}
Ejemplo 16.2 LCD.
Mostrar el mensaje BIENVENIDOS en la primera lnea del LCD, que se vaya desplazando y
luego el mensaje fijo SELECCIONE MENU en la segunda lnea.
49
#INCLUDE <16F886.h>
#USE
DELAY(CLOCK=4000000)
#FUSES XT,NOPROTECT,NOWDT,NOBROWNOUT,NOPUT,NOLVP
#DEFINE USE_PORTB_LCD TRUE
#INCLUDE <LCD.C>
#BYTE
PORTC= 7
BYTE J;
VOID MAIN()
{
SET_TRIS_C(0B11111111);
LCD_INIT();
J=16;
WHILE (J>0)
{
LCD_PUTC("\f");
LCD_GOTOXY(J,1);
LCD_PUTC(" BIENVENIDOS ");
DELAY_MS(150);
J--;
}
WHILE(1)
{
LCD_GOTOXY(J,2);
LCD_PUTC("SELECCIONE MENU:");
}
}
50
Mostrar en el LCD los nmeros digitados por el teclado telefnico, hasta completar 16 nmeros.
#INCLUDE <16F886.h>
#USE DELAY(CLOCK=4000000)
#FUSES XT,NOPROTECT,NOWDT,NOBROWNOUT,NOPUT,NOLVP
#DEFINE USE_PORTB_LCD TRUE
#DEFINE USE_PORTB_KBD
// Por defecto el teclado se conecta al puerto D,
// como el microcontrolador que se esta usando
// no tiene puerto D se conecta al puerto B.*/
#INCLUDE <LCD.C>
#INCLUDE <KBD.C>
// Incluir en el encabezado el driver para
// manejar el teclado telefnico:*/
#BYTE PORTC= 7
#DEFINE INC PORTC,0
#DEFINE DEC PORTC,1
#DEFINE START PORTC,2
CHAR K;
INT DIR;
VOID MAIN()
{
port_b_pullups(TRUE);
SET_TRIS_C(255);
LCD_INIT();
KBD_INIT();
LCD_PUTC("\f");
WHILE(TRUE)
{
DIR=0;
LCD_PUTC("\f");
while (DIR<17)
{
k=kbd_getc();
WHILE( (k=='\0'))
{
k=kbd_getc();
}
if( (k!='*')&&(k!='#'))
{
lcd_putc(k);
DIR++;
}
}
}
}
51
52
k=kbd_getc();
WHILE(k=='\0')
{
k=kbd_getc();
}
IF( (k!='\0'))
{
IF(K=='0')
VAL=0;
IF(K=='1')
VAL=1;
IF(K=='2')
VAL=2;
IF(K=='3')
VAL=3;
IF(K=='4')
VAL=4;
IF(K=='5')
VAL=5;
IF(K=='6')
VAL=6;
IF(K=='7')
VAL=7;
IF(K=='8')
VAL=8;
IF(K=='9')
VAL=9;
}
}
VOID MAIN()
{
PORT_B_PULLUPS(TRUE);
WPUB=255;
SET_TRIS_C(0B00000000);
KBD_INIT();
// Si K es igual a cero
// Val es igual a cero
LCD_INIT();
PORTC=0;
WHILE(TRUE)
{
LCD_GOTOXY(1,1);
LCD_PUTC(" BIENVENIDOS ");
LCD_GOTOXY(1,2);
LCD_PUTC(" DIGITE CLAVE ");
DELAY_MS(1000);
TECLADO();
LCD_PUTC("\f");
LCD_GOTOXY(1,1);
IF((k!='#')&&(k!='*'))
{
lcd_putc('*');
53
UNI=VAL;
}
TECLADO();
IF((k!='#')&&(k!='*'))
{
lcd_putc('*');
DEC=VAL;
}
TECLADO();
IF((k!='#')&&(k!='*'))
{
lcd_putc('*');
CEN=VAL;
}
TECLADO();
IF((k!='#')&&(k!='*'))
{
lcd_putc('*');
MIL=VAL;
}
TECLADO();
WHILE((k!='#'))
{
TECLADO();
}
IF((UNI==1)&&(DEC==2)&&(CEN==3)&&(MIL==4)) // Aqu se compara si
// los nmeros digitados
// estn correctos.*/
{
LCD_PUTC("\f");
// Se borra LCD
LCD_GOTOXY(1,1);
// Se ubica en la posicin 1,1
LCD_PUTC(" CLAVE CORRECTA ");
BIT_SET(LED1);
DELAY_MS(2000);
BIT_CLEAR(LED1);
}
ELSE
{
LCD_PUTC("\f");
LCD_GOTOXY(1,2);
LCD_PUTC(" CLAVE INVALIDA ");
BIT_SET(LED2);
DELAY_MS(4000);
BIT_CLEAR(LED2);
}
}
}
54
17
#INCLUDE <16F886.H>
#FUSES
XT,NOPROTECT,NOWDT,NOBROWNOUT,PUT,NOLVP,WRT
#USE
DELAY(CLOCK=4000000)
#BYTE
PORTC= 7
55
#BYTE
PORTB= 6
INT CONT,DIRECCION,CONT2;
VOID MAIN()
{
SET_TRIS_C(0B11111111);
// Configura el puerto C como entrada
SET_TRIS_B(0);
// Configura el puerto B como salida
PORTB=0;
// Poner el puerto B en 0
CONT=0;
// Poner la variable CONT en cero
DIRECCION=0;
// Poner la variable DIRECCION en cero
CONT2=2;
// Poner la variable CONT2 en dos
WHILE (TRUE)
// LOOP INFINITO
{
IF(BIT_TEST(PORTC,3))
// Si el bit 3 del puerto C esta en 1
{
CONT=0;
// Poner la variable CONT en cero
DIRECCION=0;
// Poner la variable DIRECCION en cero
}
IF(BIT_TEST(PORTC,0)&&(CONT<15))
// Si RC0=1 y la variable CONT es
//menor que 15
{
WRITE_EEPROM(DIRECCION,CONT); // Escribir en eeprom el valor de CONT
DELAY_MS(500);
// Retardo de 500 milisegundos
CONT++;
// Incrementa la variable CONT
DIRECCION++;
// Incrementa la variable DIRECCION
PORTB=CONT;
// Lo que hay en CONT llvelo al puerto B
}
IF(BIT_TEST(PORTC,2)&&(CONT<15))
// Si RC2=1 y la variable CONT es menor que
15
{
WRITE_EEPROM(DIRECCION,CONT2);
DELAY_MS(500);
// Retardo de 500 milisegundos
CONT2=CONT2+2;
// Incrementa en dos la variable CONT2
CONT++;
// Incrementa la variable CONT
DIRECCION++;
// Incrementa la variable DIRECCION
PORTB=CONT2;
// Lo que hay en CONT2 llvelo al puerto B
}
IF(BIT_TEST(PORTC,1)&&(CONT<15))
// Si RC1=1 y la variable CONT es menor que
15
{
CONT=0;
// Poner la variable CONT en cero
DIRECCION=0;
// Poner la variable DIRECCION en cero
WHILE(CONT<15)
// Mientras que CONT sea menor a 15
{
PORTB=READ_EEPROM(DIRECCION);
DELAY_MS(500);
// Retardo de 500 milisegundos
CONT++;
// Incrementa la variable CONT
DIRECCION++;
// Incrementa la variable DIRECCION
}
}
}
}
56
18
Como se tiene limitaciones para almacenar informacin en la memoria eeprom interna, hay
memorias eeprom seriales externas con diferente capacidad que permiten almacenar mayor
informacin. En el compilador hay drivers que permiten manejar diferentes memorias eeprom
externas seriales entre ellos la 2402.
La conexin de la memoria eeprom externa es la siguiente:
Los pasos que se deben seguir para almacenar datos en memoria eeprom externa son:
1. En el encabezado del programa incluir el driver para manejar la memoria eeprom
externa (en el ejemplo se trabaja con la 24LC02)
#INCLUDE<2402.C>
2. En el programa principal inicializar la memoria
INIT_EXT_EEPROM();
3. Para escribir en la memoria se utiliza la instruccin
WRITE_EXT_EEPROM(Direccin, Valor)
Direccin: esta limitada por la capacidad de la memoria eeprom externa.
Valor: es un byte.
Esta funcin puede durar varios milisegundos.
Para leer el contenido de la memoria eeprom externa se utiliza la siguiente instruccin:
K=READ_EXT_EEPROM(Direccin)
Ejemplo 18.1 Memoria eeprom externa
Con un teclado telefnico, un LCD y una memoria eeprom externa digitar 4 nmeros y luego
recuperarlos, en el LCD mostrar el valor digitado y el valor recuperado.
57
#INCLUDE<16F886.H>
#USE DELAY(CLOCK=4000000)
#DEFINE USE_PORTB_KBD
#FUSES XT,NOPROTECT,NOWDT,NOBROWNOUT,PUT,NOLVP,WRT
#DEFINE USE_PORTB_LCD TRUE
#INCLUDE <LCD.C>
#INCLUDE <KBD.C>
#INCLUDE <2402.C>
INT K;
// Defino la variable K como carcter
BYTE J=16,DIR;
VOID MAIN()
{
PORT_B_PULLUPS(TRUE);
LCD_INIT();
KBD_INIT();
INIT_EXT_EEPROM();
FOR (J=12; J>=2; --J)
{
LCD_GOTOXY(J,1);
(LCD_PUTC("DIGITADO:
DELAY_MS(100);
"));
// Retardo de 100 milisegundos
// LCD_PUTC("\F");
}
LCD_GOTOXY(12,1);
DIR=0;
WHILE (DIR<4)
58
{
K=0;
K=KBD_GETC();
IF( (K!='\0'))
{
LCD_PUTC(K);
WRITE_EXT_EEPROM(DIR,K);
DIR++;
}
}
DELAY_MS(500);
FOR (J=12; J>=2; --J)
{
LCD_GOTOXY(J,2);
(LCD_PUTC("RECUPERADO: "));
DELAY_MS(100);
}
LCD_GOTOXY(13,2);
DIR=0;
WHILE (DIR<4)
{
K=READ_EXT_EEPROM(DIR);
LCD_PUTC(K);
DIR++;
}
59
19
resolucin =
(VREF GND )
1024
As, por ejemplo, si VREF = +5V y VREF- es 0V, la resolucin es 5V/1024 = 4.8mV, cuando la
seal anloga sea 0V le corresponde un nmero digital = 0000000000 y para 5V ser
1111111111.
Si VREF+ = +5V y VREF- se puede determinar en todo momento a que nmero digital aproximado
corresponde cualquier seal anloga de entrada, con la frmula:
V Entrada
V
= Entrada
4.8mV 0.0048V
Por ejemplo si la seal anloga es 2V, el nmero digital aproximado, es:
2V =
416
0.0048
60
Mostrar en el LCD el valor numrico correspondiente a la seal anloga que entra por RA0.
#INCLUDE <16F886.H>
#DEVICE ADC=10
// Define que el conversor trabaja a 10 bits
#USE
DELAY(CLOCK=4000000)
#FUSES XT,NOPROTECT,NOWDT,NOBROWNOUT,PUT,NOLVP
#BYTE
PORTA=5
#DEFINE USE_PORTB_LCD TRUE
#INCLUDE <LCD.C>
LONG VOLTAJE;
// Definir la variable voltaje como una
// Variable tipo long
61
VOID MAIN()
{
SET_TRIS_A(0B11111111);
SETUP_ADC_PORTS(SAN0);
LCD_PUTC("\F");
LCD_GOTOXY(1,1);
LCD_PUTC("CONVERSOR A/D");
LCD_GOTOXY(1,2);
PRINTF(LCD_PUTC,"VALOR %LU",VOLTAJE);// Muestra el valor numrico de la
// Conversin.
DELAY_MS(200);
}
}
62
20
COMUNICACIN SERIAL
Existen dos formas comunes de transferir informacin binaria entre dos equipos, la
comunicacin paralela y la comunicacin serial.
estudia
la
63
64
65
#INCLUDE <16F886.H>
#USE DELAY(CLOCK=4000000)
#USE RS232(BAUD=9600, XMIT=PIN_C6, RCV=PIN_C7)
#DEFINE USE_PORTB_LCD TRUE
#INCLUDE <LCD.C>
#FUSES XT,NOPROTECT,NOWDT,NOBROWNOUT,PUT,NOLVP,WRT
#BYTE PORTB= 6
#BYTE PORTC= 7
VOID MAIN()
{
CHAR K;
LCD_INIT();
LCD_PUTC("\DIGITE EL TEXTO?\N");
WHILE (TRUE)
{
K=GETC();
LCD_PUTC(K);
}
}
66
BIBLIOGRAFA
PIC:
Diseo
Prctico
de
PIC:
Diseo
Prctico
de
PIC C [en lnea]. Reno, NV (USA): SCM International, Inc [citado en 2008-10-01]. Disponible en
Internet: <http://scmstore.com/micros/PICC/>
67
ANEXOS
PIC C COMPILER
El PicC C Compiler fue desarrollado para cumplir con las especificaciones del lenguaje ANSI C.
El compilador produce tres tipos de archivos. Archivos con extensin .hex que le permitir grabar
el programa ejecutable en el PIC por medio del uso de un programador. El archivo con extensin
.asm contendr un listado en assembler del programa compilado con la informacin del mapeo
de memoria. Estos archivos son muy tiles para el debugging de los programas y para
determinar la cantidad de pasos de programas (ciclos de ejecucin) tiene la aplicacin. Los
archivos con extensin .pre contienen la informacin preprocesada del programa, #defines,
#includes, etc. La cual es expandida y guardada en el archivo.
Es el producto ideal para aquellas personas que le gusta desarrollar en bajo nivel con los
recursos de un lenguaje de alto nivel como el C. Se recomienda ser utilizado por personas
vinculadas con la programacin y sintaxis de C.
Beneficios
68
Los iconos de guardar, abrir, nuevo, funcionan igual que en archivo de Microsoft, se
encuentran en el men del PIC C
Los iconos nuevos y ms utilizados son:
1. File New.
2. Se guarda el archivo
3. Sale una hoja con el nombre que se le puso
4. Se escribe el programa
69
6. Si sale un error en la programacin, el programa no muestra el cuadro anterior sino que saca
un aviso en rojo que dice el tipo de problema y en donde se encuentra el error (este lo muestra
subrayando la palabra posterior).
En este ejemplo lo que falt fue el corchete que cierra la instruccin anterior.
Nota: Los errores ms comunes son: corchetes, punto y coma, palabras mal escritas, etc.
7. Al compilar se debe tener mucho cuidado con el archivo que se esta compilando, porque
cuando hay varios abiertos el programa no sabe cual compilar.
Ejemplo A.2 Pic C Compiler.
Se realiz otro ejercicio, llamado ejercicio1 y se compila. Sin embargo, si no se tiene en cuenta lo
anterior, el programa esta compilando otro ejercicio.
70
Nota: Para que se compile el que debe ser, se debe cerrar los otros archivos.
8. Para saber que archivo es el que se quiere cerrar o el que se esta utilizando, slo se debe
observar que pestaa es la que sobresale.
Nota: La que sobresale es el archivo que esta activo.
71
CONTENIDO
INTRODUCCIN
1
CONCEPTOS BSICOS
1.1
SISTEMAS DE NUMERACIN DECIMAL (BASE 10)
1.2
SISTEMA DE NUMERACION BINARIO (BASE 2)
1.3
SISTEMA HEXADECIMAL (BASE 16)
1.4
CONVERSION DE BINARIO A DECIMAL
1.5
CONVERSION DE DECIMAL A BINARIO
1.6
CONVERSION DE HEXADECIMAL A DECIMAL
1.7
CONVERSION DE BINARIO A HEXADECIMAL
1.8
CONVERSION DE HEXADECIMAL A BINARIO
1.9
DECIMAL CODIFICADO EN BINARIO: (BCD)
1.10
REPRESENTACIN DE LOS NMEROS DE 0 A 15
1
2
2
2
3
3
3
3
4
4
4
4
2
2.1
2.2
2.3
2.4
2.5
MEMORIAS
MEMORIA RAM
MEMORIA ROM
MEMORIA EPROM
MEMORIA EEPROM
MEMORIA FLASH
5
5
5
5
5
5
3.1
3.2
3.3
INTRODUCCIN AL MICROCONTROLADOR
ORGANIZACIN DE LA MEMORIA DE DATOS RAM
DESCRIPCION DE LOS PINES
CONFIGURACION DE LOS PUERTOS
6
6
6
8
LENGUAJE DE PROGRAMACION EN C
ESTRUCTURAS DE CONTROL EN C
La estructura de control condicional if
Clusula else
Seleccin mltiple con la sentencia switch
ESTRUCTURAS DE CONTROL REPETITIVAS
Bucle while
Bucle for
Equivalencia entre For y While
Bucles infinitos
10
10
10
11
11
12
12
12
13
13
OPERADORES
OPERADORES ARITMETICOS
OPERADORES RELACIONES
OPERADORES LGICOS
OPERADORES DE INCREMENTO Y DECREMENTO
14
14
14
14
14
ENCABEZADO DE UN PROGRAMA
15
INSTRUCCIONES BASICAS
16
INSTRUCCIONES DE ROTACION
21
9
9.1
23
23
10
27
11
29
12
MULTIPLEXAJE DE DISPLAY
32
13
INTERRUPCIONES
36
14
TIMER
38
15
42
4.1
4.2
5
5.1
5.2
5.3
5.4
72
47
47
17
55
18
57
19
60
20
COMUNICACIN SERIAL
20.1
COMUNICACIN SINCRNICA:
20.2
COMUNICACIN ASINCRNICA
63
63
63
BIBLIOGRAFA
67
ANEXOS
68
73
Elaborado por:
Hugo Alberto Murillo Hoyos
Ana Cristina Tamayo
74